Author: cgutman
Date: Tue May 31 18:11:40 2011
New Revision: 52026
URL:
http://svn.reactos.org/svn/reactos?rev=52026&view=rev
Log:
[NTOSKRNL]
- Set the DNF_DISABLED flag if a driver returns with the HardwareDisabled flag set to true
(but only BEFORE starting the device)
- Don't try to start a device with the DNF_DISABLED flag set
- Send IRP_MN_QUERY_CAPABILITIES (again) and IRP_MN_QUERY_PNP_DEVICE_STATE after the
device has started
- Write the UINumber and Capabilities registry entries in IopQueryDeviceCapabilities so
they will be updated after every IRP_MN_QUERY_CAPABILITIES is sent
- Set the DNUF_DONT_SHOW_IN_UI flag in response to the NoDisplayInUI flag set in
DEVICE_CAPABILITIES or PNP_DEVICE_DONT_DISPLAY_IN_UI set after sending
IRP_MN_QUERY_PNP_DEVICE_STATE
- Set DNUF_NBOT_DISABLEABLE if PNP_DEVICE_NOT_DISABLEABLE is set after sending
IRP_MN_QUERY_PNP_DEVICE_STATE
- Remove duplicate code
- Fix sending GUID_DEVICE_ARRIVAL (patch by Eric Kohl)
- IRPs sent to PnP devices on enumeration and start are now completely compatible with
Windows XP/2003/Vista
Modified:
trunk/reactos/ntoskrnl/include/internal/io.h
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Tue May 31 18:11:40 2011
@@ -602,6 +602,11 @@
NTSTATUS
NTAPI
+IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
+ PDEVICE_CAPABILITIES DeviceCaps);
+
+NTSTATUS
+NTAPI
IopSynchronousCall(
IN PDEVICE_OBJECT DeviceObject,
IN PIO_STACK_LOCATION IoStackLocation,
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] Tue May 31 18:11:40 2011
@@ -235,25 +235,23 @@
PDEVICE_NODE DeviceNode;
NTSTATUS Status;
PVOID Dummy;
+ DEVICE_CAPABILITIES DeviceCapabilities;
/* Get the device node */
DeviceNode = IopGetDeviceNode(DeviceObject);
+ ASSERT(!(DeviceNode->Flags & DNF_DISABLED));
+
/* Build the I/O stack locaiton */
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_START_DEVICE;
- /* Check if we didn't already report the resources */
- if (!(DeviceNode->Flags & DNF_RESOURCE_REPORTED))
- {
- /* Report them */
- Stack.Parameters.StartDevice.AllocatedResources =
- DeviceNode->ResourceList;
- Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
- DeviceNode->ResourceListTranslated;
- }
-
+ Stack.Parameters.StartDevice.AllocatedResources =
+ DeviceNode->ResourceList;
+ Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
+ DeviceNode->ResourceListTranslated;
+
/* Do the call */
Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
if (!NT_SUCCESS(Status))
@@ -267,6 +265,17 @@
DPRINT1("Warning: PnP Start failed (%wZ)\n",
&DeviceNode->InstancePath);
return;
}
+
+ DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after
start)\n");
+
+ Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status);
+ }
+
+ /* Invalidate device state so IRP_MN_QUERY_PNP_DEVICE_STATE is sent */
+ IoInvalidateDeviceState(DeviceObject);
/* Otherwise, mark us as started */
DeviceNode->Flags |= DNF_STARTED;
@@ -316,7 +325,6 @@
{
/* Enumerate us */
IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations);
- IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
Status = STATUS_SUCCESS;
}
else
@@ -337,6 +345,9 @@
HANDLE InstanceHandle = INVALID_HANDLE_VALUE, ControlHandle = INVALID_HANDLE_VALUE;
UNICODE_STRING KeyName;
OBJECT_ATTRIBUTES ObjectAttributes;
+
+ if (DeviceNode->Flags & DNF_DISABLED)
+ return STATUS_SUCCESS;
Status = IopAssignDeviceResources(DeviceNode);
if (!NT_SUCCESS(Status))
@@ -383,6 +394,9 @@
{
IO_STATUS_BLOCK StatusBlock;
IO_STACK_LOCATION Stack;
+ NTSTATUS Status;
+ HANDLE InstanceKey;
+ UNICODE_STRING ValueName;
/* Set up the Header */
RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
@@ -396,10 +410,49 @@
Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
/* Send the IRP */
- return IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
- &StatusBlock,
- IRP_MN_QUERY_CAPABILITIES,
- &Stack);
+ Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
+ &StatusBlock,
+ IRP_MN_QUERY_CAPABILITIES,
+ &Stack);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IRP_MN_QUERY_CAPABILITIES failed with status 0x%x\n", Status);
+ return Status;
+ }
+
+ DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCaps + 4);
+
+ if (DeviceCaps->NoDisplayInUI)
+ DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
+ else
+ DeviceNode->UserFlags &= DNUF_DONT_SHOW_IN_UI;
+
+ Status = IopCreateDeviceKeyPath(&DeviceNode->InstancePath, 0,
&InstanceKey);
+ if (NT_SUCCESS(Status))
+ {
+ /* Set 'Capabilities' value */
+ RtlInitUnicodeString(&ValueName, L"Capabilities");
+ Status = ZwSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ (PVOID)&DeviceNode->CapabilityFlags,
+ sizeof(ULONG));
+
+ /* Set 'UINumber' value */
+ if (DeviceCaps->UINumber != MAXULONG)
+ {
+ RtlInitUnicodeString(&ValueName, L"UINumber");
+ Status = ZwSetValueKey(InstanceKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ &DeviceCaps->UINumber,
+ sizeof(ULONG));
+ }
+ }
+
+ return Status;
}
static VOID NTAPI
@@ -1303,7 +1356,7 @@
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
}
- DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack\n");
+ DPRINT("Sending IRP_MN_QUERY_CAPABILITIES to device stack (after
enumeration)\n");
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
if (!NT_SUCCESS(Status))
@@ -1311,7 +1364,15 @@
DPRINT("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status);
}
- DeviceNode->CapabilityFlags = *(PULONG)((ULONG_PTR)&DeviceCapabilities + 4);
+ /* This bit is only check after enumeration */
+ if (DeviceCapabilities.HardwareDisabled)
+ {
+ /* FIXME: Cleanup device */
+ DeviceNode->Flags |= DNF_DISABLED;
+ return STATUS_SUCCESS;
+ }
+ else
+ DeviceNode->Flags &= ~DNF_DISABLED;
if (!DeviceCapabilities.UniqueID)
{
@@ -1371,29 +1432,6 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create the instance key! (Status %lx)\n", Status);
- }
-
- {
- /* Set 'Capabilities' value */
- RtlInitUnicodeString(&ValueName, L"Capabilities");
- Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_DWORD,
- (PVOID)&DeviceNode->CapabilityFlags,
- sizeof(ULONG));
-
- /* Set 'UINumber' value */
- if (DeviceCapabilities.UINumber != MAXULONG)
- {
- RtlInitUnicodeString(&ValueName, L"UINumber");
- Status = ZwSetValueKey(InstanceKey,
- &ValueName,
- 0,
- REG_DWORD,
- &DeviceCapabilities.UINumber,
- sizeof(ULONG));
- }
}
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
@@ -1696,6 +1734,15 @@
ULONG i;
DPRINT("DeviceObject 0x%p\n", DeviceObject);
+
+ if (DeviceNode->Flags & DNF_NEED_ENUMERATION_ONLY)
+ {
+ DeviceNode->Flags &= ~DNF_NEED_ENUMERATION_ONLY;
+
+ DPRINT("Sending GUID_DEVICE_ARRIVAL\n");
+ IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
+ &DeviceNode->InstancePath);
+ }
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
@@ -1746,12 +1793,6 @@
&ChildDeviceNode);
if (NT_SUCCESS(Status))
{
- DPRINT("Sending GUID_DEVICE_ARRIVAL\n");
-
- /* Report the device to the user-mode pnp manager */
- IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
- &ChildDeviceNode->InstancePath);
-
/* Mark the node as enumerated */
ChildDeviceNode->Flags |= DNF_ENUMERATED;
@@ -3162,33 +3203,6 @@
NTSTATUS
NTAPI
-PpIrpQueryCapabilities(IN PDEVICE_OBJECT DeviceObject,
- OUT PDEVICE_CAPABILITIES DeviceCaps)
-{
- PVOID Dummy;
- IO_STACK_LOCATION Stack;
-
- PAGED_CODE();
-
- /* Set up the Header */
- RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
- DeviceCaps->Size = sizeof(DEVICE_CAPABILITIES);
- DeviceCaps->Version = 1;
- DeviceCaps->Address = -1;
- DeviceCaps->UINumber = -1;
-
- /* Set up the Stack */
- RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
- Stack.MajorFunction = IRP_MJ_PNP;
- Stack.MinorFunction = IRP_MN_QUERY_CAPABILITIES;
- Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
-
- /* Send the IRP */
- return IopSynchronousCall(DeviceObject, &Stack, &Dummy);
-}
-
-NTSTATUS
-NTAPI
PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject,
IN PHANDLE DeviceInstanceHandle,
IN ACCESS_MASK DesiredAccess)
@@ -3446,7 +3460,7 @@
case DevicePropertyAddress:
/* Query the device caps */
- Status = PpIrpQueryCapabilities(DeviceObject, &DeviceCaps);
+ Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
return STATUS_OBJECT_NAME_NOT_FOUND;
@@ -3607,6 +3621,16 @@
return;
}
+ if (PnPFlags & PNP_DEVICE_NOT_DISABLEABLE)
+ DeviceNode->UserFlags |= DNUF_NOT_DISABLEABLE;
+ else
+ DeviceNode->UserFlags &= ~DNUF_NOT_DISABLEABLE;
+
+ if (PnPFlags & PNP_DEVICE_DONT_DISPLAY_IN_UI)
+ DeviceNode->UserFlags |= DNUF_DONT_SHOW_IN_UI;
+ else
+ DeviceNode->UserFlags &= ~DNUF_DONT_SHOW_IN_UI;
+
if ((PnPFlags & PNP_DEVICE_REMOVED) ||
((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags &
PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
{