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

📄 create.c

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

        if (VolumeOpen) {

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

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

                try_return( Status = STATUS_ACCESS_DENIED );
            }

            //
            //  If they wanted to open a directory, surprise.
            //

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

                try_return( Status = STATUS_NOT_A_DIRECTORY );
            }

            //
            //  Acquire the Fcb first.
            //

            CurrentFcb = Vcb->VolumeDasdFcb;
            CdAcquireFcbExclusive( IrpContext, CurrentFcb, FALSE );

            try_return( Status = CdOpenExistingFcb( IrpContext,
                                                    IrpSp,
                                                    &CurrentFcb,
                                                    UserVolumeOpen,
                                                    FALSE,
                                                    NULL ));
        }

        //
        //  At this point CurrentFcb points to the deepest Fcb for this open
        //  in the tree.  Let's acquire this Fcb to keep it from being deleted
        //  beneath us.
        //

        CdAcquireFcbExclusive( IrpContext, NextFcb, FALSE );
        CurrentFcb = NextFcb;

        //
        //  Do a prefix search if there is more of the name to parse.
        //

        if (RemainingName.FileName.Length != 0) {

            //
            //  Do the prefix search to find the longest matching name.
            //

            CdFindPrefix( IrpContext,
                          &CurrentFcb,
                          &RemainingName.FileName,
                          IgnoreCase );
        }

        //
        //  If the remaining name length is zero then we have found our
        //  target.
        //

        if (RemainingName.FileName.Length == 0) {

            //
            //  If this is a file so verify the user didn't want to open
            //  a directory.
            //

            if (SafeNodeType( CurrentFcb ) == CDFS_NTC_FCB_DATA) {

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

                try_return( Status = CdOpenExistingFcb( IrpContext,
                                                        IrpSp,
                                                        &CurrentFcb,
                                                        UserFileOpen,
                                                        IgnoreCase,
                                                        RelatedCcb ));

            //
            //  This is a directory.  Verify the user didn't want to open
            //  as a file.
            //

            } else if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) {

                try_return( Status = STATUS_FILE_IS_A_DIRECTORY );

            //
            //  Open the file as a directory.
            //

            } else {

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

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

                    try_return( Status = STATUS_ACCESS_DENIED );
                }

                try_return( Status = CdOpenExistingFcb( IrpContext,
                                                        IrpSp,
                                                        &CurrentFcb,
                                                        UserDirectoryOpen,
                                                        IgnoreCase,
                                                        RelatedCcb ));
            }
        }

        //
        //  We have more work to do.  We have a starting Fcb which we own shared.
        //  We also have the remaining name to parse.  Walk through the name
        //  component by component looking for the full name.
        //

        //
        //  Our starting Fcb better be a directory.
        //

        if (!FlagOn( CurrentFcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) {

            try_return( Status = STATUS_OBJECT_PATH_NOT_FOUND );
        }

        //
        //  If we can't wait then post this request.
        //

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

            CdRaiseStatus( IrpContext, STATUS_CANT_WAIT );
        }

        //
        //  Make sure the final name has no version string.
        //

        FinalName.VersionString.Length = 0;

        while (TRUE) {

            ShortNameMatch = FALSE;

            //
            //  Split off the next component from the name.
            //

            CdDissectName( IrpContext,
                           &RemainingName.FileName,
                           &FinalName.FileName );

            //
            //  Go ahead and look this entry up in the path table.
            //

            CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry );
            CleanupCompoundPathEntry = TRUE;

            FoundEntry = CdFindPathEntry( IrpContext,
                                          CurrentFcb,
                                          &FinalName,
                                          IgnoreCase,
                                          &CompoundPathEntry );

            //
            //  If we didn't find the entry then check if the current name
            //  is a possible short name.
            //

            if (!FoundEntry) {

                ShortNameDirentOffset = CdShortNameDirentOffset( IrpContext, &FinalName.FileName );

                //
                //  If there is an embedded short name offset then look for the
                //  matching long name in the directory.
                //

                if (ShortNameDirentOffset != MAXULONG) {

                    if (CleanupFileContext) {

                        CdCleanupFileContext( IrpContext, &FileContext );
                    }

                    CdInitializeFileContext( IrpContext, &FileContext );
                    CleanupFileContext = TRUE;

                    FoundEntry = CdFindFileByShortName( IrpContext,
                                                        CurrentFcb,
                                                        &FinalName,
                                                        IgnoreCase,
                                                        ShortNameDirentOffset,
                                                        &FileContext );

                    //
                    //  If we found an entry and it is a directory then look
                    //  this up in the path table.
                    //

                    if (FoundEntry) {

                        ShortNameMatch = TRUE;

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

                            CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry );
                            CdInitializeCompoundPathEntry( IrpContext, &CompoundPathEntry );

                            FoundEntry = CdFindPathEntry( IrpContext,
                                                          CurrentFcb,
                                                          &FileContext.InitialDirent->Dirent.CdCaseFileName,
                                                          IgnoreCase,
                                                          &CompoundPathEntry );

                            //
                            //  We better find this entry.
                            //

                            if (!FoundEntry) {

                                CdRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
                            }

                            //
                            //  Upcase the name with the short name if case
                            //  insensitive.
                            //

                            if (IgnoreCase) {

                                CdUpcaseName( IrpContext, &FinalName, &FinalName );
                            }

                        //
                        //  We found a matching file.  If we are at the last
                        //  entry then break out of the loop and open the
                        //  file below.  Otherwise we return an error.
                        //

                        } else if (RemainingName.FileName.Length == 0) {

                            //
                            //  Break out of the loop.  We will process the dirent
                            //  below.
                            //

                            MatchingName = &FileContext.ShortName;
                            break;

                        } else {

                            try_return( Status = STATUS_OBJECT_PATH_NOT_FOUND );
                        }
                    }
                }

                //
                //  We didn't find the name in either the path table or as
                //  a short name in a directory.  If the remaining name
                //  length is zero then break out of the loop to search
                //  the directory.
                //

                if (!FoundEntry) {

                    if (RemainingName.FileName.Length == 0) {

                        break;

                    //
                    //  Otherwise this path could not be cracked.
                    //

                    } else {

                        try_return( Status = STATUS_OBJECT_PATH_NOT_FOUND );
                    }
                }
            }

            //
            //  If this is an ignore case open then copy the exact case
            //  in the file object name.  If it was a short name match then
            //  the name must be upcase already.
            //

            if (IgnoreCase && !ShortNameMatch) {

                RtlCopyMemory( FinalName.FileName.Buffer,
                               CompoundPathEntry.PathEntry.CdDirName.FileName.Buffer,
                               CompoundPathEntry.PathEntry.CdDirName.FileName.Length );
            }

            //
            //  If we have found the last component then open this as a directory
            //  and return to our caller.
            //

            if (RemainingName.FileName.Length == 0) {

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

                    try_return( Status = STATUS_FILE_IS_A_DIRECTORY );
                }

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

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

                    try_return( Status = STATUS_ACCESS_DENIED );
                }

                try_return( Status = CdOpenDirectoryFromPathEntry( IrpContext,
                                                                   IrpSp,
                                                                   Vcb,
                                                                   &CurrentFcb,
                                                                   &FinalName,
                                                                   IgnoreCase,
                                                                   ShortNameMatch,
                                                                   &CompoundPathEntry.PathEntry,
                                                                   TRUE,
                                                                   RelatedCcb ));
            }

            //
            //  Otherwise open an Fcb for this intermediate index Fcb.
            //

            CdOpenDirectoryFromPathEntry( IrpContext,
                                          IrpSp,
                                          Vcb,
                                          &CurrentFcb,
                                          &FinalName,
                                          IgnoreCase,
                                          ShortNameMatch,
                                          &CompoundPathEntry.PathEntry,
                                          FALSE,
                                          NULL );

            CdCleanupCompoundPathEntry( IrpContext, &CompoundPathEntry );
            CleanupCompoundPathEntry = FALSE;
        }

        //
        //  We need to scan the current directory for a matching file name
        //  if we don't already have one.
        //

        if (!FoundEntry) {

            if (CleanupFileContext) {

                CdCleanupFileContext( IrpContext, &FileContext );
            }

            CdInitializeFileContext( IrpContext, &FileContext );
            CleanupFileContext = TRUE;

            //
            //  Split our search name into separate components.
            //

            CdConvertNameToCdName( IrpContext, &FinalName );

            FoundEntry = CdFindFile( IrpContext,
                                     CurrentFcb,
                                     &FinalName,
                                     IgnoreCase,
                                     &FileContext,
                                     &MatchingName );
        }

        //
        //  If we didn't find a match then check if the name is invalid to
        //  determine which error code to return.
        //

        if (!FoundEntry) {

            if ((CreateDisposition == FILE_OPEN) ||
                (CreateDisposition == FILE_OVERWRITE)) {

                try_return( Status = STATUS_OBJECT_NAME_NOT_FOUND );
            }

            //
            //  Any other operation return STATUS_ACCESS_DENIED.
            //

            try_return( Status = STATUS_ACCESS_DENIED );
        }

        //
        //  If this is a directory then the disk is corrupt because it wasn't

⌨️ 快捷键说明

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