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

📄 create.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
            try_return( Iosb.Status = STATUS_OBJECT_PATH_NOT_FOUND );
        }

        //
        //  Otherwise we continue on processing the Irp and allowing ourselves
        //  to block for I/O as necessary.  Find/create additional dcb's for
        //  the one we're trying to open.  We loop until either remaining part
        //  is empty or we get a bad filename.  When we exit FinalName is
        //  the last name in the string we're after, and ParentDcb is the
        //  parent directory that will contain the opened/created
        //  file/directory.
        //
        //  Make sure the rest of the name is valid in at least the LFN
        //  character set (which just happens to be that of HPFS).
        //
        //  If we are not in ChicagoMode, use FAT symantics.
        //

        ParentDcb = Fcb;
        FirstLoop = TRUE;

        while (TRUE) {

            //
            //  We do one little optimization here on the first itterration of
            //  the loop since we know that we have already tried to convert
            //  FinalOemName from the original UNICODE.
            //

            if (FirstLoop) {

                FirstLoop = FALSE;
                RemainingPart = NextRemainingPart;
                Status = OemFinalName.Length ? STATUS_SUCCESS : STATUS_UNMAPPABLE_CHARACTER;

            } else {

                //
                //  Dissect the remaining part.
                //

                DebugTrace(0, Dbg, "Dissecting the name %Z\n", &RemainingPart);

                FsRtlDissectName( RemainingPart,
                                  &FinalName,
                                  &RemainingPart );

                //
                //  If RemainingPart starts with a backslash the name is
                //  invalid.
                //  Check for no more than 255 characters in FinalName
                //

                if (((RemainingPart.Length != 0) && (RemainingPart.Buffer[0] == L'\\')) ||
                    (FinalName.Length > 255*sizeof(WCHAR))) {

                    try_return( Iosb.Status = STATUS_OBJECT_NAME_INVALID );
                }

                //
                //  Now, try to convert this one component into Oem.  If it works
                //  then that's great, otherwise we have to try with the UNICODE
                //  name instead.
                //

                FatEnsureStringBufferEnough( &OemFinalName,
                                             FinalName.Length);

                Status = RtlUpcaseUnicodeStringToCountedOemString( &OemFinalName, &FinalName, FALSE );
            }

            if (NT_SUCCESS(Status)) {

                //
                //  We'll start by trying to locate the dirent for the name.  Note
                //  that we already know that there isn't an Fcb/Dcb for the file
                //  otherwise we would have found it when we did our prefix lookup.
                //

                if (FatIsNameShortOemValid( IrpContext, OemFinalName, FALSE, FALSE, FALSE )) {

                    FatStringTo8dot3( IrpContext,
                                      OemFinalName,
                                      &LocalCcb.OemQueryTemplate.Constant );

                    LocalCcb.Flags = 0;

                } else {

                    LocalCcb.Flags = CCB_FLAG_SKIP_SHORT_NAME_COMPARE;
                }

            } else {

                LocalCcb.Flags = CCB_FLAG_SKIP_SHORT_NAME_COMPARE;

                if (Status != STATUS_UNMAPPABLE_CHARACTER) {

                    try_return( Iosb.Status = Status );
                }
            }

            //
            //  Now we know a lot about the final name, so do legal name
            //  checking here.
            //

            if (FatData.ChicagoMode) {

                if (!FatIsNameLongUnicodeValid( IrpContext, &FinalName, FALSE, FALSE, FALSE )) {

                    try_return( Iosb.Status = STATUS_OBJECT_NAME_INVALID );
                }

            } else {

                if (FlagOn(LocalCcb.Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE)) {

                    try_return( Iosb.Status = STATUS_OBJECT_NAME_INVALID );
                }
            }

            DebugTrace(0, Dbg, "FinalName is %Z\n", &FinalName);
            DebugTrace(0, Dbg, "RemainingPart is %Z\n", &RemainingPart);

            FatEnsureStringBufferEnough( &UpcasedFinalName,
                                         FinalName.Length);

            if (!NT_SUCCESS(Status = RtlUpcaseUnicodeString( &UpcasedFinalName, &FinalName, FALSE))) {

                try_return( Iosb.Status = Status );
            }

            LocalCcb.UnicodeQueryTemplate =  UpcasedFinalName;
            LocalCcb.ContainsWildCards = FALSE;

            Lfn.Length = 0;

            FatLocateDirent( IrpContext,
                             ParentDcb,
                             &LocalCcb,
                             0,
                             &Dirent,
                             &DirentBcb,
                             &DirentByteOffset,
                             &FileNameOpenedDos,
                             &Lfn);
            //
            //  Remember we read this Dcb for error recovery.
            //

            FinalDcb = ParentDcb;

            //
            //  If the remaining part is now empty then this is the last name
            //  in the string and the one we want to open
            //

            if (RemainingPart.Length == 0) { break; }

            //
            //  We didn't find a dirent, bail.
            //

            if (Dirent == NULL) {

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

            //
            //  We now have a dirent, make sure it is a directory
            //

            if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) {

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

            //
            //  Compute the LfnByteOffset.
            //

            LfnByteOffset = DirentByteOffset -
                            FAT_LFN_DIRENTS_NEEDED(&Lfn) * sizeof(LFN_DIRENT);

            //
            //  Create a dcb for the new directory
            //

            ParentDcb = FatCreateDcb( IrpContext,
                                      Vcb,
                                      ParentDcb,
                                      LfnByteOffset,
                                      DirentByteOffset,
                                      Dirent,
                                      &Lfn );

            //
            //  Remember we created this Dcb for error recovery.
            //

            FinalDcb = ParentDcb;

            FatSetFullNameInFcb( IrpContext, ParentDcb, &FinalName );
        }

        //
        //  First check if the user wanted to open the target directory
        //  and if so then call the subroutine to finish the open.
        //

        if (OpenTargetDirectory) {

            Iosb = FatOpenTargetDirectory( IrpContext,
                                           FileObject,
                                           ParentDcb,
                                           DesiredAccess,
                                           ShareAccess,
                                           Dirent ? TRUE : FALSE);

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

        if (Dirent != NULL) {

            //
            //  Compute the LfnByteOffset.
            //

            LfnByteOffset = DirentByteOffset -
                            FAT_LFN_DIRENTS_NEEDED(&Lfn) * sizeof(LFN_DIRENT);

            //
            //  We were able to locate an existing dirent entry, so now
            //  see if it is a directory that we're trying to open.
            //

            if (FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) {

                //
                //  Make sure its okay to open a directory
                //

                if (NonDirectoryFile) {

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

                    try_return( Iosb.Status = STATUS_FILE_IS_A_DIRECTORY );
                }

                DebugTrace(0, Dbg, "Open existing directory\n", 0);

                Iosb = FatOpenExistingDirectory( IrpContext,
                                                 FileObject,
                                                 Vcb,
                                                 ParentDcb,
                                                 Dirent,
                                                 LfnByteOffset,
                                                 DirentByteOffset,
                                                 &Lfn,
                                                 DesiredAccess,
                                                 ShareAccess,
                                                 CreateDisposition,
                                                 NoEaKnowledge,
                                                 DeleteOnClose );
                Irp->IoStatus.Information = Iosb.Information;
                try_return( Iosb.Status );
            }

            //
            //  Otherwise we're trying to open and existing file, and we
            //  need to check if the user only wanted to open a directory.
            //

            if (OpenDirectory) {

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

                try_return( Iosb.Status = STATUS_NOT_A_DIRECTORY );
            }

            DebugTrace(0, Dbg, "Open existing file\n", 0);

            if ( TrailingBackslash ) {
               try_return( Iosb.Status = STATUS_OBJECT_NAME_INVALID );
            }

            Iosb = FatOpenExistingFile( IrpContext,
                                        FileObject,
                                        Vcb,
                                        ParentDcb,
                                        Dirent,
                                        LfnByteOffset,
                                        DirentByteOffset,
                                        &Lfn,
                                        DesiredAccess,
                                        ShareAccess,
                                        AllocationSize,
                                        EaBuffer,
                                        EaLength,
                                        FileAttributes,
                                        CreateDisposition,
                                        IsPagingFile,
                                        NoEaKnowledge,
                                        DeleteOnClose,
                                        FileNameOpenedDos );

            //
            //  Check if we need to set the cache support flag in
            //  the file object
            //

            if (NT_SUCCESS(Iosb.Status) && !NoIntermediateBuffering) {

                FileObject->Flags |= FO_CACHE_SUPPORTED;
            }

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

        //
        //  We can't locate a dirent so this is a new file.
        //

        //
        //  Now check to see if we wanted to only open an existing file.
        //  And then case on whether we wanted to create a file or a directory.
        //

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

            DebugTrace( 0, Dbg, "Cannot open nonexisting file\n", 0);

            try_return( Iosb.Status = STATUS_OBJECT_NAME_NOT_FOUND );
        }

        //
        //  Skip a few cycles later if we know now that the Oem name is not
        //  valid 8.3.
        //

        if (FlagOn(LocalCcb.Flags, CCB_FLAG_SKIP_SHORT_NAME_COMPARE)) {

            OemFinalName.Length = 0;
        }

        //
        //  Determine the granted access for this operation now.
        //

        if (!NT_SUCCESS( Iosb.Status = FatCheckSystemSecurityAccess( IrpContext ))) {

            try_return( Iosb );
        }

        if (CreateDirectory) {

            DebugTrace(0, Dbg, "Create new directory\n", 0);

            //
            //  If this media is write protected, don't even try the create.
            //

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

            //
            //  Don't allow people to create directories with the
            //  temporary bit set.
            //

            if (TemporaryFile) {

                try_return( Iosb.Status = STATUS_INVALID_PARAMETER );
            }

            Iosb = FatCreateNewDirectory( IrpContext,
                                          FileObject,
                                          Vcb,
                                          ParentDcb,
                                          &OemFinalName,
                                          &FinalName,
                                          DesiredAccess,
                                          ShareAccess,
                                          EaBuffer,
                                          EaLength,
                                          FileAttributes,
                                          NoEaKnowledge,
                                          DeleteOnClose );

⌨️ 快捷键说明

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