https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6889cff5b578296d956e5a...
commit 6889cff5b578296d956e5a4a0e9c8c0e46d328cc Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Sun Oct 27 11:35:23 2019 +0100 Commit: Pierre Schweitzer pierre@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: