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/io.h?rev=52026&r1=52025&r2=52026&view=diff
==============================================================================
--- 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.c?rev=52026&r1=52025&r2=52026&view=diff
==============================================================================
--- 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)))
     {


Reply via email to