📄 rawfs.c
字号:
/* Check what kind of request this is */
switch (IoStackLocation->Parameters.FileSystemControl.FsControlCode)
{
/* Oplock requests */
case FSCTL_REQUEST_OPLOCK_LEVEL_1:
case FSCTL_REQUEST_OPLOCK_LEVEL_2:
case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
case FSCTL_OPLOCK_BREAK_NOTIFY:
/* We don't handle them */
Status = STATUS_NOT_IMPLEMENTED;
break;
/* Lock request */
case FSCTL_LOCK_VOLUME:
/* Make sure we're not locked, and that we're alone */
if (!(Vcb->VcbState & 1) && (Vcb->OpenCount == 1))
{
/* Lock the VCB */
Vcb->VcbState |= 1;
Status = STATUS_SUCCESS;
}
else
{
/* Otherwise, we can't do this */
Status = STATUS_ACCESS_DENIED;
}
break;
/* Unlock request */
case FSCTL_UNLOCK_VOLUME:
/* Make sure we're locked */
if (!(Vcb->VcbState & 1))
{
/* Let caller know we're not */
Status = STATUS_NOT_LOCKED;
}
else
{
/* Unlock the VCB */
Vcb->VcbState &= ~1;
Status = STATUS_SUCCESS;
}
break;
/* Dismount request */
case FSCTL_DISMOUNT_VOLUME:
/* Make sure we're locked */
if (Vcb->VcbState & 1)
{
/* Do nothing, just return success */
Status = STATUS_SUCCESS;
}
else
{
/* We can't dismount, device not locked */
Status = STATUS_ACCESS_DENIED;
}
break;
/* Unknown request */
default:
/* Fail */
Status = STATUS_INVALID_PARAMETER;
break;
}
/* Unlock device and return */
KeReleaseMutex(&Vcb->Mutex, FALSE);
return Status;
}
NTSTATUS
NTAPI
RawFileSystemControl(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
PAGED_CODE();
/* Check the kinds of FSCTLs that we support */
switch (IoStackLocation->MinorFunction)
{
/* User-mode request */
case IRP_MN_USER_FS_REQUEST:
/* Handle it */
Status = RawUserFsCtrl(IoStackLocation, Vcb);
break;
/* Mount request */
case IRP_MN_MOUNT_VOLUME:
/* Mount the volume */
Status = RawMountVolume(IoStackLocation);
break;
case IRP_MN_VERIFY_VOLUME:
/* We don't do verifies */
Status = STATUS_WRONG_VOLUME;
Vcb->Vpb->RealDevice->Flags &= ~DO_VERIFY_VOLUME;
/* Check if we should delete the device */
if (RawCheckForDismount(Vcb, FALSE))
{
/* Do it */
IoDeleteDevice((PDEVICE_OBJECT)
CONTAINING_RECORD(Vcb,
VOLUME_DEVICE_OBJECT,
Vcb));
}
/* We're done */
break;
/* Invalid request */
default:
/* Fail it */
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
/* Complete the request */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
RawQueryInformation(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
PULONG Length;
PFILE_POSITION_INFORMATION Buffer;
PAGED_CODE();
/* Get information from the IRP */
Length = &IoStackLocation->Parameters.QueryFile.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
/* We only handle this request */
if (IoStackLocation->Parameters.QueryFile.FileInformationClass ==
FilePositionInformation)
{
/* Validate buffer size */
if (*Length < sizeof(FILE_POSITION_INFORMATION))
{
/* Invalid, fail */
Irp->IoStatus.Information = 0;
Status = STATUS_BUFFER_OVERFLOW;
}
else
{
/* Get offset and update length */
Buffer->CurrentByteOffset = IoStackLocation->FileObject->
CurrentByteOffset;
*Length -= sizeof(FILE_POSITION_INFORMATION);
/* Set IRP Status information */
Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
Status = STATUS_SUCCESS;
}
}
/* Complete it */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
RawSetInformation(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
PULONG Length;
PFILE_POSITION_INFORMATION Buffer;
PDEVICE_OBJECT DeviceObject;
PAGED_CODE();
/* Get information from the IRP */
Length = &IoStackLocation->Parameters.QueryFile.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
/* We only handle this request */
if (IoStackLocation->Parameters.QueryFile.FileInformationClass ==
FilePositionInformation)
{
/* Get the DO */
DeviceObject = IoGetRelatedDeviceObject(IoStackLocation->FileObject);
/* Make sure the offset is aligned */
if ((Buffer->CurrentByteOffset.LowPart &
DeviceObject->AlignmentRequirement))
{
/* It's not, fail */
Status = STATUS_INVALID_PARAMETER;
}
else
{
/* Otherwise, set offset */
IoStackLocation->FileObject->CurrentByteOffset = Buffer->
CurrentByteOffset;
/* Set IRP Status information */
Status = STATUS_SUCCESS;
}
}
/* Complete it */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
RawQueryFsVolumeInfo(IN PVCB Vcb,
IN PFILE_FS_VOLUME_INFORMATION Buffer,
IN OUT PULONG Length)
{
PAGED_CODE();
/* Clear the buffer and stub it out */
RtlZeroMemory( Buffer, sizeof(FILE_FS_VOLUME_INFORMATION));
Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
Buffer->SupportsObjects = FALSE;
Buffer->VolumeLabelLength = 0;
/* Return length and success */
*Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawQueryFsSizeInfo(IN PVCB Vcb,
IN PFILE_FS_SIZE_INFORMATION Buffer,
IN OUT PULONG Length)
{
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_OBJECT RealDevice;
DISK_GEOMETRY DiskGeometry;
PARTITION_INFORMATION PartitionInformation;
BOOLEAN DiskHasPartitions;
PAGED_CODE();
/* Validate the buffer */
if (*Length < sizeof(FILE_FS_SIZE_INFORMATION))
{
/* Fail */
return STATUS_BUFFER_OVERFLOW;
}
/* Clear the buffer, initialize the event and set the DO */
RtlZeroMemory(Buffer, sizeof(FILE_FS_SIZE_INFORMATION));
KeInitializeEvent(&Event, NotificationEvent, FALSE);
RealDevice = Vcb->Vpb->RealDevice;
/* Build query IRP */
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
RealDevice,
NULL,
0,
&DiskGeometry,
sizeof(DISK_GEOMETRY),
FALSE,
&Event,
&IoStatusBlock);
/* Call driver and check if we're pending */
Status = IoCallDriver(RealDevice, Irp);
if (Status == STATUS_PENDING)
{
/* Wait on driver to finish */
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock.Status;
}
/* Fail if we couldn't get CHS data */
if (!NT_SUCCESS(Status))
{
*Length = 0;
return Status;
}
/* Check if this is a floppy */
if (FlagOn(RealDevice->Characteristics, FILE_FLOPPY_DISKETTE))
{
/* Floppies don't have partitions */
DiskHasPartitions = FALSE;
}
else
{
/* Setup query IRP */
KeResetEvent(&Event);
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
RealDevice,
NULL,
0,
&PartitionInformation,
sizeof(PARTITION_INFORMATION),
FALSE,
&Event,
&IoStatusBlock);
/* Call driver and check if we're pending */
Status = IoCallDriver(RealDevice, Irp);
if (Status == STATUS_PENDING)
{
/* Wait on driver to finish */
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock.Status;
}
/* If this was an invalid request, then the disk is not partitioned */
if (Status == STATUS_INVALID_DEVICE_REQUEST)
{
DiskHasPartitions = FALSE;
}
else
{
/* Otherwise, it must be */
ASSERT(NT_SUCCESS(Status));
DiskHasPartitions = TRUE;
}
}
/* Set sector data */
Buffer->BytesPerSector = DiskGeometry.BytesPerSector;
Buffer->SectorsPerAllocationUnit = 1;
/* Calculate allocation units */
if (DiskHasPartitions)
{
/* Use partition data */
Buffer->TotalAllocationUnits =
RtlExtendedLargeIntegerDivide(PartitionInformation.PartitionLength,
DiskGeometry.BytesPerSector,
NULL);
}
else
{
/* Use CHS */
Buffer->TotalAllocationUnits =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -