Partager via


FLT_CREATEFILE_TARGET_ECP_CONTEXT structure (fltkernel.h)

La structure FLT_CREATEFILE_TARGET_ECP_CONTEXT est un paramètre de création supplémentaire (ECP) utilisé pour renvoyer les informations cibles d’analyse à l’appelant de FltCreateFileEx2.

Syntaxe

typedef struct _FLT_CREATEFILE_TARGET_ECP_CONTEXT {
  PFLT_INSTANCE               Instance;
  PFLT_VOLUME                 Volume;
  PFLT_FILE_NAME_INFORMATION  FileNameInformation;
  FLT_CREATEFILE_TARGET_FLAGS Flags;
} FLT_CREATEFILE_TARGET_ECP_CONTEXT, *PFLT_CREATEFILE_TARGET_ECP_CONTEXT;

Membres

Instance

Le filtre instance attaché à la cible ajustée.

Volume

Volume cible ajusté.

FileNameInformation

Informations de fichier pour la cible ajustée.

Flags

Indicateurs contrôlant l’opération d’analyse. Cette valeur peut être 0 ou suivante.

Valeur Signification
FLTTCFL_AUTO_REPARSE
Demandez à fltCreateFileEx2 de tenter une opération d’analyse lorsqu’une cible est introuvable avec les informations du fichier d’origine.

Remarques

Lorsqu’un appelant de FltCreateFileEx2 souhaite activer l’analyse pour une cible de volume, un FLT_CREATEFILE_TARGET_ECP_CONTEXT peut être inclus en tant qu’ECP dans la liste ECP dans le paramètre DriverContext . Si cet ECP est présent, FltCreateFileEx2 ajuste l’appareil cible pour l’opération de création et tente de trouver un instance filtré d’un volume approprié pour les informations de fichier données. Si le gestionnaire de filtres ne trouve pas de instance correspondant pour l’appelant sur le volume cible, il définit les membres Volume et FileNameInformation de FLT_CREATEFILE_TARGET_ECP_CONTEXT pour la nouvelle cible. L’appelant peut ensuite utiliser ces informations pour décider de la meilleure façon de procéder.

Si l’appelant de FltCreateFileEx2 a l’intention de gérer l’opération d’analyse elle-même, l’indicateur FLTTCFL_AUTO_REPARSE est effacé du membre Flags . Dans ce cas, FltCreateFileEx2 place les informations d’ajustement cible initiales dans l’ECP, puis retourne, mettant fin à la tentative de création de fichier.

Si les valeurs dans Instance, Volume ou FileNameInformation sont définies dans un ECP reconnu, il s’agit d’objets référencés. Un appelant de FltCreateFileEx2 est chargé d’appeler FltObjectDereference pour Instance et Volume, et FltReleaseFileNameInformation pour FileNameInformation.

L’exemple de routine suivant montre comment un minifiltre peut appeler FltCreateFileEx2 avec FLT_CREATEFILE_TARGET_ECP_CONTEXT pour gérer une analyse sur un autre volume si nécessaire pour trouver une cible de fichier.

NTSTATUS
CrossVolumeCreate(
    _In_ PUNICODE_STRING FileName,
    _In_ PFLT_FILTER Filter,
    _In_ PFLT_INSTANCE Instance,
    _Inout_ PIO_STATUS_BLOCK IoStatus,
    _Out_ PHANDLE Handle,
    _Outptr_ PFILE_OBJECT *FileObject
    )
/*++

Routine Description:

     Issues a targeted create and handles cross volume reparse.

Arguments:

    FileName - The name of the file to open

    Filter – The filter issuing the create

    Instance - The filter instance for the targeted create

    IoStatus - Receives the operation status

    Handle - Receives the file handle

    FileObject - Receives the file object

Return Value:

    status of the operation

--*/
{
    PFLT_CREATEFILE_TARGET_ECP_CONTEXT ecpContext;
    PECP_LIST ecpList;
    PFLT_FILE_NAME_INFORMATION fileNameInformation;
    IO_DRIVER_CREATE_CONTEXT myCreateContext;
    OBJECT_ATTRIBUTES objAttr;
    NTSTATUS status;

    ecpContext = NULL;
    ecpList = NULL;
    fileNameInformation = NULL;
    status = STATUS_SUCCESS;

    InitializeObjectAttributes( &objAttr,
                                FileName,
                                OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL );

    //
    //  First we optimistically send a targeted create that is not
    //  setup to handle cross-volume reparse.
    //

    status = FltCreateFileEx2( Filter,
                               Instance,
                               Handle,
                               FileObject,
                               FILE_READ_DATA|FILE_WRITE_DATA,
                               &objAttr,
                               IoStatus,
                               NULL,
                               0,
                               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                               FILE_OPEN_IF,
                               FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                               NULL,
                               0,
                               IO_IGNORE_SHARE_ACCESS_CHECK,
                               NULL );

    if (!NT_SUCCESS(status)) {

        if ((status != STATUS_INVALID_DEVICE_OBJECT_PARAMETER) &&
            (status != STATUS_MOUNT_POINT_NOT_RESOLVED)) {

            goto CrossVolumeCreateExit;
        }

    } else {

        //
        //  The create succeeded. There must not have been a cross-volume
        //  reparse.
        //

        goto CrossVolumeCreateExit;
    }

    //
    //  The create failed traversing a cross-volume link.
    //  Issue another create with a targeting ECP so that
    //  we can handle cross-volume reparse.
    //

    status = FltAllocateExtraCreateParameterList( Filter,
                                                  0,
                                                  &ecpList );
    if (!NT_SUCCESS( status )) {
        goto CrossVolumeCreateExit;
    }

    status = FltAllocateExtraCreateParameter( Filter,
                                              &GUID_ECP_FLT_CREATEFILE_TARGET,
                                              sizeof(FLT_CREATEFILE_TARGET_ECP_CONTEXT),
                                              0,
                                              NULL,
                                              POOL_TAG,
                                              &ecpContext );

    if (!NT_SUCCESS( status )) {
        goto CrossVolumeCreateExit;
    }

    //
    //  Initialize the ECP with the FLTTCFL_AUTO_REPARSE flag which
    //  tells filter manager to handle the cross-volume reparse
    //  internally when possible (when it can find our instance
    //  on the target volume). If this flag is not set, the filter will
    //  be responsible for calling FltCreateFileEx2 with appropriate
    //  Instance parameter.
    //

    ecpContext->Flags = FLTTCFL_AUTO_REPARSE;

    ecpContext->Instance = NULL;
    ecpContext->Volume = NULL;
    ecpContext->FileNameInformation = NULL;

    status = FltInsertExtraCreateParameter( Filter,
                                            ecpList,
                                            ecpContext );
    if (!NT_SUCCESS( status )) {
        goto CrossVolumeCreateExit;
    }

    IoInitializeDriverCreateContext( &myCreateContext );
    myCreateContext.ExtraCreateParameter = ecpList;

    InitializeObjectAttributes( &objAttr,
                                FileName,
                                OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL );

    status = FltCreateFileEx2( Filter,
                               Instance,
                               Handle,
                               FileObject,
                               FILE_READ_DATA|FILE_WRITE_DATA,
                               &objAttr,
                               IoStatus,
                               NULL,
                               0,
                               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                               FILE_OPEN_IF,
                               FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                               NULL,
                               0,
                               IO_IGNORE_SHARE_ACCESS_CHECK,
                               &myCreateContext );

    if (!NT_SUCCESS(status)) {

        if ((status != STATUS_INVALID_DEVICE_OBJECT_PARAMETER) &&
            (status != STATUS_MOUNT_POINT_NOT_RESOLVED)) {

            goto CrossVolumeCreateExit;
        }

    } else {

        goto CrossVolumeCreateExit;
    }

    //
    //  Filter manager should have acknowledged the ECP. If it
    //  is not acknowledged, it does not contain any cross-volume
    //  targeting information.
    //

    if (!FltIsEcpAcknowledged( Filter, ecpContext)) { 
        goto CrossVolumeCreateExit;
    }

    //
    //  Filter manager could not automatically handle the
    //  cross-volume traversal. We choose to send the create
    //  to the top of the stack on the target volume indicated
    //  in the targeting ECP.
    //

    //
    //  The ECP may contain pointers to referenced objects. We
    //  need to deal with those references before reusing the
    //  ECP.
    //

    if (ecpContext->Volume != NULL) {
        FltObjectDereference( ecpContext->Volume );
        ecpContext->Volume = NULL;
    }

    //
    //  Note:  since we flagged the ECP to automatically handle
    //  cross-volume reparse, the create should have failed after
    //  we traversed a mountpoint only if our filter did not have
    //  an instance on the target volume. In that case we would
    //  expect the Instance field in the ECP to be NULL. We still
    //  demonstrate derefing the instance for the general case.
    //

    if (ecpContext->Instance != NULL) {
        FltObjectDereference( ecpContext->Instance );
        ecpContext->Instance = NULL;
    }

    fileNameInformation = ecpContext->FileNameInformation;
    ecpContext->FileNameInformation = NULL;

    //
    //  Tell filter manager to not handle the cross-volume
    //  reparse itself. Presumably a filter would do this if it
    //  did not want the create automatically targeted at its
    //  instance on another volume.
    //

    ecpContext->Flags = 0;

    //
    //  Reinitialize the targeting ECP to it can be reused.
    //

    FltPrepareToReuseEcp( Filter, ecpContext );

    IoInitializeDriverCreateContext( &myCreateContext );
    myCreateContext.ExtraCreateParameter = ecpList;

    InitializeObjectAttributes( &objAttr,
                                &fileNameInformation->Name,
                                OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL );

    status = FltCreateFileEx2( Filter,
                               NULL,
                               Handle,
                               FileObject,
                               FILE_READ_DATA|FILE_WRITE_DATA,
                               &objAttr,
                               IoStatus,
                               NULL,
                               0,
                               FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                               FILE_OPEN_IF,
                               FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                               NULL,
                               0,
                               IO_IGNORE_SHARE_ACCESS_CHECK,
                               &myCreateContext );

    if (!NT_SUCCESS(status)) {

        if ((status != STATUS_INVALID_DEVICE_OBJECT_PARAMETER) &&
            (status != STATUS_MOUNT_POINT_NOT_RESOLVED)) {

            goto CrossVolumeCreateExit;
        }

        //
        //  We hit another cross-volume link. For the purposes of
        //  this example we are just giving up. An actual filter
        //  would determine the next target instance based on the
        //  information provided in the targeting ECP. Some of the
        //  possibilities are:
        //  1) If the Instance field in the ECP is available, target
        //     the create to this instance.
        //  2) If the Instance field is NULL, attempt to attach
        //     an instance based on the Volume parameter in the ECP
        //     and then target that new instance.
        //  3) Use the FileNameInformation provided in the ECP and a
        //     NULL instance to target the top of the other
        //     volume's stack.
        //

    } else {

        goto CrossVolumeCreateExit;
    }

CrossVolumeCreateExit:

    if (ecpContext != NULL && 
        FltIsEcpAcknowledged( Filter, ecpContext)) {

        FltRemoveExtraCreateParameter( Filter,
                                       ecpList,
                                       &GUID_ECP_FLT_CREATEFILE_TARGET,
                                       &ecpContext,
                                       NULL );

        if (ecpContext->Instance != NULL) {
            FltObjectDereference( ecpContext->Instance );
        }

        if (ecpContext->Volume != NULL) {
            FltObjectDereference( ecpContext->Volume );
        }

        if (ecpContext->FileNameInformation != NULL) {
            FltReleaseFileNameInformation( ecpContext->FileNameInformation );
        }

        FltFreeExtraCreateParameter( Filter, ecpContext );
    }

    if (ecpList != NULL) {
        FltFreeExtraCreateParameterList( Filter, ecpList );
    }

    if (fileNameInformation != NULL) {
        FltReleaseFileNameInformation( fileNameInformation );
    }

    return status;
}

Configuration requise

Condition requise Valeur
Client minimal pris en charge Cette structure est disponible à partir de Windows 8.
En-tête fltkernel.h (incluez FltKernel.h)

Voir aussi

FltCreateFileEx2

FltObjectDereference

FltReleaseFileNameInformation