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

📄 allocsup.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    AllocSup.c

Abstract:

    This module implements mappings to physical blocks on UDF media.  The basic
    structure used here is the Pcb, which contains lookup information for each
    partition reference in the volume.

Author:

    Dan Lovinger    [DanLo]   5-Sep-1996

Revision History:

--*/

#include "UdfProcs.h"

//
//  The Bug check file id for this module
//

#define BugCheckFileId                   (UDFS_BUG_CHECK_ALLOCSUP)

//
//  The local debug trace level
//

#define Dbg                              (UDFS_DEBUG_LEVEL_ALLOCSUP)

//
//  Local support routines.
//

PPCB
UdfCreatePcb (
    IN ULONG NumberOfPartitions
    );

NTSTATUS
UdfLoadSparingTables(
    PIRP_CONTEXT IrpContext,
    PVCB Vcb,
    PPCB Pcb,
    ULONG Reference
    );


#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfAddToPcb)
#pragma alloc_text(PAGE, UdfCompletePcb)
#pragma alloc_text(PAGE, UdfCreatePcb)
#pragma alloc_text(PAGE, UdfDeletePcb)
#pragma alloc_text(PAGE, UdfEquivalentPcb)
#pragma alloc_text(PAGE, UdfInitializePcb)
#pragma alloc_text(PAGE, UdfLookupAllocation)
#pragma alloc_text(PAGE, UdfLookupMetaVsnOfExtent)
#pragma alloc_text(PAGE, UdfLookupPsnOfExtent)
#endif


BOOLEAN
UdfLookupAllocation (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN LONGLONG FileOffset,
    OUT PLONGLONG DiskOffset,
    OUT PULONG ByteCount
    )

/*++

Routine Description:

    This routine looks through the mapping information for the file
    to find the logical diskoffset and number of bytes at that offset.

    This routine assumes we are looking up a valid range in the file.  If
    a mapping does not exist,

Arguments:

    Fcb - Fcb representing this stream.

    FileOffset - Lookup the allocation beginning at this point.

    DiskOffset - Address to store the logical disk offset.

    ByteCount - Address to store the number of contiguous bytes beginning
        at DiskOffset above.

Return Value:

    BOOLEAN - whether the extent is unrecorded data

--*/

{
    PVCB Vcb;

    BOOLEAN Recorded = TRUE;

    BOOLEAN Result;

    LARGE_INTEGER LocalPsn;
    LARGE_INTEGER LocalSectorCount;

    PAGED_CODE();

    //
    //  Check inputs
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_FCB( Fcb );

    //
    //  We will never be looking up the allocations of embedded objects.
    //

    ASSERT( !FlagOn( Fcb->FcbState, FCB_STATE_EMBEDDED_DATA ));

    Vcb = Fcb->Vcb;

    LocalPsn.QuadPart = LocalSectorCount.QuadPart = 0;

    //
    //  Lookup the entry containing this file offset.
    //

    if (FlagOn( Fcb->FcbState, FCB_STATE_VMCB_MAPPING )) {

        //
        //  Map this offset into the metadata stream.
        //

        ASSERT( SectorOffset( Vcb, FileOffset ) == 0 );

        Result = UdfVmcbVbnToLbn( &Vcb->Vmcb,
                                  SectorsFromBytes( Vcb, FileOffset ),
                                  &LocalPsn.LowPart,
                                  &LocalSectorCount.LowPart );

        ASSERT( Result );

    } else {

        //
        //  Map this offset in a regular stream.
        //

        ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MCB_INITIALIZED ));

        Result = FsRtlLookupLargeMcbEntry( &Fcb->Mcb,
                                           LlSectorsFromBytes( Vcb, FileOffset ),
                                           &LocalPsn.QuadPart,
                                           &LocalSectorCount.QuadPart,
                                           NULL,
                                           NULL,
                                           NULL );
    }

    //
    //  If within the Mcb then we use the data out of this entry and are nearly done.
    //

    if (Result) {

        if ( LocalPsn.QuadPart == -1 ) {

            //
            //  Regular files can have holey allocations which represent unrecorded extents.  For
            //  such extents which are sandwiched in between recorded extents of the file, the Mcb
            //  package tells us that it found a valid mapping but that it doesn't correspond to
            //  any extents on the media yet.  In this case, simply fake the disk offset.  The
            //  returned sector count is accurate.
            //

            *DiskOffset = 0;

            Recorded = FALSE;

        } else {

            //
            //  Now mimic the effects of physical sector sparing.  This may shrink the size of the
            //  returned run if sparing interrupted the extent on disc.
            //

            ASSERT( LocalPsn.HighPart == 0 );

            if (Vcb->Pcb->SparingMcb) {

                LONGLONG SparingPsn;
                LONGLONG SparingSectorCount;

                if (FsRtlLookupLargeMcbEntry( Vcb->Pcb->SparingMcb,
                                              LocalPsn.LowPart,
                                              &SparingPsn,
                                              &SparingSectorCount,
                                              NULL,
                                              NULL,
                                              NULL )) {

                    //
                    //  Only emit noise if we will really change anything as a result
                    //  of the sparing table.
                    //

                    if (SparingPsn != -1 ||
                        SparingSectorCount < LocalSectorCount.QuadPart) {

                        DebugTrace(( 0, Dbg, "UdfLookupAllocation, spared [%x, +%x) onto [%x, +%x)\n",
                                             LocalPsn.LowPart,
                                             LocalSectorCount.LowPart,
                                             (ULONG) SparingPsn,
                                             (ULONG) SparingSectorCount ));
                    }

                    //
                    //  If we did not land in a hole, map the sector.
                    //

                    if (SparingPsn != -1) {

                        LocalPsn.QuadPart = SparingPsn;
                    }

                    //
                    //  The returned sector count now reduces the previous sector count.
                    //  If we landed in a hole, this indicates that the trailing edge of
                    //  the extent is spared, if not this indicates that the leading
                    //  edge is spared.
                    //

                    if (SparingSectorCount < LocalSectorCount.QuadPart) {

                        LocalSectorCount.QuadPart = SparingSectorCount;
                    }
                }
            }

            *DiskOffset = LlBytesFromSectors( Vcb, LocalPsn.QuadPart ) + SectorOffset( Vcb, FileOffset );

            //
            //  Now we can apply method 2 fixups, which will again interrupt the size of the extent.
            //

            if (FlagOn( Vcb->VcbState, VCB_STATE_METHOD_2_FIXUP )) {

                LARGE_INTEGER SectorsToRunout;

                SectorsToRunout.QuadPart= UdfMethod2NextRunoutInSectors( Vcb, *DiskOffset );

                if (SectorsToRunout.QuadPart < LocalSectorCount.QuadPart) {

                    LocalSectorCount.QuadPart = SectorsToRunout.QuadPart;
                }

                *DiskOffset = UdfMethod2TransformByteOffset( Vcb, *DiskOffset );
            }
        }

    } else {

        //
        //  We know that prior to this call the system has restricted IO to points within the
        //  the file data.  Since we failed to find a mapping this is an unrecorded extent at
        //  the end of the file, so just conjure up a proper representation.
        //

        ASSERT( FileOffset < Fcb->FileSize.QuadPart );

        *DiskOffset = 0;

        LocalSectorCount.QuadPart = LlSectorsFromBytes( Vcb, Fcb->FileSize.QuadPart ) -
                                    LlSectorsFromBytes( Vcb, FileOffset ) +
                                    1;

        Recorded = FALSE;
    }

    //
    //  Restrict to MAXULONG bytes of allocation
    //

    if (LocalSectorCount.QuadPart > SectorsFromBytes( Vcb, MAXULONG )) {

        *ByteCount = MAXULONG;

    } else {

        *ByteCount = BytesFromSectors( Vcb, LocalSectorCount.LowPart );
    }

    *ByteCount -= SectorOffset( Vcb, FileOffset );

    return Recorded;
}


VOID
UdfDeletePcb (
    IN PPCB Pcb
    )

/*++

Routine Description:

    This routine deallocates a Pcb and all ancilliary structures.

Arguments:

    Pcb - Pcb being deleted

Return Value:

    None

--*/

{
    PPARTITION Partition;

    if (Pcb->SparingMcb) {

        FsRtlUninitializeLargeMcb( Pcb->SparingMcb );
        UdfFreePool( &Pcb->SparingMcb );
    }

    for (Partition = Pcb->Partition;
         Partition < &Pcb->Partition[Pcb->Partitions];
         Partition++) {

        switch (Partition->Type) {

            case Physical:

                UdfFreePool( &Partition->Physical.PartitionDescriptor );
                UdfFreePool( &Partition->Physical.SparingMap );                

                break;

            case Virtual:
            case Uninitialized:
                break;

            default:

                ASSERT( FALSE );
                break;
        }
    }

    ExFreePool( Pcb );
}


NTSTATUS
UdfInitializePcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN OUT PPCB *Pcb,
    IN PNSR_LVOL LVD
    )

/*++

Routine Description:

    This routine walks through the partition map of a Logical Volume Descriptor
    and builds an intializing Pcb from it.  The Pcb will be ready to be used
    in searching for the partition descriptors of a volume.

Arguments:

    Vcb - The volume this Pcb will pertain to

    Pcb - Caller's pointer to the Pcb

    LVD - The Logical Volume Descriptor being used

Return Value:

    STATUS_SUCCESS if the partition map is good and the Pcb is built

    STATUS_DISK_CORRUPT_ERROR if corrupt maps are found

    STATUS_UNRECOGNIZED_VOLUME if noncompliant maps are found

--*/

{
    PPARTMAP_UDF_GENERIC Map;
    PPARTITION Partition;

    BOOLEAN Found;

    PAGED_CODE();

    //
    //  Check the input parameters
    //

    ASSERT_OPTIONAL_PCB( *Pcb );

    DebugTrace(( +1, Dbg,
                 "UdfInitializePcb, Lvd %08x\n",
                 LVD ));

⌨️ 快捷键说明

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