https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6889cff5b578296d956e5a4a0e9c8c0e46d328cc

commit 6889cff5b578296d956e5a4a0e9c8c0e46d328cc
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Sun Oct 27 11:35:23 2019 +0100
Commit:     Pierre Schweitzer <[email protected]>
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:

Reply via email to