[NTOS]: Some PnP ABI refactoring for future patches/work.

[NTOS]: Switch to PnP Add Device routine, currently mostly a copy of the original ReactOS code. However, PnP now tries to open all the required registry keys before attempting to start the device. Failures are reported and load cancelled. More work TBD.

svn path=/trunk/; revision=46841
This commit is contained in:
Sir Richard 2010-04-11 16:10:49 +00:00
parent 5d13bbcc06
commit 26d1db9190
5 changed files with 237 additions and 92 deletions

View file

@ -509,6 +509,14 @@ typedef struct _DEVICETREE_TRAVERSE_CONTEXT
//
// PNP Routines
//
NTSTATUS
NTAPI
PipCallDriverAddDevice(
IN PDEVICE_NODE DeviceNode,
IN BOOLEAN LoadDriver,
IN PDRIVER_OBJECT DriverObject
);
VOID
PnpInit(
VOID
@ -563,6 +571,15 @@ IopFreeDeviceNode(
);
NTSTATUS
NTAPI
IopSynchronousCall(
IN PDEVICE_OBJECT DeviceObject,
IN PIO_STACK_LOCATION IoStackLocation,
OUT PVOID *Information
);
NTSTATUS
NTAPI
IopInitiatePnpIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIO_STATUS_BLOCK IoStatusBlock,
@ -694,6 +711,12 @@ IoInitSystem(
//
// Device/Volume Routines
//
VOID
NTAPI
IopReadyDeviceObjects(
IN PDRIVER_OBJECT Driver
);
NTSTATUS
FASTCALL
IopInitializeDevice(

View file

@ -25,6 +25,24 @@ extern LIST_ENTRY IopTapeFsListHead;
/* PRIVATE FUNCTIONS **********************************************************/
VOID
NTAPI
IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
{
PAGED_CODE();
PDEVICE_OBJECT DeviceObject;
/* Set the driver as initialized */
Driver->Flags |= DRVO_INITIALIZED;
DeviceObject = Driver->DeviceObject;
while (DeviceObject)
{
/* Set every device as initialized too */
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
DeviceObject = DeviceObject->NextDevice;
}
}
VOID
NTAPI
IopDeleteDevice(IN PVOID ObjectBody)

View file

@ -438,7 +438,6 @@ IopInitializeDriverModule(
UNICODE_STRING RegistryKey;
PDRIVER_INITIALIZE DriverEntry;
PDRIVER_OBJECT Driver;
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
DriverEntry = ModuleObject->EntryPoint;
@ -495,14 +494,7 @@ IopInitializeDriverModule(
}
/* Set the driver as initialized */
Driver->Flags |= DRVO_INITIALIZED;
DeviceObject = Driver->DeviceObject;
while (DeviceObject)
{
/* Set every device as initialized too */
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
DeviceObject = DeviceObject->NextDevice;
}
IopReadyDeviceObjects(Driver);
if (PnpSystemInit) IopReinitializeDrivers();

View file

@ -219,4 +219,116 @@ Quickie:
return i;
}
NTSTATUS
NTAPI
PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
IN BOOLEAN LoadDriver,
IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS Status;
HANDLE EnumRootKey, SubKey, ControlKey, ClassKey, PropertiesKey;
UNICODE_STRING ClassGuid, Properties;
UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
UNICODE_STRING ControlClass =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
PWCHAR Buffer;
/* Open enumeration root key */
Status = IopOpenRegistryKeyEx(&EnumRootKey,
NULL,
&EnumRoot,
KEY_READ);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
return Status;
}
/* Open instance subkey */
Status = IopOpenRegistryKeyEx(&SubKey,
EnumRootKey,
&DeviceNode->InstancePath,
KEY_READ);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
ZwClose(EnumRootKey);
return Status;
}
/* Get class GUID */
Status = IopGetRegistryValue(SubKey,
REGSTR_VAL_CLASSGUID,
&KeyValueInformation);
if (NT_SUCCESS(Status))
{
/* Convert to unicode string */
Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &ClassGuid.Length);
ClassGuid.MaximumLength = KeyValueInformation->DataLength;
ClassGuid.Buffer = Buffer;
/* Open the key */
Status = IopOpenRegistryKeyEx(&ControlKey,
NULL,
&ControlClass,
KEY_READ);
if (!NT_SUCCESS(Status))
{
/* No class key */
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
ClassKey = NULL;
}
else
{
/* Open the class key */
Status = IopOpenRegistryKeyEx(&ClassKey,
ControlKey,
&ClassGuid,
KEY_READ);
ZwClose(ControlKey);
if (!NT_SUCCESS(Status))
{
/* No class key */
DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
ClassKey = NULL;
}
}
/* Check if we made it till here */
if (ClassKey)
{
/* Get the device properties */
RtlInitUnicodeString(&Properties, REGSTR_KEY_DEVICE_PROPERTIES);
Status = IopOpenRegistryKeyEx(&PropertiesKey,
ClassKey,
&Properties,
KEY_READ);
if (!NT_SUCCESS(Status))
{
/* No properties */
DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
PropertiesKey = NULL;
}
}
/* Free the registry data */
ExFreePool(KeyValueInformation);
}
/* Do ReactOS-style setup */
IopAttachFilterDrivers(DeviceNode, TRUE);
Status = IopInitializeDevice(DeviceNode, DriverObject);
if (NT_SUCCESS(Status))
{
IopAttachFilterDrivers(DeviceNode, FALSE);
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
Status = IopStartDevice(DeviceNode);
}
/* Return status */
return Status;
}
/* EOF */

View file

@ -618,69 +618,90 @@ IopFreeDeviceNode(PDEVICE_NODE DeviceNode)
}
NTSTATUS
IopInitiatePnpIrp(PDEVICE_OBJECT DeviceObject,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG MinorFunction,
PIO_STACK_LOCATION Stack OPTIONAL)
NTAPI
IopSynchronousCall(IN PDEVICE_OBJECT DeviceObject,
IN PIO_STACK_LOCATION IoStackLocation,
OUT PVOID *Information)
{
PDEVICE_OBJECT TopDeviceObject;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
/* Always call the top of the device stack */
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
KeInitializeEvent(
&Event,
NotificationEvent,
FALSE);
Irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP,
TopDeviceObject,
NULL,
0,
NULL,
&Event,
IoStatusBlock);
/* PNP IRPs are initialized with a status code of STATUS_NOT_SUPPORTED */
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
if (MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
{
Irp->IoStatus.Information = (ULONG_PTR)Stack->Parameters.FilterResourceRequirements.IoResourceRequirementList;
}
IrpSp = IoGetNextIrpStackLocation(Irp);
IrpSp->MinorFunction = (UCHAR)MinorFunction;
if (Stack)
{
RtlCopyMemory(&IrpSp->Parameters,
&Stack->Parameters,
sizeof(Stack->Parameters));
}
Status = IoCallDriver(TopDeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock->Status;
}
ObDereferenceObject(TopDeviceObject);
return Status;
PIRP Irp;
PIO_STACK_LOCATION IrpStack;
IO_STATUS_BLOCK IoStatusBlock;
KEVENT Event;
NTSTATUS Status;
PDEVICE_OBJECT TopDeviceObject;
PAGED_CODE();
/* Call the top of the device stack */
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
/* Allocate an IRP */
Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
/* Initialize to failure */
Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = IoStatusBlock.Information = 0;
/* Initialize the event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
/* Set them up */
Irp->UserIosb = &IoStatusBlock;
Irp->UserEvent = &Event;
/* Queue the IRP */
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
IoQueueThreadIrp(Irp);
/* Copy-in the stack */
IrpStack = IoGetNextIrpStackLocation(Irp);
*IrpStack = *IoStackLocation;
/* Call the driver */
Status = IoCallDriver(TopDeviceObject, Irp);
if (Status == STATUS_PENDING)
{
/* Wait for it */
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatusBlock.Status;
}
/* Return the information */
*Information = (PVOID)IoStatusBlock.Information;
return Status;
}
NTSTATUS
NTAPI
IopInitiatePnpIrp(IN PDEVICE_OBJECT DeviceObject,
IN OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG MinorFunction,
IN PIO_STACK_LOCATION Stack OPTIONAL)
{
IO_STACK_LOCATION IoStackLocation;
/* Fill out the stack information */
RtlZeroMemory(&IoStackLocation, sizeof(IO_STACK_LOCATION));
IoStackLocation.MajorFunction = IRP_MJ_PNP;
IoStackLocation.MinorFunction = MinorFunction;
if (Stack)
{
/* Copy the rest */
RtlCopyMemory(&IoStackLocation.Parameters,
&Stack->Parameters,
sizeof(Stack->Parameters));
}
/* Do the PnP call */
IoStatusBlock->Status = IopSynchronousCall(DeviceObject,
&IoStackLocation,
(PVOID)&IoStatusBlock->Information);
return IoStatusBlock->Status;
}
NTSTATUS
IopTraverseDeviceTreeNode(PDEVICETREE_TRAVERSE_CONTEXT Context)
@ -2909,29 +2930,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
/* Driver is loaded and initialized at this point */
if (NT_SUCCESS(Status))
{
/* Attach lower level filter drivers. */
IopAttachFilterDrivers(DeviceNode, TRUE);
/* Initialize the function driver for the device node */
Status = IopInitializeDevice(DeviceNode, DriverObject);
if (NT_SUCCESS(Status))
{
/* Attach upper level filter drivers. */
IopAttachFilterDrivers(DeviceNode, FALSE);
Status = IopStartDevice(DeviceNode);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopStartDevice(%wZ) failed with status 0x%08x\n",
&DeviceNode->InstancePath, Status);
}
}
else
{
DPRINT1("IopInitializeDevice(%wZ) failed with status 0x%08x\n",
&DeviceNode->InstancePath, Status);
}
/* Initialize the device, including all filters */
Status = PipCallDriverAddDevice(DeviceNode, FALSE, DriverObject);
}
else
{