fdo.c
来自「一个类似windows」· C语言 代码 · 共 591 行 · 第 1/2 页
C
591 行
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;
}
}
if (!Device->RemovePending) {
/* Reference the physical device object. The PnP manager
will dereference it again when it is no longer needed */
ObReferenceObject(Device->Pdo);
Relations->Objects[i] = Device->Pdo;
i++;
}
CurrentEntry = CurrentEntry->Flink;
}
if (ErrorOccurred) {
/* FIXME: Cleanup all new PDOs created in this call. Please give me SEH!!! ;-) */
/* FIXME: Should IoAttachDeviceToDeviceStack() be undone? */
if (PdoDeviceExtension) {
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceID);
RtlFreeUnicodeString(&PdoDeviceExtension->InstanceID);
RtlFreeUnicodeString(&PdoDeviceExtension->HardwareIDs);
RtlFreeUnicodeString(&PdoDeviceExtension->CompatibleIDs);
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceDescription);
RtlFreeUnicodeString(&PdoDeviceExtension->DeviceLocation);
}
ExFreePool(Relations);
return ErrorStatus;
}
Irp->IoStatus.Information = (ULONG_PTR)Relations;
DPRINT("Done\n");
return Status;
}
static NTSTATUS
FdoStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PFDO_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
ULONG FoundBusNumber = FALSE;
ULONG i;
DPRINT("Called\n");
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
AllocatedResources = IoGetCurrentIrpStackLocation(Irp)->Parameters.StartDevice.AllocatedResources;
if (!AllocatedResources)
{
DPRINT("No allocated resources sent to driver\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (AllocatedResources->Count < 1)
{
DPRINT("Not enough allocated resources sent to driver\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (AllocatedResources->List[0].PartialResourceList.Version != 1
|| AllocatedResources->List[0].PartialResourceList.Revision != 1)
return STATUS_REVISION_MISMATCH;
ASSERT(DeviceExtension->State == dsStopped);
for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
switch (ResourceDescriptor->Type)
{
case CmResourceTypeBusNumber:
{
if (FoundBusNumber || ResourceDescriptor->u.BusNumber.Length != 1)
return STATUS_INVALID_PARAMETER;
DeviceExtension->BusNumber = ResourceDescriptor->u.BusNumber.Start;
DPRINT("Found bus number resource: %lu\n", DeviceExtension->BusNumber);
FoundBusNumber = TRUE;
break;
}
default:
DPRINT1("Unknown resource descriptor type 0x%x\n", ResourceDescriptor->Type);
}
}
if (!FoundBusNumber)
{
DPRINT("Some required resources were not found in allocated resources list\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
InitializeListHead(&DeviceExtension->DeviceListHead);
KeInitializeSpinLock(&DeviceExtension->DeviceListLock);
DeviceExtension->DeviceListCount = 0;
DeviceExtension->State = dsStarted;
ExInterlockedInsertTailList(
&DriverExtension->BusListHead,
&DeviceExtension->ListEntry,
&DriverExtension->BusListLock);
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
static NTSTATUS
FdoSetPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PFDO_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
DPRINT("Called\n");
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
/* FIXME: Set device power state for the device */
Status = STATUS_UNSUCCESSFUL;
} else {
Status = STATUS_UNSUCCESSFUL;
}
return Status;
}
/*** PUBLIC ******************************************************************/
NTSTATUS
FdoPnpControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handle Plug and Play IRPs for the PCI device object
* ARGUMENTS:
* DeviceObject = Pointer to functional device object of the PCI driver
* Irp = Pointer to IRP that should be handled
* RETURNS:
* Status
*/
{
PFDO_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
DPRINT("Called\n");
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction) {
#if 0
case IRP_MN_CANCEL_REMOVE_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
break;
case IRP_MN_CANCEL_STOP_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
break;
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
Status = STATUS_NOT_IMPLEMENTED;
break;
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
Status = STATUS_NOT_IMPLEMENTED;
break;
#endif
case IRP_MN_QUERY_DEVICE_RELATIONS:
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
break;
#if 0
case IRP_MN_QUERY_PNP_DEVICE_STATE:
Status = STATUS_NOT_IMPLEMENTED;
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
break;
case IRP_MN_QUERY_STOP_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
break;
case IRP_MN_REMOVE_DEVICE:
Status = STATUS_NOT_IMPLEMENTED;
break;
#endif
case IRP_MN_START_DEVICE:
DPRINT("IRP_MN_START_DEVICE received\n");
Status = FdoStartDevice(DeviceObject, Irp);
break;
case IRP_MN_STOP_DEVICE:
/* Currently not supported */
Status = STATUS_UNSUCCESSFUL;
break;
#if 0
case IRP_MN_SURPRISE_REMOVAL:
Status = STATUS_NOT_IMPLEMENTED;
break;
#endif
default:
DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
/*
* Do NOT complete the IRP as it will be processed by the lower
* device object, which will complete the IRP
*/
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->Ldo, Irp);
return Status;
break;
}
if (Status != STATUS_PENDING) {
if (Status != STATUS_NOT_IMPLEMENTED)
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
DPRINT("Leaving. Status 0x%X\n", Status);
return Status;
}
NTSTATUS
FdoPowerControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handle power management IRPs for the PCI device object
* ARGUMENTS:
* DeviceObject = Pointer to functional device object of the PCI driver
* 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 = FdoSetPower(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 + =
减小字号Ctrl + -
显示快捷键?