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

📄 create.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
        //  in the Path Table.
        //

        if (FlagOn( FileContext.InitialDirent->Dirent.Flags, CD_ATTRIBUTE_DIRECTORY )) {

            CdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR );
        }

        //
        //  Make sure our opener didn't want a directory.
        //

        if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) ||
            FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) {

            try_return( Status = STATUS_NOT_A_DIRECTORY );
        }

        //
        //  The only create disposition we allow is OPEN.
        //

        if ((CreateDisposition != FILE_OPEN) &&
            (CreateDisposition != FILE_OPEN_IF)) {

            try_return( Status = STATUS_ACCESS_DENIED );
        }

        //
        //  If this is an ignore case open then copy the exact case
        //  in the file object name.  Any version portion should
        //  already be upcased.
        //

        if (IgnoreCase) {

            RtlCopyMemory( FinalName.FileName.Buffer,
                           MatchingName->FileName.Buffer,
                           MatchingName->FileName.Length );
        }

        //
        //  Open the file using the file context.  We already have the
        //  first and last dirents.
        //

        try_return( Status = CdOpenFileFromFileContext( IrpContext,
                                                        IrpSp,
                                                        Vcb,
                                                        &CurrentFcb,
                                                        &FinalName,
                                                        IgnoreCase,
                                                        (BOOLEAN) (MatchingName == &FileContext.ShortName),
                                                        &FileContext,
                                                        RelatedCcb ));

    try_exit:  NOTHING;
    } finally {

        //
        //  Cleanup the PathEntry if initialized.
        //

        if (CleanupCompoundPathEntry) {

            CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry );
        }

        //
        //  Cleanup the FileContext if initialized.
        //

        if (CleanupFileContext) {

            CdCleanupFileContext( IrpContext, &FileContext );
        }

        //
        //  The result of this open could be success, pending or some error
        //  condition.
        //

        if (AbnormalTermination()) {


            //
            //  In the error path we start by calling our teardown routine if we
            //  have a CurrentFcb.
            //

            if (CurrentFcb != NULL) {

                BOOLEAN RemovedFcb;

                CdTeardownStructures( IrpContext, CurrentFcb, &RemovedFcb );

                if (RemovedFcb) {

                    CurrentFcb = NULL;
                }
            }

            //
            //  No need to complete the request.
            //

            IrpContext = NULL;
            Irp = NULL;

        //
        //  If we posted this request through the oplock package we need
        //  to show that there is no reason to complete the request.
        //

        } else if (Status == STATUS_PENDING) {

            IrpContext = NULL;
            Irp = NULL;
        }

        //
        //  Release the Current Fcb if still acquired.
        //

        if (CurrentFcb != NULL) {

            CdReleaseFcb( IrpContext, CurrentFcb );
        }

        //
        //  Release the Vcb.
        //

        CdReleaseVcb( IrpContext, Vcb );

        //
        //  Call our completion routine.  It will handle the case where either
        //  the Irp and/or IrpContext are gone.
        //

        CdCompleteRequest( IrpContext, Irp, Status );
    }

    return Status;
}


//
//  Local support routine
//

NTSTATUS
CdNormalizeFileNames (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN BOOLEAN OpenByFileId,
    IN BOOLEAN IgnoreCase,
    IN TYPE_OF_OPEN RelatedTypeOfOpen,
    IN PCCB RelatedCcb OPTIONAL,
    IN PUNICODE_STRING RelatedFileName OPTIONAL,
    IN OUT PUNICODE_STRING FileName,
    IN OUT PCD_NAME RemainingName
    )

/*++

Routine Description:

    This routine is called to store the full name and upcased name into the
    filename buffer.  We only upcase the portion yet to parse.  We also
    check for a trailing backslash and lead-in double backslashes.  This
    routine also verifies the mode of the related open against the name
    currently in the filename.

Arguments:

    Vcb - Vcb for this volume.

    OpenByFileId - Indicates if the filename should be a 64 bit FileId.

    IgnoreCase - Indicates if this open is a case-insensitive operation.

    RelatedTypeOfOpen - Indicates the type of the related file object.

    RelatedCcb - Ccb for the related open.  Ignored if no relative open.

    RelatedFileName - FileName buffer for related open.  Ignored if no
        relative open.

    FileName - FileName to update in this routine.  The name should
        either be a 64-bit FileId or a Unicode string.

    RemainingName - Name with the remaining portion of the name.  This
        will begin after the related name and any separator.  For a
        non-relative open we also step over the initial separator.

Return Value:

    NTSTATUS - STATUS_SUCCESS if the names are OK, appropriate error code
        otherwise.

--*/

{
    ULONG RemainingNameLength;
    ULONG RelatedNameLength = 0;
    ULONG SeparatorLength = 0;

    ULONG BufferLength;

    UNICODE_STRING NewFileName;

    PAGED_CODE();

    //
    //  If this is the first pass then we need to build the full name and
    //  check for name compatibility.
    //

    if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_FULL_NAME )) {

        //
        //  Deal with the regular file name case first.
        //

        if (!OpenByFileId) {

            //
            //  This is here because the Win32 layer can't avoid sending me double
            //  beginning backslashes.
            //
            
            if ((FileName->Length > sizeof( WCHAR )) &&
                (FileName->Buffer[1] == L'\\') &&
                (FileName->Buffer[0] == L'\\')) {

                //
                //  If there are still two beginning backslashes, the name is bogus.
                //

                if ((FileName->Length > 2 * sizeof( WCHAR )) &&
                    (FileName->Buffer[2] == L'\\')) {

                    return STATUS_OBJECT_NAME_INVALID;
                }

                //
                //  Slide the name down in the buffer.
                //

                FileName->Length -= sizeof( WCHAR );

                RtlMoveMemory( FileName->Buffer,
                               FileName->Buffer + 1,
                               FileName->Length );
            }

            //
            //  Check for a trailing backslash.  Don't strip off if only character
            //  in the full name or for relative opens where this is illegal.
            //

            if (((FileName->Length > sizeof( WCHAR)) ||
                 ((FileName->Length == sizeof( WCHAR )) && (RelatedTypeOfOpen == UserDirectoryOpen))) &&
                (FileName->Buffer[ (FileName->Length/2) - 1 ] == L'\\')) {

                SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH );
                FileName->Length -= sizeof( WCHAR );
            }

            //
            //  Remember the length we need for this portion of the name.
            //

            RemainingNameLength = FileName->Length;

            //
            //  If this is a related file object then we verify the compatibility
            //  of the name in the file object with the relative file object.
            //

            if (RelatedTypeOfOpen != UnopenedFileObject) {

                //
                //  If the filename length was zero then it must be legal.
                //  If there are characters then check with the related
                //  type of open.
                //

                if (FileName->Length != 0) {

                    //
                    //  The name length must always be zero for a volume open.
                    //

                    if (RelatedTypeOfOpen <= UserVolumeOpen) {

                        return STATUS_INVALID_PARAMETER;

                    //
                    //  The remaining name cannot begin with a backslash.
                    //

                    } else if (FileName->Buffer[0] == L'\\' ) {

                        return STATUS_INVALID_PARAMETER;

                    //
                    //  If the related file is a user file then there
                    //  is no file with this path.
                    //

                    } else if (RelatedTypeOfOpen == UserFileOpen) {

                        return STATUS_OBJECT_PATH_NOT_FOUND;
                    }
                }

                //
                //  Remember the length of the related name when building
                //  the full name.  We leave the RelatedNameLength and
                //  SeparatorLength at zero if the relative file is opened
                //  by Id.
                //

                if (!FlagOn( RelatedCcb->Flags, CCB_FLAG_OPEN_BY_ID )) {

                    //
                    //  Add a separator if the name length is non-zero
                    //  unless the relative Fcb is at the root.
                    //

                    if ((FileName->Length != 0) &&
                        (RelatedCcb->Fcb != Vcb->RootIndexFcb)) {

                        SeparatorLength = sizeof( WCHAR );
                    }

                    RelatedNameLength = RelatedFileName->Length;
                }

            //
            //  The full name is already in the filename.  It must either
            //  be length 0 or begin with a backslash.
            //

            } else if (FileName->Length != 0) {

                if (FileName->Buffer[0] != L'\\') {

                    return STATUS_INVALID_PARAMETER;
                }

                //
                //  We will want to trim the leading backslash from the
                //  remaining name we return.
                //

                RemainingNameLength -= sizeof( WCHAR );
                SeparatorLength = sizeof( WCHAR );
            }

            //
            //  Now see if the buffer is large enough to hold the full name.
            //

            BufferLength = RelatedNameLength + SeparatorLength + RemainingNameLength;

            //
            //  Check for an overflow of the maximum filename size.
            //
            
            if (BufferLength > MAXUSHORT) {

                return STATUS_INVALID_PARAMETER;
            }
            
            //
            //  Now see if we need to allocate a new buffer.
            //

            if (FileName->MaximumLength < BufferLength) {

                NewFileName.Buffer = FsRtlAllocatePoolWithTag( CdPagedPool,
                                                               BufferLength,
                                                               TAG_FILE_NAME );

                NewFileName.MaximumLength = (USHORT) BufferLength;

            } else {

                NewFileName.Buffer = FileName->Buffer;
                NewFileName.MaximumLength = FileName->MaximumLength;
            }

            //
            //  If there is a related name then we need to slide the remaining bytes up and
            //  insert the related name.  Otherwise the name is in the correct position
            //  already.
            //

            if (RelatedNameLength != 0) {

                //
                //  Store the remaining name in its correct position.
                //

                if (RemainingNameLength != 0) {

                    RtlMoveMemory( Add2Ptr( NewFileName.Buffer, RelatedNameLength + SeparatorLength, PVOID ),
                                   FileName->Buffer,
                                   RemainingNameLength );
                }

                RtlCopyMemory( NewFileName.Buffer,
                               RelatedFileName->Buffer,
                               RelatedNameLength );

                //
                //  Add the separator if needed.
                //

                if (SeparatorLength != 0) {

⌨️ 快捷键说明

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