mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[NTOS:IO] Do device reset inside the PipDeviceActionWorker
This make the operation synchonized with the other device tree actions CORE-10456 CORE-17150
This commit is contained in:
parent
8aff2c9de7
commit
acd07e725e
3 changed files with 61 additions and 45 deletions
|
@ -544,7 +544,8 @@ typedef enum _SECURITY_DESCRIPTOR_TYPE
|
|||
typedef enum _DEVICE_ACTION
|
||||
{
|
||||
PiActionEnumDeviceTree,
|
||||
PiActionEnumRootDevices
|
||||
PiActionEnumRootDevices,
|
||||
PiActionResetDevice
|
||||
} DEVICE_ACTION;
|
||||
|
||||
//
|
||||
|
|
|
@ -2324,6 +2324,57 @@ cleanup:
|
|||
&DeviceNode->InstancePath);
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
PipResetDevice(
|
||||
_In_ PDEVICE_NODE DeviceNode)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
ASSERT(DeviceNode->Flags & DNF_ENUMERATED);
|
||||
ASSERT(DeviceNode->Flags & DNF_PROCESSED);
|
||||
|
||||
/* Check if there's already a driver loaded for this device */
|
||||
if (DeviceNode->Flags & DNF_ADDED)
|
||||
{
|
||||
/* FIXME: our drivers do not handle device removal well enough */
|
||||
#if 0
|
||||
/* Remove the device node */
|
||||
Status = IopRemoveDevice(DeviceNode);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Invalidate device relations for the parent to reenumerate the device */
|
||||
DPRINT1("A new driver will be loaded for '%wZ' (FDO above removed)\n", &DeviceNode->InstancePath);
|
||||
Status = IoInvalidateDeviceRelations(DeviceNode->Parent->PhysicalDeviceObject, BusRelations);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* A driver has already been loaded for this device */
|
||||
DPRINT("A reboot is required for the current driver for '%wZ' to be replaced\n", &DeviceNode->InstancePath);
|
||||
DeviceNode->Problem = CM_PROB_NEED_RESTART;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: What if the device really is disabled? */
|
||||
DeviceNode->Flags &= ~DNF_DISABLED;
|
||||
DeviceNode->Problem = 0;
|
||||
|
||||
/* Load service data from the registry */
|
||||
Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Start the service and begin PnP initialization of the device again */
|
||||
DPRINT("A new driver will be loaded for '%wZ' (no FDO above)\n", &DeviceNode->InstancePath);
|
||||
Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
static
|
||||
PCSTR
|
||||
|
@ -2336,6 +2387,8 @@ ActionToStr(
|
|||
return "PiActionEnumDeviceTree";
|
||||
case PiActionEnumRootDevices:
|
||||
return "PiActionEnumRootDevices";
|
||||
case PiActionResetDevice:
|
||||
return "PiActionResetDevice";
|
||||
default:
|
||||
return "(request unknown)";
|
||||
}
|
||||
|
@ -2376,6 +2429,10 @@ PipDeviceActionWorker(
|
|||
status = PipEnumerateDevice(deviceNode);
|
||||
break;
|
||||
|
||||
case PiActionResetDevice:
|
||||
status = PipResetDevice(deviceNode);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Unimplemented device action %u\n", Request->Action);
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -1037,8 +1037,7 @@ static NTSTATUS
|
|||
IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PDEVICE_NODE DeviceNode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DeviceInstance;
|
||||
|
||||
Status = IopCaptureUnicodeString(&DeviceInstance, &ResetDeviceData->DeviceInstance);
|
||||
|
@ -1060,48 +1059,7 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
|
|||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
/* Get the device node */
|
||||
DeviceNode = IopGetDeviceNode(DeviceObject);
|
||||
|
||||
ASSERT(DeviceNode->Flags & DNF_ENUMERATED);
|
||||
ASSERT(DeviceNode->Flags & DNF_PROCESSED);
|
||||
|
||||
/* Check if there's already a driver loaded for this device */
|
||||
if (DeviceNode->Flags & DNF_ADDED)
|
||||
{
|
||||
#if 0
|
||||
/* Remove the device node */
|
||||
Status = IopRemoveDevice(DeviceNode);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Invalidate device relations for the parent to reenumerate the device */
|
||||
DPRINT1("A new driver will be loaded for '%wZ' (FDO above removed)\n", &DeviceNode->InstancePath);
|
||||
Status = IoSynchronousInvalidateDeviceRelations(DeviceNode->Parent->PhysicalDeviceObject, BusRelations);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* A driver has already been loaded for this device */
|
||||
DPRINT("A reboot is required for the current driver for '%wZ' to be replaced\n", &DeviceNode->InstancePath);
|
||||
DeviceNode->Problem = CM_PROB_NEED_RESTART;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: What if the device really is disabled? */
|
||||
DeviceNode->Flags &= ~DNF_DISABLED;
|
||||
DeviceNode->Problem = 0;
|
||||
|
||||
/* Load service data from the registry */
|
||||
Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Start the service and begin PnP initialization of the device again */
|
||||
DPRINT("A new driver will be loaded for '%wZ' (no FDO above)\n", &DeviceNode->InstancePath);
|
||||
Status = IopActionInitChildServices(DeviceNode, DeviceNode->Parent);
|
||||
}
|
||||
}
|
||||
Status = PiPerformSyncDeviceAction(DeviceObject, PiActionResetDevice);
|
||||
|
||||
ObDereferenceObject(DeviceObject);
|
||||
|
||||
|
|
Loading…
Reference in a new issue