- Move FdcAddDevice from fdo.c to fdc.c.
- Create a PDO for each enumerated floppy disk drive.

svn path=/trunk/; revision=61149
This commit is contained in:
Eric Kohl 2013-11-29 23:52:53 +00:00
parent 24f5ab191b
commit f26a26f9ea
3 changed files with 187 additions and 95 deletions

View file

@ -14,13 +14,65 @@
#include <debug.h> #include <debug.h>
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
ULONG ControllerCount = 0; ULONG ControllerCount = 0;
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
static
NTSTATUS
NTAPI
FdcAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo)
{
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
PDEVICE_OBJECT Fdo = NULL;
NTSTATUS Status;
DPRINT1("FdcAddDevice()\n");
ASSERT(DriverObject);
ASSERT(Pdo);
/* Create functional device object */
Status = IoCreateDevice(DriverObject,
sizeof(FDO_DEVICE_EXTENSION),
NULL,
FILE_DEVICE_CONTROLLER,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&Fdo);
if (NT_SUCCESS(Status))
{
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
DeviceExtension->Common.IsFDO = TRUE;
DeviceExtension->Common.DeviceObject = Fdo;
DeviceExtension->Pdo = Pdo;
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
IoDeleteDevice(Fdo);
return Status;
}
Fdo->Flags |= DO_DIRECT_IO;
Fdo->Flags |= DO_POWER_PAGABLE;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
}
return Status;
}
static static
VOID VOID
NTAPI NTAPI

View file

@ -6,7 +6,9 @@
* PROGRAMMERS: Eric Kohl * PROGRAMMERS: Eric Kohl
*/ */
#include <ntifs.h>
#include <ntddk.h> #include <ntddk.h>
#include <stdio.h>
#include <debug.h> #include <debug.h>
#define MAX_DEVICE_NAME 255 #define MAX_DEVICE_NAME 255
@ -20,53 +22,54 @@ typedef struct _DRIVE_INFO
{ {
struct _CONTROLLER_INFO *ControllerInfo; struct _CONTROLLER_INFO *ControllerInfo;
UCHAR UnitNumber; /* 0,1,2,3 */ UCHAR UnitNumber; /* 0,1,2,3 */
LARGE_INTEGER MotorStartTime; // LARGE_INTEGER MotorStartTime;
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
CM_FLOPPY_DEVICE_DATA FloppyDeviceData; CM_FLOPPY_DEVICE_DATA FloppyDeviceData;
// DISK_GEOMETRY DiskGeometry; // DISK_GEOMETRY DiskGeometry;
UCHAR BytesPerSectorCode; // UCHAR BytesPerSectorCode;
WCHAR SymLinkBuffer[MAX_DEVICE_NAME]; // WCHAR SymLinkBuffer[MAX_DEVICE_NAME];
WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN]; // WCHAR ArcPathBuffer[MAX_ARC_PATH_LEN];
ULONG DiskChangeCount; // ULONG DiskChangeCount;
BOOLEAN Initialized; // BOOLEAN Initialized;
} DRIVE_INFO, *PDRIVE_INFO; } DRIVE_INFO, *PDRIVE_INFO;
typedef struct _CONTROLLER_INFO typedef struct _CONTROLLER_INFO
{ {
BOOLEAN Populated; BOOLEAN Populated;
BOOLEAN Initialized; // BOOLEAN Initialized;
ULONG ControllerNumber; // ULONG ControllerNumber;
INTERFACE_TYPE InterfaceType; // INTERFACE_TYPE InterfaceType;
ULONG BusNumber; // ULONG BusNumber;
ULONG Level; // ULONG Level;
KIRQL MappedLevel; // KIRQL MappedLevel;
ULONG Vector; // ULONG Vector;
ULONG MappedVector; // ULONG MappedVector;
KINTERRUPT_MODE InterruptMode; // KINTERRUPT_MODE InterruptMode;
PUCHAR BaseAddress; PUCHAR BaseAddress;
ULONG Dma; // ULONG Dma;
ULONG MapRegisters; // ULONG MapRegisters;
PVOID MapRegisterBase; // PVOID MapRegisterBase;
BOOLEAN Master; // BOOLEAN Master;
KEVENT SynchEvent; // KEVENT SynchEvent;
KDPC Dpc; // KDPC Dpc;
PKINTERRUPT InterruptObject; // PKINTERRUPT InterruptObject;
PADAPTER_OBJECT AdapterObject; // PADAPTER_OBJECT AdapterObject;
UCHAR NumberOfDrives; UCHAR NumberOfDrives;
BOOLEAN ImpliedSeeks; // BOOLEAN ImpliedSeeks;
DRIVE_INFO DriveInfo[MAX_DRIVES_PER_CONTROLLER]; DRIVE_INFO DriveInfo[MAX_DRIVES_PER_CONTROLLER];
PDRIVE_INFO CurrentDrive; // PDRIVE_INFO CurrentDrive;
BOOLEAN Model30; // BOOLEAN Model30;
KEVENT MotorStoppedEvent; // KEVENT MotorStoppedEvent;
KTIMER MotorTimer; // KTIMER MotorTimer;
KDPC MotorStopDpc; // KDPC MotorStopDpc;
BOOLEAN StopDpcQueued; // BOOLEAN StopDpcQueued;
} CONTROLLER_INFO, *PCONTROLLER_INFO; } CONTROLLER_INFO, *PCONTROLLER_INFO;
typedef struct _COMMON_DEVICE_EXTENSION typedef struct _COMMON_DEVICE_EXTENSION
{ {
BOOLEAN IsFDO; BOOLEAN IsFDO;
PDEVICE_OBJECT DeviceObject;
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
typedef struct _FDO_DEVICE_EXTENSION typedef struct _FDO_DEVICE_EXTENSION
@ -74,7 +77,6 @@ typedef struct _FDO_DEVICE_EXTENSION
COMMON_DEVICE_EXTENSION Common; COMMON_DEVICE_EXTENSION Common;
PDEVICE_OBJECT LowerDevice; PDEVICE_OBJECT LowerDevice;
PDEVICE_OBJECT Fdo;
PDEVICE_OBJECT Pdo; PDEVICE_OBJECT Pdo;
CONTROLLER_INFO ControllerInfo; CONTROLLER_INFO ControllerInfo;
@ -82,12 +84,22 @@ typedef struct _FDO_DEVICE_EXTENSION
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
/* fdo.c */ typedef struct _PDO_DEVICE_EXTENSION
{
COMMON_DEVICE_EXTENSION Common;
NTSTATUS PDEVICE_OBJECT Fdo;
NTAPI PDRIVE_INFO DriveInfo;
FdcAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo); UNICODE_STRING DeviceDescription; // REG_SZ
UNICODE_STRING DeviceId; // REG_SZ
UNICODE_STRING InstanceId; // REG_SZ
UNICODE_STRING HardwareIds; // REG_MULTI_SZ
UNICODE_STRING CompatibleIds; // REG_MULTI_SZ
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
/* fdo.c */
NTSTATUS NTSTATUS
NTAPI NTAPI

View file

@ -72,57 +72,6 @@ ForwardIrpAndForget(
} }
NTSTATUS
NTAPI
FdcAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo)
{
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
PDEVICE_OBJECT Fdo = NULL;
NTSTATUS Status;
DPRINT1("FdcAddDevice()\n");
ASSERT(DriverObject);
ASSERT(Pdo);
/* Create functional device object */
Status = IoCreateDevice(DriverObject,
sizeof(FDO_DEVICE_EXTENSION),
NULL,
FILE_DEVICE_CONTROLLER,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&Fdo);
if (NT_SUCCESS(Status))
{
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
DeviceExtension->Common.IsFDO = TRUE;
DeviceExtension->Fdo = Fdo;
DeviceExtension->Pdo = Pdo;
Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
IoDeleteDevice(Fdo);
return Status;
}
Fdo->Flags |= DO_DIRECT_IO;
Fdo->Flags |= DO_POWER_PAGABLE;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
}
return Status;
}
static static
@ -318,15 +267,24 @@ FdcFdoQueryBusRelations(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
OUT PDEVICE_RELATIONS *DeviceRelations) OUT PDEVICE_RELATIONS *DeviceRelations)
{ {
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
INTERFACE_TYPE InterfaceType = Isa; INTERFACE_TYPE InterfaceType = Isa;
CONFIGURATION_TYPE ControllerType = DiskController; CONFIGURATION_TYPE ControllerType = DiskController;
CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral; CONFIGURATION_TYPE PeripheralType = FloppyDiskPeripheral;
PDEVICE_RELATIONS Relations;
PDRIVE_INFO DriveInfo;
PDEVICE_OBJECT Pdo;
WCHAR DeviceNameBuffer[80];
UNICODE_STRING DeviceName;
ULONG DeviceNumber = 0;
ULONG Size;
ULONG i;
NTSTATUS Status; NTSTATUS Status;
DPRINT1("FdcFdoQueryBusRelations() called\n"); DPRINT1("FdcFdoQueryBusRelations() called\n");
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
Status = IoQueryDeviceDescription(&InterfaceType, Status = IoQueryDeviceDescription(&InterfaceType,
NULL, NULL,
@ -335,13 +293,83 @@ FdcFdoQueryBusRelations(
&PeripheralType, &PeripheralType,
NULL, NULL,
FdcFdoConfigCallback, FdcFdoConfigCallback,
DeviceExtension); FdoDeviceExtension);
if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND)) if (!NT_SUCCESS(Status) && (Status != STATUS_NO_MORE_ENTRIES))
{
return Status; return Status;
Size = sizeof(DEVICE_RELATIONS) +
sizeof(Relations->Objects) * (FdoDeviceExtension->ControllerInfo.NumberOfDrives - 1);
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
if (Relations == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
} }
return STATUS_SUCCESS; Relations->Count = FdoDeviceExtension->ControllerInfo.NumberOfDrives;
for (i = 0; i < FdoDeviceExtension->ControllerInfo.NumberOfDrives; i++)
{
DriveInfo = &FdoDeviceExtension->ControllerInfo.DriveInfo[i];
if (DriveInfo->DeviceObject == NULL)
{
do
{
swprintf(DeviceNameBuffer, L"\\Device\\FloppyPDO%lu", DeviceNumber++);
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
DPRINT1("Device name: %S\n", DeviceNameBuffer);
/* Create physical device object */
Status = IoCreateDevice(FdoDeviceExtension->Common.DeviceObject->DriverObject,
sizeof(PDO_DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_MASS_STORAGE,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&Pdo);
}
while (Status == STATUS_OBJECT_NAME_COLLISION);
if (!NT_SUCCESS(Status))
{
DPRINT1("PDO creation failed (Status 0x%08lx)\n", Status);
goto done;
}
DPRINT1("PDO created: %S\n", DeviceNameBuffer);
DriveInfo->DeviceObject = Pdo;
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
PdoDeviceExtension->Common.IsFDO = FALSE;
PdoDeviceExtension->Common.DeviceObject = Pdo;
PdoDeviceExtension->Fdo = FdoDeviceExtension->Common.DeviceObject;
PdoDeviceExtension->DriveInfo = DriveInfo;
Pdo->Flags |= DO_DIRECT_IO;
Pdo->Flags |= DO_POWER_PAGABLE;
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
}
ObReferenceObject(DriveInfo->DeviceObject);
Relations->Objects[i] = DriveInfo->DeviceObject;
}
done:
if (NT_SUCCESS(Status))
{
*DeviceRelations = Relations;
}
else
{
if (Relations != NULL)
ExFreePool(Relations);
}
return Status;
} }