📄 rawfs.c
字号:
RtlExtendedIntegerMultiply(DiskGeometry.Cylinders,
DiskGeometry.TracksPerCylinder *
DiskGeometry.SectorsPerTrack);
}
/* Set available units */
Buffer->AvailableAllocationUnits = Buffer->TotalAllocationUnits;
/* Return length and success */
*Length -= sizeof(FILE_FS_SIZE_INFORMATION);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawQueryFsDeviceInfo(IN PVCB Vcb,
IN PFILE_FS_DEVICE_INFORMATION Buffer,
IN OUT PULONG Length)
{
PAGED_CODE();
/* Validate buffer */
if (*Length < sizeof(FILE_FS_DEVICE_INFORMATION))
{
/* Fail */
return STATUS_BUFFER_OVERFLOW;
}
/* Clear buffer and write information */
RtlZeroMemory(Buffer, sizeof(FILE_FS_DEVICE_INFORMATION));
Buffer->DeviceType = FILE_DEVICE_DISK;
Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
/* Return length and success */
*Length -= sizeof(FILE_FS_DEVICE_INFORMATION);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawQueryFsAttributeInfo(IN PVCB Vcb,
IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
IN OUT PULONG Length)
{
const WCHAR szRawFSName[] = L"RAW";
ULONG ReturnLength;
PAGED_CODE();
/* Check if the buffer is large enough for our name ("RAW") */
ReturnLength = FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION,
FileSystemName[sizeof(szRawFSName) / sizeof(szRawFSName[0])]);
if (*Length < ReturnLength) return STATUS_BUFFER_OVERFLOW;
/* Output the data */
Buffer->FileSystemAttributes = 0;
Buffer->MaximumComponentNameLength = 0;
Buffer->FileSystemNameLength = 6;
RtlCopyMemory(&Buffer->FileSystemName[0], szRawFSName, sizeof(szRawFSName));
/* Return length and success */
*Length -= ReturnLength;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawQueryVolumeInformation(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
ULONG Length;
PVOID Buffer;
PAGED_CODE();
/* Get IRP Data */
Length = IoStackLocation->Parameters.QueryVolume.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
/* Check the kind of request */
switch (IoStackLocation->Parameters.QueryVolume.FsInformationClass)
{
/* Volume information request */
case FileFsVolumeInformation:
Status = RawQueryFsVolumeInfo(Vcb, Buffer, &Length);
break;
/* File system size invormation */
case FileFsSizeInformation:
Status = RawQueryFsSizeInfo(Vcb, Buffer, &Length);
break;
/* Device information */
case FileFsDeviceInformation:
Status = RawQueryFsDeviceInfo(Vcb, Buffer, &Length);
break;
/* Attribute information */
case FileFsAttributeInformation:
Status = RawQueryFsAttributeInfo(Vcb, Buffer, &Length);
break;
/* Invalid request */
default:
/* Fail it */
Status = STATUS_INVALID_PARAMETER;
break;
}
/* Set status and complete the request */
Irp->IoStatus.Information = IoStackLocation->
Parameters.QueryVolume.Length - Length;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
RawCleanup(IN PVCB Vcb,
IN PIRP Irp,
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status;
PAGED_CODE();
/* Make sure we can clean up */
Status = KeWaitForSingleObject(&Vcb->Mutex,
Executive,
KernelMode,
FALSE,
NULL);
ASSERT(NT_SUCCESS(Status));
/* Remove shared access and complete the request */
IoRemoveShareAccess(IoStackLocation->FileObject, &Vcb->ShareAccess);
KeReleaseMutex(&Vcb->Mutex, FALSE);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
RawDispatch(IN PVOLUME_DEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION IoStackLocation;
PVCB Vcb;
PAGED_CODE();
/* Get the stack location */
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
/* Differentiate between Volume DO and FS DO */
if ((((PDEVICE_OBJECT)DeviceObject)->Size == sizeof(DEVICE_OBJECT)) &&
!((IoStackLocation->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
(IoStackLocation->MinorFunction == IRP_MN_MOUNT_VOLUME)))
{
/* This is an FS DO. Stub out the common calls */
if ((IoStackLocation->MajorFunction == IRP_MJ_CREATE) ||
(IoStackLocation->MajorFunction == IRP_MJ_CLEANUP) ||
(IoStackLocation->MajorFunction == IRP_MJ_CLOSE))
{
/* Return success for them */
Status = STATUS_SUCCESS;
}
else
{
/* Anything else, we don't support */
Status = STATUS_INVALID_DEVICE_REQUEST;
}
/* Complete the request */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return Status;
}
/* Otherwise, get our VCB and start handling the IRP */
FsRtlEnterFileSystem();
Vcb = &DeviceObject->Vcb;
/* Check what kind of IRP this is */
switch (IoStackLocation->MajorFunction)
{
/* Cleanup request */
case IRP_MJ_CLEANUP:
Status = RawCleanup(Vcb, Irp, IoStackLocation);
break;
/* Close request */
case IRP_MJ_CLOSE:
Status = RawClose(Vcb, Irp, IoStackLocation);
break;
/* Create request */
case IRP_MJ_CREATE:
Status = RawCreate(Vcb, Irp, IoStackLocation);
break;
/* FSCTL request */
case IRP_MJ_FILE_SYSTEM_CONTROL:
Status = RawFileSystemControl(Vcb, Irp, IoStackLocation);
break;
/* R/W or IOCTL request */
case IRP_MJ_READ:
case IRP_MJ_WRITE:
case IRP_MJ_DEVICE_CONTROL:
Status = RawReadWriteDeviceControl(Vcb, Irp, IoStackLocation);
break;
/* Information query request */
case IRP_MJ_QUERY_INFORMATION:
Status = RawQueryInformation(Vcb, Irp, IoStackLocation);
break;
/* Information set request */
case IRP_MJ_SET_INFORMATION:
Status = RawSetInformation(Vcb, Irp, IoStackLocation);
break;
/* Volume information request */
case IRP_MJ_QUERY_VOLUME_INFORMATION:
Status = RawQueryVolumeInformation(Vcb, Irp, IoStackLocation);
break;
/* Unexpected request */
default:
/* Anything else is pretty bad */
KeBugCheck(FILE_SYSTEM);
}
/* Return the status */
FsRtlExitFileSystem();
return Status;
}
NTSTATUS
NTAPI
RawShutdown(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
/* Unregister file systems */
#if 0 // FIXME: This freezes ROS at shutdown. PnP Problem?
IoUnregisterFileSystem(RawDiskDeviceObject);
IoUnregisterFileSystem(RawCdromDeviceObject);
IoUnregisterFileSystem(RawTapeDeviceObject);
/* Delete the devices */
IoDeleteDevice(RawDiskDeviceObject);
IoDeleteDevice(RawCdromDeviceObject);
IoDeleteDevice(RawTapeDeviceObject);
#endif
/* Complete the request */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return STATUS_SUCCESS;
}
VOID
NTAPI
RawUnload(IN PDRIVER_OBJECT DriverObject)
{
#if 0 // FIXME: DriverUnload is never called
/* Dereference device objects */
ObDereferenceObject(RawDiskDeviceObject);
ObDereferenceObject(RawCdromDeviceObject);
ObDereferenceObject(RawTapeDeviceObject);
#endif
}
NTSTATUS
NTAPI
RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DeviceName;
NTSTATUS Status;
/* Create the raw disk device */
RtlInitUnicodeString(&DeviceName, L"\\Device\\RawDisk");
Status = IoCreateDevice(DriverObject,
0,
NULL,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&RawDiskDeviceObject);
if (!NT_SUCCESS(Status)) return Status;
/* Create the raw CDROM device */
RtlInitUnicodeString(&DeviceName, L"\\Device\\RawCdRom");
Status = IoCreateDevice(DriverObject,
0,
NULL,
FILE_DEVICE_CD_ROM_FILE_SYSTEM,
0,
FALSE,
&RawCdromDeviceObject);
if (!NT_SUCCESS(Status)) return Status;
/* Create the raw tape device */
RtlInitUnicodeString(&DeviceName, L"\\Device\\RawTape");
Status = IoCreateDevice(DriverObject,
0,
NULL,
FILE_DEVICE_TAPE_FILE_SYSTEM,
0,
FALSE,
&RawTapeDeviceObject);
if (!NT_SUCCESS(Status)) return Status;
/* Set Direct I/O for all devices */
RawDiskDeviceObject->Flags |= DO_DIRECT_IO;
RawCdromDeviceObject->Flags |= DO_DIRECT_IO;
RawTapeDeviceObject->Flags |= DO_DIRECT_IO;
/* Set generic stubs */
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_READ] =
DriverObject->MajorFunction[IRP_MJ_WRITE] =
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)RawDispatch;
/* Shutdown and unload */
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = RawShutdown;
DriverObject->DriverUnload = RawUnload;
/* Register the file systems */
IoRegisterFileSystem(RawDiskDeviceObject);
IoRegisterFileSystem(RawCdromDeviceObject);
IoRegisterFileSystem(RawTapeDeviceObject);
#if 0 // FIXME: DriverUnload is never called
/* Reference device objects */
ObReferenceObject(RawDiskDeviceObject);
ObReferenceObject(RawCdromDeviceObject);
ObReferenceObject(RawTapeDeviceObject);
#endif
return STATUS_SUCCESS;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -