mirror of
https://github.com/reactos/reactos.git
synced 2024-07-08 05:35:06 +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
|
@ -600,6 +600,11 @@ IopFreeDeviceNode(
|
|||
IN PDEVICE_NODE DeviceNode
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
||||
PDEVICE_CAPABILITIES DeviceCaps);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IopSynchronousCall(
|
||||
|
|
|
@ -235,25 +235,23 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
|
|||
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))
|
||||
|
@ -268,6 +266,17 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
|
|||
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;
|
||||
DeviceNode->Flags &= ~DNF_STOPPED;
|
||||
|
@ -316,7 +325,6 @@ IopStartAndEnumerateDevice(IN PDEVICE_NODE DeviceNode)
|
|||
{
|
||||
/* Enumerate us */
|
||||
IoSynchronousInvalidateDeviceRelations(DeviceObject, BusRelations);
|
||||
IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
|
@ -338,6 +346,9 @@ IopStartDevice(
|
|||
UNICODE_STRING KeyName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
if (DeviceNode->Flags & DNF_DISABLED)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Status = IopAssignDeviceResources(DeviceNode);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto ByeBye;
|
||||
|
@ -383,6 +394,9 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
|||
{
|
||||
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 @@ IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
|
|||
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 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
|||
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 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
|||
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)
|
||||
{
|
||||
|
@ -1373,29 +1434,6 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
|||
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");
|
||||
|
||||
Stack.Parameters.QueryId.IdType = BusQueryHardwareIDs;
|
||||
|
@ -1697,6 +1735,15 @@ IopEnumerateDevice(
|
|||
|
||||
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");
|
||||
|
||||
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
|
||||
|
@ -1746,12 +1793,6 @@ IopEnumerateDevice(
|
|||
&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;
|
||||
|
||||
|
@ -3160,33 +3201,6 @@ PnpBusTypeGuidGet(IN USHORT Index,
|
|||
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
|
||||
NTAPI
|
||||
PnpDeviceObjectToDeviceInstance(IN PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -3446,7 +3460,7 @@ IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
|
|||
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 @@ IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
|
|||
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)))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue