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

📄 strucsup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:

Routine Description:

    This routine is called to verify and process the TOC for this disk.
    We hide a data track for a CD+ volume.

Arguments:

    TargetDeviceObject - Device object to send TOC request to.

    CdromToc - Pointer to TOC structure.

    Length - On input this is the length of the TOC.  On return is the TOC
        length we will show to the user.

    TrackCount - This is the count of tracks for the TOC.  We use this
        when creating a pseudo directory for a music disk.

    DiskFlags - We return flags indicating what we know about this disk.

Return Value:

    NTSTATUS - The result of trying to read the TOC.

--*/

{
    NTSTATUS Status;
    IO_STATUS_BLOCK Iosb;
    CDROM_READ_TOC_EX Command;

    ULONG CurrentTrack;
    ULONG LocalTrackCount;
    ULONG LocalTocLength;
    ULONG Address = 0;

    union {

        UCHAR BigEndian[2];
        USHORT Length;

    } BiasedTocLength;

    PTRACK_DATA Track;

    PAGED_CODE();

    //
    //  Zero the command block.  This conveniently corresponds to an
    //  LBA mode READ_TOC request.
    //
    
    RtlZeroMemory( &Command, sizeof( Command));

    //
    //  Go ahead and read the table of contents
    //

    Status = CdPerformDevIoCtrlEx( IrpContext,
                                   IOCTL_CDROM_READ_TOC_EX,
                                   TargetDeviceObject,
                                   &Command,
                                   sizeof( Command),
                                   CdromToc,
                                   sizeof( CDROM_TOC_LARGE ),
                                   FALSE,
                                   TRUE,
                                   &Iosb );

    //
    //  Nothing to process if this request fails.
    //

    if (Status != STATUS_SUCCESS) {

        return Status;
    }

    //
    //  Get the number of tracks and stated size of this structure.
    //

    CurrentTrack = 0;
    LocalTrackCount = CdromToc->LastTrack - CdromToc->FirstTrack + 1;
    LocalTocLength = PtrOffset( CdromToc, &CdromToc->TrackData[LocalTrackCount + 1] );

    //
    //  Get out if there is an immediate problem with the TOC.
    //

    if ((LocalTocLength > Iosb.Information) ||
        (CdromToc->FirstTrack > CdromToc->LastTrack)) {

        Status = STATUS_DISK_CORRUPT_ERROR;
        return Status;
    }

    //
    //  Walk through the individual tracks.  Stop at the first data track after
    //  any lead-in audio tracks.
    //

    do {

        //
        //  Get the next track.
        //

        Track = &CdromToc->TrackData[CurrentTrack];

        //
        //  If this is a data track then check if we have only seen audio tracks
        //  to this point.
        //

        if (FlagOn( Track->Control, TOC_DATA_TRACK )) {

            //
            //  If we have only seen audio tracks then assume this is a
            //  CD+ disk.  Hide the current data track and only return
            //  the previous audio tracks.  Set the disk type to be mixed
            //  data/audio.
            //

            if (FlagOn( *DiskFlags, CDROM_DISK_AUDIO_TRACK ) &&
                !FlagOn( *DiskFlags, CDROM_DISK_DATA_TRACK )) {

                //
                //  Remove one track from the TOC.
                //

                CdromToc->LastTrack -= 1;

                //
                //  Knock 2.5 minutes off the current track to hide the final leadin.
                //  2.5 min = 150 sec = (x 75) 11250 frames (sectors).
                //
                
                SwapCopyUchar4( &Address, &Track->Address);
                Address -= 11250;
                SwapCopyUchar4( &Track->Address, &Address);

                Track->TrackNumber = TOC_LAST_TRACK;

                //
                //  Set the disk type to mixed data/audio.
                //

                SetFlag( *DiskFlags, CDROM_DISK_DATA_TRACK );

                break;
            }

            //
            //  Set the flag to indicate data tracks present.
            //

            SetFlag( *DiskFlags, CDROM_DISK_DATA_TRACK );

        //
        //  If this is a audio track then set the flag indicating audio
        //  tracks.
        //

        } else {

            SetFlag( *DiskFlags, CDROM_DISK_AUDIO_TRACK );
        }

        //
        //  Set our index for the next track.
        //

        CurrentTrack += 1;

    } while (CurrentTrack < LocalTrackCount);

    //
    //  Set the length to point just past the last track we looked at.
    //

    *TrackCount = CurrentTrack;
    *Length = PtrOffset( CdromToc, &CdromToc->TrackData[CurrentTrack + 1] );
    BiasedTocLength.Length = (USHORT) *Length - 2;

    CdromToc->Length[0] = BiasedTocLength.BigEndian[1];
    CdromToc->Length[1] = BiasedTocLength.BigEndian[0];

    return Status;
}


//
//  Local support routine
//

VOID
CdDeleteFcb (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb
    )

/*++

Routine Description:

    This routine is called to cleanup and deallocate an Fcb.  We know there
    are no references remaining.  We cleanup any auxilary structures and
    deallocate this Fcb.

Arguments:

    Fcb - This is the Fcb to deallcoate.

Return Value:

    None

--*/

{
    PVCB Vcb = NULL;
    PAGED_CODE();

    //
    //  Sanity check the counts.
    //

    ASSERT( Fcb->FcbCleanup == 0 );
    ASSERT( Fcb->FcbReference == 0 );

    //
    //  Release any Filter Context structures associated with this FCB
    //

    FsRtlTeardownPerStreamContexts( &Fcb->Header );

    //
    //  Start with the common structures.
    //

    CdUninitializeMcb( IrpContext, Fcb );

    CdDeleteFcbNonpaged( IrpContext, Fcb->FcbNonpaged );

    //
    //  Check if we need to deallocate the prefix name buffer.
    //

    if ((Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer != (PWCHAR) Fcb->FileNamePrefix.FileNameBuffer) &&
        (Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer != NULL)) {

        CdFreePool( &Fcb->FileNamePrefix.ExactCaseName.FileName.Buffer );
    }

    //
    //  Now look at the short name prefix.
    //

    if (Fcb->ShortNamePrefix != NULL) {

        CdFreePool( &Fcb->ShortNamePrefix );
    }

    //
    //  Now do the type specific structures.
    //

    switch (Fcb->NodeTypeCode) {

    case CDFS_NTC_FCB_PATH_TABLE:
    case CDFS_NTC_FCB_INDEX:

        ASSERT( Fcb->FileObject == NULL );
        ASSERT( IsListEmpty( &Fcb->FcbQueue ));

        if (Fcb == Fcb->Vcb->RootIndexFcb) {

            Vcb = Fcb->Vcb;
            Vcb->RootIndexFcb = NULL;

        } else if (Fcb == Fcb->Vcb->PathTableFcb) {

            Vcb = Fcb->Vcb;
            Vcb->PathTableFcb = NULL;
        }

        CdDeallocateFcbIndex( IrpContext, Fcb );
        break;

    case CDFS_NTC_FCB_DATA :

        if (Fcb->FileLock != NULL) {

            FsRtlFreeFileLock( Fcb->FileLock );
        }

        FsRtlUninitializeOplock( &Fcb->Oplock );

        if (Fcb == Fcb->Vcb->VolumeDasdFcb) {

            Vcb = Fcb->Vcb;
            Vcb->VolumeDasdFcb = NULL;
        }

        CdDeallocateFcbData( IrpContext, Fcb );
    }

    //
    //  Decrement the Vcb reference count if this is a system
    //  Fcb.
    //

    if (Vcb != NULL) {

        InterlockedDecrement( &Vcb->VcbReference );
        InterlockedDecrement( &Vcb->VcbUserReference );
    }

    return;
}


//
//  Local support routine
//

PFCB_NONPAGED
CdCreateFcbNonpaged (
    IN PIRP_CONTEXT IrpContext
    )

/*++

Routine Description:

    This routine is called to create and initialize the non-paged portion
    of an Fcb.

Arguments:

Return Value:

    PFCB_NONPAGED - Pointer to the created nonpaged Fcb.  NULL if not created.

--*/

{
    PFCB_NONPAGED FcbNonpaged;

    PAGED_CODE();

    //
    //  Allocate the non-paged pool and initialize the various
    //  synchronization objects.
    //

    FcbNonpaged = CdAllocateFcbNonpaged( IrpContext );

    if (FcbNonpaged != NULL) {

        RtlZeroMemory( FcbNonpaged, sizeof( FCB_NONPAGED ));

        FcbNonpaged->NodeTypeCode = CDFS_NTC_FCB_NONPAGED;
        FcbNonpaged->NodeByteSize = sizeof( FCB_NONPAGED );

        ExInitializeResourceLite( &FcbNonpaged->FcbResource );
        ExInitializeFastMutex( &FcbNonpaged->FcbMutex );
    }

    return FcbNonpaged;
}


//
//  Local support routine
//

VOID
CdDeleteFcbNonpaged (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB_NONPAGED FcbNonpaged
    )

/*++

Routine Description:

    This routine is called to cleanup the non-paged portion of an Fcb.

Arguments:

    FcbNonpaged - Structure to clean up.

Return Value:

    None

--*/

{
    PAGED_CODE();

    ExDeleteResourceLite( &FcbNonpaged->FcbResource );

    CdDeallocateFcbNonpaged( IrpContext, FcbNonpaged );

    return;
}


//
//  Local support routine
//

RTL_GENERIC_COMPARE_RESULTS
CdFcbTableCompare (
    IN PRTL_GENERIC_TABLE FcbTable,
    IN PVOID Fid1,
    IN PVOID Fid2
    )

/*++

Routine Description:

    This routine is the Cdfs compare routine called by the generic table package.
    If will compare the two File Id values and return a comparison result.

Arguments:

    FcbTable - This is the table being searched.

    Fid1 - First key value.

    Fid2 - Second key value.

Return Value:

    RTL_GENERIC_COMPARE_RESULTS - The results of comparing the two
        input structures

--*/

{
    FILE_ID Id1, Id2;
    PAGED_CODE();

    Id1 = *((FILE_ID UNALIGNED *) Fid1);
    Id2 = *((FILE_ID UNALIGNED *) Fid2);

    if (Id1.QuadPart < Id2.QuadPart) {

        return GenericLessThan;

    } else if (Id1.QuadPart > Id2.QuadPart) {

        return GenericGreaterThan;

    } else {

        return GenericEqual;
    }

    UNREFERENCED_PARAMETER( FcbTable );
}


//
//  Local support routine
//

PVOID
CdAllocateFcbTable (
    IN PRTL_GENERIC_TABLE FcbTable,
    IN CLONG ByteSize
    )

/*++

Routine Description:

    This is a generic table support routine to allocate memory

Arguments:

    FcbTable - Supplies the generic table being used

    ByteSize - Supplies the number of bytes to allocate

Return Value:

    PVOID - Returns a pointer to the allocated data

--*/

{
    PAGED_CODE();

    return( FsRtlAllocatePoolWithTag( CdPagedPool, ByteSize, TAG_FCB_TABLE ));
}


//
//  Local support routine
//

VOID
CdDeallocateFcbTable (
    IN PRTL_GENERIC_TABLE FcbTable,
    IN PVOID Buffer
    )

/*++

Routine Description:

    This is a generic table support routine that deallocates memory

Arguments:

    FcbTable - Supplies the generic table being used

    Buffer - Supplies the buffer being deallocated

Return Value:

    None.

--*/

{
    PAGED_CODE();

    CdFreePool( &Buffer );

  

⌨️ 快捷键说明

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