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

📄 create.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 4 页
字号:

    __try {

        ExAcquireResourceExclusiveLite(
            &Vcb->MainResource, TRUE );
        
        VcbResourceAcquired = TRUE;

        if (Irp->Overlay.AllocationSize.HighPart) {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }
        
        if (!(Inode = ExAllocatePoolWithTag (
              PagedPool, sizeof(RFSD_INODE), 'EInd' ) )) {
            __leave;
        }

        RtlZeroMemory(Inode, sizeof(RFSD_INODE));

        FileName.MaximumLength = IrpSp->FileObject->FileName.MaximumLength;
        FileName.Length = IrpSp->FileObject->FileName.Length;

        FileName.Buffer = ExAllocatePool(PagedPool, FileName.MaximumLength);
        if (!FileName.Buffer) {   
            Status = STATUS_INSUFFICIENT_RESOURCES;
            __leave;
        }

        RtlZeroMemory(FileName.Buffer, FileName.MaximumLength);
        RtlCopyMemory(FileName.Buffer, IrpSp->FileObject->FileName.Buffer, FileName.Length);

        if (IrpSp->FileObject->RelatedFileObject) {
            ParentFcb = (PRFSD_FCB)(IrpSp->FileObject->RelatedFileObject->FsContext);
        }

        if ((FileName.Length > sizeof(WCHAR)) &&
            (FileName.Buffer[1] == L'\\') &&
            (FileName.Buffer[0] == L'\\')) {
            
            FileName.Length -= sizeof(WCHAR);
            
            RtlMoveMemory( &FileName.Buffer[0],
                &FileName.Buffer[1],
                FileName.Length );
            
            //
            //  Bad Name if there are still beginning backslashes.
            //
            
            if ((FileName.Length > sizeof(WCHAR)) &&
                (FileName.Buffer[1] == L'\\') &&
                (FileName.Buffer[0] == L'\\')) {
                                
                Status = STATUS_OBJECT_NAME_INVALID;

                __leave;
            }
        }

        if (IsFlagOn(Options, FILE_OPEN_BY_FILE_ID)) {
            Status = STATUS_NOT_IMPLEMENTED;
            __leave;
        }

        RfsdPrint((DBG_INFO, "RfsdCreateFile: %S (NameLen=%xh) Paging=%xh Option: %xh.\n",
            FileName.Buffer, FileName.Length, IsPagingFile, IrpSp->Parameters.Create.Options));

        if (ParentFcb) {
            ParentMcb = ParentFcb->RfsdMcb;
        }

        Status = RfsdLookupFileName(
                        Vcb,
                        &FileName,
                        ParentMcb,
                        &RfsdMcb,
                        Inode );

        if (!NT_SUCCESS(Status)) {
            UNICODE_STRING  PathName;
            UNICODE_STRING  RealName;
            UNICODE_STRING  RemainName;

            LONG            i = 0;


            PathName = FileName;

            RfsdPrint((DBG_INFO, "RfsdCreateFile: File %S will be created.\n", PathName.Buffer));

            RfsdMcb = NULL;

            if (PathName.Buffer[PathName.Length/2 - 1] == L'\\') {
                if (DirectoryFile) {
                    PathName.Length -=2;
                    PathName.Buffer[PathName.Length/2] = 0;
                } else {
                    Status = STATUS_NOT_A_DIRECTORY;
                    __leave;
                }
            }

            if (!ParentMcb) {
                if (PathName.Buffer[0] != L'\\') {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                } else {
                    ParentMcb = Vcb->McbTree;
                }
            }

Dissecting:

            FsRtlDissectName(PathName, &RealName, &RemainName);

            if (((RemainName.Length != 0) && (RemainName.Buffer[0] == L'\\')) ||
                (RealName.Length >= 256*sizeof(WCHAR))) {
                Status = STATUS_OBJECT_NAME_INVALID;
                __leave;
            }

            if (RemainName.Length != 0) {

                PRFSD_MCB   RetMcb;

                Status = RfsdLookupFileName (
                                Vcb,
                                &RealName,
                                ParentMcb,
                                &RetMcb,
                                Inode      );

                if (!NT_SUCCESS(Status)) {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                ParentMcb = RetMcb;
                PathName  = RemainName;

                goto Dissecting;
            }

            if (FsRtlDoesNameContainWildCards(&RealName)) {
                Status = STATUS_OBJECT_NAME_INVALID;
                __leave;
            }

            ParentFcb = ParentMcb->RfsdFcb;

            if (!ParentFcb) {

                PRFSD_INODE pTmpInode = ExAllocatePool( PagedPool, 
                                                        sizeof(RFSD_INODE));
                if (!pTmpInode) {
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    __leave;
                }
				
				if(!RfsdLoadInode(Vcb, &(ParentMcb->Key), pTmpInode)) {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                ParentFcb = RfsdAllocateFcb(Vcb,  ParentMcb, pTmpInode);

                if (!ParentFcb) {
                    ExFreePool(pTmpInode);
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                    __leave;
                }

                bParentFcbCreated = TRUE;
                ParentFcb->ReferenceCount++;
            }

            // We need to create a new one ?
            if ((CreateDisposition == FILE_CREATE ) ||
                (CreateDisposition == FILE_OPEN_IF) ||
                (CreateDisposition == FILE_OVERWRITE_IF)) {

                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
                    IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
                                                  Vcb->Vpb->RealDevice );
                     SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);

                    RfsdRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
                }

                if (DirectoryFile) {
                    if (TemporaryFile) {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }

                if (!ParentFcb) {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                if (DirectoryFile) {
                    if ( RFSD_IS_ROOT_KEY(ParentFcb->RfsdMcb->Key) ) {
                        if ( (RealName.Length == 0x10) && 
                             memcmp(RealName.Buffer, L"Recycled\0", 0x10) == 0) {
                            SetFlag( IrpSp->Parameters.Create.FileAttributes,
                                     FILE_ATTRIBUTE_READONLY );
                        }
                    }

					Status = STATUS_UNSUCCESSFUL;
#if DISABLED
                    Status = RfsdCreateInode( IrpContext,
                                              Vcb, 
                                              ParentFcb,
                                              RFSD_FT_DIR,
                                              IrpSp->Parameters.Create.FileAttributes,
                                              &RealName);
#endif
                } else {
					Status = STATUS_UNSUCCESSFUL;
#if DISABLED
                    Status = RfsdCreateInode( IrpContext,
                                              Vcb,
                                              ParentFcb,
                                              RFSD_FT_REG_FILE,
                                              IrpSp->Parameters.Create.FileAttributes,
                                              &RealName);
#endif
                }
                
                if (NT_SUCCESS(Status)) {

                    bCreated = TRUE;

                    Irp->IoStatus.Information = FILE_CREATED;                    
                    Status = RfsdLookupFileName (
                                Vcb,
                                &RealName,
                                ParentMcb,
                                &RfsdMcb,
                                Inode      );

                    if (NT_SUCCESS(Status)) {

                        if (DirectoryFile) {
DbgBreak();
#if DISABLED		// dirctl.c  [ see also in cleanup.c ]
									RfsdNotifyReportChange(
                                   IrpContext,
                                   Vcb,
                                   ParentFcb,
                                   FILE_NOTIFY_CHANGE_DIR_NAME,
                                   FILE_ACTION_ADDED );
                        } else {
                            RfsdNotifyReportChange(
                                   IrpContext,
                                   Vcb,
                                   ParentFcb,
                                   FILE_NOTIFY_CHANGE_FILE_NAME,
                                   FILE_ACTION_ADDED );
#endif
								}
                    } else {
                        DbgBreak();
                    }
                } else {
                    DbgBreak();
                }
            } else if (OpenTargetDirectory) {
                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                if (!ParentFcb) {
                    Status = STATUS_OBJECT_PATH_NOT_FOUND;
                    __leave;
                }

                RtlZeroMemory( IrpSp->FileObject->FileName.Buffer,
                               IrpSp->FileObject->FileName.MaximumLength);
                IrpSp->FileObject->FileName.Length = RealName.Length;

                RtlCopyMemory( IrpSp->FileObject->FileName.Buffer,
                               RealName.Buffer,
                               RealName.Length );

                Fcb = ParentFcb;

                Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
                Status = STATUS_SUCCESS;
            } else {
                Status = STATUS_OBJECT_NAME_NOT_FOUND;
                __leave;
            }

        } else { // File / Dir already exists.

            if (OpenTargetDirectory) {

                if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
                    Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
                }

                Irp->IoStatus.Information = FILE_EXISTS;
                Status = STATUS_SUCCESS;

                RtlZeroMemory( IrpSp->FileObject->FileName.Buffer,
                               IrpSp->FileObject->FileName.MaximumLength);
                IrpSp->FileObject->FileName.Length = RfsdMcb->ShortName.Length;

                RtlCopyMemory( IrpSp->FileObject->FileName.Buffer,
                               RfsdMcb->ShortName.Buffer,
                               RfsdMcb->ShortName.Length );

                //Let Mcb pointer to it's parent
                RfsdMcb = RfsdMcb->Parent;

                goto Openit;
            }

            // We can not create if one exists
            if (CreateDisposition == FILE_CREATE) {
                Irp->IoStatus.Information = FILE_EXISTS;
                Status = STATUS_OBJECT_NAME_COLLISION;
                __leave;
            }

            if(IsFlagOn(RfsdMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY)) {

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

                    Status = STATUS_OBJECT_NAME_COLLISION;
                    __leave;
                }

                if (NonDirectoryFile) {
                    Status = STATUS_FILE_IS_A_DIRECTORY;
                    __leave;
                }

                if (RFSD_IS_ROOT_KEY(RfsdMcb->Key)) {

                    if (DeleteOnClose) {
                        Status = STATUS_CANNOT_DELETE;
                        __leave;
                    }

                    if (OpenTargetDirectory) {
                        Status = STATUS_INVALID_PARAMETER;
                        __leave;
                    }
                }
            }

            Irp->IoStatus.Information = FILE_OPENED;
        }

Openit:
        
        if (RfsdMcb) {

            Fcb = RfsdMcb->RfsdFcb;

            if (!Fcb) {
                Fcb = RfsdAllocateFcb (Vcb, RfsdMcb, Inode);
                bFcbAllocated = TRUE;
            }
        }
        
        if (Fcb) {

⌨️ 快捷键说明

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