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

📄 allocsup.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 4 页
字号:
    //
    //  Delete a pre-existing (partially initialized from a failed
    //  crawl of a VDS) Pcb.
    //

    if (*Pcb != NULL) {

        UdfDeletePcb( *Pcb );
        *Pcb = NULL;
    }

    *Pcb = UdfCreatePcb( LVD->MapTableCount );

    //
    //  Walk the table of partition maps intializing the Pcb for the descriptor
    //  initialization pass.
    //

    for (Map = (PPARTMAP_UDF_GENERIC) LVD->MapTable,
         Partition = (*Pcb)->Partition;

         Partition < &(*Pcb)->Partition[(*Pcb)->Partitions];

         Map = Add2Ptr( Map, Map->Length, PPARTMAP_UDF_GENERIC ),
         Partition++) {

        //
        //  Now check that this LVD can actually contain this map entry.  First check that
        //  the descriptor can contain the first few fields, then check that it can hold
        //  all of the bytes claimed by the descriptor.
        //

        if (Add2Ptr( Map, sizeof( PARTMAP_GENERIC ), PCHAR ) > Add2Ptr( LVD, ISONsrLvolSize( LVD ), PCHAR ) ||
            Add2Ptr( Map, Map->Length,               PCHAR ) > Add2Ptr( LVD, ISONsrLvolSize( LVD ), PCHAR )) {

            DebugTrace(( 0, Dbg,
                         "UdfInitializePcb, map at +%04x beyond Lvd size %04x\n",
                         (PCHAR) Map - (PCHAR) LVD,
                         ISONsrLvolSize( LVD )));

            DebugTrace(( -1, Dbg,
                         "UdfInitializePcb -> STATUS_DISK_CORRUPT_ERROR\n" ));

            return STATUS_DISK_CORRUPT_ERROR;
        }

        //
        //  Now load up this map entry.
        //

        switch (Map->Type) {

            case PARTMAP_TYPE_PHYSICAL:

                {
                    PPARTMAP_PHYSICAL MapPhysical = (PPARTMAP_PHYSICAL) Map;

                    //
                    //  Type 1 - Physical Partition
                    //

                    DebugTrace(( 0, Dbg,
                                 "UdfInitializePcb, map reference %02x is Physical (Partition # %08x)\n",
                                 (Partition - (*Pcb)->Partition)/sizeof(PARTITION),
                                 MapPhysical->Partition ));

                    //
                    //  It must be the case that the volume the partition is on is the first
                    //  one since we only do single disc UDF.  This will have already been
                    //  checked by the caller.
                    //

                    if (MapPhysical->VolSetSeq > 1) {

                        DebugTrace(( 0, Dbg,
                                     "UdfInitializePcb, ... but physical partition resides on volume set volume # %08x (> 1)!\n",
                                     MapPhysical->VolSetSeq ));

                        DebugTrace(( -1, Dbg,
                                     "UdfInitializePcb -> STATUS_DISK_CORRUPT_ERROR\n" ));

                        return STATUS_DISK_CORRUPT_ERROR;
                    }

                    SetFlag( (*Pcb)->Flags, PCB_FLAG_PHYSICAL_PARTITION );
                    Partition->Type = Physical;
                    Partition->Physical.PartitionNumber = MapPhysical->Partition;
                }

                break;

            case PARTMAP_TYPE_PROXY:

                //
                //  Type 2 - a Proxy Partition, something not explicitly physical.
                //

                DebugTrace(( 0, Dbg,
                             "UdfInitializePcb, map reference %02x is a proxy\n",
                             (Partition - (*Pcb)->Partition)/sizeof(PARTITION)));

                //
                //  Handle the various types of proxy partitions we recognize
                //

                if (UdfDomainIdentifierContained( &Map->PartID,
                                                  &UdfVirtualPartitionDomainIdentifier,
                                                  UDF_VERSION_150,
                                                  UDF_VERSION_RECOGNIZED )) {

                    {
                        PPARTMAP_VIRTUAL MapVirtual = (PPARTMAP_VIRTUAL) Map;

                        //
                        //  Only one of these guys can exist, since there can be only one VAT per media surface.
                        //

                        if (FlagOn( (*Pcb)->Flags, PCB_FLAG_VIRTUAL_PARTITION )) {

                            DebugTrace(( 0, Dbg,
                                         "UdfInitializePcb, ... but this is a second virtual partition!?!!\n" ));

                            DebugTrace(( -1, Dbg,
                                         "UdfInitializePcb -> STATUS_UNCRECOGNIZED_VOLUME\n" ));

                            return STATUS_UNRECOGNIZED_VOLUME;
                        }

                        DebugTrace(( 0, Dbg,
                                     "UdfInitializePcb, ... Virtual (Partition # %08x)\n",
                                     MapVirtual->Partition ));

                        SetFlag( (*Pcb)->Flags, PCB_FLAG_VIRTUAL_PARTITION );
                        Partition->Type = Virtual;

                        //
                        //  We will convert the partition number to a partition reference
                        //  before returning.
                        //

                        Partition->Virtual.RelatedReference = MapVirtual->Partition;
                    }

                } else if (UdfDomainIdentifierContained( &Map->PartID,
                                                         &UdfSparablePartitionDomainIdentifier,
                                                         UDF_VERSION_150,
                                                         UDF_VERSION_RECOGNIZED )) {

                    {
                        NTSTATUS Status;
                        PPARTMAP_SPARABLE MapSparable = (PPARTMAP_SPARABLE) Map;

                        //
                        //  It must be the case that the volume the partition is on is the first
                        //  one since we only do single disc UDF.  This will have already been
                        //  checked by the caller.
                        //

                        if (MapSparable->VolSetSeq > 1) {

                            DebugTrace(( 0, Dbg,
                                         "UdfInitializePcb, ... but sparable partition resides on volume set volume # %08x (> 1)!\n",
                                         MapSparable->VolSetSeq ));

                            DebugTrace(( -1, Dbg,
                                         "UdfInitializePcb -> STATUS_DISK_CORRUPT_ERROR\n" ));

                            return STATUS_DISK_CORRUPT_ERROR;
                        }

                        DebugTrace(( 0, Dbg,
                                     "UdfInitializePcb, ... Sparable (Partition # %08x)\n",
                                     MapSparable->Partition ));

                        //
                        //  We pretend that sparable partitions are basically the same as
                        //  physical partitions.  Since we are not r/w (and will never be
                        //  on media that requires host-based sparing in any case), this
                        //  is a good simplification.
                        //

                        SetFlag( (*Pcb)->Flags, PCB_FLAG_SPARABLE_PARTITION );
                        Partition->Type = Physical;
                        Partition->Physical.PartitionNumber = MapSparable->Partition;

                        //
                        //  Save this map for use when the partition descriptor is found.
                        //  We can't load the sparing table at this time because we have
                        //  to turn the Lbn->Psn mapping into a Psn->Psn mapping.  UDF
                        //  believes that the way sparing will be used in concert with
                        //  the Lbn->Psn mapping engine (like UdfLookupPsnOfExtent).
                        //
                        //  Unfortunately, this would be a bit painful at this time.
                        //  The users of UdfLookupPsnOfExtent would need to iterate
                        //  over a new interface (not so bad) but the Vmcb package
                        //  would need to be turned inside out so that it didn't do
                        //  the page-filling alignment of blocks in the metadata
                        //  stream - instead, UdfLookupMetaVsnOfExtent would need to
                        //  do this itself.  I choose to lay the sparing engine into
                        //  the read path and raw sector read engine instead.
                        //

                        Partition->Physical.SparingMap = FsRtlAllocatePoolWithTag( PagedPool,
                                                                                   sizeof(PARTMAP_SPARABLE),
                                                                                   TAG_NSR_FSD);
                        RtlCopyMemory( Partition->Physical.SparingMap,
                                       MapSparable,
                                       sizeof(PARTMAP_SPARABLE));
                    }

                } else {

                    DebugTrace(( 0, Dbg,
                                 "UdfInitializePcb, ... but we don't recognize this proxy!\n" ));

                    DebugTrace(( -1, Dbg,
                                 "UdfInitializePcb -> STATUS_UNRECOGNIZED_VOLUME\n" ));

                    return STATUS_UNRECOGNIZED_VOLUME;
                }

                break;

            default:

                DebugTrace(( 0, Dbg,
                             "UdfInitializePcb, map reference %02x is of unknown type %02x\n",
                             Map->Type ));

                DebugTrace(( -1, Dbg,
                             "UdfInitializePcb -> STATUS_UNRECOGNIZED_VOLUME\n" ));

                return STATUS_UNRECOGNIZED_VOLUME;
                break;
        }
    }

    if (!FlagOn( (*Pcb)->Flags, PCB_FLAG_PHYSICAL_PARTITION | PCB_FLAG_SPARABLE_PARTITION )) {

        DebugTrace(( 0, Dbg,
                     "UdfInitializePcb, no physical partition seen on this logical volume!\n" ));

        DebugTrace(( -1, Dbg,
                     "UdfInitializePcb -> STATUS_UNRECOGNIZED_VOLUME\n" ));

        return STATUS_UNRECOGNIZED_VOLUME;
    }

    if (FlagOn( (*Pcb)->Flags, PCB_FLAG_VIRTUAL_PARTITION )) {

        PPARTITION Host;

        //
        //  Confirm the validity of any type 2 virtual maps on this volume
        //  and convert partition numbers to partition references that will
        //  immediately index an element of the Pcb.
        //

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

            if (Partition->Type == Virtual) {

                //
                //  Go find the partition this thing is talking about
                //

                Found = FALSE;

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

                    if (Host->Type == Physical &&
                        Host->Physical.PartitionNumber ==
                        Partition->Virtual.RelatedReference) {

                        Partition->Virtual.RelatedReference =
                            (USHORT)(Host - (*Pcb)->Partition)/sizeof(PARTITION);
                        Found = TRUE;
                        break;
                    }
                }

                //
                //  Failure to find a physical partition for this virtual guy
                //  is not a good sign.
                //

                if (!Found) {

                    return STATUS_DISK_CORRUPT_ERROR;
                }
            }
        }
    }

    DebugTrace(( -1, Dbg,
             "UdfInitializePcb -> STATUS_SUCCESS\n" ));

    return STATUS_SUCCESS;
}


VOID
UdfAddToPcb (
    IN PPCB Pcb,
    IN PNSR_PART PartitionDescriptor
)

/*++

Routine Description:

    This routine possibly adds a partition descriptor into a Pcb if it
    turns out to be of higher precendence than a descriptor already
    present.  Used in building a Pcb already initialized in preperation
    for UdfCompletePcb.

Arguments:

    Vcb - Vcb of the volume the Pcb describes

    Pcb - Pcb being filled in

Return Value:

    None. An old partition descriptor may be returned in the input field.

--*/

{
    USHORT Reference;

    PAGED_CODE();

    //
    //  Check inputs
    //

    ASSERT_PCB( Pcb );
    ASSERT( PartitionDescriptor );

    for (Reference = 0;
         Reference < Pcb->Partitions;
         Reference++) {

        DebugTrace(( 0, Dbg, "UdfAddToPcb,  considering partition reference %d (type %d)\n", (ULONG)Reference, Pcb->Partition[Reference].Type));
        
        switch (Pcb->Partition[Reference].Type) {

            case Physical:

                //
                //  Now possibly store this descriptor in the Pcb if it is
                //  the partition number for this partition reference.
                //

                if (Pcb->Partition[Reference].Physical.PartitionNumber == PartitionDescriptor->Number) {

                    //
                    //  It seems to be legal (if questionable) for multiple partition maps to reference 
                    //  the same partition descriptor.  So we make a copy of the descriptor for each 
                    //  referencing partitionmap to make life easier when it comes to freeing it.
                    //

                    UdfStoreVolumeDescriptorIfPrevailing( (PNSR_VD_GENERIC *) &Pcb->Partition[Reference].Physical.PartitionDescriptor,
                                                          (PNSR_VD_GENERIC) PartitionDescriptor );
                }
                
                break;

            case Virtual:
                break;

            default:

                ASSERT(FALSE);
                break;
        }
    }
}


NTSTATUS
UdfCompletePcb (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PPCB Pcb
    )

/*++

Routine Description:

    This routine completes initialization of a Pcb which has been filled
    in with partition descriptors.  Initialization-time data such as the
    physical partition descriptors will be returned to the system.

Arguments:

    Vcb - Vcb of the volume the Pcb describes

    Pcb - Pcb being completed

Return Value:

    NTSTATUS according to whether intialization completion was succesful

--*/

{
    ULONG Reference;

    NTSTATUS Status;

⌨️ 快捷键说明

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