[FDC]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 30 Nov 2013 10:07:50 +0000 (10:07 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 30 Nov 2013 10:07:50 +0000 (10:07 +0000)
Implement IRP_MN_QUERY_CAPABILITIES and IRP_MN_QUERY_ID for the PDOs.

svn path=/trunk/; revision=61153

reactos/drivers/storage/fdc/fdc/CMakeLists.txt
reactos/drivers/storage/fdc/fdc/fdc.h
reactos/drivers/storage/fdc/fdc/fdo.c
reactos/drivers/storage/fdc/fdc/misc.c [new file with mode: 0644]
reactos/drivers/storage/fdc/fdc/pdo.c

index 63eb32d..8dc87de 100644 (file)
@@ -2,6 +2,7 @@
 add_library(fdc SHARED
     fdc.c
     fdo.c
+    misc.c
     pdo.c
     fdc.rc)
 
index 8a9cfbe..e63099c 100644 (file)
@@ -22,9 +22,10 @@ typedef struct _DRIVE_INFO
 {
     struct _CONTROLLER_INFO  *ControllerInfo;
     UCHAR                    UnitNumber; /* 0,1,2,3 */
-//    LARGE_INTEGER            MotorStartTime;
-    PDEVICE_OBJECT            DeviceObject;
+    ULONG                    PeripheralNumber;
+    PDEVICE_OBJECT           DeviceObject;
     CM_FLOPPY_DEVICE_DATA    FloppyDeviceData;
+//    LARGE_INTEGER            MotorStartTime;
 //    DISK_GEOMETRY            DiskGeometry;
 //    UCHAR                    BytesPerSectorCode;
 //    WCHAR                    SymLinkBuffer[MAX_DEVICE_NAME];
@@ -98,20 +99,30 @@ typedef struct _PDO_DEVICE_EXTENSION
     UNICODE_STRING CompatibleIds;     // REG_MULTI_SZ
 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
 
+#define FDC_TAG 'acdF'
 
 /* fdo.c */
 
 NTSTATUS
 NTAPI
-FdcFdoPnp(IN PDEVICE_OBJECT DeviceObject,
-          IN PIRP Irp);
+FdcFdoPnp(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp);
+
+/* misc.c */
+
+NTSTATUS
+DuplicateUnicodeString(
+    IN ULONG Flags,
+    IN PCUNICODE_STRING SourceString,
+    OUT PUNICODE_STRING DestinationString);
 
 /* pdo.c */
 
 NTSTATUS
 NTAPI
-FdcPdoPnp(IN PDEVICE_OBJECT DeviceObject,
-          IN PIRP Irp);
-
+FdcPdoPnp(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp);
 
-/* EOF */
\ No newline at end of file
+/* EOF */
index bc9c700..58d04b2 100644 (file)
@@ -232,6 +232,7 @@ FdcFdoConfigCallback(
 
         DriveInfo->ControllerInfo = &DeviceExtension->ControllerInfo;
         DriveInfo->UnitNumber = i;
+        DriveInfo->PeripheralNumber = PeripheralNumber;
 
         DriveInfo->FloppyDeviceData.MaxDensity = FloppyDeviceData->MaxDensity;
         DriveInfo->FloppyDeviceData.MountDensity = FloppyDeviceData->MountDensity;
@@ -261,6 +262,63 @@ FdcFdoConfigCallback(
 }
 
 
+static
+NTSTATUS
+PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs)
+{
+    WCHAR Buffer[256];
+    UNICODE_STRING BufferU;
+    ULONG Index;
+
+    Index = 0;
+    Index += swprintf(&Buffer[Index],
+                      L"FDC\\GENERIC_FLOPPY_DRIVE");
+    Index++;
+
+    Buffer[Index] = UNICODE_NULL;
+
+    BufferU.Length = BufferU.MaximumLength = (USHORT) Index * sizeof(WCHAR);
+    BufferU.Buffer = Buffer;
+
+    return DuplicateUnicodeString(0, &BufferU, HardwareIDs);
+}
+
+
+static
+NTSTATUS
+PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs)
+{
+    WCHAR Buffer[256];
+    UNICODE_STRING BufferU;
+    ULONG Index;
+
+    Index = 0;
+    Index += swprintf(&Buffer[Index],
+                      L"GenFloppyDisk");
+    Index++;
+
+    Buffer[Index] = UNICODE_NULL;
+
+    BufferU.Length = BufferU.MaximumLength = (USHORT)Index * sizeof(WCHAR);
+    BufferU.Buffer = Buffer;
+
+    return DuplicateUnicodeString(0, &BufferU, CompatibleIDs);
+}
+
+
+static
+NTSTATUS
+PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
+                          ULONG PeripheralNumber)
+{
+    WCHAR Buffer[3];
+
+    swprintf(Buffer, L"%02X", PeripheralNumber & 0xff);
+
+    return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
+}
+
+
 static
 NTSTATUS
 FdcFdoQueryBusRelations(
@@ -352,6 +410,59 @@ FdcFdoQueryBusRelations(
             Pdo->Flags |= DO_DIRECT_IO;
             Pdo->Flags |= DO_POWER_PAGABLE;
             Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+            /* Add Device ID string */
+            RtlCreateUnicodeString(&PdoDeviceExtension->DeviceId,
+                                   L"FDC\\GENERIC_FLOPPY_DRIVE");
+            DPRINT1("DeviceID: %S\n", PdoDeviceExtension->DeviceId.Buffer);
+
+            /* Add Hardware IDs string */
+            Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIds);
+            if (!NT_SUCCESS(Status))
+            {
+//                ErrorStatus = Status;
+//                ErrorOccurred = TRUE;
+                break;
+            }
+
+            /* Add Compatible IDs string */
+            Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIds);
+            if (!NT_SUCCESS(Status))
+            {
+//                ErrorStatus = Status;
+//                ErrorOccurred = TRUE;
+                break;
+            }
+
+            /* Add Instance ID string */
+            Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceId,
+                                               DriveInfo->PeripheralNumber);
+            if (!NT_SUCCESS(Status))
+            {
+//                ErrorStatus = Status;
+//                ErrorOccurred = TRUE;
+                break;
+            }
+
+#if 0
+             /* Add device description string */
+            Status = PciCreateDeviceDescriptionString(&PdoDeviceExtension->DeviceDescription, Device);
+            if (!NT_SUCCESS(Status))
+            {
+//                ErrorStatus = Status;
+//                ErrorOccurred = TRUE;
+                break;
+            }
+
+            /* Add device location string */
+            Status = PciCreateDeviceLocationString(&PdoDeviceExtension->DeviceLocation, Device);
+            if (!NT_SUCCESS(Status))
+            {
+//                ErrorStatus = Status;
+//                ErrorOccurred = TRUE;
+                break;
+            }
+#endif
         }
 
         ObReferenceObject(DriveInfo->DeviceObject);
diff --git a/reactos/drivers/storage/fdc/fdc/misc.c b/reactos/drivers/storage/fdc/fdc/misc.c
new file mode 100644 (file)
index 0000000..fc45531
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * PROJECT:        ReactOS Floppy Disk Controller Driver
+ * LICENSE:        GNU GPLv2 only as published by the Free Software Foundation
+ * FILE:           drivers/storage/fdc/fdc/misc.c
+ * PURPOSE:        Misc Routines
+ * PROGRAMMERS:    Eric Kohl
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "fdc.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+DuplicateUnicodeString(
+    IN ULONG Flags,
+    IN PCUNICODE_STRING SourceString,
+    OUT PUNICODE_STRING DestinationString)
+{
+    USHORT DestMaxLength;
+
+    if (SourceString == NULL ||
+        DestinationString == NULL ||
+        SourceString->Length > SourceString->MaximumLength ||
+        (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL) ||
+        Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING ||
+        Flags >= 4)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if ((SourceString->Length == 0) &&
+        (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
+                   RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
+    {
+        DestinationString->Length = 0;
+        DestinationString->MaximumLength = 0;
+        DestinationString->Buffer = NULL;
+    }
+    else
+    {
+        DestMaxLength = SourceString->Length;
+
+        if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
+            DestMaxLength += sizeof(UNICODE_NULL);
+
+        DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, FDC_TAG);
+        if (DestinationString->Buffer == NULL)
+            return STATUS_NO_MEMORY;
+
+        RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
+        DestinationString->Length = SourceString->Length;
+        DestinationString->MaximumLength = DestMaxLength;
+
+        if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
+            DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+/* EOF */
index 86ef711..8b3d3d5 100644 (file)
 
 /* FUNCTIONS ******************************************************************/
 
+static
+NTSTATUS
+FdcPdoQueryCapabilities(
+    IN PDEVICE_OBJECT DeviceObject,
+    PIO_STACK_LOCATION IrpSp)
+{
+    PPDO_DEVICE_EXTENSION DeviceExtension;
+    PDEVICE_CAPABILITIES DeviceCapabilities;
+
+    DPRINT("Called\n");
+
+    DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
+
+    if (DeviceCapabilities->Version != 1)
+        return STATUS_UNSUCCESSFUL;
+
+    DeviceCapabilities->UniqueID = FALSE;
+    DeviceCapabilities->Address = DeviceExtension->DriveInfo->PeripheralNumber;
+
+    return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+FdcPdoQueryId(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIO_STACK_LOCATION IrpSp,
+    OUT ULONG_PTR *Information)
+{
+    PPDO_DEVICE_EXTENSION DeviceExtension;
+    PUNICODE_STRING SourceString;
+    UNICODE_STRING String;
+    NTSTATUS Status;
+
+    DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    RtlInitUnicodeString(&String, NULL);
+
+    switch (IrpSp->Parameters.QueryId.IdType)
+    {
+        case BusQueryDeviceID:
+            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+            SourceString = &DeviceExtension->DeviceId;
+            break;
+
+        case BusQueryHardwareIDs:
+            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+            SourceString = &DeviceExtension->HardwareIds;
+            break;
+
+        case BusQueryCompatibleIDs:
+            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
+            SourceString = &DeviceExtension->CompatibleIds;
+            break;
+
+        case BusQueryInstanceID:
+            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
+            SourceString = &DeviceExtension->InstanceId;
+            break;
+
+        default:
+            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n",
+                    IrpSp->Parameters.QueryId.IdType);
+            ASSERT(FALSE);
+            return STATUS_NOT_SUPPORTED;
+    }
+
+    Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+                                    SourceString,
+                                    &String);
+
+    *Information = (ULONG_PTR)String.Buffer;
+
+    return Status;
+}
+
+
 NTSTATUS
 NTAPI
 FdcPdoPnp(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    NTSTATUS Status = STATUS_NOT_SUPPORTED;
+    PIO_STACK_LOCATION IrpSp;
+    ULONG_PTR Information = 0;
+    NTSTATUS Status;
+
     DPRINT1("FdcPdoPnp()\n");
+
+    Status = Irp->IoStatus.Status;
+
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+    switch (IrpSp->MinorFunction)
+    {
+        case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+            DPRINT1("Unimplemented IRP_MN_DEVICE_USAGE_NOTIFICATION received\n");
+            break;
+
+        case IRP_MN_EJECT:
+            DPRINT1("Unimplemented IRP_MN_EJECT received\n");
+            break;
+
+        case IRP_MN_QUERY_BUS_INFORMATION:
+            DPRINT1("IRP_MN_QUERY_BUS_INFORMATION received\n");
+            break;
+
+        case IRP_MN_QUERY_CAPABILITIES:
+            DPRINT1("IRP_MN_QUERY_CAPABILITIES received\n");
+            Status = FdcPdoQueryCapabilities(DeviceObject, IrpSp);
+            break;
+
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+            DPRINT1("IRP_MN_QUERY_DEVICE_RELATIONS received\n");
+            break;
+
+        case IRP_MN_QUERY_DEVICE_TEXT:
+            DPRINT1("IRP_MN_QUERY_DEVICE_TEXT received\n");
+            break;
+
+        case IRP_MN_QUERY_ID:
+            DPRINT1("IRP_MN_QUERY_ID received\n");
+            Status = FdcPdoQueryId(DeviceObject, IrpSp, &Information);
+            break;
+
+        case IRP_MN_QUERY_PNP_DEVICE_STATE:
+            DPRINT1("Unimplemented IRP_MN_QUERY_ID received\n");
+            break;
+
+        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+            DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
+            break;
+
+        case IRP_MN_QUERY_RESOURCES:
+            DPRINT1("IRP_MN_QUERY_RESOURCES received\n");
+            break;
+
+        case IRP_MN_SET_LOCK:
+            DPRINT1("Unimplemented IRP_MN_SET_LOCK received\n");
+            break;
+
+        case IRP_MN_START_DEVICE:
+            DPRINT1("IRP_MN_START_DEVICE received\n");
+            break;
+
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_CANCEL_STOP_DEVICE:
+        case IRP_MN_STOP_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+        case IRP_MN_SURPRISE_REMOVAL:
+            Status = STATUS_SUCCESS;
+            break;
+
+        case IRP_MN_REMOVE_DEVICE:
+            DPRINT1("IRP_MN_REMOVE_DEVICE received\n");
+            break;
+
+        case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+            DPRINT1("IRP_MN_FILTER_RESOURCE_REQUIREMENTS received\n");
+            /* Nothing to do */
+            Irp->IoStatus.Status = Status;
+            break;
+
+        default:
+            DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
+            break;
+    }
+
+    Irp->IoStatus.Information = Information;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    DPRINT1("Leaving. Status 0x%X\n", Status);
+
     return Status;
 }