create.c

来自「This is a ReiserFs file system driver fo」· C语言 代码 · 共 1,522 行 · 第 1/4 页

C
1,522
字号
            if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED)) {
                Status = STATUS_FILE_DELETED;
                __leave;
            }

            if (FlagOn(Fcb->Flags, FCB_DELETE_PENDING)) {
                Status = STATUS_DELETE_PENDING;
                __leave;
            }

            if (bCreated) {
DbgBreak();
#if DISABLED  // ONLY FOR WRITE SUPPORT?

                //
                //  This file is just created.
                //

                if (DirectoryFile) {
                    UNICODE_STRING EntryName;
                    USHORT  NameBuf[6];

                    RtlZeroMemory(&NameBuf, 6 * sizeof(USHORT));

                    EntryName.Length = EntryName.MaximumLength = 2;
                    EntryName.Buffer = &NameBuf[0];
                    NameBuf[0] = (USHORT)'.';

                    RfsdAddEntry( IrpContext, Vcb, Fcb,
                                  RFSD_FT_DIR,
                                  Fcb->RfsdMcb->Key,
                                  &EntryName );

                    RfsdSaveInode( IrpContext, Vcb,
                                   Fcb->RfsdMcb->Key,
                                   Fcb->Inode );

                    EntryName.Length = EntryName.MaximumLength = 4;
                    EntryName.Buffer = &NameBuf[0];
                    NameBuf[0] = NameBuf[1] = (USHORT)'.';

                    RfsdAddEntry( IrpContext, Vcb, Fcb,
                                  RFSD_FT_DIR,
                                  Fcb->RfsdMcb->Parent->Inode,
                                  &EntryName );

                    RfsdSaveInode( IrpContext, Vcb,
                                   Fcb->RfsdMcb->Parent->Inode,
                                   ParentFcb->Inode );
                } else {
DbgBreak();		 
#if DISABLED
                    Status = RfsdExpandFile(
                                IrpContext, Vcb, Fcb,
                                &(Irp->Overlay.AllocationSize));
#endif

                    if (!NT_SUCCESS(Status)) {

                        DbgBreak();

                        __leave;
                    }
                }
#endif
            } else {

                //
                //  This file alreayd exists.
                //

                if (DeleteOnClose) {

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

                    if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
                        Status = STATUS_MEDIA_WRITE_PROTECTED;

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

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

                        RfsdRaiseStatus(IrpContext, STATUS_MEDIA_WRITE_PROTECTED);
                    }

                    SetFlag(Fcb->Flags, FCB_DELETE_ON_CLOSE);

                } else {

                    //
                    // Just to Open file (Open/OverWrite ...)
                    //

                    if ((!IsDirectory(Fcb)) && (IsFlagOn(IrpSp->FileObject->Flags,
                                                FO_NO_INTERMEDIATE_BUFFERING))) {
                        Fcb->Header.IsFastIoPossible = FastIoIsPossible;

                        if (IsFlagOn(IrpSp->FileObject->Flags, FO_CACHE_SUPPORTED) &&
                            (Fcb->SectionObject.DataSectionObject != NULL)) {

                            if (Fcb->NonCachedOpenCount == Fcb->OpenHandleCount) {
                                /* IsFlagOn(FileObject->Flags, FO_FILE_MODIFIED) */

                                if(!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
                                    CcFlushCache(&Fcb->SectionObject, NULL, 0, NULL);
                                    ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
                                }

                                CcPurgeCacheSection(&Fcb->SectionObject,
                                                     NULL,
                                                     0,
                                                     FALSE );
                            }
                        }
                    }
                }
            }

            if (!IsDirectory(Fcb)) {
                if (!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) {
                    if ((CreateDisposition == FILE_SUPERSEDE) && !IsPagingFile){
                        DesiredAccess |= DELETE;
                    } else if (((CreateDisposition == FILE_OVERWRITE) ||
                            (CreateDisposition == FILE_OVERWRITE_IF)) && !IsPagingFile) {
                        DesiredAccess |= (FILE_WRITE_DATA | FILE_WRITE_EA |
                                          FILE_WRITE_ATTRIBUTES );
                    }
                }
            }

            if (Fcb->OpenHandleCount > 0) {
                Status = IoCheckShareAccess( DesiredAccess,
                                             ShareAccess,
                                             IrpSp->FileObject,
                                             &(Fcb->ShareAccess),
                                             TRUE );

                if (!NT_SUCCESS(Status)) {
                    __leave;
                }
            } else {
                IoSetShareAccess( DesiredAccess,
                                  ShareAccess,
                                  IrpSp->FileObject,
                                  &(Fcb->ShareAccess) );
            }

            Ccb = RfsdAllocateCcb();

            Fcb->OpenHandleCount++;
            Fcb->ReferenceCount++;

            if (IsFlagOn(IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING)) {
                Fcb->NonCachedOpenCount++;
            }

            Vcb->OpenFileHandleCount++;
            Vcb->ReferenceCount++;
            
            IrpSp->FileObject->FsContext = (void*)Fcb;
            IrpSp->FileObject->FsContext2 = (void*) Ccb;
            IrpSp->FileObject->PrivateCacheMap = NULL;
            IrpSp->FileObject->SectionObjectPointer = &(Fcb->SectionObject);
            IrpSp->FileObject->Vpb = Vcb->Vpb;

            Status = STATUS_SUCCESS;

            RfsdPrint((DBG_INFO, "RfsdCreateFile: %s OpenCount: %u ReferCount: %u\n",
                Fcb->AnsiFileName.Buffer, Fcb->OpenHandleCount, Fcb->ReferenceCount));

            if (!IsDirectory(Fcb) && !NoIntermediateBuffering ) {
                IrpSp->FileObject->Flags |= FO_CACHE_SUPPORTED;
            }

            if (!bCreated && !IsDirectory(Fcb)) {
                if ( DeleteOnClose || 
                    IsFlagOn(DesiredAccess, FILE_WRITE_DATA) || 
                    (CreateDisposition == FILE_OVERWRITE) ||
                    (CreateDisposition == FILE_OVERWRITE_IF)) {
                    if (!MmFlushImageSection( &Fcb->SectionObject,
                                              MmFlushForWrite )) {

                        Status = DeleteOnClose ? STATUS_CANNOT_DELETE :
                                                 STATUS_SHARING_VIOLATION;
                        __leave;
                    }
                }

                if ((CreateDisposition == FILE_SUPERSEDE) ||
                    (CreateDisposition == FILE_OVERWRITE) ||
                    (CreateDisposition == FILE_OVERWRITE_IF)) {

#if RFSD_READ_ONLY
					Status = STATUS_MEDIA_WRITE_PROTECTED;
                    __leave;
#endif


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

                    Status = RfsdSupersedeOrOverWriteFile( IrpContext,
                                                  Vcb,
                                                  Fcb,
                                                  CreateDisposition );

                    if (NT_SUCCESS(Status)) {
                        __leave;
                    }

DbgBreak();
#if DISABLED   
                    Status = RfsdExpandFile(
                                IrpContext,
                                Vcb,
                                Fcb,
                                &(Irp->Overlay.AllocationSize));
#endif

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

DbgBreak();
#if DISABLED   // dirctl.c
                    RfsdNotifyReportChange(
                               IrpContext,
                               Vcb,
                               Fcb,
                               FILE_NOTIFY_CHANGE_LAST_WRITE |
                               FILE_NOTIFY_CHANGE_ATTRIBUTES |
                               FILE_NOTIFY_CHANGE_SIZE,
                               FILE_ACTION_MODIFIED );
#endif

                    if (CreateDisposition == FILE_SUPERSEDE) {
                        Irp->IoStatus.Information = FILE_SUPERSEDED;
                    } else {
                        Irp->IoStatus.Information = FILE_OVERWRITTEN;
                    }
#endif
                }
            }
        }
    } __finally {

        if (FileName.Buffer)
            ExFreePool(FileName.Buffer);

        if (bParentFcbCreated) {
            ParentFcb->ReferenceCount--;
        }

        if (VcbResourceAcquired) {
            ExReleaseResourceForThreadLite(
                &Vcb->MainResource,
                ExGetCurrentResourceThread() );
        }

        if (!bFcbAllocated) {
            if (Inode)
                ExFreePool(Inode);
        } else {
            if (!Fcb && Inode)
                ExFreePool(Inode);
        }
    }
    
    return Status;
}

NTSTATUS
RfsdCreateVolume(PRFSD_IRP_CONTEXT IrpContext, PRFSD_VCB Vcb)
{
    PIO_STACK_LOCATION  IrpSp;
    PIRP                Irp;

    NTSTATUS            Status;

    ACCESS_MASK         DesiredAccess;
    ULONG               ShareAccess;

    ULONG               Options;
    BOOLEAN             DirectoryFile;
    BOOLEAN             OpenTargetDirectory;

    ULONG               CreateDisposition;

	RfsdPrint((DBG_FUNC, "Entering CreateVolume\n"));

    Irp = IrpContext->Irp;
    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    Options  = IrpSp->Parameters.Create.Options;
    
    DirectoryFile = IsFlagOn(Options, FILE_DIRECTORY_FILE);
    OpenTargetDirectory = IsFlagOn(IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);

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

    DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess;
    ShareAccess   = IrpSp->Parameters.Create.ShareAccess;

    if (DirectoryFile) {
        return STATUS_NOT_A_DIRECTORY;
    }

    if (OpenTargetDirectory) {
        return STATUS_INVALID_PARAMETER;
    }

    if ( (CreateDisposition != FILE_OPEN) && 
         (CreateDisposition != FILE_OPEN_IF) ) {
        return STATUS_ACCESS_DENIED;
    }

    Status = STATUS_SUCCESS;

    if (Vcb->OpenHandleCount > 0) {
        Status = IoCheckShareAccess( DesiredAccess, ShareAccess,
                                     IrpSp->FileObject,
                                     &(Vcb->ShareAccess), TRUE);

        if (!NT_SUCCESS(Status)) {
            goto errorout;
        }
    } else {
        IoSetShareAccess( DesiredAccess, ShareAccess,
                          IrpSp->FileObject,
                          &(Vcb->ShareAccess)   );
    }

    if (FlagOn(DesiredAccess, FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA)) {
        ExAcquireResourceExclusive(&Vcb->MainResource, TRUE);

	    RfsdFlushFiles(Vcb, FALSE);
	    RfsdFlushVolume(Vcb, FALSE);

        ExReleaseResource(&Vcb->MainResource);
    }

    {
        PRFSD_CCB   Ccb = RfsdAllocateCcb();

        if (Ccb == NULL) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto errorout;
        }

        IrpSp->FileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
        IrpSp->FileObject->FsContext  = Vcb;
        IrpSp->FileObject->FsContext2 = Ccb;

        Vcb->ReferenceCount++;
        Vcb->OpenHandleCount++;

        Irp->IoStatus.Information = FILE_OPENED;
    }

errorout:

    return Status;
}


⌨️ 快捷键说明

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