diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index b870d7afa93..40cc4105c90 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -30,6 +30,7 @@ class2.sys=,,,,,,x,,,,,,4 isapnp.sys=,,,,,,,,,,,,4 kdcom.dll=,,,,,,,,,,,,2 disk.sys=,,,,,,x,,,,,,4 +fdc.sys=,,,,,,,,,,,,4 floppy.sys=,,,,,,x,,,,,,4 i8042prt.sys=,,,,,,x,,,,,,4 kbdclass.sys=,,,,,,x,,,,,,4 @@ -60,6 +61,7 @@ PCI\CC_0104 = uniata PCI\CC_0105 = uniata PCI\CC_0106 = uniata *PNP0600 = uniata +*PNP0700 = fdc [BootBusExtenders.Load] acpi = acpi.sys @@ -68,6 +70,7 @@ isapnp = isapnp.sys [BusExtenders.Load] pciide = pciide.sys +fdc = fdc.sys [SCSI.Load] uniata = uniata.sys diff --git a/reactos/drivers/storage/CMakeLists.txt b/reactos/drivers/storage/CMakeLists.txt index 724a1d90658..ff51e59f461 100644 --- a/reactos/drivers/storage/CMakeLists.txt +++ b/reactos/drivers/storage/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(class) add_subdirectory(classpnp) +add_subdirectory(fdc) add_subdirectory(floppy) add_subdirectory(ide) add_subdirectory(port) diff --git a/reactos/drivers/storage/directory.rbuild b/reactos/drivers/storage/directory.rbuild index e25b40aae9e..2c451011738 100644 --- a/reactos/drivers/storage/directory.rbuild +++ b/reactos/drivers/storage/directory.rbuild @@ -4,6 +4,9 @@ + + + diff --git a/reactos/drivers/storage/fdc/CMakeLists.txt b/reactos/drivers/storage/fdc/CMakeLists.txt new file mode 100644 index 00000000000..fc6b28e7a12 --- /dev/null +++ b/reactos/drivers/storage/fdc/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(fdc) diff --git a/reactos/drivers/storage/fdc/directory.rbuild b/reactos/drivers/storage/fdc/directory.rbuild new file mode 100644 index 00000000000..f270c6bb0bb --- /dev/null +++ b/reactos/drivers/storage/fdc/directory.rbuild @@ -0,0 +1,7 @@ + + + + + + + diff --git a/reactos/drivers/storage/fdc/fdc/CMakeLists.txt b/reactos/drivers/storage/fdc/fdc/CMakeLists.txt new file mode 100644 index 00000000000..c43e3465b08 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/CMakeLists.txt @@ -0,0 +1,13 @@ + +add_library(fdc SHARED + fdc.c + fdo.c + pdo.c + fdc.rc) + +target_link_libraries(fdc) + +set_module_type(fdc kernelmodedriver) +add_importlibs(fdc hal ntoskrnl) + +add_cd_file(TARGET fdc DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/reactos/drivers/storage/fdc/fdc/SOURCES b/reactos/drivers/storage/fdc/fdc/SOURCES new file mode 100644 index 00000000000..7f4ef12c9a0 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/SOURCES @@ -0,0 +1,5 @@ +TARGETNAME=fdc +TARGETTYPE=DRIVER +TARGETPATH=obj +SOURCES= fdc.c fdo.c pdo.c +MSC_WARNING_LEVEL=/W3 /WX diff --git a/reactos/drivers/storage/fdc/fdc/fdc.c b/reactos/drivers/storage/fdc/fdc/fdc.c new file mode 100644 index 00000000000..d4b1783e870 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/fdc.c @@ -0,0 +1,153 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Serial enumerator driver + * FILE: drivers/storage/fdc/fdc/fdc.c + * PURPOSE: Floppy class driver entry point + * + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +#include "fdc.h" + +#define NDEBUG +#include + +static NTSTATUS +NTAPI +FdcAddDevice(IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PhysicalDeviceObject) +{ + NTSTATUS Status; + PDEVICE_OBJECT DeviceObject; + PFDC_FDO_EXTENSION DeviceExtension; + + Status = IoCreateDevice(DriverObject, + sizeof(FDC_FDO_EXTENSION), + NULL, + FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create device object (Status: 0x%x)\n", Status); + return Status; + } + + DeviceExtension = DeviceObject->DeviceExtension; + + DeviceExtension->Common.IsFDO = TRUE; + DeviceExtension->Common.DeviceObject = DeviceObject; + DeviceExtension->Common.DriverObject = DriverObject; + + InitializeListHead(&DeviceExtension->FloppyDriveList); + DeviceExtension->FloppyDriveListCount = 0; + KeInitializeSpinLock(&DeviceExtension->FloppyDriveListLock); + + DeviceObject->Flags |= DO_POWER_PAGABLE; + + DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(DeviceObject, + PhysicalDeviceObject); + if (!DeviceExtension->Ldo) + { + DPRINT1("Failed to attach to device stack\n"); + IoDeleteDevice(DeviceObject); + return STATUS_UNSUCCESSFUL; + } + + DPRINT("FdcAddDevice completed successfully\n"); + + return STATUS_SUCCESS; +} + +static NTSTATUS +NTAPI +FdcPnpDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension; + + if (DevExt->IsFDO) + return FdcFdoPnpDispatch(DeviceObject, Irp); + else + return FdcPdoPnpDispatch(DeviceObject, Irp); +} + +static NTSTATUS +NTAPI +FdcPowerDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension; + + if (DevExt->IsFDO) + return FdcFdoPowerDispatch(DeviceObject, Irp); + else + return FdcPdoPowerDispatch(DeviceObject, Irp); +} + +static NTSTATUS +NTAPI +FdcDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension; + + if (DevExt->IsFDO) + return FdcFdoDeviceControlDispatch(DeviceObject, Irp); + else + return FdcPdoDeviceControlDispatch(DeviceObject, Irp); +} + +static NTSTATUS +NTAPI +FdcInternalDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension; + + if (DevExt->IsFDO) + return FdcFdoInternalDeviceControlDispatch(DeviceObject, Irp); + else + return FdcPdoInternalDeviceControlDispatch(DeviceObject, Irp); +} + +static NTSTATUS +NTAPI +FdcCreateClose(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = FILE_OPENED; + + return STATUS_SUCCESS; +} + +static VOID +NTAPI +FdcUnload(IN PDRIVER_OBJECT DriverObject) +{ + DPRINT1("FDC Unloaded\n"); +} + +NTSTATUS +NTAPI +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegPath) +{ + DriverObject->DriverUnload = FdcUnload; + DriverObject->DriverExtension->AddDevice = FdcAddDevice; + + DriverObject->MajorFunction[IRP_MJ_CREATE] = FdcCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = FdcCreateClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FdcDeviceControlDispatch; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = FdcInternalDeviceControlDispatch; + DriverObject->MajorFunction[IRP_MJ_PNP] = FdcPnpDispatch; + DriverObject->MajorFunction[IRP_MJ_POWER] = FdcPowerDispatch; + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/reactos/drivers/storage/fdc/fdc/fdc.h b/reactos/drivers/storage/fdc/fdc/fdc.h new file mode 100644 index 00000000000..fad060578f3 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/fdc.h @@ -0,0 +1,77 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Serial enumerator driver + * FILE: drivers/storage/fdc/fdc/fdc.h + * PURPOSE: Floppy class driver header + * + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +int _cdecl swprintf(const WCHAR *, ...); + +typedef struct _FDC_COMMON_EXTENSION +{ + BOOLEAN IsFDO; + PDEVICE_OBJECT DeviceObject; + PDRIVER_OBJECT DriverObject; +} FDC_COMMON_EXTENSION, *PFDC_COMMON_EXTENSION; + +typedef struct _FDC_FDO_EXTENSION +{ + FDC_COMMON_EXTENSION Common; + + LIST_ENTRY FloppyDriveList; + ULONG FloppyDriveListCount; + KSPIN_LOCK FloppyDriveListLock; + + PDEVICE_OBJECT Ldo; + + CM_FLOPPY_DEVICE_DATA FloppyDeviceData; +} FDC_FDO_EXTENSION, *PFDC_FDO_EXTENSION; + +typedef struct _FDC_PDO_EXTENSION +{ + FDC_COMMON_EXTENSION Common; + + ULONG FloppyNumber; + + PFDC_FDO_EXTENSION FdoDevExt; + + LIST_ENTRY ListEntry; +} FDC_PDO_EXTENSION, *PFDC_PDO_EXTENSION; + +/* fdo.c */ +NTSTATUS +FdcFdoPnpDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +NTSTATUS +FdcFdoPowerDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +NTSTATUS +FdcFdoDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +NTSTATUS +FdcFdoInternalDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +/* pdo.c */ +NTSTATUS +FdcPdoPnpDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +NTSTATUS +FdcPdoPowerDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +NTSTATUS +FdcPdoDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); + +NTSTATUS +FdcPdoInternalDeviceControlDispatch(PDEVICE_OBJECT DeviceObject, + PIRP Irp); diff --git a/reactos/drivers/storage/fdc/fdc/fdc.rbuild b/reactos/drivers/storage/fdc/fdc/fdc.rbuild new file mode 100644 index 00000000000..5a63730dc45 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/fdc.rbuild @@ -0,0 +1,12 @@ + + + + + . + ntoskrnl + hal + fdc.c + fdo.c + pdo.c + fdc.rc + diff --git a/reactos/drivers/storage/fdc/fdc/fdc.rc b/reactos/drivers/storage/fdc/fdc/fdc.rc new file mode 100644 index 00000000000..fabcbb356d5 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/fdc.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "Floppy Disk Controller Driver\0" +#define REACTOS_STR_INTERNAL_NAME "fdc\0" +#define REACTOS_STR_ORIGINAL_FILENAME "fdc.sys\0" +#include diff --git a/reactos/drivers/storage/fdc/fdc/fdo.c b/reactos/drivers/storage/fdc/fdc/fdo.c new file mode 100644 index 00000000000..5cf9c0f0ba0 --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/fdo.c @@ -0,0 +1,292 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Serial enumerator driver + * FILE: drivers/storage/fdc/fdc/fdo.c + * PURPOSE: Floppy class driver FDO functions + * + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +#include "fdc.h" + +#define NDEBUG +#include + +static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion; + +static NTSTATUS NTAPI +ForwardIrpAndWaitCompletion(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + UNREFERENCED_PARAMETER(DeviceObject); + if (Irp->PendingReturned) + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS NTAPI +ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + KEVENT Event; + NTSTATUS Status; + PDEVICE_OBJECT LowerDevice = ((PFDC_FDO_EXTENSION)DeviceObject->DeviceExtension)->Ldo; + ASSERT(LowerDevice); + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + IoCopyCurrentIrpStackLocationToNext(Irp); + + IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); + + Status = IoCallDriver(LowerDevice, Irp); + if (Status == STATUS_PENDING) + { + Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + if (NT_SUCCESS(Status)) + Status = Irp->IoStatus.Status; + } + + return Status; +} + +static NTSTATUS +AddFloppyDiskDevice(PFDC_FDO_EXTENSION DevExt) +{ + NTSTATUS Status; + PFDC_PDO_EXTENSION PdoDevExt; + PDEVICE_OBJECT DeviceObject; + + Status = IoCreateDevice(DevExt->Common.DriverObject, + sizeof(FDC_PDO_EXTENSION), + NULL, + FILE_DEVICE_CONTROLLER, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create PDO device (Status: 0x%x)\n", Status); + return Status; + } + + PdoDevExt = DeviceObject->DeviceExtension; + + PdoDevExt->Common.IsFDO = FALSE; + PdoDevExt->Common.DeviceObject = DeviceObject; + PdoDevExt->Common.DriverObject = DevExt->Common.DriverObject; + PdoDevExt->FdoDevExt = DevExt; + PdoDevExt->FloppyNumber = DevExt->FloppyDriveListCount++; + + ExInterlockedInsertTailList(&DevExt->FloppyDriveList, + &PdoDevExt->ListEntry, + &DevExt->FloppyDriveListLock); + + DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + return STATUS_SUCCESS; +} + +static NTSTATUS +EnumerateDevices(PFDC_FDO_EXTENSION DevExt) +{ + /* FIXME: Hardcoded */ + if (DevExt->FloppyDriveListCount == 0) + return AddFloppyDiskDevice(DevExt); + + return STATUS_SUCCESS; +} + +static NTSTATUS +FdcFdoQueryBusRelations(PFDC_FDO_EXTENSION DevExt, + PIRP Irp) +{ + PDEVICE_RELATIONS DeviceRelations; + KIRQL OldIrql; + ULONG i; + PFDC_PDO_EXTENSION PdoDevExt; + PLIST_ENTRY ListEntry; + NTSTATUS Status; + + Status = EnumerateDevices(DevExt); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Device enumeration failed (Status: 0x%x)\n", Status); + return Status; + } + + KeAcquireSpinLock(&DevExt->FloppyDriveListLock, &OldIrql); + + DeviceRelations = ExAllocatePool(NonPagedPool, + sizeof(DEVICE_RELATIONS) + sizeof(DeviceRelations->Objects) * + (DevExt->FloppyDriveListCount - 1)); + if (!DeviceRelations) + { + DPRINT1("Failed to allocate memory for device relations\n"); + KeReleaseSpinLock(&DevExt->FloppyDriveListLock, OldIrql); + return STATUS_INSUFFICIENT_RESOURCES; + } + + DeviceRelations->Count = DevExt->FloppyDriveListCount; + + ListEntry = DevExt->FloppyDriveList.Flink; + i = 0; + while (ListEntry != &DevExt->FloppyDriveList) + { + PdoDevExt = CONTAINING_RECORD(ListEntry, FDC_PDO_EXTENSION, ListEntry); + + ObReferenceObject(PdoDevExt->Common.DeviceObject); + + DeviceRelations->Objects[i++] = PdoDevExt->Common.DeviceObject; + + ListEntry = ListEntry->Flink; + } + + KeReleaseSpinLock(&DevExt->FloppyDriveListLock, OldIrql); + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +} + +static NTSTATUS +FdcFdoStartDevice(PFDC_FDO_EXTENSION DevExt, + PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + PCM_PARTIAL_RESOURCE_LIST ResourceList; + ULONG i; + + ResourceList = &IrpSp->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList; + + DPRINT1("Descriptor count: %d\n", ResourceList->Count); + + for (i = 0; i < ResourceList->Count; i++) + { + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->PartialDescriptors[i]; + + if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific) + { + RtlCopyMemory(&DevExt->FloppyDeviceData, + (PartialDescriptor + 1), + sizeof(CM_FLOPPY_DEVICE_DATA)); + } + } + + return STATUS_SUCCESS; +} + +NTSTATUS +FdcFdoPnpDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_FDO_EXTENSION DevExt = DeviceObject->DeviceExtension; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status = Irp->IoStatus.Status; + + switch (IrpSp->MinorFunction) + { + case IRP_MN_CANCEL_STOP_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + Status = STATUS_SUCCESS; + break; + + case IRP_MN_START_DEVICE: + DPRINT("Starting FDC FDO\n"); + + Status = ForwardIrpAndWait(DeviceObject, Irp); + if (NT_SUCCESS(Status)) + { + Status = FdcFdoStartDevice(DevExt, Irp, IrpSp); + } + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; + case IRP_MN_STOP_DEVICE: + DPRINT("Stopping FDC FDO\n"); + /* We don't need to do anything here */ + Status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + /* We don't care */ + Status = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + DPRINT("Removing FDC FDO\n"); + + /* Undo what we did in FdcAddDevice */ + IoDetachDevice(DevExt->Ldo); + + IoDeleteDevice(DeviceObject); + + Status = STATUS_SUCCESS; + break; + case IRP_MN_SURPRISE_REMOVAL: + /* Nothing special to do here to deal with surprise removal */ + Status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_DEVICE_RELATIONS: + if (IrpSp->Parameters.QueryDeviceRelations.Type == BusRelations) + { + Status = FdcFdoQueryBusRelations(DevExt, Irp); + + Irp->IoStatus.Status = Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; + } + break; + } + + Irp->IoStatus.Status = Status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DevExt->Ldo, Irp); +} + +NTSTATUS +FdcFdoPowerDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_FDO_EXTENSION DevExt = DeviceObject->DeviceExtension; + + DPRINT1("Power request not handled\n"); + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DevExt->Ldo, Irp); +} + +NTSTATUS +FdcFdoDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + /* FIXME: We don't handle any of these yet */ + + DPRINT1("Device control request not handled\n"); + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Irp->IoStatus.Status; +} + +NTSTATUS +FdcFdoInternalDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + /* FIXME: We don't handle any of these yet */ + + DPRINT1("Internal device control request not handled\n"); + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Irp->IoStatus.Status; +} \ No newline at end of file diff --git a/reactos/drivers/storage/fdc/fdc/pdo.c b/reactos/drivers/storage/fdc/fdc/pdo.c new file mode 100644 index 00000000000..cbf240b9ffb --- /dev/null +++ b/reactos/drivers/storage/fdc/fdc/pdo.c @@ -0,0 +1,260 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Serial enumerator driver + * FILE: drivers/storage/fdc/fdc/pdo.c + * PURPOSE: Floppy class driver PDO functions + * + * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org) + */ + +#include + +#define INITGUID +#include + +#include "fdc.h" + +#define NDEBUG +#include + +static NTSTATUS +FdcPdoQueryId(PFDC_PDO_EXTENSION DevExt, + PIRP Irp, + PIO_STACK_LOCATION IrpSp) +{ + WCHAR Buffer[100]; + PWCHAR BufferP; + + switch (IrpSp->Parameters.QueryId.IdType) + { + case BusQueryDeviceID: + BufferP = L"FDC\\GENERIC_FLOPPY_DRIVE"; + break; + case BusQueryHardwareIDs: + BufferP = L"FDC\\GENERIC_FLOPPY_DRIVE\0"; + break; + case BusQueryCompatibleIDs: + BufferP = L"GenFloppyDisk\0"; + break; + case BusQueryInstanceID: + swprintf(Buffer, L"%d", DevExt->FloppyNumber); + BufferP = Buffer; + break; + default: + return STATUS_UNSUCCESSFUL; + } + + Irp->IoStatus.Information = (ULONG_PTR)BufferP; + + return STATUS_SUCCESS; +} + +#if 0 +static NTSTATUS +FdcPdoQueryBusInformation(PIRP Irp) +{ + PPNP_BUS_INFORMATION BusInformation; + + BusInformation = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION)); + if (!BusInformation) + { + DPRINT1("Failed to allocate PnP bus info struct\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + BusInformation->BusTypeGuid = GUID_BUS_TYPE_INTERNAL; + BusInformation->LegacyBusType = Internal; + BusInformation->BusNumber = 0; + + Irp->IoStatus.Information = (ULONG_PTR)BusInformation; + + return STATUS_SUCCESS; +} +#endif + +static NTSTATUS +FdcPdoQueryCapabilities(PFDC_PDO_EXTENSION DevExt, + PIO_STACK_LOCATION IrpSp) +{ + PDEVICE_CAPABILITIES DevCaps = IrpSp->Parameters.DeviceCapabilities.Capabilities; + + DevCaps->DeviceD1 = 0; + DevCaps->DeviceD2 = 0; + DevCaps->LockSupported = 0; + DevCaps->EjectSupported = 0; + DevCaps->Removable = 0; + DevCaps->DockDevice = 0; + DevCaps->UniqueID = 0; + DevCaps->SilentInstall = 0; + DevCaps->RawDeviceOK = 0; + DevCaps->SurpriseRemovalOK = 0; + DevCaps->WakeFromD0 = 0; + DevCaps->WakeFromD1 = 0; + DevCaps->WakeFromD2 = 0; + DevCaps->WakeFromD3 = 0; + DevCaps->HardwareDisabled = 0; + DevCaps->NoDisplayInUI = 0; + DevCaps->Address = DevExt->FloppyNumber; + DevCaps->SystemWake = PowerSystemUnspecified; + DevCaps->DeviceWake = PowerDeviceUnspecified; + DevCaps->D1Latency = 0; + DevCaps->D2Latency = 0; + DevCaps->D3Latency = 0; + + return STATUS_SUCCESS; +} + +static NTSTATUS +FdcPdoQueryTargetDeviceRelations(PFDC_PDO_EXTENSION DevExt, + PIRP Irp) +{ + PDEVICE_RELATIONS DeviceRelations; + + DeviceRelations = ExAllocatePool(NonPagedPool, + sizeof(DEVICE_RELATIONS)); + if (!DeviceRelations) + { + DPRINT1("Failed to allocate memory for device relations\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + DeviceRelations->Count = 1; + DeviceRelations->Objects[0] = DevExt->Common.DeviceObject; + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + + return STATUS_SUCCESS; +} + +static VOID +FdcPdoRemoveDevice(PFDC_PDO_EXTENSION DevExt) +{ + KIRQL OldIrql; + + KeAcquireSpinLock(&DevExt->FdoDevExt->FloppyDriveListLock, &OldIrql); + RemoveEntryList(&DevExt->ListEntry); + KeReleaseSpinLock(&DevExt->FdoDevExt->FloppyDriveListLock, OldIrql); + + IoDeleteDevice(DevExt->Common.DeviceObject); +} + +NTSTATUS +FdcPdoPnpDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDC_PDO_EXTENSION DevExt = DeviceObject->DeviceExtension; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status = Irp->IoStatus.Status; + PWCHAR Buffer; + + switch (IrpSp->MinorFunction) + { + case IRP_MN_CANCEL_STOP_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + Status = STATUS_SUCCESS; + break; + case IRP_MN_START_DEVICE: + DPRINT("Starting FDC PDO\n"); + Status = STATUS_SUCCESS; + break; + case IRP_MN_STOP_DEVICE: + DPRINT("Stopping FDC PDO\n"); + /* We don't need to do anything here */ + Status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + /* We don't care */ + Status = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + DPRINT("Removing FDC PDO\n"); + + FdcPdoRemoveDevice(DevExt); + + Status = STATUS_SUCCESS; + break; + case IRP_MN_SURPRISE_REMOVAL: + /* Nothing special to do here to deal with surprise removal */ + Status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_DEVICE_TEXT: + Buffer = L"Floppy disk drive"; + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + Status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_ID: + Status = FdcPdoQueryId(DevExt, Irp, IrpSp); + break; + case IRP_MN_QUERY_CAPABILITIES: + Status = FdcPdoQueryCapabilities(DevExt, IrpSp); + break; + case IRP_MN_QUERY_DEVICE_RELATIONS: + if (IrpSp->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) + { + Status = FdcPdoQueryTargetDeviceRelations(DevExt, Irp); + } + break; +#if 0 + case IRP_MN_QUERY_BUS_INFORMATION: + Status = FdcPdoQueryBusInformation(Irp); + break; +#endif + case IRP_MN_QUERY_RESOURCES: + case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: + /* All resources are owned by the controller's FDO */ + break; + default: + break; + } + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +NTSTATUS +FdcPdoPowerDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT1("Power request not handled\n"); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Irp->IoStatus.Status; +} + +NTSTATUS +FdcPdoDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + /* FIXME: We don't handle any of these yet */ + + DPRINT1("Device control request not handled\n"); + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Irp->IoStatus.Status; +} + +NTSTATUS +FdcPdoInternalDeviceControlDispatch(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + /* FIXME: We don't handle any of these yet */ + + DPRINT1("Internal device control request not handled\n"); + + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Irp->IoStatus.Status; +} \ No newline at end of file diff --git a/reactos/media/inf/fdc.inf b/reactos/media/inf/fdc.inf index dd6750249c2..b2a47fc0fe8 100644 Binary files a/reactos/media/inf/fdc.inf and b/reactos/media/inf/fdc.inf differ