mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 02:34:53 +00:00
[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:
parent
5d13bbcc06
commit
26d1db9190
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue