Author: cgutman
Date: Thu May 26 22:49:27 2011
New Revision: 51944
URL:
http://svn.reactos.org/svn/reactos?rev=51944&view=rev
Log:
[NTOSKRNL]
- Implement IoInvalidateDeviceState
Modified:
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Thu May 26 22:49:27 2011
@@ -168,6 +168,20 @@
return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
+NTSTATUS
+NTAPI
+IopQueryStopDevice(IN PDEVICE_OBJECT DeviceObject)
+{
+ IO_STACK_LOCATION Stack;
+ PVOID Dummy;
+
+ RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+ Stack.MajorFunction = IRP_MJ_PNP;
+ Stack.MinorFunction = IRP_MN_QUERY_STOP_DEVICE;
+
+ return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+}
+
VOID
NTAPI
IopSendRemoveDevice(IN PDEVICE_OBJECT DeviceObject)
@@ -180,6 +194,21 @@
Stack.MinorFunction = IRP_MN_REMOVE_DEVICE;
/* Drivers should never fail a IRP_MN_REMOVE_DEVICE request */
+ IopSynchronousCall(DeviceObject, &Stack, &Dummy);
+}
+
+VOID
+NTAPI
+IopSendStopDevice(IN PDEVICE_OBJECT DeviceObject)
+{
+ IO_STACK_LOCATION Stack;
+ PVOID Dummy;
+
+ RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+ Stack.MajorFunction = IRP_MJ_PNP;
+ Stack.MinorFunction = IRP_MN_STOP_DEVICE;
+
+ /* Drivers should never fail a IRP_MN_STOP_DEVICE request */
IopSynchronousCall(DeviceObject, &Stack, &Dummy);
}
@@ -298,12 +327,6 @@
HANDLE InstanceHandle = INVALID_HANDLE_VALUE, ControlHandle = INVALID_HANDLE_VALUE;
UNICODE_STRING KeyName;
OBJECT_ATTRIBUTES ObjectAttributes;
-
- if (DeviceNode->Flags & (DNF_STARTED | DNF_START_REQUEST_PENDING))
- {
- /* Nothing to do here */
- return STATUS_SUCCESS;
- }
Status = IopAssignDeviceResources(DeviceNode);
if (!NT_SUCCESS(Status))
@@ -3551,13 +3574,93 @@
}
/*
- * @unimplemented
+ * @implemented
*/
VOID
NTAPI
IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
{
- UNIMPLEMENTED;
+ PDEVICE_NODE DeviceNode = IopGetDeviceNode(PhysicalDeviceObject);
+ IO_STACK_LOCATION Stack;
+ ULONG PnPFlags;
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
+ Stack.MajorFunction = IRP_MJ_PNP;
+ Stack.MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE;
+
+ Status = IopSynchronousCall(PhysicalDeviceObject, &Stack,
(PVOID*)&PnPFlags);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IRP_MN_QUERY_PNP_DEVICE_STATE failed with status 0x%x\n",
Status);
+ return;
+ }
+
+ if ((PnPFlags & PNP_DEVICE_REMOVED) ||
+ ((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags &
PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
+ {
+ /* Surprise removal */
+
+ IopSendSurpriseRemoval(PhysicalDeviceObject);
+
+ /* Tell the user-mode PnP manager that a device was removed */
+ IopQueueTargetDeviceEvent(&GUID_DEVICE_SURPRISE_REMOVAL,
+ &DeviceNode->InstancePath);
+
+ IopSendRemoveDevice(PhysicalDeviceObject);
+ }
+ else if ((PnPFlags & PNP_DEVICE_FAILED) && (PnPFlags &
PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED))
+ {
+ /* Stop for resource rebalance */
+
+ if (NT_SUCCESS(IopQueryStopDevice(PhysicalDeviceObject)))
+ {
+ IopSendStopDevice(PhysicalDeviceObject);
+ }
+ }
+
+ /* Resource rebalance */
+ if (PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)
+ {
+ DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n");
+
+ Status = IopInitiatePnpIrp(PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_RESOURCES,
+ NULL);
+ if (NT_SUCCESS(Status) && IoStatusBlock.Information)
+ {
+ DeviceNode->BootResources =
+ (PCM_RESOURCE_LIST)IoStatusBlock.Information;
+ IopDeviceNodeSetFlag(DeviceNode, DNF_HAS_BOOT_CONFIG);
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %x) or
IoStatusBlock.Information=NULL\n", Status);
+ DeviceNode->BootResources = NULL;
+ }
+
+ DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device
stack\n");
+
+ Status = IopInitiatePnpIrp(PhysicalDeviceObject,
+ &IoStatusBlock,
+ IRP_MN_QUERY_RESOURCE_REQUIREMENTS,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ DeviceNode->ResourceRequirements =
+ (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information;
+ }
+ else
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status %08lx)\n", Status);
+ DeviceNode->ResourceRequirements = NULL;
+ }
+
+ /* IRP_MN_FILTER_RESOURCE_REQUIREMENTS is called indirectly by IopStartDevice */
+ IopStartDevice(DeviceNode);
+ }
}
/**