list(APPEND SOURCE
fdo.c
+ miniport.c
misc.c
pdo.c
storport.c
add_library(storport SHARED
${SOURCE}
+ guid.c
storport.rc
${CMAKE_CURRENT_BINARY_DIR}/storport.def)
/* FUNCTIONS ******************************************************************/
+static
+NTSTATUS
+PortFdoStartMiniport(
+ _In_ PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+ PHW_INITIALIZATION_DATA InitData;
+ INTERFACE_TYPE InterfaceType;
+ NTSTATUS Status;
+
+ DPRINT1("PortFdoStartDevice(%p)\n", DeviceExtension);
+
+ /* Get the interface type of the lower device */
+ InterfaceType = GetBusInterface(DeviceExtension->LowerDevice);
+ if (InterfaceType == InterfaceTypeUndefined)
+ return STATUS_NO_SUCH_DEVICE;
+
+ /* Get the driver init data for the given interface type */
+ InitData = PortGetDriverInitData(DeviceExtension->DriverExtension,
+ InterfaceType);
+ if (InitData == NULL)
+ return STATUS_NO_SUCH_DEVICE;
+
+ /* Initialize the miniport */
+ MiniportInitialize(&DeviceExtension->Miniport,
+ DeviceExtension,
+ InitData);
+
+ /* Call the miniports FindAdapter function */
+ Status = MiniportFindAdapter(&DeviceExtension->Miniport);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MiniportFindAdapter() failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ /* Call the miniports HwInitialize function */
+ Status = MiniportHwInitialize(&DeviceExtension->Miniport);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MiniportHwInitialize() failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
static
NTSTATUS
NTAPI
_In_ PFDO_DEVICE_EXTENSION DeviceExtension,
_In_ PIRP Irp)
{
+ NTSTATUS Status;
+
DPRINT1("PortFdoStartDevice(%p %p)\n",
DeviceExtension, Irp);
ASSERT(DeviceExtension->ExtensionType == FdoExtension);
- return STATUS_SUCCESS;
+ /* Start the lower device if the FDO is in 'stopped' state */
+ if (DeviceExtension->PnpState == dsStopped)
+ {
+ Status = ForwardIrpAndWait(DeviceExtension->LowerDevice, Irp);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ForwardIrpAndWait() failed (Status 0x%08lx)\n", Status);
+ return Status;
+ }
+ }
+
+ /* Change to the 'started' state */
+ DeviceExtension->PnpState = dsStarted;
+
+ /* Start the miniport (FindAdapter & Initialize) */
+ Status = PortFdoStartMiniport(DeviceExtension);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("FdoStartMiniport() failed (Status 0x%08lx)\n", Status);
+ DeviceExtension->PnpState = dsStopped;
+ }
+
+ return Status;
}
{
case IRP_MN_START_DEVICE: /* 0x00 */
DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
- /* Call lower driver */
- Status = ForwardIrpAndWait(DeviceExtension->LowerDevice, Irp);
- if (NT_SUCCESS(Status))
- {
- Status = PortFdoStartDevice(DeviceExtension, Irp);
- }
+ Status = PortFdoStartDevice(DeviceExtension, Irp);
break;
case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */
--- /dev/null
+/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
+
+#include <ntdef.h>
+#include <initguid.h>
+#include <ioevent.h>
+#include <wdmguid.h>
+
+#define DEVICE_TYPE ULONG
+#include <ntddstor.h>
+
+/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */
--- /dev/null
+/*
+ * PROJECT: ReactOS Storport Driver
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Miniport interface code
+ * COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+MiniportInitialize(
+ _In_ PMINIPORT Miniport,
+ _In_ PFDO_DEVICE_EXTENSION DeviceExtension,
+ _In_ PHW_INITIALIZATION_DATA InitData)
+{
+ Miniport->DeviceExtension = DeviceExtension;
+ Miniport->InitData = InitData;
+}
+
+
+NTSTATUS
+MiniportFindAdapter(
+ _In_ PMINIPORT Miniport)
+{
+ BOOLEAN Reserved = FALSE;
+ ULONG Result;
+ NTSTATUS Status;
+
+ DPRINT1("MiniportFindAdapter(%p)\n", Miniport);
+
+ Result = Miniport->InitData->HwFindAdapter(NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &Reserved);
+ DPRINT1("HwFindAdapter() returned %lu\n", Result);
+
+ switch (Result)
+ {
+ case SP_RETURN_NOT_FOUND:
+ DPRINT1("SP_RETURN_NOT_FOUND\n");
+ Status = STATUS_NOT_FOUND;
+ break;
+
+ case SP_RETURN_FOUND:
+ DPRINT1("SP_RETURN_FOUND\n");
+ Status = STATUS_SUCCESS;
+ break;
+
+ case SP_RETURN_ERROR:
+ DPRINT1("SP_RETURN_ERROR\n");
+ Status = STATUS_ADAPTER_HARDWARE_ERROR;
+ break;
+
+ case SP_RETURN_BAD_CONFIG:
+ DPRINT1("SP_RETURN_BAD_CONFIG\n");
+ Status = STATUS_DEVICE_CONFIGURATION_ERROR;
+ break;
+
+ default:
+ DPRINT1("Unknown result: %lu\n", Result);
+ Status = STATUS_INTERNAL_ERROR;
+ break;
+ }
+
+ return Status;
+}
+
+
+NTSTATUS
+MiniportHwInitialize(
+ _In_ PMINIPORT Miniport)
+{
+ NTSTATUS Status;
+
+ DPRINT1("MiniportHwInitialize(%p)\n", Miniport);
+
+ Status = Miniport->InitData->HwInitialize(NULL);
+ DPRINT1("HwInitialize() returned 0x%08lx\n", Status);
+
+ return Status;
+}
+
+/* EOF */
return IoCallDriver(LowerDevice, Irp);
}
+
+INTERFACE_TYPE
+GetBusInterface(
+ PDEVICE_OBJECT DeviceObject)
+{
+ GUID Guid;
+ ULONG Length;
+ NTSTATUS Status;
+
+ Status = IoGetDeviceProperty(DeviceObject,
+ DevicePropertyBusTypeGuid,
+ sizeof(Guid),
+ &Guid,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ return InterfaceTypeUndefined;
+
+ if (RtlCompareMemory(&Guid, &GUID_BUS_TYPE_PCMCIA, sizeof(GUID)) == sizeof(GUID))
+ return PCMCIABus;
+ else if (RtlCompareMemory(&Guid, &GUID_BUS_TYPE_PCI, sizeof(GUID)) == sizeof(GUID))
+ return PCIBus;
+ else if (RtlCompareMemory(&Guid, &GUID_BUS_TYPE_ISAPNP, sizeof(GUID)) == sizeof(GUID))
+ return PNPISABus;
+
+ return InterfaceTypeUndefined;
+}
+
/* EOF */
#include <wdm.h>
#include <ntddk.h>
#include <stdio.h>
+#include <memory.h>
/* Declare STORPORT_API functions as exports rather than imports */
#define _STORPORT_
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <mountdev.h>
+#include <wdmguid.h>
+
+/* Memory Tags */
+#define TAG_GLOBAL_DATA 'DGtS'
+#define TAG_INIT_DATA 'DItS'
typedef enum
{
PdoExtension
} EXTENSION_TYPE;
+typedef struct _DRIVER_INIT_DATA
+{
+ LIST_ENTRY Entry;
+ HW_INITIALIZATION_DATA HwInitData;
+} DRIVER_INIT_DATA, *PDRIVER_INIT_DATA;
+
typedef struct _DRIVER_OBJECT_EXTENSION
{
EXTENSION_TYPE ExtensionType;
-
PDRIVER_OBJECT DriverObject;
KSPIN_LOCK AdapterListLock;
LIST_ENTRY AdapterListHead;
ULONG AdapterCount;
+ LIST_ENTRY InitDataListHead;
} DRIVER_OBJECT_EXTENSION, *PDRIVER_OBJECT_EXTENSION;
+typedef struct _MINIPORT
+{
+ struct _FDO_DEVICE_EXTENSION *DeviceExtension;
+ PHW_INITIALIZATION_DATA InitData;
+} MINIPORT, *PMINIPORT;
+
typedef struct _FDO_DEVICE_EXTENSION
{
EXTENSION_TYPE ExtensionType;
PDEVICE_OBJECT LowerDevice;
PDEVICE_OBJECT PhysicalDevice;
- DEVICE_STATE PnpState;
+ PDRIVER_OBJECT_EXTENSION DriverExtension;
+ DEVICE_STATE PnpState;
LIST_ENTRY AdapterListEntry;
+
+ MINIPORT Miniport;
+
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
_In_ PIRP Irp);
+/* miniport.c */
+
+VOID
+MiniportInitialize(
+ _In_ PMINIPORT Miniport,
+ _In_ PFDO_DEVICE_EXTENSION DeviceExtension,
+ _In_ PHW_INITIALIZATION_DATA HwInitializationData);
+
+NTSTATUS
+MiniportFindAdapter(
+ _In_ PMINIPORT Miniport);
+
+NTSTATUS
+MiniportHwInitialize(
+ _In_ PMINIPORT Miniport);
+
+
/* misc.c */
NTSTATUS
_In_ PDEVICE_OBJECT LowerDevice,
_In_ PIRP Irp);
+INTERFACE_TYPE
+GetBusInterface(
+ PDEVICE_OBJECT DeviceObject);
/* pdo.c */
/* storport.c */
+PHW_INITIALIZATION_DATA
+PortGetDriverInitData(
+ PDRIVER_OBJECT_EXTENSION DriverExtension,
+ INTERFACE_TYPE InterfaceType);
+
NTSTATUS
NTAPI
DriverEntry(
/* FUNCTIONS ******************************************************************/
+static
+NTSTATUS
+PortAddDriverInitData(
+ PDRIVER_OBJECT_EXTENSION DriverExtension,
+ PHW_INITIALIZATION_DATA HwInitializationData)
+{
+ PDRIVER_INIT_DATA InitData;
+
+ DPRINT1("PortAddDriverInitData()\n");
+
+ InitData = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(DRIVER_INIT_DATA),
+ TAG_INIT_DATA);
+ if (InitData == NULL)
+ return STATUS_NO_MEMORY;
+
+ RtlCopyMemory(&InitData->HwInitData,
+ HwInitializationData,
+ sizeof(HW_INITIALIZATION_DATA));
+
+ InsertHeadList(&DriverExtension->InitDataListHead,
+ &InitData->Entry);
+
+ return STATUS_SUCCESS;
+}
+
+
+static
+VOID
+PortDeleteDriverInitData(
+ PDRIVER_OBJECT_EXTENSION DriverExtension)
+{
+ PDRIVER_INIT_DATA InitData;
+ PLIST_ENTRY ListEntry;
+
+ DPRINT1("PortDeleteDriverInitData()\n");
+
+ ListEntry = DriverExtension->InitDataListHead.Flink;
+ while (ListEntry != &DriverExtension->InitDataListHead)
+ {
+ InitData = CONTAINING_RECORD(ListEntry,
+ DRIVER_INIT_DATA,
+ Entry);
+
+ RemoveEntryList(&InitData->Entry);
+
+ ExFreePoolWithTag(InitData,
+ TAG_INIT_DATA);
+
+ ListEntry = DriverExtension->InitDataListHead.Flink;
+ }
+}
+
+
+PHW_INITIALIZATION_DATA
+PortGetDriverInitData(
+ PDRIVER_OBJECT_EXTENSION DriverExtension,
+ INTERFACE_TYPE InterfaceType)
+{
+ PDRIVER_INIT_DATA InitData;
+ PLIST_ENTRY ListEntry;
+
+ DPRINT1("PortGetDriverInitData()\n");
+
+ ListEntry = DriverExtension->InitDataListHead.Flink;
+ while (ListEntry != &DriverExtension->InitDataListHead)
+ {
+ InitData = CONTAINING_RECORD(ListEntry,
+ DRIVER_INIT_DATA,
+ Entry);
+ if (InitData->HwInitData.AdapterInterfaceType == InterfaceType)
+ return &InitData->HwInitData;
+
+ ListEntry = ListEntry->Flink;
+ }
+
+ return NULL;
+}
+
+
static
NTSTATUS
NTAPI
(PVOID)DriverEntry);
ASSERT(DriverObjectExtension->ExtensionType == DriverExtension);
+ DeviceExtension->DriverExtension = DriverObjectExtension;
+
KeAcquireInStackQueuedSpinLock(&DriverObjectExtension->AdapterListLock,
&LockHandle);
PortUnload(
_In_ PDRIVER_OBJECT DriverObject)
{
+ PDRIVER_OBJECT_EXTENSION DriverExtension;
+
DPRINT1("PortUnload(%p)\n",
DriverObject);
+
+ DriverExtension = IoGetDriverObjectExtension(DriverObject,
+ (PVOID)DriverEntry);
+ if (DriverExtension != NULL)
+ {
+ PortDeleteDriverInitData(DriverExtension);
+ }
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
- IoCompleteRequest( Irp, IO_NO_INCREMENT );
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
InitializeListHead(&DriverObjectExtension->AdapterListHead);
KeInitializeSpinLock(&DriverObjectExtension->AdapterListLock);
+ InitializeListHead(&DriverObjectExtension->InitDataListHead);
/* Set handlers */
DriverObject->DriverExtension->AddDevice = PortAddDevice;
DriverObject->MajorFunction[IRP_MJ_PNP] = PortDispatchPnp;
}
+ /* Add the initialzation data to the driver extension */
+ Status = PortAddDriverInitData(DriverObjectExtension,
+ HwInitializationData);
+
DPRINT1("StorPortInitialize() done (Status 0x%08lx)\n", Status);
return Status;
#define REACTOS_STR_FILE_DESCRIPTION "Storport Driver"
#define REACTOS_STR_INTERNAL_NAME "storport"
#define REACTOS_STR_ORIGINAL_FILENAME "storport.sys"
-#include <reactos/version.rc>
\ No newline at end of file
+#include <reactos/version.rc>