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

📄 write.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * COPYRIGHT:        GNU GENERAL PUBLIC LICENSE VERSION 2
 * PROJECT:          ReiserFs file system driver for Windows NT/2000/XP/Vista.
 * FILE:             write.c
 * PURPOSE:          
 * PROGRAMMER:       Mark Piper, Matt Wu, Bo Brant閚.
 * HOMEPAGE:         
 * UPDATE HISTORY: 
 */
#if 0
/* INCLUDES *****************************************************************/

#include "rfsd.h"

/* GLOBALS ***************************************************************/

extern PRFSD_GLOBAL RfsdGlobal;

/* DEFINITIONS *************************************************************/

typedef struct _RFSD_FLPFLUSH_CONTEXT {

    PRFSD_VCB    Vcb;
    PRFSD_FCB    Fcb;
    PFILE_OBJECT FileObject;

    KDPC        Dpc;
    KTIMER      Timer;
    WORK_QUEUE_ITEM Item;

} RFSD_FLPFLUSH_CONTEXT, *PRFSD_FLPFLUSH_CONTEXT;

VOID
RfsdFloppyFlush(IN PVOID Parameter);

VOID
RfsdFloppyFlushDpc (
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2);



NTSTATUS
RfsdWriteComplete (IN PRFSD_IRP_CONTEXT IrpContext);

NTSTATUS
RfsdWriteFile (IN PRFSD_IRP_CONTEXT IrpContext);

NTSTATUS
RfsdWriteVolume (IN PRFSD_IRP_CONTEXT IrpContext);

VOID
RfsdDeferWrite(IN PRFSD_IRP_CONTEXT, PIRP Irp);

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, RfsdFloppyFlush)
#pragma alloc_text(PAGE, RfsdStartFloppyFlushDpc)
#pragma alloc_text(PAGE, RfsdZeroHoles)
#pragma alloc_text(PAGE, RfsdWrite)
#pragma alloc_text(PAGE, RfsdWriteVolume)
#pragma alloc_text(PAGE, RfsdWriteInode)
#pragma alloc_text(PAGE, RfsdWriteFile)
#pragma alloc_text(PAGE, RfsdWriteComplete)
#endif

/* FUNCTIONS *************************************************************/

VOID
RfsdFloppyFlush(IN PVOID Parameter)
{
    PRFSD_FLPFLUSH_CONTEXT Context;
    PFILE_OBJECT           FileObject;
    PRFSD_FCB Fcb;
    PRFSD_VCB Vcb;

    Context = (PRFSD_FLPFLUSH_CONTEXT) Parameter;
    FileObject = Context->FileObject;
    Fcb = Context->Fcb;
    Vcb = Context->Vcb;

    RfsdPrint((DBG_USER, "RfsdFloppyFlushing ...\n"));

    IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP);

    if (Vcb) {
        ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
        ExReleaseResource(&Vcb->PagingIoResource);

        CcFlushCache(&(Vcb->SectionObject), NULL, 0, NULL);
    }

    if (FileObject) {
        ASSERT(Fcb == (PRFSD_FCB)FileObject->FsContext);

        ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
        ExReleaseResource(&Fcb->PagingIoResource);

        CcFlushCache(&(Fcb->SectionObject), NULL, 0, NULL);

        ObDereferenceObject(FileObject);
    }

    IoSetTopLevelIrp(NULL);

    ExFreePool(Parameter);
}

VOID
RfsdFloppyFlushDpc (
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2
    )
{
    PRFSD_FLPFLUSH_CONTEXT Context;

    Context = (PRFSD_FLPFLUSH_CONTEXT) DeferredContext;

    RfsdPrint((DBG_USER, "RfsdFloppyFlushDpc is to be started...\n"));

    ExInitializeWorkItem( &Context->Item,
                          RfsdFloppyFlush,
                          Context );

    ExQueueWorkItem(&Context->Item, CriticalWorkQueue);
}

VOID
RfsdStartFloppyFlushDpc (
    PRFSD_VCB   Vcb,
    PRFSD_FCB   Fcb,
    PFILE_OBJECT FileObject )
{
    LARGE_INTEGER          OneSecond;
    PRFSD_FLPFLUSH_CONTEXT Context;

    ASSERT(IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK));

    Context = ExAllocatePool(NonPagedPool,sizeof(PRFSD_FLPFLUSH_CONTEXT));

    if (!Context) {
        DbgBreak();
        return;
    }

    KeInitializeTimer(&Context->Timer);

    KeInitializeDpc( &Context->Dpc,
                     RfsdFloppyFlushDpc,
                     Context );

    Context->Vcb = Vcb;
    Context->Fcb = Fcb;
    Context->FileObject = FileObject;

    if (FileObject) {
        ObReferenceObject(FileObject);
    }

    OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
    KeSetTimer( &Context->Timer,
                OneSecond,
                &Context->Dpc );
}

BOOLEAN
RfsdZeroHoles (
    IN PRFSD_IRP_CONTEXT IrpContext,
    IN PRFSD_VCB Vcb,
    IN PFILE_OBJECT FileObject,
    IN LONGLONG Offset,
    IN LONGLONG Count
    )
{
    LARGE_INTEGER StartAddr = {0,0};
    LARGE_INTEGER EndAddr = {0,0};

    StartAddr.QuadPart = (Offset + (SECTOR_SIZE - 1)) &
                         ~((LONGLONG)SECTOR_SIZE - 1);

    EndAddr.QuadPart = (Offset + Count + (SECTOR_SIZE - 1)) &
                       ~((LONGLONG)SECTOR_SIZE - 1);

    if (StartAddr.QuadPart < EndAddr.QuadPart) {
        return CcZeroData( FileObject,
                       &StartAddr,
                       &EndAddr,
                       IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
    }

    return TRUE;
}


VOID
RfsdDeferWrite(IN PRFSD_IRP_CONTEXT IrpContext, PIRP Irp)
{
    ASSERT(IrpContext->Irp == Irp);

    RfsdQueueRequest(IrpContext);
}


NTSTATUS
RfsdWriteVolume (IN PRFSD_IRP_CONTEXT IrpContext)
{
    NTSTATUS            Status = STATUS_UNSUCCESSFUL;

    PRFSD_VCB           Vcb;
    PRFSD_CCB           Ccb;
    PRFSD_FCBVCB        FcbOrVcb;
    PFILE_OBJECT        FileObject;

    PDEVICE_OBJECT      DeviceObject;

    PIRP                Irp;
    PIO_STACK_LOCATION  IoStackLocation;

    ULONG               Length;
    LARGE_INTEGER       ByteOffset;

    BOOLEAN             PagingIo;
    BOOLEAN             Nocache;
    BOOLEAN             SynchronousIo;
    BOOLEAN             MainResourceAcquired = FALSE;
    BOOLEAN             PagingIoResourceAcquired = FALSE;

    BOOLEAN             bDeferred = FALSE;

    PUCHAR              Buffer;

    __try {

        ASSERT(IrpContext);
        
        ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
            (IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
        
        DeviceObject = IrpContext->DeviceObject;
    
        Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
        
        ASSERT(Vcb != NULL);
        
        ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
            (Vcb->Identifier.Size == sizeof(RFSD_VCB)));
        
        FileObject = IrpContext->FileObject;

        FcbOrVcb = (PRFSD_FCBVCB) FileObject->FsContext;
        
        ASSERT(FcbOrVcb);
        
        if (!(FcbOrVcb->Identifier.Type == RFSDVCB && (PVOID)FcbOrVcb == (PVOID)Vcb)) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        Ccb = (PRFSD_CCB) FileObject->FsContext2;

        Irp = IrpContext->Irp;
            
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
            
        Length = IoStackLocation->Parameters.Write.Length;
        ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;
            
        PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
        Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
        SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);

        RfsdPrint((DBG_INFO, "RfsdWriteVolume: Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
                             ByteOffset.QuadPart, Length, PagingIo, Nocache));

        if (Length == 0) {
            Irp->IoStatus.Information = 0;
            Status = STATUS_SUCCESS;
            __leave;
        }
      
        // For the case of "Direct Access Storage Device", we
        // need flush/purge the cache
    
        if (Ccb != NULL) {

            ExAcquireResourceExclusive(&Vcb->MainResource, TRUE);
            MainResourceAcquired = TRUE;

            Status = RfsdPurgeVolume( Vcb, TRUE);

            ExReleaseResource(&Vcb->MainResource);
            MainResourceAcquired = FALSE;

            if(!IsFlagOn(Ccb->Flags, CCB_ALLOW_EXTENDED_DASD_IO)) {
                if (ByteOffset.QuadPart + Length > Vcb->Header.FileSize.QuadPart) {
                    Length = (ULONG)(Vcb->Header.FileSize.QuadPart - ByteOffset.QuadPart);
                }
            }

            {
                RFSD_BDL BlockArray;

                if ((ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
                   (Length & (SECTOR_SIZE - 1)) ) {
                    Status = STATUS_INVALID_PARAMETER;
                    __leave;
                }

                Status = RfsdLockUserBuffer(
                    IrpContext->Irp,
                    Length,
                    IoReadAccess );
                
                if (!NT_SUCCESS(Status)) {
                    __leave;
                }

                BlockArray.Irp = NULL;
                BlockArray.Lba = ByteOffset.QuadPart;;
                BlockArray.Offset = 0;
                BlockArray.Length = Length;

                Status = RfsdReadWriteBlocks(IrpContext,
                                    Vcb,
                                    &BlockArray,
                                    Length,
                                    1,
                                    FALSE   );
                Irp = IrpContext->Irp;

                __leave;
            }
        }                    

        if (Nocache &&
           (ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
            Length & (SECTOR_SIZE - 1))) {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
            ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
            Status = STATUS_PENDING;
            __leave;
        }
        
        if (ByteOffset.QuadPart >=
            Vcb->PartitionInformation.PartitionLength.QuadPart  ) {
            Irp->IoStatus.Information = 0;
            Status = STATUS_END_OF_FILE;
            __leave;
        }

#if FALSE

        if (!Nocache) {

            BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
            BOOLEAN bWait  = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
            BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);

            if ( !CcCanIWrite( 
                      FileObject,
                      Length,
                      (bWait && bQueue),
                      bAgain ) ) {

                SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);

                CcDeferWrite( FileObject,
                              (PCC_POST_DEFERRED_WRITE)RfsdDeferWrite,
                              IrpContext,
                              Irp,
                              Length,
                              bAgain );

                bDeferred = TRUE;

                DbgBreak();

                Status = STATUS_PENDING;

                __leave;
            }
        }

#endif

        if (Nocache && !PagingIo && (Vcb->SectionObject.DataSectionObject != NULL))  {

            ExAcquireResourceExclusive(&Vcb->MainResource, TRUE);
            MainResourceAcquired = TRUE;

            ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
            ExReleaseResource(&Vcb->PagingIoResource);

            CcFlushCache( &(Vcb->SectionObject),
                          &ByteOffset,
                          Length,
                          &(Irp->IoStatus));

            if (!NT_SUCCESS(Irp->IoStatus.Status))  {
                Status = Irp->IoStatus.Status;
                __leave;
            }

            ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
            ExReleaseResource(&Vcb->PagingIoResource);

            CcPurgeCacheSection( &(Vcb->SectionObject),
                                 (PLARGE_INTEGER)&(ByteOffset),
                                 Length,
                                 FALSE );

            ExReleaseResource(&Vcb->MainResource);
            MainResourceAcquired = FALSE;
        }

        if (!PagingIo) {

            if (!ExAcquireResourceExclusiveLite(
                &Vcb->MainResource,
                IrpContext->IsSynchronous )) {
                Status = STATUS_PENDING;
                __leave;
            }
            
            MainResourceAcquired = TRUE;

        } else {

/*
            ULONG ResShCnt, ResExCnt; 
            ResShCnt = ExIsResourceAcquiredSharedLite(&Vcb->PagingIoResource);
            ResExCnt = ExIsResourceAcquiredExclusiveLite(&Vcb->PagingIoResource);

            RfsdPrint((DBG_USER, "PagingIoRes: %xh:%xh Synchronous=%xh\n", ResShCnt, ResExCnt, IrpContext->IsSynchronous));
*/

            if (Ccb) {

                if (!ExAcquireResourceSharedLite(
                    &Vcb->PagingIoResource,
                    IrpContext->IsSynchronous )) {
                    Status = STATUS_PENDING;
                    __leave;
                }
            
                PagingIoResourceAcquired = TRUE;
            }
        }
        
        if (!Nocache) {

            if ( (ByteOffset.QuadPart + Length) >
                 Vcb->PartitionInformation.PartitionLength.QuadPart ){
                Length = (ULONG) (
                    Vcb->PartitionInformation.PartitionLength.QuadPart -
                    ByteOffset.QuadPart);

                Length &= ~((ULONG)SECTOR_SIZE - 1);
            }

            if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {

                CcPrepareMdlWrite (
                    Vcb->StreamObj,
                    &ByteOffset,
                    Length,

⌨️ 快捷键说明

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