📄 pdo.c
字号:
Length);
return Size;
}
static BOOLEAN NTAPI
InterfacePciDevicePresent(
IN USHORT VendorID,
IN USHORT DeviceID,
IN UCHAR RevisionID,
IN USHORT SubVendorID,
IN USHORT SubSystemID,
IN ULONG Flags)
{
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PPCI_DEVICE PciDevice;
PLIST_ENTRY CurrentBus, CurrentEntry;
KIRQL OldIrql;
BOOLEAN Found = FALSE;
KeAcquireSpinLock(&DriverExtension->BusListLock, &OldIrql);
CurrentBus = DriverExtension->BusListHead.Flink;
while (!Found && CurrentBus != &DriverExtension->BusListHead)
{
FdoDeviceExtension = CONTAINING_RECORD(CurrentBus, FDO_DEVICE_EXTENSION, ListEntry);
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->DeviceListLock);
CurrentEntry = FdoDeviceExtension->DeviceListHead.Flink;
while (!Found && CurrentEntry != &FdoDeviceExtension->DeviceListHead)
{
PciDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
if (PciDevice->PciConfig.VendorID == VendorID &&
PciDevice->PciConfig.DeviceID == DeviceID)
{
if (!(Flags & PCI_USE_SUBSYSTEM_IDS) || (
PciDevice->PciConfig.u.type0.SubVendorID == SubVendorID &&
PciDevice->PciConfig.u.type0.SubSystemID == SubSystemID))
{
if (!(Flags & PCI_USE_REVISION) ||
PciDevice->PciConfig.RevisionID == RevisionID)
{
DPRINT("Found the PCI device\n");
Found = TRUE;
}
}
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension->DeviceListLock);
CurrentBus = CurrentBus->Flink;
}
KeReleaseSpinLock(&DriverExtension->BusListLock, OldIrql);
return Found;
}
static BOOLEAN
CheckPciDevice(
IN PPCI_COMMON_CONFIG PciConfig,
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
{
if ((Parameters->Flags & PCI_USE_VENDEV_IDS) && (
PciConfig->VendorID != Parameters->VendorID ||
PciConfig->DeviceID != Parameters->DeviceID))
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_CLASS_SUBCLASS) && (
PciConfig->BaseClass != Parameters->BaseClass ||
PciConfig->SubClass != Parameters->SubClass))
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_PROGIF) &&
PciConfig->ProgIf != Parameters->ProgIf)
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_SUBSYSTEM_IDS) && (
PciConfig->u.type0.SubVendorID != Parameters->SubVendorID ||
PciConfig->u.type0.SubSystemID != Parameters->SubSystemID))
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_REVISION) &&
PciConfig->RevisionID != Parameters->RevisionID)
{
return FALSE;
}
return TRUE;
}
static BOOLEAN NTAPI
InterfacePciDevicePresentEx(
IN PVOID Context,
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
PFDO_DEVICE_EXTENSION MyFdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PPCI_DEVICE PciDevice;
PLIST_ENTRY CurrentBus, CurrentEntry;
KIRQL OldIrql;
BOOLEAN Found = FALSE;
DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
Context, Parameters);
if (!Parameters || Parameters->Size != sizeof(PCI_DEVICE_PRESENCE_PARAMETERS))
return FALSE;
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
MyFdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
if (Parameters->Flags & PCI_USE_LOCAL_DEVICE)
{
return CheckPciDevice(&DeviceExtension->PciDevice->PciConfig, Parameters);
}
KeAcquireSpinLock(&DriverExtension->BusListLock, &OldIrql);
CurrentBus = DriverExtension->BusListHead.Flink;
while (!Found && CurrentBus != &DriverExtension->BusListHead)
{
FdoDeviceExtension = CONTAINING_RECORD(CurrentBus, FDO_DEVICE_EXTENSION, ListEntry);
if (!(Parameters->Flags & PCI_USE_LOCAL_BUS) || FdoDeviceExtension == MyFdoDeviceExtension)
{
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->DeviceListLock);
CurrentEntry = FdoDeviceExtension->DeviceListHead.Flink;
while (!Found && CurrentEntry != &FdoDeviceExtension->DeviceListHead)
{
PciDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
if (CheckPciDevice(&PciDevice->PciConfig, Parameters))
{
DPRINT("Found the PCI device\n");
Found = TRUE;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension->DeviceListLock);
}
CurrentBus = CurrentBus->Flink;
}
KeReleaseSpinLock(&DriverExtension->BusListLock, OldIrql);
return Found;
}
static NTSTATUS
PdoQueryInterface(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
NTSTATUS Status;
if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
&GUID_BUS_INTERFACE_STANDARD, sizeof(GUID)) == sizeof(GUID))
{
/* BUS_INTERFACE_STANDARD */
if (IrpSp->Parameters.QueryInterface.Version < 1)
Status = STATUS_NOT_SUPPORTED;
else if (IrpSp->Parameters.QueryInterface.Size < sizeof(BUS_INTERFACE_STANDARD))
Status = STATUS_BUFFER_TOO_SMALL;
else
{
PBUS_INTERFACE_STANDARD BusInterface;
BusInterface = (PBUS_INTERFACE_STANDARD)IrpSp->Parameters.QueryInterface.Interface;
BusInterface->Size = sizeof(BUS_INTERFACE_STANDARD);
BusInterface->Version = 1;
BusInterface->TranslateBusAddress = InterfaceBusTranslateBusAddress;
BusInterface->GetDmaAdapter = InterfaceBusGetDmaAdapter;
BusInterface->SetBusData = InterfaceBusSetBusData;
BusInterface->GetBusData = InterfaceBusGetBusData;
Status = STATUS_SUCCESS;
}
}
else if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
&GUID_PCI_DEVICE_PRESENT_INTERFACE, sizeof(GUID)) == sizeof(GUID))
{
/* PCI_DEVICE_PRESENT_INTERFACE */
if (IrpSp->Parameters.QueryInterface.Version < 1)
Status = STATUS_NOT_SUPPORTED;
else if (IrpSp->Parameters.QueryInterface.Size < sizeof(PCI_DEVICE_PRESENT_INTERFACE))
Status = STATUS_BUFFER_TOO_SMALL;
else
{
PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface;
PciDevicePresentInterface = (PPCI_DEVICE_PRESENT_INTERFACE)IrpSp->Parameters.QueryInterface.Interface;
PciDevicePresentInterface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
PciDevicePresentInterface->Version = 1;
PciDevicePresentInterface->IsDevicePresent = InterfacePciDevicePresent;
PciDevicePresentInterface->IsDevicePresentEx = InterfacePciDevicePresentEx;
Status = STATUS_SUCCESS;
}
}
else
{
/* Not a supported interface */
return STATUS_NOT_SUPPORTED;
}
if (NT_SUCCESS(Status))
{
/* Add a reference for the returned interface */
PINTERFACE Interface;
Interface = (PINTERFACE)IrpSp->Parameters.QueryInterface.Interface;
Interface->Context = DeviceObject;
Interface->InterfaceReference = InterfaceReference;
Interface->InterfaceDereference = InterfaceDereference;
Interface->InterfaceReference(Interface->Context);
}
return Status;
}
static NTSTATUS
PdoReadConfig(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
ULONG Size;
DPRINT("PdoReadConfig() called\n");
Size = InterfaceBusGetBusData(
DeviceObject,
IrpSp->Parameters.ReadWriteConfig.WhichSpace,
IrpSp->Parameters.ReadWriteConfig.Buffer,
IrpSp->Parameters.ReadWriteConfig.Offset,
IrpSp->Parameters.ReadWriteConfig.Length);
if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
{
DPRINT1("Size %lu Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
Irp->IoStatus.Information = 0;
return STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Information = Size;
return STATUS_SUCCESS;
}
static NTSTATUS
PdoWriteConfig(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
ULONG Size;
DPRINT1("PdoWriteConfig() called\n");
/* Get PCI configuration space */
Size = InterfaceBusSetBusData(
DeviceObject,
IrpSp->Parameters.ReadWriteConfig.WhichSpace,
IrpSp->Parameters.ReadWriteConfig.Buffer,
IrpSp->Parameters.ReadWriteConfig.Offset,
IrpSp->Parameters.ReadWriteConfig.Length);
if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
{
DPRINT1("Size %lu Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
Irp->IoStatus.Information = 0;
return STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Information = Size;
return STATUS_SUCCESS;
}
static NTSTATUS
PdoSetPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
DPRINT("Called\n");
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
Status = STATUS_SUCCESS;
switch (IrpSp->Parameters.Power.State.SystemState) {
default:
Status = STATUS_UNSUCCESSFUL;
}
} else {
Status = STATUS_UNSUCCESSFUL;
}
return Status;
}
/*** PUBLIC ******************************************************************/
NTSTATUS
PdoPnpControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handle Plug and Play IRPs for the child device
* ARGUMENTS:
* DeviceObject = Pointer to physical device object of the child device
* Irp = Pointer to IRP that should be handled
* RETURNS:
* Status
*/
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
DPRINT("Called\n");
Status = Irp->IoStatus.Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction) {
#if 0
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
break;
case IRP_MN_EJECT:
break;
#endif
case IRP_MN_QUERY_BUS_INFORMATION:
Status = PdoQueryBusInformation(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_QUERY_CAPABILITIES:
Status = PdoQueryCapabilities(DeviceObject, Irp, IrpSp);
break;
#if 0
case IRP_MN_QUERY_DEVICE_RELATIONS:
/* FIXME: Possibly handle for RemovalRelations */
break;
#endif
case IRP_MN_QUERY_DEVICE_TEXT:
DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
Status = PdoQueryDeviceText(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_QUERY_ID:
DPRINT("IRP_MN_QUERY_ID received\n");
Status = PdoQueryId(DeviceObject, Irp, IrpSp);
break;
#if 0
case IRP_MN_QUERY_PNP_DEVICE_STATE:
break;
#endif
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
Status = PdoQueryResourceRequirements(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_QUERY_RESOURCES:
DPRINT("IRP_MN_QUERY_RESOURCES received\n");
Status = PdoQueryResources(DeviceObject, Irp, IrpSp);
break;
#if 0
case IRP_MN_SET_LOCK:
break;
#endif
case IRP_MN_START_DEVICE:
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_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
Status = STATUS_SUCCESS;
break;
case IRP_MN_QUERY_INTERFACE:
DPRINT("IRP_MN_QUERY_INTERFACE received\n");
Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_READ_CONFIG:
DPRINT("IRP_MN_READ_CONFIG received\n");
Status = PdoReadConfig(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_WRITE_CONFIG:
DPRINT("IRP_MN_WRITE_CONFIG received\n");
Status = PdoWriteConfig(DeviceObject, Irp, IrpSp);
break;
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
DPRINT("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;
}
if (Status != STATUS_PENDING) {
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
DPRINT("Leaving. Status 0x%X\n", Status);
return Status;
}
NTSTATUS
PdoPowerControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handle power management IRPs for the child device
* ARGUMENTS:
* DeviceObject = Pointer to physical device object of the child device
* Irp = Pointer to IRP that should be handled
* RETURNS:
* Status
*/
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
DPRINT("Called\n");
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction) {
case IRP_MN_SET_POWER:
Status = PdoSetPower(DeviceObject, Irp, IrpSp);
break;
default:
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
Status = STATUS_NOT_IMPLEMENTED;
break;
}
if (Status != STATUS_PENDING) {
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
DPRINT("Leaving. Status 0x%X\n", Status);
return Status;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -