Esempio n. 1
0
VOID
FatPrepareWriteVolumeFile (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN VBO StartingVbo,
    IN ULONG ByteCount,
    OUT PBCB *Bcb,
    OUT PVOID *Buffer,
    IN BOOLEAN Reversible,
    IN BOOLEAN Zero
    )

/*++

Routine Description:

    This routine first looks to see if the specified range of sectors,
    is already in the cache.  If so, it increments the BCB PinCount,
    sets the BCB dirty, and returns with the location of the sectors.

    If the sectors are not in the cache and Wait is TRUE, it finds a
    free BCB (potentially causing a flush), and clears out the entire
    buffer.  Once this is done, it increments the BCB PinCount, sets the
    BCB dirty, and returns with the location of the sectors.

    If the sectors are not in the cache and Wait is FALSE, this routine
    raises STATUS_CANT_WAIT.

Arguments:

    Vcb - Pointer to the VCB for the volume

    StartingVbo - The virtual offset of the first byte to be written

    ByteCount - Number of bytes to be written

    Bcb - Returns a pointer to the BCB which is valid until unpinned

    Buffer - Returns a pointer to the sectors, which is valid until unpinned

    Reversible - Supplies TRUE if the specified range of modification should
        be repinned so that the operation can be reversed in a controlled
        fashion if errors are encountered.
    
    Zero - Supplies TRUE if the specified range of bytes should be zeroed

--*/

{
    LARGE_INTEGER Vbo;

    PAGED_CODE();
    
    //
    //  Check to see that all references are within the Bios Parameter Block
    //  or the fat(s).
    //

    ASSERT( ((StartingVbo + ByteCount) <= (ULONG)
            (FatRootDirectoryLbo( &Vcb->Bpb ))));

    DebugTrace(+1, Dbg, "FatPrepareWriteVolumeFile\n", 0);
    DebugTrace( 0, Dbg, "Vcb         = %08lx\n", Vcb);
    DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", (ULONG)StartingVbo);
    DebugTrace( 0, Dbg, "ByteCount   = %08lx\n", ByteCount);
    DebugTrace( 0, Dbg, "Zero        = %08lx\n", Zero);

    //
    //  Call the Cache manager to attempt the transfer.
    //

    Vbo.QuadPart = StartingVbo;

    if (!CcPinRead( Vcb->VirtualVolumeFile,
                    &Vbo,
                    ByteCount,
                    BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
                    Bcb,
                    Buffer )) {

        ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

        //
        // Could not read the data without waiting (cache miss).
        //

        FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
    }

    //
    //  This keeps the data pinned until we complete the request
    //  and writes the dirty bit through to the disk.
    //

    DbgDoit( IrpContext->PinCount += 1 )

    try {

        if (Zero) {
            
            RtlZeroMemory( *Buffer, ByteCount );
        }

        FatSetDirtyBcb( IrpContext, *Bcb, Vcb, Reversible );

    } finally {

        if (AbnormalTermination()) {

            FatUnpinBcb(IrpContext, *Bcb);
        }
    }

    DebugTrace(-1, Dbg, "FatPrepareWriteVolumeFile -> VOID, *Bcb = %08lx\n", *Bcb);

    return;
}
Esempio n. 2
0
VOID
FatReadVolumeFile (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN VBO StartingVbo,
    IN ULONG ByteCount,
    OUT PBCB *Bcb,
    OUT PVOID *Buffer
    )

/*++

Routine Description:

    This routine is called when the specified range of sectors is to be
    read into the cache.  In fat, the volume file only contains the boot
    sector, reserved sectors, and the "fat(s)."  Thus the volume file is
    of fixed size and only extends up to (but not not including) the root
    directory entry, and will never move or change size.

    The fat volume file is also peculiar in that, since it starts at the
    logical beginning of the disk, Vbo == Lbo.

Arguments:

    Vcb - Pointer to the VCB for the volume

    StartingVbo - The virtual offset of the first desired byte

    ByteCount - Number of bytes desired

    Bcb - Returns a pointer to the BCB which is valid until unpinned

    Buffer - Returns a pointer to the sectors, which is valid until unpinned

--*/

{
    LARGE_INTEGER Vbo;

    PAGED_CODE();

    //
    //  Check to see that all references are within the Bios Parameter Block
    //  or the fat(s).  A special case is made when StartingVbo == 0 at
    //  mounting time since we do not know how big the fat is.
    //

    ASSERT( ((StartingVbo == 0) || ((StartingVbo + ByteCount) <= (ULONG)
            (FatRootDirectoryLbo( &Vcb->Bpb ) + PAGE_SIZE))));

    DebugTrace(+1, Dbg, "FatReadVolumeFile\n", 0);
    DebugTrace( 0, Dbg, "Vcb         = %08lx\n", Vcb);
    DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo);
    DebugTrace( 0, Dbg, "ByteCount   = %08lx\n", ByteCount);

    //
    //  Call the Cache manager to attempt the transfer.
    //

    Vbo.QuadPart = StartingVbo;

    if (!CcMapData( Vcb->VirtualVolumeFile,
                    &Vbo,
                    ByteCount,
                    BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
                    Bcb,
                    Buffer )) {

        ASSERT( !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );

        //
        // Could not read the data without waiting (cache miss).
        //

        FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
    }

    DbgDoit( IrpContext->PinCount += 1 )

    DebugTrace(-1, Dbg, "FatReadVolumeFile -> VOID, *BCB = %08lx\n", *Bcb);

    return;
}
Esempio n. 3
0
VOID
NTAPI
FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext,
                 IN PVCB Vcb)
{
    PFCB Dcb;

    /* Make sure it's not already created */
    ASSERT(!Vcb->RootDcb);

    /* Allocate the DCB */
    Dcb = FsRtlAllocatePoolWithTag(NonPagedPool,
                                   sizeof(FCB),
                                   TAG_FCB);

    /* Zero it */
    RtlZeroMemory(Dcb, sizeof(FCB));

    /* Assign it to the VCB */
    Vcb->RootDcb = Dcb;

    /* Set its header */
    Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB;
    Dcb->Header.NodeByteSize = sizeof(FCB);

    /* FCB is in a good condition */
    Dcb->Condition = FcbGood;

    /* Initialize FCB's resource */
    Dcb->Header.Resource = &Dcb->Resource;
    ExInitializeResourceLite(&Dcb->Resource);

    /* Initialize Paging Io resource*/
    Dcb->Header.PagingIoResource = &Dcb->PagingIoResource;
    ExInitializeResourceLite(&Dcb->PagingIoResource);

    /* Initialize a list of parent DCBs*/
    InitializeListHead(&Dcb->ParentDcbLinks);

    /* Set VCB */
    Dcb->Vcb = Vcb;

    /* Initialize parent's DCB list */
    InitializeListHead(&Dcb->Dcb.ParentDcbList);

    /* Initialize the full file name */
    Dcb->FullFileName.Buffer = L"\\";
    Dcb->FullFileName.Length = 1 * sizeof(WCHAR);
    Dcb->FullFileName.MaximumLength = 2 * sizeof(WCHAR);

    Dcb->ShortName.Name.Ansi.Buffer = "\\";
    Dcb->ShortName.Name.Ansi.Length = 1;
    Dcb->ShortName.Name.Ansi.MaximumLength = 2 * sizeof(CHAR);

    /* Fill dirent attribute byte copy */
    Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY;

    /* Initialize advanced FCB header fields */
    ExInitializeFastMutex(&Dcb->HeaderMutex);
    FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex);

    /* Set up first cluster field depending on FAT type */
    if (TRUE/*FatIsFat32(Vcb)*/)
    {
        /* First cluster is really the first cluster of this volume */
        Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster;

        /* Calculate size of FAT32 root dir */
        Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF;
        //FatLookupFileAllocationSize(IrpContext, Dcb);
        DPRINT1("Calculation of a size of a root dir is missing!\n");

        Dcb->Header.FileSize.QuadPart = Dcb->Header.AllocationSize.QuadPart;
    }
    else
    {
#if 0
        /* Add MCB entry */
        FatAddMcbEntry(Vcb,
                       &Dcb->Mcb,
                       0,
                       FatRootDirectoryLbo(&Vcb->Bpb),
                       FatRootDirectorySize(&Vcb->Bpb));

        /* Set a real size of the root directory */
        Dcb->Header.FileSize.QuadPart = FatRootDirectorySize(&Vcb->Bpb);
        Dcb->Header.AllocationSize.QuadPart = Dcb->Header.FileSize.QuadPart;
#endif
        UNIMPLEMENTED;
    }
}