📄 fsctrl.c
字号:
/*++
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 + -