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

📄 create.c

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

    CCB LocalCcb;
    UNICODE_STRING Lfn;
    WCHAR LfnBuffer[ FAT_CREATE_INITIAL_NAME_BUF_SIZE];

    //
    //  Get the current IRP stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatCommonCreate\n", 0 );
    DebugTrace( 0, Dbg, "Irp                       = %08lx\n", Irp );
    DebugTrace( 0, Dbg, "->Flags                   = %08lx\n", Irp->Flags );
    DebugTrace( 0, Dbg, "->FileObject              = %08lx\n", IrpSp->FileObject );
    DebugTrace( 0, Dbg, " ->RelatedFileObject      = %08lx\n", IrpSp->FileObject->RelatedFileObject );
    DebugTrace( 0, Dbg, " ->FileName               = %Z\n",    &IrpSp->FileObject->FileName );
    DebugTrace( 0, Dbg, "->AllocationSize.LowPart  = %08lx\n", Irp->Overlay.AllocationSize.LowPart );
    DebugTrace( 0, Dbg, "->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart );
    DebugTrace( 0, Dbg, "->SystemBuffer            = %08lx\n", Irp->AssociatedIrp.SystemBuffer );
    DebugTrace( 0, Dbg, "->DesiredAccess           = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
    DebugTrace( 0, Dbg, "->Options                 = %08lx\n", IrpSp->Parameters.Create.Options );
    DebugTrace( 0, Dbg, "->FileAttributes          = %04x\n",  IrpSp->Parameters.Create.FileAttributes );
    DebugTrace( 0, Dbg, "->ShareAccess             = %04x\n",  IrpSp->Parameters.Create.ShareAccess );
    DebugTrace( 0, Dbg, "->EaLength                = %08lx\n", IrpSp->Parameters.Create.EaLength );

    //
    //  This is here because the Win32 layer can't avoid sending me double
    //  beginning backslashes.
    //

    if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) &&
        (IrpSp->FileObject->FileName.Buffer[1] == L'\\') &&
        (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) {

        IrpSp->FileObject->FileName.Length -= sizeof(WCHAR);

        RtlMoveMemory( &IrpSp->FileObject->FileName.Buffer[0],
                       &IrpSp->FileObject->FileName.Buffer[1],
                       IrpSp->FileObject->FileName.Length );

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

        if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) &&
            (IrpSp->FileObject->FileName.Buffer[1] == L'\\') &&
            (IrpSp->FileObject->FileName.Buffer[0] == L'\\')) {

            FatCompleteRequest( IrpContext, Irp, STATUS_OBJECT_NAME_INVALID );

            DebugTrace(-1, Dbg, "FatCommonCreate -> STATUS_OBJECT_NAME_INVALID\n", 0);
            return STATUS_OBJECT_NAME_INVALID;
        }
    }

    //
    //  Reference our input parameters to make things easier
    //

    ASSERT( IrpSp->Parameters.Create.SecurityContext != NULL );

    FileObject        = IrpSp->FileObject;
    FileName          = FileObject->FileName;
    RelatedFileObject = FileObject->RelatedFileObject;
    AllocationSize    = Irp->Overlay.AllocationSize.LowPart;
    EaBuffer          = Irp->AssociatedIrp.SystemBuffer;
    DesiredAccess     = &IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
    Options           = IrpSp->Parameters.Create.Options;
    FileAttributes    = (UCHAR)(IrpSp->Parameters.Create.FileAttributes & ~FILE_ATTRIBUTE_NORMAL);
    ShareAccess       = IrpSp->Parameters.Create.ShareAccess;
    EaLength          = IrpSp->Parameters.Create.EaLength;


    //
    //  Set up the file object's Vpb pointer in case anything happens.
    //  This will allow us to get a reasonable pop-up.
    //

    if ( RelatedFileObject != NULL ) {
        FileObject->Vpb = RelatedFileObject->Vpb;
    }

    //
    //  Force setting the archive bit in the attributes byte to follow OS/2,
    //  & DOS semantics.  Also mask out any extraneous bits, note that
    //  we can't use the ATTRIBUTE_VALID_FLAGS constant because that has
    //  the control and normal flags set.
    //
    //  Delay setting ARCHIVE in case this is a directory: DavidGoe 2/16/95
    //

    FileAttributes   &= (FILE_ATTRIBUTE_READONLY |
                         FILE_ATTRIBUTE_HIDDEN   |
                         FILE_ATTRIBUTE_SYSTEM   |
                         FILE_ATTRIBUTE_ARCHIVE );

    //
    //  Locate the volume device object and Vcb that we are trying to access
    //

    Vcb = &((PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject)->Vcb;

    //
    //  Decipher Option flags and values
    //

    //
    //  If this is an open by fileid operation, just fail it explicitly.  FAT's
    //  source of fileids is not reversible for open operations.
    //

    if (BooleanFlagOn( Options, FILE_OPEN_BY_FILE_ID )) {

        FatCompleteRequest( IrpContext, Irp, STATUS_NOT_IMPLEMENTED );
        return STATUS_NOT_IMPLEMENTED;
    }

    DirectoryFile           = BooleanFlagOn( Options, FILE_DIRECTORY_FILE );
    NonDirectoryFile        = BooleanFlagOn( Options, FILE_NON_DIRECTORY_FILE );
    SequentialOnly          = BooleanFlagOn( Options, FILE_SEQUENTIAL_ONLY );
    NoIntermediateBuffering = BooleanFlagOn( Options, FILE_NO_INTERMEDIATE_BUFFERING );
    NoEaKnowledge           = BooleanFlagOn( Options, FILE_NO_EA_KNOWLEDGE );
    DeleteOnClose           = BooleanFlagOn( Options, FILE_DELETE_ON_CLOSE );

    TemporaryFile = BooleanFlagOn( IrpSp->Parameters.Create.FileAttributes,
                                   FILE_ATTRIBUTE_TEMPORARY );

    CreateDisposition = (Options >> 24) & 0x000000ff;

    IsPagingFile = BooleanFlagOn( IrpSp->Flags, SL_OPEN_PAGING_FILE );
    OpenTargetDirectory = BooleanFlagOn( IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY );

    CreateDirectory = (BOOLEAN)(DirectoryFile &&
                                ((CreateDisposition == FILE_CREATE) ||
                                 (CreateDisposition == FILE_OPEN_IF)));

    OpenDirectory   = (BOOLEAN)(DirectoryFile &&
                                ((CreateDisposition == FILE_OPEN) ||
                                 (CreateDisposition == FILE_OPEN_IF)));


    //
    //  Make sure the input large integer is valid and that the dir/nondir
    //  indicates a storage type we understand.
    //

    if (Irp->Overlay.AllocationSize.HighPart != 0 ||
        (DirectoryFile && NonDirectoryFile)) {

        FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );

        DebugTrace(-1, Dbg, "FatCommonCreate -> STATUS_INVALID_PARAMETER\n", 0);
        return STATUS_INVALID_PARAMETER;
    }

    //
    //  Acquire exclusive access to the vcb, and enqueue the Irp if
    //  we didn't get it.
    //

    if (!FatAcquireExclusiveVcb( IrpContext, Vcb )) {

        DebugTrace(0, Dbg, "Cannot acquire Vcb\n", 0);

        Iosb.Status = FatFsdPostRequest( IrpContext, Irp );

        DebugTrace(-1, Dbg, "FatCommonCreate -> %08lx\n", Iosb.Status );
        return Iosb.Status;
    }

    //
    //  Make sure we haven't been called recursively by a filter inside an existing
    //  create request.
    //

    if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_CREATE_IN_PROGRESS)) {

        FatBugCheck( 0, 0, 0);
    }

    //
    //  Initialize the DirentBcb to null
    //

    DirentBcb = NULL;

    //
    //  Initialize our temp strings with their stack buffers.
    //

    OemFinalName.Length = 0;
    OemFinalName.MaximumLength = sizeof( OemBuffer);
    OemFinalName.Buffer = OemBuffer;

    UpcasedFinalName.Length = 0;
    UpcasedFinalName.MaximumLength = sizeof( UpcasedBuffer);
    UpcasedFinalName.Buffer = UpcasedBuffer;

    Lfn.Length = 0;
    Lfn.MaximumLength = sizeof( LfnBuffer);
    Lfn.Buffer = LfnBuffer;

    try {

        //
        //  Make sure the vcb is in a usable condition.  This will raise
        //  and error condition if the volume is unusable
        //

        FatVerifyVcb( IrpContext, Vcb );

        //
        //  If the Vcb is locked then we cannot open another file
        //

        if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_LOCKED)) {

            DebugTrace(0, Dbg, "Volume is locked\n", 0);

            Status = STATUS_ACCESS_DENIED;
            if (Vcb->VcbCondition != VcbGood) {

                Status = STATUS_VOLUME_DISMOUNTED;
            }
            try_return( Iosb.Status = Status );
        }

        //
        //  Don't allow the DELETE_ON_CLOSE option if the volume is
        //  write-protected.
        //

        if (DeleteOnClose && FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED)) {

            //
            //  Set the real device for the pop-up info, and set the verify
            //  bit in the device object, so that we will force a verify
            //  in case the user put the correct media back in.
            //

            IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
                                          Vcb->Vpb->RealDevice );

            SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);

            FatRaiseStatus( IrpContext, STATUS_MEDIA_WRITE_PROTECTED );
        }

        //
        //  If this is a fat32 volume, EA's are not supported.
        //

        if (EaBuffer != NULL) {

            try_return( Iosb.Status = STATUS_EAS_NOT_SUPPORTED );
        }

        //
        //  Check if we are opening the volume and not a file/directory.
        //  We are opening the volume if the name is empty and there
        //  isn't a related file object.  If there is a related file object
        //  then it is the Vcb itself.
        //

        if (FileName.Length == 0) {

            PVCB DecodeVcb;

            if (RelatedFileObject == NULL ||
                FatDecodeFileObject( RelatedFileObject,
                                     &DecodeVcb,
                                     &Fcb,
                                     &Ccb ) == UserVolumeOpen) {

                ASSERT( RelatedFileObject == NULL || Vcb == DecodeVcb );

                //
                //  Check if we were to open a directory
                //

                if (DirectoryFile) {

                    DebugTrace(0, Dbg, "Cannot open volume as a directory\n", 0);

                    try_return( Iosb.Status = STATUS_NOT_A_DIRECTORY );
                }

                //
                //  Can't open the TargetDirectory of the DASD volume.
                //

                if (OpenTargetDirectory) {

                    try_return( Iosb.Status = STATUS_INVALID_PARAMETER );
                }

                DebugTrace(0, Dbg, "Opening the volume, Vcb = %08lx\n", Vcb);

                CollectCreateHitStatistics(Vcb);

                Iosb = FatOpenVolume( IrpContext,
                                      FileObject,
                                      Vcb,
                                      DesiredAccess,
                                      ShareAccess,
                                      CreateDisposition );

                Irp->IoStatus.Information = Iosb.Information;
                try_return( Iosb.Status );
            }
        }

        //
        //  If there is a related file object then this is a relative open.
        //  The related file object is the directory to start our search at.
        //  Return an error if it is not a directory.
        //

        if (RelatedFileObject != NULL) {

            PVCB RelatedVcb;
            PDCB RelatedDcb;
            PCCB RelatedCcb;
            TYPE_OF_OPEN TypeOfOpen;

            TypeOfOpen = FatDecodeFileObject( RelatedFileObject,
                                              &RelatedVcb,
                                              &RelatedDcb,
                                              &RelatedCcb );

            if (TypeOfOpen != UserFileOpen &&
                TypeOfOpen != UserDirectoryOpen) {

                DebugTrace(0, Dbg, "Invalid related file object\n", 0);

                try_return( Iosb.Status = STATUS_OBJECT_PATH_NOT_FOUND );
            }

            //
            //  A relative open must be via a relative path.
            //

            if (FileName.Length != 0 &&
                FileName.Buffer[0] == L'\\') {

                try_return( Iosb.Status = STATUS_OBJECT_NAME_INVALID );
            }

            //
            //  Set up the file object's Vpb pointer in case anything happens.
            //

            ASSERT( Vcb == RelatedVcb );

            FileObject->Vpb = RelatedFileObject->Vpb;

            //
            //  Now verify the related Fcb so we don't get in trouble later
            //  by assuming its in good shape.
            //

            FatVerifyFcb( IrpContext, RelatedDcb );

            ParentDcb = RelatedDcb;

        } else {

            //
            //  This is not a relative open, so check if we're
            //  opening the root dcb
            //

            if ((FileName.Length == sizeof(WCHAR)) &&
                (FileName.Buffer[0] == L'\\')) {

                //
                //  Check if we were not supposed to open a directory
                //

                if (NonDirectoryFile) {

                    DebugTrace(0, Dbg, "Cannot open root directory as a file\n", 0);

                    try_return( Iosb.Status = STATUS_FILE_IS_A_DIRECTORY );
                }

                //
                //  Can't open the TargetDirectory of the root directory.
                //

                if (OpenTargetDirectory) {

                    try_return( Iosb.Status = STATUS_INVALID_PARAMETER );
                }

                //
                //  Not allowed to delete root directory.
                //

                if (DeleteOnClose) {

                    try_return( Iosb.Status = STATUS_CANNOT_DELETE );
                }

                DebugTrace(0, Dbg, "Opening root dcb\n", 0);

                CollectCreateHitStatistics(Vcb);

⌨️ 快捷键说明

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