https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6889cff5b578296d956e5…
commit 6889cff5b578296d956e5a4a0e9c8c0e46d328cc
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sun Oct 27 11:35:23 2019 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sun Oct 27 11:35:23 2019 +0100
[FLOPPY] Make floppy drives letters being handled by the MountMgr
This involves many changes/fixes in the floppy driver:
- Stop creating ourselves our DOS device, it's up to the MountMgr or to the
kernel;
- Report each new floppy drive to the MountMgr (this is a hack for now);
- As a consequence, stop storing the symlink name into the DRIVE_INFO structure;
- Store the device name instead;
- On IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, don't return DOS device, but device name;
- On IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, properly return if buffer is way too small;
- Hackplement IOCTL_MOUNTDEV_QUERY_UNIQUE_ID so that it returns device name.
---
drivers/storage/floppy/floppy.c | 134 ++++++++++++++++++++++++++++++++--------
drivers/storage/floppy/floppy.h | 2 +-
drivers/storage/floppy/ioctl.c | 40 ++++++++++--
3 files changed, 142 insertions(+), 34 deletions(-)
diff --git a/drivers/storage/floppy/floppy.c b/drivers/storage/floppy/floppy.c
index 4234b0f8bb8..b67c6096872 100644
--- a/drivers/storage/floppy/floppy.c
+++ b/drivers/storage/floppy/floppy.c
@@ -406,9 +406,6 @@ Unload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING Link;
- RtlInitUnicodeString(&Link,
gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
- IoDeleteSymbolicLink(&Link);
-
RtlInitUnicodeString(&Link,
gControllerInfo[i].DriveInfo[j].ArcPathBuffer);
IoDeassignArcName(&Link);
@@ -811,6 +808,98 @@ InitController(PCONTROLLER_INFO ControllerInfo)
}
+static VOID NTAPI
+ReportToMountMgr(UCHAR ControlerId, UCHAR DriveId)
+/*
+ * FUNCTION: Called to report a new controler to the MountMgr
+ * ARGUMENTS:
+ * ControlerId: ID of the controler
+ * DriveId: ID of the device for the controler
+ * RETURNS:
+ * Nothing
+ * NOTES:
+ * - This is a hack to allow MountMgr handling our devices
+ */
+{
+ NTSTATUS Status;
+ UNICODE_STRING MountMgrDevice;
+ PDEVICE_OBJECT DeviceObject;
+ PFILE_OBJECT FileObject;
+ PMOUNTMGR_TARGET_NAME MountTarget;
+ ULONG DeviceLen;
+ PIRP Irp;
+ KEVENT Event;
+ IO_STATUS_BLOCK IoStatus;
+
+ /* First, get MountMgr DeviceObject */
+ RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
+ Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
+ &FileObject, &DeviceObject);
+
+ if(!NT_SUCCESS(Status))
+ {
+ WARN_(FLOPPY, "ReportToMountMgr: Can't get MountMgr pointers
%lx\n", Status);
+ return;
+ }
+
+ DeviceLen =
wcslen(&gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer[0]) *
sizeof(WCHAR);
+
+ /* Allocate input buffer to report our floppy device */
+ MountTarget = ExAllocatePool(NonPagedPool,
+ sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen);
+
+ if(!MountTarget)
+ {
+ WARN_(FLOPPY, "ReportToMountMgr: Allocation of mountTarget failed\n");
+ ObDereferenceObject(FileObject);
+ return;
+ }
+
+ MountTarget->DeviceNameLength = DeviceLen;
+ RtlCopyMemory(MountTarget->DeviceName,
+ gControllerInfo[ControlerId].DriveInfo[DriveId].DeviceNameBuffer,
+ DeviceLen);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ /* Build the IRP used to communicate with the MountMgr */
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
+ DeviceObject,
+ MountTarget,
+ sizeof(MOUNTMGR_TARGET_NAME) + DeviceLen,
+ NULL,
+ 0,
+ FALSE,
+ &Event,
+ &IoStatus);
+
+ if(!Irp)
+ {
+ WARN_(FLOPPY, "ReportToMountMgr: Allocation of irp failed\n");
+ ExFreePool(MountTarget);
+ ObDereferenceObject(FileObject);
+ return;
+ }
+
+ /* Call the MountMgr */
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING) {
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ /* We're done */
+
+ INFO_(FLOPPY, "Reported to the MountMgr: %lx\n", Status);
+
+ ExFreePool(MountTarget);
+ ObDereferenceObject(FileObject);
+
+ return;
+}
+
+
static BOOLEAN NTAPI
AddControllers(PDRIVER_OBJECT DriverObject)
/*
@@ -912,9 +1001,7 @@ AddControllers(PDRIVER_OBJECT DriverObject)
/* 3: per-drive setup */
for(j = 0; j < gControllerInfo[i].NumberOfDrives; j++)
{
- WCHAR DeviceNameBuf[MAX_DEVICE_NAME];
UNICODE_STRING DeviceName;
- UNICODE_STRING LinkName;
UNICODE_STRING ArcPath;
UCHAR DriveNumber;
@@ -936,9 +1023,8 @@ AddControllers(PDRIVER_OBJECT DriverObject)
DriveNumber = (UCHAR)(i*4 + j); /* loss of precision is OK; there are only 16
of 'em */
- RtlZeroMemory(&DeviceNameBuf, MAX_DEVICE_NAME * sizeof(WCHAR));
- swprintf(DeviceNameBuf, L"\\Device\\Floppy%d", DriveNumber);
- RtlInitUnicodeString(&DeviceName, DeviceNameBuf);
+ swprintf(gControllerInfo[i].DriveInfo[j].DeviceNameBuffer,
L"\\Device\\Floppy%d", DriveNumber);
+ RtlInitUnicodeString(&DeviceName,
gControllerInfo[i].DriveInfo[j].DeviceNameBuffer);
if(IoCreateDevice(DriverObject, sizeof(PVOID), &DeviceName,
FILE_DEVICE_DISK, FILE_REMOVABLE_MEDIA |
FILE_FLOPPY_DISKETTE, FALSE,
@@ -949,7 +1035,9 @@ AddControllers(PDRIVER_OBJECT DriverObject)
continue; /* continue on to next drive */
}
- INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n",
DeviceNameBuf, gControllerInfo[i].DriveInfo[j].DeviceObject);
+ INFO_(FLOPPY, "AddControllers: New device: %S (0x%p)\n",
+ gControllerInfo[i].DriveInfo[j].DeviceNameBuffer,
+ gControllerInfo[i].DriveInfo[j].DeviceObject);
/* 3b.5: Create an ARC path in case we're booting from this drive */
swprintf(gControllerInfo[i].DriveInfo[j].ArcPathBuffer,
@@ -961,38 +1049,30 @@ AddControllers(PDRIVER_OBJECT DriverObject)
/* 3c: Set flags up */
gControllerInfo[i].DriveInfo[j].DeviceObject->Flags |= DO_DIRECT_IO;
- /* 3d: Create a symlink */
- swprintf(gControllerInfo[i].DriveInfo[j].SymLinkBuffer,
L"\\DosDevices\\%c:", DriveNumber + 'A');
- RtlInitUnicodeString(&LinkName,
gControllerInfo[i].DriveInfo[j].SymLinkBuffer);
- if(IoCreateSymbolicLink(&LinkName, &DeviceName) != STATUS_SUCCESS)
- {
- WARN_(FLOPPY, "AddControllers: Unable to create a symlink for drive
%d\n", DriveNumber);
- IoDisconnectInterrupt(gControllerInfo[i].InterruptObject);
- IoDeassignArcName(&ArcPath);
- continue; /* continue to next drive */
- }
-
- /* 3e: Increase global floppy drives count */
+ /* 3d: Increase global floppy drives count */
IoGetConfigurationInformation()->FloppyCount++;
- /* 3f: Set up the DPC */
+ /* 3e: Set up the DPC */
IoInitializeDpcRequest(gControllerInfo[i].DriveInfo[j].DeviceObject,
(PIO_DPC_ROUTINE)DpcForIsr);
- /* 3g: Point the device extension at our DriveInfo struct */
+ /* 3f: Point the device extension at our DriveInfo struct */
gControllerInfo[i].DriveInfo[j].DeviceObject->DeviceExtension =
&gControllerInfo[i].DriveInfo[j];
- /* 3h: neat comic strip */
+ /* 3g: neat comic strip */
- /* 3i: set the initial media type to unknown */
+ /* 3h: set the initial media type to unknown */
memset(&gControllerInfo[i].DriveInfo[j].DiskGeometry, 0,
sizeof(DISK_GEOMETRY));
gControllerInfo[i].DriveInfo[j].DiskGeometry.MediaType = Unknown;
- /* 3j: Now that we're done, set the Initialized flag so we know to free
this in Unload */
+ /* 3i: Now that we're done, set the Initialized flag so we know to free
this in Unload */
gControllerInfo[i].DriveInfo[j].Initialized = TRUE;
- /* 3k: Clear the DO_DEVICE_INITIALIZING flag */
+ /* 3j: Clear the DO_DEVICE_INITIALIZING flag */
gControllerInfo[i].DriveInfo[j].DeviceObject->Flags &=
~DO_DEVICE_INITIALIZING;
+ /* 3k: Report to the MountMgr */
+ ReportToMountMgr(i, j);
+
/* 3l: Attempt to get drive info - if a floppy is already present */
StartMotor(&gControllerInfo[i].DriveInfo[j]);
RWDetermineMediaType(&gControllerInfo[i].DriveInfo[j], TRUE);
diff --git a/drivers/storage/floppy/floppy.h b/drivers/storage/floppy/floppy.h
index cd0301ca533..3dfd7c63160 100644
--- a/drivers/storage/floppy/floppy.h
+++ b/drivers/storage/floppy/floppy.h
@@ -48,8 +48,8 @@ typedef struct _DRIVE_INFO
CM_FLOPPY_DEVICE_DATA FloppyDeviceData;
DISK_GEOMETRY DiskGeometry;
UCHAR BytesPerSectorCode;
- WCHAR SymLinkBuffer[MAX_DEVICE_NAME];
WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN];
+ WCHAR DeviceNameBuffer[MAX_DEVICE_NAME];
ULONG DiskChangeCount;
BOOLEAN Initialized;
} DRIVE_INFO, *PDRIVE_INFO;
diff --git a/drivers/storage/floppy/ioctl.c b/drivers/storage/floppy/ioctl.c
index 74a35175cb1..e6073a95299 100644
--- a/drivers/storage/floppy/ioctl.c
+++ b/drivers/storage/floppy/ioctl.c
@@ -75,6 +75,7 @@ DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
ULONG Code = Stack->Parameters.DeviceIoControl.IoControlCode;
BOOLEAN DiskChanged;
PMOUNTDEV_NAME Name;
+ PMOUNTDEV_UNIQUE_ID UniqueId;
TRACE_(FLOPPY, "DeviceIoctl called\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -256,27 +257,54 @@ DeviceIoctlPassive(PDRIVE_INFO DriveInfo, PIRP Irp)
Irp->IoStatus.Information = 0;
break;
+ case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
+ if(OutputLength < sizeof(MOUNTDEV_UNIQUE_ID))
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+
+ UniqueId = Irp->AssociatedIrp.SystemBuffer;
+ UniqueId->UniqueIdLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) *
sizeof(WCHAR);
+
+ if(OutputLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) +
UniqueId->UniqueIdLength)
+ {
+ Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
+ Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
+ break;
+ }
+
+ RtlCopyMemory(UniqueId->UniqueId, &DriveInfo->DeviceNameBuffer[0],
+ UniqueId->UniqueIdLength);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) +
UniqueId->UniqueIdLength;
+ break;
+
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
- if (OutputLength < sizeof(MOUNTDEV_NAME)) {
+ if(OutputLength < sizeof(MOUNTDEV_NAME))
+ {
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
- Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
+ Irp->IoStatus.Information = 0;
break;
}
Name = Irp->AssociatedIrp.SystemBuffer;
- Name->NameLength = wcslen(&DriveInfo->SymLinkBuffer[0]) *
sizeof(WCHAR);
+ Name->NameLength = wcslen(&DriveInfo->DeviceNameBuffer[0]) *
sizeof(WCHAR);
- if (OutputLength < sizeof(USHORT) + Name->NameLength) {
+ if(OutputLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + Name->NameLength)
+ {
Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
break;
}
- RtlCopyMemory(Name->Name, &DriveInfo->SymLinkBuffer[0],
+ RtlCopyMemory(Name->Name, &DriveInfo->DeviceNameBuffer[0],
Name->NameLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(USHORT) + Name->NameLength;
+ Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) +
Name->NameLength;
break;
default: