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

📄 fsctl.c

📁 FSD file system driver
💻 C
📖 第 1 页 / 共 3 页
字号:
	}

	return Status;
}


NTSTATUS
FFSInvalidateVolumes(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	NTSTATUS            Status;
	PIRP                Irp;
	PIO_STACK_LOCATION  IrpSp;

	HANDLE              Handle;

	PLIST_ENTRY         ListEntry;

	PFILE_OBJECT        FileObject;
	PDEVICE_OBJECT      DeviceObject;
	BOOLEAN             GlobalResourceAcquired = FALSE;

	LUID Privilege = {SE_TCB_PRIVILEGE, 0};

	__try
	{
		Irp   = IrpContext->Irp;
		IrpSp = IoGetCurrentIrpStackLocation(Irp);

		if (!SeSinglePrivilegeCheck(Privilege, Irp->RequestorMode))
		{
			Status = STATUS_PRIVILEGE_NOT_HELD;
			__leave;
		}

		if (
#ifndef _GNU_NTIFS_
				IrpSp->Parameters.FileSystemControl.InputBufferLength
#else
				((PEXTENDED_IO_STACK_LOCATION)(IrpSp))->
				Parameters.FileSystemControl.InputBufferLength
#endif
				!= sizeof(HANDLE))
		{
			Status = STATUS_INVALID_PARAMETER;

			__leave;
		}

		Handle = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;

		Status = ObReferenceObjectByHandle(Handle,
				0,
				*IoFileObjectType,
				KernelMode,
				&FileObject,
				NULL);

		if (!NT_SUCCESS(Status))
		{
			__leave;
		}
		else
		{
			ObDereferenceObject(FileObject);
			DeviceObject = FileObject->DeviceObject;
		}

		FFSPrint((DBG_INFO, "FFSInvalidateVolumes: FileObject=%xh ...\n", FileObject));

		ExAcquireResourceExclusiveLite(
				&FFSGlobal->Resource,
				TRUE);

		GlobalResourceAcquired = TRUE;

		ListEntry = FFSGlobal->VcbList.Flink;

		while (ListEntry != &FFSGlobal->VcbList)
		{
			PFFS_VCB Vcb;

			Vcb = CONTAINING_RECORD(ListEntry, FFS_VCB, Next);

			ListEntry = ListEntry->Flink;

			FFSPrint((DBG_INFO, "FFSInvalidateVolumes: Vcb=%xh Vcb->Vpb=%xh...\n", Vcb, Vcb->Vpb));
			if (Vcb->Vpb && (Vcb->Vpb->RealDevice == DeviceObject))
			{
				ExAcquireResourceExclusive(&Vcb->MainResource, TRUE);
				FFSPrint((DBG_INFO, "FFSInvalidateVolumes: FFSPurgeVolume...\n"));
				FFSPurgeVolume(Vcb, FALSE);
				ClearFlag(Vcb->Flags, VCB_MOUNTED);
				ExReleaseResource(&Vcb->MainResource);

				//
				// Vcb is still attached on the list ......
				//

				if (ListEntry->Blink == &Vcb->Next)
				{
					FFSPrint((DBG_INFO, "FFSInvalidateVolumes: FFSCheckDismount...\n"));
					FFSCheckDismount(IrpContext, Vcb, FALSE);
				}
			}
		}
	}

	__finally
	{
		if (GlobalResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&FFSGlobal->Resource,
					ExGetCurrentResourceThread());
		}

		FFSCompleteIrpContext(IrpContext, Status);
	}

	return Status;
}


NTSTATUS
FFSAllowExtendedDasdIo(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PIO_STACK_LOCATION IrpSp;
	PFFS_VCB Vcb;
	PFFS_CCB Ccb;

	IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);

	Vcb = (PFFS_VCB)IrpSp->FileObject->FsContext;
	Ccb = (PFFS_CCB)IrpSp->FileObject->FsContext2;

	ASSERT(Vcb != NULL);

	ASSERT((Vcb->Identifier.Type == FFSVCB) &&
			(Vcb->Identifier.Size == sizeof(FFS_VCB)));

	ASSERT(IsMounted(Vcb));

	if (Ccb)
	{
		SetFlag(Ccb->Flags, CCB_ALLOW_EXTENDED_DASD_IO);

		FFSCompleteIrpContext(IrpContext, STATUS_SUCCESS);

		return STATUS_SUCCESS;
	}
	else
	{
		return STATUS_INVALID_PARAMETER;
	}
}


NTSTATUS
FFSUserFsRequest(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PIRP                Irp;
	PIO_STACK_LOCATION  IoStackLocation;
	ULONG               FsControlCode;
	NTSTATUS            Status;

	ASSERT(IrpContext);

	ASSERT((IrpContext->Identifier.Type == FFSICX) &&
			(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

	Irp = IrpContext->Irp;

	IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

#ifndef _GNU_NTIFS_
	FsControlCode =
		IoStackLocation->Parameters.FileSystemControl.FsControlCode;
#else
	FsControlCode = ((PEXTENDED_IO_STACK_LOCATION)
			IoStackLocation)->Parameters.FileSystemControl.FsControlCode;
#endif

	switch (FsControlCode)
	{
		case FSCTL_LOCK_VOLUME:
			Status = FFSLockVolume(IrpContext);
			break;

		case FSCTL_UNLOCK_VOLUME:
			Status = FFSUnlockVolume(IrpContext);
			break;

		case FSCTL_DISMOUNT_VOLUME:
			Status = FFSDismountVolume(IrpContext);
			break;

		case FSCTL_IS_VOLUME_MOUNTED:
			Status = FFSIsVolumeMounted(IrpContext);
			break;

		case FSCTL_INVALIDATE_VOLUMES:
			Status = FFSInvalidateVolumes(IrpContext);
			break;

#if (_WIN32_WINNT >= 0x0500)
		case FSCTL_ALLOW_EXTENDED_DASD_IO:
			Status = FFSAllowExtendedDasdIo(IrpContext);
			break;
#endif //(_WIN32_WINNT >= 0x0500)

		default:

			FFSPrint((DBG_ERROR, "FFSUserFsRequest: Invalid User Request: %xh.\n", FsControlCode));
			Status = STATUS_INVALID_DEVICE_REQUEST;

			FFSCompleteIrpContext(IrpContext,  Status);
	}

	return Status;
}


BOOLEAN
FFSIsMediaWriteProtected(
	IN PFFS_IRP_CONTEXT   IrpContext,
	IN PDEVICE_OBJECT     TargetDevice)
{
	PIRP            Irp;
	KEVENT          Event;
	NTSTATUS        Status;
	IO_STATUS_BLOCK IoStatus;

	KeInitializeEvent(&Event, NotificationEvent, FALSE);

	Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_IS_WRITABLE,
			TargetDevice,
			NULL,
			0,
			NULL,
			0,
			FALSE,
			&Event,
			&IoStatus);

	if (Irp == NULL)
	{
		return FALSE;
	}

	SetFlag(IoGetNextIrpStackLocation(Irp)->Flags, SL_OVERRIDE_VERIFY_VOLUME);

	Status = IoCallDriver(TargetDevice, Irp);

	if (Status == STATUS_PENDING)
	{

		(VOID) KeWaitForSingleObject(&Event,
					      Executive,
					      KernelMode,
					      FALSE,
					      (PLARGE_INTEGER)NULL);

		Status = IoStatus.Status;
	}

	return (BOOLEAN)(Status == STATUS_MEDIA_WRITE_PROTECTED);
}


NTSTATUS
FFSMountVolume(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT              MainDeviceObject;
	BOOLEAN                     GlobalDataResourceAcquired = FALSE;
	PIRP                        Irp;
	PIO_STACK_LOCATION          IoStackLocation;
	PDEVICE_OBJECT              TargetDeviceObject;
	NTSTATUS                    Status = STATUS_UNRECOGNIZED_VOLUME;
	PDEVICE_OBJECT              VolumeDeviceObject = NULL;
	PFFS_VCB                    Vcb;
	PFFS_SUPER_BLOCK            FFSSb = NULL;
	ULONG                       dwBytes;
	DISK_GEOMETRY               DiskGeometry;

	__try
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		MainDeviceObject = IrpContext->DeviceObject;

		//
		//  Make sure we can wait.
		//

		SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);

		//
		// This request is only allowed on the main device object
		//
		if (MainDeviceObject != FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			__leave;
		}

		ExAcquireResourceExclusiveLite(
				&(FFSGlobal->Resource),
				TRUE);

		GlobalDataResourceAcquired = TRUE;

		if (FlagOn(FFSGlobal->Flags, FFS_UNLOAD_PENDING))
		{
			Status = STATUS_UNRECOGNIZED_VOLUME;
			__leave;
		}

		Irp = IrpContext->Irp;

		IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

		TargetDeviceObject =
			IoStackLocation->Parameters.MountVolume.DeviceObject;

		dwBytes = sizeof(DISK_GEOMETRY);
		Status = FFSDiskIoControl(
					TargetDeviceObject,
					IOCTL_DISK_GET_DRIVE_GEOMETRY,
					NULL,
					0,
					&DiskGeometry,
					&dwBytes);

		if (!NT_SUCCESS(Status))
		{
			__leave;
		}

		Status = IoCreateDevice(
					MainDeviceObject->DriverObject,
					sizeof(FFS_VCB),
					NULL,
					FILE_DEVICE_DISK_FILE_SYSTEM,
					0,
					FALSE,
					&VolumeDeviceObject);

		if (!NT_SUCCESS(Status))
		{
			__leave;
		}

		VolumeDeviceObject->StackSize = (CCHAR)(TargetDeviceObject->StackSize + 1);

		if (TargetDeviceObject->AlignmentRequirement > 
				VolumeDeviceObject->AlignmentRequirement)
		{

			VolumeDeviceObject->AlignmentRequirement = 
				TargetDeviceObject->AlignmentRequirement;
		}

		(IoStackLocation->Parameters.MountVolume.Vpb)->DeviceObject =
			VolumeDeviceObject;

		Vcb = (PFFS_VCB)VolumeDeviceObject->DeviceExtension;

		RtlZeroMemory(Vcb, sizeof(FFS_VCB));

		Vcb->Identifier.Type = FFSVCB;
		Vcb->Identifier.Size = sizeof(FFS_VCB);

		Vcb->TargetDeviceObject = TargetDeviceObject;
		Vcb->DiskGeometry = DiskGeometry;

		Status = FFSLoadDiskLabel(TargetDeviceObject, Vcb);

		if (!NT_SUCCESS(Status))
		{
			__leave;
		}


		FFSSb = Vcb->ffs_super_block;

		Vcb->BlockSize = FFSSb->fs_bsize;
		Vcb->SectorBits = FFSLog2(SECTOR_SIZE);

		Status = FFSInitializeVcb(IrpContext, Vcb, FFSSb, TargetDeviceObject, 
				VolumeDeviceObject, IoStackLocation->Parameters.MountVolume.Vpb);

		if (NT_SUCCESS(Status))
		{
			if (FFSIsMediaWriteProtected(IrpContext, TargetDeviceObject))
			{
				SetFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
			}
			else
			{
				ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
			}

			SetFlag(Vcb->Flags, VCB_MOUNTED);

			FFSInsertVcb(Vcb);

			ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
		}
	}

	__finally
	{
		if (GlobalDataResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&FFSGlobal->Resource,
					ExGetCurrentResourceThread());
		}

		if (!NT_SUCCESS(Status))
		{
			if (FFSSb)
			{
				ExFreePool(FFSSb);
			}

			if (VolumeDeviceObject)
			{
				IoDeleteDevice(VolumeDeviceObject);
			}
		}

		if (!IrpContext->ExceptionInProgress)
		{
			if (NT_SUCCESS(Status))
			{
				ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
			}

			FFSCompleteIrpContext(IrpContext,  Status);
		}
	}

	return Status;
}


NTSTATUS
FFSVerifyVolume(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT          DeviceObject;
	NTSTATUS                Status = STATUS_UNSUCCESSFUL;
	PFFS_SUPER_BLOCK        FFSSb = NULL;
	PFFS_VCB                Vcb;
	BOOLEAN                 VcbResourceAcquired = FALSE;
	BOOLEAN                 GlobalResourceAcquired = FALSE;
	PIRP                    Irp;
	PIO_STACK_LOCATION      IoStackLocation;
	ULONG                   ChangeCount;
	ULONG                   dwReturn;

	__try
	{
		ASSERT(IrpContext != NULL);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;
		//
		// This request is not allowed on the main device object
		//
		if (DeviceObject == FFSGlobal->DeviceObject)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			__leave;
		}

		ExAcquireResourceExclusiveLite(
				&FFSGlobal->Resource,
				TRUE);

		GlobalResourceAcquired = TRUE;

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		ExAcquireResourceExclusiveLite(
				&Vcb->MainResource,
				TRUE);

		VcbResourceAcquired = TRUE;

		if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME))
		{
			Status = STATUS_SUCCESS;
			__leave;
		}

		if (!IsMounted(Vcb))
		{
			Status = STATUS_WRONG_VOLUME;
			__leave;
		}

		dwReturn = sizeof(ULONG);
		Status = FFSDiskIoControl(
				Vcb->TargetDeviceObject,
				IOCTL_DISK_CHECK_VERIFY,
				NULL,

⌨️ 快捷键说明

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