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

📄 create.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 5 页
字号:

            NextFcb->RootExtentLength = DirContext->Fid->Icb.Length.Length;

            UdfInitializeIcbContextFromFcb( IrpContext, &IcbContext, NextFcb );
            CleanupIcbContext = TRUE;

            UdfLookupActiveIcb( IrpContext, &IcbContext );
            
            UdfInitializeFcbFromIcbContext( IrpContext,
                                            NextFcb,
                                            &IcbContext );

            UdfCleanupIcbContext( IrpContext, &IcbContext );
            CleanupIcbContext = FALSE;

        }

        //
        //  Now try to acquire the new Fcb without waiting.  We will reference
        //  the Fcb and retry with wait if unsuccessful.
        //

        if (!UdfAcquireFcbExclusive( IrpContext, NextFcb, TRUE )) {

            NextFcb->FcbReference += 1;

            UdfUnlockVcb( IrpContext, Vcb );

            UdfReleaseFcb( IrpContext, *CurrentFcb );
            UdfAcquireFcbExclusive( IrpContext, NextFcb, FALSE );
            UdfAcquireFcbExclusive( IrpContext, *CurrentFcb, FALSE );

            UdfLockVcb( IrpContext, Vcb );
            NextFcb->FcbReference -= 1;
        }

        //
        //  Move down to this new Fcb.  Remember that we still own the parent however.
        //

        ParentFcb = *CurrentFcb;
        *CurrentFcb = NextFcb;

        //
        //  Store this name into the prefix table for the parent.
        //

        OpenLcb = UdfInsertPrefix( IrpContext,
                                   NextFcb,
                                   ( ShortNameMatch?
                                     &DirContext->ShortObjectName :
                                     &DirContext->CaseObjectName ),
                                   ShortNameMatch,
                                   IgnoreCase,
                                   ParentFcb );

        //
        //  Now increment the reference counts for the parent and drop the Vcb.
        //

        DebugTrace(( +1, Dbg,
                     "UdfOpenObjectFromDirContext, PFcb %08x Vcb %d/%d Fcb %d/%d\n", ParentFcb,
                     Vcb->VcbReference,
                     Vcb->VcbUserReference,
                     ParentFcb->FcbReference,
                     ParentFcb->FcbUserReference ));

        UdfIncrementReferenceCounts( IrpContext, ParentFcb, 1, 1 );
        
        DebugTrace(( -1, Dbg, 
                     "UdfOpenObjectFromDirContext, Vcb %d/%d Fcb %d/%d\n",
                     Vcb->VcbReference,
                     Vcb->VcbUserReference,
                     ParentFcb->FcbReference,
                     ParentFcb->FcbUserReference ));

        UdfUnlockVcb( IrpContext, Vcb );
        UnlockVcb = FALSE;

        //
        //  Perform initialization associated with the directory context.
        //
            
        UdfInitializeLcbFromDirContext( IrpContext,
                                        OpenLcb,
                                        DirContext );

        //
        //  Release the parent Fcb at this point.
        //

        UdfReleaseFcb( IrpContext, ParentFcb );
        ParentFcb = NULL;

        //
        //  Call our worker routine to complete the open.
        //

        if (PerformUserOpen) {

            Status = UdfCompleteFcbOpen( IrpContext,
                                         IrpSp,
                                         Vcb,
                                         CurrentFcb,
                                         OpenLcb,
                                         TypeOfOpen,
                                         CcbFlags,
                                         IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
        }

    } finally {

        //
        //  Unlock the Vcb if held.
        //

        if (UnlockVcb) {

            UdfUnlockVcb( IrpContext, Vcb );
        }

        //
        //  Release the parent if held.
        //

        if (ParentFcb != NULL) {

            UdfReleaseFcb( IrpContext, ParentFcb );
        }

        //
        //  Destroy the new Fcb if it was not fully initialized.
        //

        if (NextFcb && !FlagOn( NextFcb->FcbState, FCB_STATE_INITIALIZED )) {

            UdfDeleteFcb( IrpContext, NextFcb );
        }

        //
        //  Clean up the Icb context if used.
        //

        if (CleanupIcbContext) {

            UdfCleanupIcbContext( IrpContext, &IcbContext );
        }
    }

    return Status;
}


//
//  Local support routine
//

NTSTATUS
UdfCompleteFcbOpen (
    IN PIRP_CONTEXT IrpContext,
    PIO_STACK_LOCATION IrpSp,
    IN PVCB Vcb,
    IN OUT PFCB *CurrentFcb,
    IN PLCB OpenLcb OPTIONAL,
    IN TYPE_OF_OPEN TypeOfOpen,
    IN ULONG UserCcbFlags,
    IN ACCESS_MASK DesiredAccess
    )

/*++

Routine Description:

    This is the worker routine which takes an existing Fcb and completes
    the open.  We will do any necessary oplock checks and sharing checks.
    Finally we will create the Ccb and update the file object and any
    file object flags.

Arguments:

    IrpSp - Stack location for the current request.

    Vcb - Vcb for the current volume.

    CurrentFcb - Address of pointer to Fcb to open.  We clear this field if
        we release the resource for this file.
        
    OpenLcb - Lcb this Fcb is being opened by

    TypeOfOpen - Type of open for this request.

    UserCcbFlags - Flags to OR into the Ccb flags.

    DesiredAccess - Desired access for this open.

Return Value:

    NTSTATUS - STATUS_SUCCESS if we complete this request, STATUS_PENDING if
        the oplock package takes the Irp or SHARING_VIOLATION if there is a
        sharing check conflict.

--*/

{
    NTSTATUS Status;
    NTSTATUS OplockStatus = STATUS_SUCCESS;
    ULONG Information = FILE_OPENED;

    BOOLEAN LockVolume = FALSE;

    PFCB Fcb = *CurrentFcb;
    PCCB Ccb;

    PAGED_CODE();

    //
    //  If this a volume open and the user wants to lock the volume then
    //  purge and lock the volume.
    //

    if ((TypeOfOpen <= UserVolumeOpen) &&
        !FlagOn( IrpSp->Parameters.Create.ShareAccess, FILE_SHARE_READ )) {

        //
        //  If there are open handles then fail this immediately.
        //

        if (Vcb->VcbCleanup != 0) {

            return STATUS_SHARING_VIOLATION;
        }

        //
        //  If we can't wait then force this to be posted.
        //

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

            UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT );
        }

        LockVolume = TRUE;

        //
        //  Purge the volume and make sure all of the user references
        //  are gone.
        //

        Status = UdfPurgeVolume( IrpContext, Vcb, FALSE );

        if (Status != STATUS_SUCCESS) {

            return Status;
        }

        //
        //  Now force all of the delayed close operations to go away.
        //

        UdfFspClose( Vcb );

        if (Vcb->VcbUserReference > Vcb->VcbResidualUserReference) {

            return STATUS_SHARING_VIOLATION;
        }
    }

    //
    //  If the Fcb already existed then we need to check the oplocks and
    //  the share access.
    //

    if (Fcb->FcbCleanup != 0) {

        //
        //  If this is a user file open then check whether there are any
        //  batch oplock.
        //

        if (TypeOfOpen == UserFileOpen) {

            //
            //  Store the address of the Fcb for a possible teardown into
            //  the IrpContext.  We will release this in the call to
            //  prepost the Irp.
            //

            IrpContext->TeardownFcb = CurrentFcb;

            if (FsRtlCurrentBatchOplock( &Fcb->Oplock )) {

                //
                //  We remember if a batch oplock break is underway for the
                //  case where the sharing check fails.
                //

                Information = FILE_OPBATCH_BREAK_UNDERWAY;

                OplockStatus = FsRtlCheckOplock( &Fcb->Oplock,
                                                 IrpContext->Irp,
                                                 IrpContext,
                                                 UdfOplockComplete,
                                                 UdfPrePostIrp );

                if (OplockStatus == STATUS_PENDING) {

                    return STATUS_PENDING;
                }
            }

            //
            //  Check the share access before breaking any exclusive oplocks.
            //

            Status = IoCheckShareAccess( DesiredAccess,
                                         IrpSp->Parameters.Create.ShareAccess,
                                         IrpSp->FileObject,
                                         &Fcb->ShareAccess,
                                         FALSE );

            if (!NT_SUCCESS( Status )) {

                return Status;
            }

            //
            //  Now check that we can continue based on the oplock state of the
            //  file.
            //

            OplockStatus = FsRtlCheckOplock( &Fcb->Oplock,
                                             IrpContext->Irp,
                                             IrpContext,
                                             UdfOplockComplete,
                                             UdfPrePostIrp );

            if (OplockStatus == STATUS_PENDING) {

                return STATUS_PENDING;
            }

            IrpContext->TeardownFcb = NULL;

        //
        //  Otherwise just do the sharing check.
        //

        } else {

            Status = IoCheckShareAccess( DesiredAccess,
                                         IrpSp->Parameters.Create.ShareAccess,
                                         IrpSp->FileObject,
                                         &Fcb->ShareAccess,
                                         FALSE );

            if (!NT_SUCCESS( Status )) {

                return Status;
            }
        }
    }

    //
    //  Create the Ccb now.
    //

    Ccb = UdfCreateCcb( IrpContext, Fcb, OpenLcb, UserCcbFlags );

    //
    //  Update the share access.
    //

    if (Fcb->FcbCleanup == 0) {

        IoSetShareAccess( DesiredAccess,
                          IrpSp->Parameters.Create.ShareAccess,
                          IrpSp->FileObject,
                          &Fcb->ShareAccess );

    } else {

        IoUpdateShareAccess( IrpSp->FileObject, &Fcb->ShareAccess );
    }

    //
    //  Set the file object type.
    //

    UdfSetFileObject( IrpContext, IrpSp->FileObject, TypeOfOpen, Fcb, Ccb );

    //
    //  Set the appropriate cache flags for a user file object.
    //

    if (TypeOfOpen == UserFileOpen) {

        if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NO_INTERMEDIATE_BUFFERING )) {

            SetFlag( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING );

        } else {

            SetFlag( IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED );
        }
    }
    //
    //  Update the open and cleanup counts.  Check the fast io state here.
    //

    UdfLockVcb( IrpContext, Vcb );

    UdfIncrementCleanupCounts( IrpContext, Fcb );
    
    DebugTrace(( +1, Dbg,
                 "UdfCompleteFcbOpen, Fcb %08x Vcb %d/%d Fcb %d/%d\n", Fcb,
                 Vcb->VcbReference,
                 Vcb->VcbUserReference,
                 Fcb->FcbReference,
                 Fcb->FcbUserReference ));

    UdfIncrementReferenceCounts( IrpContext, Fcb, 1, 1 );
    
    DebugTrace(( -1, Dbg,
                 "UdfCompleteFcbOpen, Vcb %d/%d Fcb %d/%d\n",
                 Vcb->VcbReference,
                 Vcb->VcbUserReference,
                 Fcb->FcbReference,
                 Fcb->FcbUserReference ));

    if (LockVolume) {

        Vcb->VolumeLockFileObject = IrpSp->FileObject;
        SetFlag( Vcb->VcbState, VCB_STATE_LOCKED );
    }

    UdfUnlockVcb( IrpContext, Vcb );

    UdfLockFcb( IrpContext, Fcb );

    if (TypeOfOpen == UserFileOpen) {

        Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb );

    } else {

        Fcb->IsFastIoPossible = FastIoIsNotPossible;
    }

    UdfUnlockFcb

⌨️ 快捷键说明

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