mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:05:42 +00:00
[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 svn path=/trunk/; revision=52026
This commit is contained in:
parent
d6680bc1fa
commit
200cdb6daf
2 changed files with 103 additions and 74 deletions
|
@ -600,6 +600,11 @@ IopFreeDeviceNode(
|
||||||
IN PDEVICE_NODE DeviceNode
|
IN PDEVICE_NODE DeviceNode
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||||
|
PDEVICE_CAPABILITIES DeviceCaps);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopSynchronousCall(
|
IopSynchronousCall(
|
||||||
|
|
|
@ -235,24 +235,22 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
|
||||||
PDEVICE_NODE DeviceNode;
|
PDEVICE_NODE DeviceNode;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID Dummy;
|
PVOID Dummy;
|
||||||
|
DEVICE_CAPABILITIES DeviceCapabilities;
|
||||||
|
|
||||||
/* Get the device node */
|
/* Get the device node */
|
||||||
DeviceNode = IopGetDeviceNode(DeviceObject);
|
DeviceNode = IopGetDeviceNode(DeviceObject);
|
||||||
|
|
||||||
|
ASSERT(!(DeviceNode->Flags & DNF_DISABLED));
|
||||||
|
|
||||||
/* Build the I/O stack locaiton */
|
/* Build the I/O stack locaiton */
|
||||||
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
|
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
|
||||||
Stack.MajorFunction = IRP_MJ_PNP;
|
Stack.MajorFunction = IRP_MJ_PNP;
|
||||||
Stack.MinorFunction = IRP_MN_START_DEVICE;
|
Stack.MinorFunction = IRP_MN_START_DEVICE;
|
||||||
|
|
||||||
/* Check if we didn't already report the resources */
|
Stack.Parameters.StartDevice.AllocatedResources =
|
||||||
if (!(DeviceNode->Flags & DNF_RESOURCE_REPORTED))
|
DeviceNode->ResourceList;
|
||||||
{
|
Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
|
||||||
/* Report them */
|
DeviceNode->ResourceListTranslated;
|
||||||
Stack.Parameters.StartDevice.AllocatedResources =
|
|
||||||
DeviceNode->ResourceList;
|
|
||||||
Stack.Parameters.StartDevice.AllocatedResourcesTranslated =
|
|
||||||
DeviceNode->ResourceListTranslated;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the call */
|
/* Do the call */
|
||||||
Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
|
Status = IopSynchronousCall(DeviceObject, &Stack, &Dummy);
|
||||||
|
@ -268,6 +266,17 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
|
||||||
return;
|
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 */
|
/* Otherwise, mark us as started */
|
||||||
DeviceNode->Flags |= DNF_STARTED;
|
DeviceNode->Flags |= DNF_STARTED;
|
||||||
DeviceNode->Flags &= ~DNF_STOPPED;
|
DeviceNode->Flags &= ~DNF_STOPPED;
|
||||||
|
@ -316,7 +325,6 @@ IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode)
|
||||||
{
|
{
|
||||||
/* Enumerate us */
|
/* Enumerate us */
|
||||||
IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations);
|
IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations);
|
||||||
IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -338,6 +346,9 @@ IopStartDevice(
|
||||||
UNICODE_STRING KeyName;
|
UNICODE_STRING KeyName;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
|
||||||
|
if (DeviceNode->Flags & DNF_DISABLED)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
Status = IopAssignDeviceResources(DeviceNode);
|
Status = IopAssignDeviceResources(DeviceNode);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
|
@ -383,6 +394,9 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK StatusBlock;
|
IO_STATUS_BLOCK StatusBlock;
|
||||||
IO_STACK_LOCATION Stack;
|
IO_STACK_LOCATION Stack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE InstanceKey;
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
|
||||||
/* Set up the Header */
|
/* Set up the Header */
|
||||||
RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
|
RtlZeroMemory(DeviceCaps, sizeof(DEVICE_CAPABILITIES));
|
||||||
|
@ -396,10 +410,49 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||||
Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
|
Stack.Parameters.DeviceCapabilities.Capabilities = DeviceCaps;
|
||||||
|
|
||||||
/* Send the IRP */
|
/* Send the IRP */
|
||||||
return IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
|
Status = IopInitiatePnpIrp(DeviceNode->PhysicalDeviceObject,
|
||||||
&StatusBlock,
|
&StatusBlock,
|
||||||
IRP_MN_QUERY_CAPABILITIES,
|
IRP_MN_QUERY_CAPABILITIES,
|
||||||
&Stack);
|
&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
|
static VOID NTAPI
|
||||||
|
@ -1303,7 +1356,7 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
||||||
DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status);
|
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);
|
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCapabilities);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1311,7 +1364,15 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
||||||
DPRINT("IopInitiatePnpIrp() failed (Status 0x%08lx)\n", Status);
|
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)
|
if (!DeviceCapabilities.UniqueID)
|
||||||
{
|
{
|
||||||
|
@ -1373,29 +1434,6 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
||||||
DPRINT1("Failed to create the instance key! (Status %lx)\n", 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");
|
DPRINT("Sending IRP_MN_QUERY_ID.BusQueryHardwareIDs to device stack\n");
|
||||||
|
|
||||||
Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
|
Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
|
||||||
|
@ -1697,6 +1735,15 @@ IopEnumerateDevice(
|
||||||
|
|
||||||
DPRINT("DeviceObject 0x%p\n", DeviceObject);
|
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");
|
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
|
||||||
|
|
||||||
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
|
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
|
||||||
|
@ -1746,12 +1793,6 @@ IopEnumerateDevice(
|
||||||
&ChildDeviceNode);
|
&ChildDeviceNode);
|
||||||
if (NT_SUCCESS(Status))
|
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 */
|
/* Mark the node as enumerated */
|
||||||
ChildDeviceNode->Flags |= DNF_ENUMERATED;
|
ChildDeviceNode->Flags |= DNF_ENUMERATED;
|
||||||
|
|
||||||
|
@ -3160,33 +3201,6 @@ PnpBusTypeGuidGet(IN USHORT Index,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject,
|
PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -3446,7 +3460,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
|
||||||
case DevicePropertyAddress:
|
case DevicePropertyAddress:
|
||||||
|
|
||||||
/* Query the device caps */
|
/* Query the device caps */
|
||||||
Status = PpIrpQueryCapabilities(DeviceObject, &DeviceCaps);
|
Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
|
||||||
if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
|
if (!NT_SUCCESS(Status) || (DeviceCaps.Address == MAXULONG))
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
|
||||||
|
@ -3607,6 +3621,16 @@ IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||||
return;
|
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) ||
|
if ((PnPFlags & PNP_DEVICE_REMOVED) ||
|
||||||
((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
|
((PnPFlags & PNP_DEVICE_FAILED) && !(PnPFlags & PNP_DEVICE_RESOURCE_REQUIREMENTS_CHANGED)))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue