Freigeben über


FLT_CREATEFILE_TARGET_ECP_CONTEXT-Struktur (fltkernel.h)

Die FLT_CREATEFILE_TARGET_ECP_CONTEXT-Struktur ist ein zusätzlicher Create-Parameter (ECP), der verwendet wird, um Analysezielinformationen an den Aufrufer von FltCreateFileEx2 zurückzugeben.

Syntax

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;

Member

Instance

Der Filter instance an das angepasste Ziel angefügt.

Volume

Die angepasste Ziellautstärke.

FileNameInformation

Die Dateiinformationen für das angepasste Ziel.

Flags

Flags, die den Analysevorgang steuern. Dieser Wert kann entweder 0 oder der folgende sein.

Wert Bedeutung
FLTTCFL_AUTO_REPARSE
Fordern Sie an, dass FltCreateFileEx2 versucht, einen Analysevorgang durchzuführen, wenn ein Ziel nicht mit den ursprünglichen Dateiinformationen gefunden wird.

Hinweise

Wenn ein Aufrufer von FltCreateFileEx2 die Analyse für ein Volumeziel aktivieren möchte, kann ein FLT_CREATEFILE_TARGET_ECP_CONTEXT als ECP in die ECP-Liste im DriverContext-Parameter eingeschlossen werden. Wenn dieses ECP vorhanden ist, passt FltCreateFileEx2 das Zielgerät für den Erstellungsvorgang an und versucht, eine gefilterte instance eines Volumes zu finden, das für die angegebenen Dateiinformationen geeignet ist. Wenn der Filter-Manager keine entsprechende instance für den Aufrufer auf dem Zielvolume findet, legt er die Member Volume und FileNameInformation von FLT_CREATEFILE_TARGET_ECP_CONTEXT für das neue Ziel fest. Der Aufrufer kann dann anhand dieser Informationen entscheiden, wie er am besten fortfahren möchte.

Wenn der Aufrufer von FltCreateFileEx2 beabsichtigt, den Analysevorgang selbst zu verarbeiten, wird das flag FLTTCFL_AUTO_REPARSE aus dem Flags-Element gelöscht. In diesem Fall platziert FltCreateFileEx2 die anfänglichen Zielanpassungsinformationen im ECP und gibt dann zurück, was den Versuch zum Erstellen der Datei beendet.

Wenn die Werte in Instance, Volume oder FileNameInformation in einem bestätigten ECP festgelegt sind, handelt es sich um Objekte, auf die verwiesen wird. Ein Aufrufer von FltCreateFileEx2 ist für den Aufruf von FltObjectDereference für Instance und Volume und FltReleaseFileNameInformation für FileNameInformation verantwortlich.

Die folgende Beispielroutine veranschaulicht, wie ein Minifilter FltCreateFileEx2 mit FLT_CREATEFILE_TARGET_ECP_CONTEXT aufrufen kann, um eine Analyse für ein anderes Volume zu verarbeiten, wenn dies für die Suche nach einem Dateiziel erforderlich ist.

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;
}

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Diese Struktur ist ab Windows 8 verfügbar.
Kopfzeile fltkernel.h (fltKernel.h einschließen)

Weitere Informationen

FltCreateFileEx2

FltObjectDereference

FltReleaseFileNameInformation