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

📄 fsctrl.c

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

Copyright (c) 1996  Microsoft Corporation

Module Name:

    FsCtrl.c

Abstract:

    This module implements the File System Control routines for Udfs called
    by the Fsd/Fsp dispatch drivers.

Author:

    Dan Lovinger    [DanLo]   11-Jun-1996

Revision History:

--*/

#include "UdfProcs.h"

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

#define BugCheckFileId                   (UDFS_BUG_CHECK_FSCTRL)

//
//  The local debug trace level
//

#define Dbg                              (UDFS_DEBUG_LEVEL_FSCTRL)

//
//  Local constants
//

BOOLEAN UdfDisable = FALSE;

//
//  Local macros
//

INLINE
VOID
UdfStoreFileSetDescriptorIfPrevailing (
    IN OUT PNSR_FSD *StoredFSD,
    IN OUT PNSR_FSD *NewFSD
    )
{
    PNSR_FSD TempFSD;

    //
    //  If we haven't stored a fileset descriptor or the fileset number
    //  of the stored descriptor is less than the new descriptor, swap the
    //  pointers around.
    //

    if (*StoredFSD == NULL || (*StoredFSD)->FileSet < (*NewFSD)->FileSet) {

        TempFSD = *StoredFSD;
        *StoredFSD = *NewFSD;
        *NewFSD = TempFSD;
    }
}

//
//  Local support routines
//

VOID
UdfDetermineVolumeBounding ( 
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PULONG S,
    IN PULONG N
    );

NTSTATUS
UdfDismountVolume (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfFindAnchorVolumeDescriptor (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN OUT PNSR_ANCHOR *AnchorVolumeDescriptor
    );

NTSTATUS
UdfFindFileSetDescriptor (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PLONGAD LongAd,
    IN OUT PNSR_FSD *FileSetDescriptor
    );

NTSTATUS
UdfFindVolumeDescriptors (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN PEXTENTAD Extent,
    IN OUT PPCB *Pcb,
    IN OUT PNSR_PVD *PrimaryVolumeDescriptor,
    IN OUT PNSR_LVOL *LogicalVolumeDescriptor
    );

NTSTATUS
UdfInvalidateVolumes (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfIsPathnameValid (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

BOOLEAN
UdfIsRemount (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    OUT PVCB *OldVcb
    );

UdfIsVolumeDirty (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfIsVolumeMounted (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfLockVolume (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfMountVolume(
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfOplockRequest (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

BOOLEAN
UdfRecognizeVolume (
    IN PIRP_CONTEXT IrpContext,
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG SectorSize,
    IN OUT PBOOLEAN Bridge
    );

VOID
UdfScanForDismountedVcb (
    IN PIRP_CONTEXT IrpContext
    );

NTSTATUS
UdfUnlockVolume (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

VOID
UdfUpdateVolumeLabel (
    IN PIRP_CONTEXT IrpContext,
    IN PWCHAR VolumeLabel,
    IN OUT PUSHORT VolumeLabelLength,
    IN PUCHAR Dstring,
    IN UCHAR FieldLength
    );

VOID
UdfUpdateVolumeSerialNumber (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PULONG VolumeSerialNumber,
    IN PNSR_FSD Fsd
    );

NTSTATUS
UdfUserFsctl (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

NTSTATUS
UdfVerifyVolume (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfCommonFsControl)
#pragma alloc_text(PAGE, UdfDetermineVolumeBounding)
#pragma alloc_text(PAGE, UdfDismountVolume)
#pragma alloc_text(PAGE, UdfFindAnchorVolumeDescriptor)
#pragma alloc_text(PAGE, UdfFindFileSetDescriptor)
#pragma alloc_text(PAGE, UdfFindVolumeDescriptors)
#pragma alloc_text(PAGE, UdfIsPathnameValid)
#pragma alloc_text(PAGE, UdfIsRemount)
#pragma alloc_text(PAGE, UdfIsVolumeDirty)
#pragma alloc_text(PAGE, UdfIsVolumeMounted)
#pragma alloc_text(PAGE, UdfLockVolume)
#pragma alloc_text(PAGE, UdfLockVolumeInternal)
#pragma alloc_text(PAGE, UdfMountVolume)
#pragma alloc_text(PAGE, UdfOplockRequest)
#pragma alloc_text(PAGE, UdfRecognizeVolume)
#pragma alloc_text(PAGE, UdfScanForDismountedVcb)
#pragma alloc_text(PAGE, UdfStoreVolumeDescriptorIfPrevailing)
#pragma alloc_text(PAGE, UdfUnlockVolume)
#pragma alloc_text(PAGE, UdfUnlockVolumeInternal)
#pragma alloc_text(PAGE, UdfUpdateVolumeLabel)
#pragma alloc_text(PAGE, UdfUpdateVolumeSerialNumber)
#pragma alloc_text(PAGE, UdfUserFsctl)
#pragma alloc_text(PAGE, UdfVerifyVolume)
#endif


VOID
UdfStoreVolumeDescriptorIfPrevailing (
    IN OUT PNSR_VD_GENERIC *StoredVD,
    IN OUT PNSR_VD_GENERIC NewVD
    )

/*++

Routine Description:

    This routine updates Volume Descriptor if the new descriptor
    is more prevailing than the one currently stored.

Arguments:

    StoredVD - pointer to a currently stored descriptor

    NewVD - pointer to a candidate descriptor

Return Value:

    None.

--*/

{
    PNSR_VD_GENERIC TempVD;

    //
    //  If we haven't stored a volume descriptor or the sequence number
    //  of the stored descriptor is less than the new descriptor, make a copy
    //  of it and store it.
    //

    if ((NULL == *StoredVD) || ((*StoredVD)->Sequence < NewVD->Sequence)) {

        if ( NULL == *StoredVD)  {

            *StoredVD = (PNSR_VD_GENERIC) FsRtlAllocatePoolWithTag( UdfNonPagedPool,
                                                                    sizeof(NSR_VD_GENERIC),
                                                                    TAG_NSR_VDSD );
        }

        RtlCopyMemory( *StoredVD,  NewVD,  sizeof( NSR_VD_GENERIC));
    }
}


NTSTATUS
UdfCommonFsControl (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for doing FileSystem control operations called
    by both the fsd and fsp threads

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    PAGED_CODE();

    //
    //  Check the input parameters
    //

    ASSERT_IRP_CONTEXT( IrpContext );
    ASSERT_IRP( Irp );

    //
    //  Get a pointer to the current Irp stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  We know this is a file system control so we'll case on the
    //  minor function, and call a internal worker routine to complete
    //  the irp.
    //

    switch (IrpSp->MinorFunction) {

    case IRP_MN_MOUNT_VOLUME:

        Status = UdfMountVolume( IrpContext, Irp );
        break;

    case IRP_MN_VERIFY_VOLUME:

        Status = UdfVerifyVolume( IrpContext, Irp );
        break;

    case IRP_MN_USER_FS_REQUEST:

        Status = UdfUserFsctl( IrpContext, Irp );
        break;

    default:

        UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
        Status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    return Status;
}


//
//  Local support routine
//

NTSTATUS
UdfUserFsctl (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )
/*++

Routine Description:

    This is the common routine for implementing the user's requests made
    through NtFsControlFile.

Arguments:

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    PAGED_CODE();

    //
    //  Case on the control code.
    //

    switch ( IrpSp->Parameters.FileSystemControl.FsControlCode ) {

    case FSCTL_REQUEST_OPLOCK_LEVEL_1 :
    case FSCTL_REQUEST_OPLOCK_LEVEL_2 :
    case FSCTL_REQUEST_BATCH_OPLOCK :
    case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE :
    case FSCTL_OPBATCH_ACK_CLOSE_PENDING :
    case FSCTL_OPLOCK_BREAK_NOTIFY :
    case FSCTL_OPLOCK_BREAK_ACK_NO_2 :
    case FSCTL_REQUEST_FILTER_OPLOCK :

        Status = UdfOplockRequest( IrpContext, Irp );
        break;

    case FSCTL_LOCK_VOLUME :

        Status = UdfLockVolume( IrpContext, Irp );
        break;

    case FSCTL_UNLOCK_VOLUME :

        Status = UdfUnlockVolume( IrpContext, Irp );
        break;

    case FSCTL_DISMOUNT_VOLUME :

        Status = UdfDismountVolume( IrpContext, Irp );
        break;

    case FSCTL_IS_VOLUME_DIRTY :

        Status = UdfIsVolumeDirty( IrpContext, Irp );
        break;

    case FSCTL_IS_VOLUME_MOUNTED :

        Status = UdfIsVolumeMounted( IrpContext, Irp );
        break;

    case FSCTL_IS_PATHNAME_VALID :

        Status = UdfIsPathnameValid( IrpContext, Irp );
        break;

    case FSCTL_INVALIDATE_VOLUMES :

        Status = UdfInvalidateVolumes( IrpContext, Irp );
        break;


    //
    //  We don't support any of the known or unknown requests.
    //

    case FSCTL_MARK_VOLUME_DIRTY :
    case FSCTL_QUERY_RETRIEVAL_POINTERS :
    case FSCTL_GET_COMPRESSION :
    case FSCTL_SET_COMPRESSION :
    case FSCTL_MARK_AS_SYSTEM_HIVE :
    case FSCTL_QUERY_FAT_BPB :
    default:

        UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
        Status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    return Status;
}


//
//  Local support routine
//

NTSTATUS
UdfOplockRequest (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine to handle oplock requests made via the
    NtFsControlFile call.

Arguments:

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;
    PFCB Fcb;
    PCCB Ccb;

    ULONG OplockCount = 0;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    PAGED_CODE();

    //
    //  We only permit oplock requests on files.
    //

    if (UdfDecodeFileObject( IrpSp->FileObject,
                             &Fcb,

⌨️ 快捷键说明

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