Implement IRP_MN_QUERY_CAPABILITIES and IRP_MN_QUERY_ID for the PDOs.

svn path=/trunk/; revision=61153
This commit is contained in:
Eric Kohl 2013-11-30 10:07:50 +00:00
parent 627ea08f31
commit f4e1b2faf9
5 changed files with 366 additions and 9 deletions

View file

@ -2,6 +2,7 @@
add_library(fdc SHARED
fdc.c
fdo.c
misc.c
pdo.c
fdc.rc)

View 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 */
/* EOF */

View 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);

View file

@ -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 */

View file

@ -12,14 +12,182 @@
/* 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;
}