[ros-diffs] [sginsberg] 35427: - Cleanup and reformat parts of pnpmgr (no code change)

sginsberg at svn.reactos.org sginsberg at svn.reactos.org
Mon Aug 18 15:30:17 CEST 2008


Author: sginsberg
Date: Mon Aug 18 08:30:17 2008
New Revision: 35427

URL: http://svn.reactos.org/svn/reactos?rev=35427&view=rev
Log:
- Cleanup and reformat parts of pnpmgr (no code change)

Modified:
    trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c?rev=35427&r1=35426&r2=35427&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,16 +1,14 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/plugplay.c
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/plugplay.c
  * PURPOSE:         Plug-and-play interface routines
- *
  * PROGRAMMERS:     Eric Kohl <eric.kohl at t-online.de>
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
-
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -113,127 +111,6 @@
 
   return STATUS_SUCCESS;
 }
-
-
-/*
- * Plug and Play event structure used by NtGetPlugPlayEvent.
- *
- * EventGuid
- *    Can be one of the following values:
- *       GUID_HWPROFILE_QUERY_CHANGE
- *       GUID_HWPROFILE_CHANGE_CANCELLED
- *       GUID_HWPROFILE_CHANGE_COMPLETE
- *       GUID_TARGET_DEVICE_QUERY_REMOVE
- *       GUID_TARGET_DEVICE_REMOVE_CANCELLED
- *       GUID_TARGET_DEVICE_REMOVE_COMPLETE
- *       GUID_PNP_CUSTOM_NOTIFICATION
- *       GUID_PNP_POWER_NOTIFICATION
- *       GUID_DEVICE_* (see above)
- *
- * EventCategory
- *    Type of the event that happened.
- *
- * Result
- *    ?
- *
- * Flags
- *    ?
- *
- * TotalSize
- *    Size of the event block including the device IDs and other
- *    per category specific fields.
- */
-/*
- * NtGetPlugPlayEvent
- *
- * Returns one Plug & Play event from a global queue.
- *
- * Parameters
- *    Reserved1
- *    Reserved2
- *       Always set to zero.
- *
- *    Buffer
- *       The buffer that will be filled with the event information on
- *       successful return from the function.
- *
- *    BufferSize
- *       Size of the buffer pointed by the Buffer parameter. If the
- *       buffer size is not large enough to hold the whole event
- *       information, error STATUS_BUFFER_TOO_SMALL is returned and
- *       the buffer remains untouched.
- *
- * Return Values
- *    STATUS_PRIVILEGE_NOT_HELD
- *    STATUS_BUFFER_TOO_SMALL
- *    STATUS_SUCCESS
- *
- * Remarks
- *    This function isn't multi-thread safe!
- *
- * @implemented
- */
-NTSTATUS STDCALL
-NtGetPlugPlayEvent(IN ULONG Reserved1,
-                   IN ULONG Reserved2,
-                   OUT PPLUGPLAY_EVENT_BLOCK Buffer,
-                   IN ULONG BufferSize)
-{
-  PPNP_EVENT_ENTRY Entry;
-  NTSTATUS Status;
-
-  DPRINT("NtGetPlugPlayEvent() called\n");
-
-  /* Function can only be called from user-mode */
-  if (KeGetPreviousMode() == KernelMode)
-  {
-    DPRINT1("NtGetPlugPlayEvent cannot be called from kernel mode!\n");
-    return STATUS_ACCESS_DENIED;
-  }
-
-  /* Check for Tcb privilege */
-  if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
-                              UserMode))
-  {
-    DPRINT1("NtGetPlugPlayEvent: Caller does not hold the SeTcbPrivilege privilege!\n");
-    return STATUS_PRIVILEGE_NOT_HELD;
-  }
-
-  /* Wait for a PnP event */
-  DPRINT("Waiting for pnp notification event\n");
-  Status = KeWaitForSingleObject(&IopPnpNotifyEvent,
-                                 UserRequest,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
-  if (!NT_SUCCESS(Status))
-  {
-    DPRINT1("KeWaitForSingleObject() failed (Status %lx)\n", Status);
-    return Status;
-  }
-
-  /* Get entry from the tail of the queue */
-  Entry = CONTAINING_RECORD(IopPnpEventQueueHead.Blink,
-                            PNP_EVENT_ENTRY,
-                            ListEntry);
-
-  /* Check the buffer size */
-  if (BufferSize < Entry->Event.TotalSize)
-  {
-    DPRINT1("Buffer is too small for the pnp-event\n");
-    return STATUS_BUFFER_TOO_SMALL;
-  }
-
-  /* Copy event data to the user buffer */
-  memcpy(Buffer,
-         &Entry->Event,
-         Entry->Event.TotalSize);
-
-  DPRINT("NtGetPlugPlayEvent() done\n");
-
-  return STATUS_SUCCESS;
-}
-
 
 static PDEVICE_OBJECT
 IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
@@ -706,6 +583,128 @@
     return Status;
 }
 
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * Plug and Play event structure used by NtGetPlugPlayEvent.
+ *
+ * EventGuid
+ *    Can be one of the following values:
+ *       GUID_HWPROFILE_QUERY_CHANGE
+ *       GUID_HWPROFILE_CHANGE_CANCELLED
+ *       GUID_HWPROFILE_CHANGE_COMPLETE
+ *       GUID_TARGET_DEVICE_QUERY_REMOVE
+ *       GUID_TARGET_DEVICE_REMOVE_CANCELLED
+ *       GUID_TARGET_DEVICE_REMOVE_COMPLETE
+ *       GUID_PNP_CUSTOM_NOTIFICATION
+ *       GUID_PNP_POWER_NOTIFICATION
+ *       GUID_DEVICE_* (see above)
+ *
+ * EventCategory
+ *    Type of the event that happened.
+ *
+ * Result
+ *    ?
+ *
+ * Flags
+ *    ?
+ *
+ * TotalSize
+ *    Size of the event block including the device IDs and other
+ *    per category specific fields.
+ */
+
+/*
+ * NtGetPlugPlayEvent
+ *
+ * Returns one Plug & Play event from a global queue.
+ *
+ * Parameters
+ *    Reserved1
+ *    Reserved2
+ *       Always set to zero.
+ *
+ *    Buffer
+ *       The buffer that will be filled with the event information on
+ *       successful return from the function.
+ *
+ *    BufferSize
+ *       Size of the buffer pointed by the Buffer parameter. If the
+ *       buffer size is not large enough to hold the whole event
+ *       information, error STATUS_BUFFER_TOO_SMALL is returned and
+ *       the buffer remains untouched.
+ *
+ * Return Values
+ *    STATUS_PRIVILEGE_NOT_HELD
+ *    STATUS_BUFFER_TOO_SMALL
+ *    STATUS_SUCCESS
+ *
+ * Remarks
+ *    This function isn't multi-thread safe!
+ *
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+NtGetPlugPlayEvent(IN ULONG Reserved1,
+                   IN ULONG Reserved2,
+                   OUT PPLUGPLAY_EVENT_BLOCK Buffer,
+                   IN ULONG BufferSize)
+{
+  PPNP_EVENT_ENTRY Entry;
+  NTSTATUS Status;
+
+  DPRINT("NtGetPlugPlayEvent() called\n");
+
+  /* Function can only be called from user-mode */
+  if (KeGetPreviousMode() == KernelMode)
+  {
+    DPRINT1("NtGetPlugPlayEvent cannot be called from kernel mode!\n");
+    return STATUS_ACCESS_DENIED;
+  }
+
+  /* Check for Tcb privilege */
+  if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
+                              UserMode))
+  {
+    DPRINT1("NtGetPlugPlayEvent: Caller does not hold the SeTcbPrivilege privilege!\n");
+    return STATUS_PRIVILEGE_NOT_HELD;
+  }
+
+  /* Wait for a PnP event */
+  DPRINT("Waiting for pnp notification event\n");
+  Status = KeWaitForSingleObject(&IopPnpNotifyEvent,
+                                 UserRequest,
+                                 KernelMode,
+                                 FALSE,
+                                 NULL);
+  if (!NT_SUCCESS(Status))
+  {
+    DPRINT1("KeWaitForSingleObject() failed (Status %lx)\n", Status);
+    return Status;
+  }
+
+  /* Get entry from the tail of the queue */
+  Entry = CONTAINING_RECORD(IopPnpEventQueueHead.Blink,
+                            PNP_EVENT_ENTRY,
+                            ListEntry);
+
+  /* Check the buffer size */
+  if (BufferSize < Entry->Event.TotalSize)
+  {
+    DPRINT1("Buffer is too small for the pnp-event\n");
+    return STATUS_BUFFER_TOO_SMALL;
+  }
+
+  /* Copy event data to the user buffer */
+  memcpy(Buffer,
+         &Entry->Event,
+         Entry->Event.TotalSize);
+
+  DPRINT("NtGetPlugPlayEvent() done\n");
+
+  return STATUS_SUCCESS;
+}
 
 /*
  * NtPlugPlayControl
@@ -763,7 +762,8 @@
  *
  * @unimplemented
  */
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass,
                   IN OUT PVOID Buffer,
                   IN ULONG BufferLength)
@@ -844,5 +844,3 @@
 
     return STATUS_NOT_IMPLEMENTED;
 }
-
-/* EOF */

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c?rev=35427&r1=35426&r2=35427&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpdma.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/pnpdma.c
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnpdma.c
  * PURPOSE:         PnP manager DMA routines
- *
  * PROGRAMMERS:     Filip Navara (xnavara at volny.cz)
  */
 
@@ -14,69 +13,74 @@
 #include <internal/debug.h>
 #include <wdmguid.h>
 
-/* FUNCTIONS *****************************************************************/
+/* PUBLIC FUNCTIONS **********************************************************/
 
 /*
  * @implemented
  */
-PDMA_ADAPTER STDCALL
-IoGetDmaAdapter(
-  IN PDEVICE_OBJECT PhysicalDeviceObject,
-  IN PDEVICE_DESCRIPTION DeviceDescription,
-  IN OUT PULONG NumberOfMapRegisters)
+PDMA_ADAPTER
+NTAPI
+IoGetDmaAdapter(IN PDEVICE_OBJECT PhysicalDeviceObject,
+                IN PDEVICE_DESCRIPTION DeviceDescription,
+                IN OUT PULONG NumberOfMapRegisters)
 {
-  NTSTATUS Status;
-  ULONG ResultLength;
-  BUS_INTERFACE_STANDARD BusInterface;
-  IO_STATUS_BLOCK IoStatusBlock;
-  IO_STACK_LOCATION Stack;
-  DEVICE_DESCRIPTION PrivateDeviceDescription;
-  PDMA_ADAPTER Adapter = NULL;
+    NTSTATUS Status;
+    ULONG ResultLength;
+    BUS_INTERFACE_STANDARD BusInterface;
+    IO_STATUS_BLOCK IoStatusBlock;
+    IO_STACK_LOCATION Stack;
+    DEVICE_DESCRIPTION PrivateDeviceDescription;
+    PDMA_ADAPTER Adapter = NULL;
 
-  DPRINT("IoGetDmaAdapter called\n");
+    DPRINT("IoGetDmaAdapter called\n");
 
-  /*
-   * Try to create DMA adapter through bus driver.
-   */
 
-  if (PhysicalDeviceObject != NULL)
-  {
-    if (DeviceDescription->InterfaceType == PNPBus ||
-        DeviceDescription->InterfaceType == InterfaceTypeUndefined)
+    /* Try to create DMA adapter through bus driver */
+    if (PhysicalDeviceObject)
     {
-      RtlCopyMemory(&PrivateDeviceDescription, DeviceDescription,
-        sizeof(DEVICE_DESCRIPTION));
-      Status = IoGetDeviceProperty(PhysicalDeviceObject,
-         DevicePropertyLegacyBusType, sizeof(INTERFACE_TYPE),
-         &PrivateDeviceDescription.InterfaceType, &ResultLength);
-      if (!NT_SUCCESS(Status))
-        PrivateDeviceDescription.InterfaceType = Internal;
-      DeviceDescription = &PrivateDeviceDescription;
+        if (DeviceDescription->InterfaceType == PNPBus ||
+            DeviceDescription->InterfaceType == InterfaceTypeUndefined)
+        {
+            RtlCopyMemory(&PrivateDeviceDescription,
+                          DeviceDescription,
+                          sizeof(DEVICE_DESCRIPTION));
+
+            Status = IoGetDeviceProperty(PhysicalDeviceObject,
+                                         DevicePropertyLegacyBusType,
+                                         sizeof(INTERFACE_TYPE),
+                                         &PrivateDeviceDescription.InterfaceType,
+                                         &ResultLength);
+
+            if (!NT_SUCCESS(Status))
+                PrivateDeviceDescription.InterfaceType = Internal;
+
+            DeviceDescription = &PrivateDeviceDescription;
+        }
+
+        Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
+        Stack.Parameters.QueryInterface.Version = 1;
+        Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
+        Stack.Parameters.QueryInterface.InterfaceType =
+            &GUID_BUS_INTERFACE_STANDARD;
+
+        Status = IopInitiatePnpIrp(PhysicalDeviceObject,
+                                   &IoStatusBlock,
+                                   IRP_MN_QUERY_INTERFACE,
+                                   &Stack);
+
+        if (NT_SUCCESS(Status))
+        {
+            Adapter = BusInterface.GetDmaAdapter(BusInterface.Context,
+                                                 DeviceDescription,
+                                                 NumberOfMapRegisters);
+
+            BusInterface.InterfaceDereference(BusInterface.Context);
+            if (Adapter) return Adapter;
+        }
     }
 
-    Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
-    Stack.Parameters.QueryInterface.Version = 1;
-    Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
-    Stack.Parameters.QueryInterface.InterfaceType =
-      &GUID_BUS_INTERFACE_STANDARD;
-    Status = IopInitiatePnpIrp(PhysicalDeviceObject, &IoStatusBlock,
-      IRP_MN_QUERY_INTERFACE, &Stack);
-    if (NT_SUCCESS(Status))
-    {
-      Adapter = BusInterface.GetDmaAdapter(BusInterface.Context,
-        DeviceDescription, NumberOfMapRegisters);
-      BusInterface.InterfaceDereference(BusInterface.Context);
-      if (Adapter != NULL)
-        return Adapter;
-    }
-  }
-
-  /*
-   * Fallback to HAL.
-   */
-
-  return HalGetDmaAdapter(PhysicalDeviceObject, DeviceDescription,
-                          NumberOfMapRegisters);
+    /* Fall back to HAL */
+    return HalGetDmaAdapter(PhysicalDeviceObject,
+                            DeviceDescription,
+                            NumberOfMapRegisters);
 }
-
-/* EOF */

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c?rev=35427&r1=35426&r2=35427&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,17 +1,15 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/pnpmgr.c
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnpmgr.c
  * PURPOSE:         Initializes the PnP manager
- *
  * PROGRAMMERS:     Casper S. Hornstrup (chorns at users.sourceforge.net)
- *                  Hervé Poussineau (hpoussin at reactos.org)
+ *                  Copyright 2007 Hervé Poussineau (hpoussin at reactos.org)
  */
 
 /* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
-
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -224,7 +222,7 @@
 }
 
 NTSTATUS
-STDCALL
+NTAPI
 IopQueryDeviceCapabilities(PDEVICE_NODE DeviceNode,
                            PDEVICE_CAPABILITIES DeviceCaps)
 {
@@ -265,466 +263,6 @@
     ExFreePool(Data);
 }
 
-/*
- * @implemented
- */
-VOID
-NTAPI
-IoInvalidateDeviceRelations(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN DEVICE_RELATION_TYPE Type)
-{
-    PIO_WORKITEM WorkItem;
-    PINVALIDATE_DEVICE_RELATION_DATA Data;
-
-    Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
-    if (!Data)
-        return;
-    WorkItem = IoAllocateWorkItem(DeviceObject);
-    if (!WorkItem)
-    {
-        ExFreePool(Data);
-        return;
-    }
-
-    ObReferenceObject(DeviceObject);
-    Data->DeviceObject = DeviceObject;
-    Data->Type = Type;
-    Data->WorkItem = WorkItem;
-
-    IoQueueWorkItem(
-        WorkItem,
-        IopAsynchronousInvalidateDeviceRelations,
-        DelayedWorkQueue,
-        Data);
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
-                    IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
-                    IN ULONG BufferLength,
-                    OUT PVOID PropertyBuffer,
-                    OUT PULONG ResultLength)
-{
-    PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
-    DEVICE_CAPABILITIES DeviceCaps;
-    ULONG Length;
-    PVOID Data = NULL;
-    PWSTR Ptr;
-    NTSTATUS Status;
-
-    DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
-
-    *ResultLength = 0;
-
-    if (DeviceNode == NULL)
-        return STATUS_INVALID_DEVICE_REQUEST;
-
-    switch (DeviceProperty)
-    {
-    case DevicePropertyBusNumber:
-        Length = sizeof(ULONG);
-        Data = &DeviceNode->ChildBusNumber;
-        break;
-
-        /* Complete, untested */
-    case DevicePropertyBusTypeGuid:
-        /* Sanity check */
-        if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
-            (DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
-        {
-            /* Return the GUID */
-            *ResultLength = sizeof(GUID);
-
-            /* Check if the buffer given was large enough */
-            if (BufferLength < *ResultLength)
-            {
-                return STATUS_BUFFER_TOO_SMALL;
-            }
-
-            /* Copy the GUID */
-            RtlCopyMemory(PropertyBuffer,
-                &(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
-                sizeof(GUID));
-            return STATUS_SUCCESS;
-        }
-        else
-        {
-            return STATUS_OBJECT_NAME_NOT_FOUND;
-        }
-        break;
-
-    case DevicePropertyLegacyBusType:
-        Length = sizeof(INTERFACE_TYPE);
-        Data = &DeviceNode->ChildInterfaceType;
-        break;
-
-    case DevicePropertyAddress:
-        /* Query the device caps */
-        Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
-        if (NT_SUCCESS(Status) && (DeviceCaps.Address != (ULONG)-1))
-        {
-            /* Return length */
-            *ResultLength = sizeof(ULONG);
-
-            /* Check if the buffer given was large enough */
-            if (BufferLength < *ResultLength)
-            {
-                return STATUS_BUFFER_TOO_SMALL;
-            }
-
-            /* Return address */
-            *(PULONG)PropertyBuffer = DeviceCaps.Address;
-            return STATUS_SUCCESS;
-        }
-        else
-        {
-            return STATUS_OBJECT_NAME_NOT_FOUND;
-        }
-        break;
-
-//    case DevicePropertyUINumber:
-//      if (DeviceNode->CapabilityFlags == NULL)
-//         return STATUS_INVALID_DEVICE_REQUEST;
-//      Length = sizeof(ULONG);
-//      Data = &DeviceNode->CapabilityFlags->UINumber;
-//      break;
-
-    case DevicePropertyClassName:
-    case DevicePropertyClassGuid:
-    case DevicePropertyDriverKeyName:
-    case DevicePropertyManufacturer:
-    case DevicePropertyFriendlyName:
-    case DevicePropertyHardwareID:
-    case DevicePropertyCompatibleIDs:
-    case DevicePropertyDeviceDescription:
-    case DevicePropertyLocationInformation:
-    case DevicePropertyUINumber:
-        {
-            LPCWSTR RegistryPropertyName;
-            UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
-            UNICODE_STRING ValueName;
-            KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
-            ULONG ValueInformationLength;
-            HANDLE KeyHandle, EnumRootHandle;
-            NTSTATUS Status;
-
-            switch (DeviceProperty)
-            {
-            case DevicePropertyClassName:
-                RegistryPropertyName = L"Class"; break;
-            case DevicePropertyClassGuid:
-                RegistryPropertyName = L"ClassGuid"; break;
-            case DevicePropertyDriverKeyName:
-                RegistryPropertyName = L"Driver"; break;
-            case DevicePropertyManufacturer:
-                RegistryPropertyName = L"Mfg"; break;
-            case DevicePropertyFriendlyName:
-                RegistryPropertyName = L"FriendlyName"; break;
-            case DevicePropertyHardwareID:
-                RegistryPropertyName = L"HardwareID"; break;
-            case DevicePropertyCompatibleIDs:
-                RegistryPropertyName = L"CompatibleIDs"; break;
-            case DevicePropertyDeviceDescription:
-                RegistryPropertyName = L"DeviceDesc"; break;
-            case DevicePropertyLocationInformation:
-                RegistryPropertyName = L"LocationInformation"; break;
-            case DevicePropertyUINumber:
-                RegistryPropertyName = L"UINumber"; break;
-            default:
-                /* Should not happen */
-                ASSERT(FALSE);
-                return STATUS_UNSUCCESSFUL;
-            }
-
-            DPRINT("Registry property %S\n", RegistryPropertyName);
-
-            /* Open Enum key */
-            Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL,
-                &EnumRoot, KEY_READ);
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status);
-                return Status;
-            }
-
-            /* Open instance key */
-            Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle,
-                &DeviceNode->InstancePath, KEY_READ);
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Error opening InstancePath, Status=0x%08x\n", Status);
-                ZwClose(EnumRootHandle);
-                return Status;
-            }
-
-            /* Allocate buffer to read as much data as required by the caller */
-            ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
-                Data[0]) + BufferLength;
-            ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
-            if (!ValueInformation)
-            {
-                ZwClose(KeyHandle);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            /* Read the value */
-            RtlInitUnicodeString(&ValueName, RegistryPropertyName);
-            Status = ZwQueryValueKey(KeyHandle, &ValueName,
-                KeyValuePartialInformation, ValueInformation,
-                ValueInformationLength,
-                &ValueInformationLength);
-            ZwClose(KeyHandle);
-
-            /* Return data */
-            *ResultLength = ValueInformation->DataLength;
-
-            if (!NT_SUCCESS(Status))
-            {
-                DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status, *ResultLength);
-                ExFreePool(ValueInformation);
-                if (Status == STATUS_BUFFER_OVERFLOW)
-                    return STATUS_BUFFER_TOO_SMALL;
-                else
-                    return Status;
-            }
-
-            /* FIXME: Verify the value (NULL-terminated, correct format). */
-            RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
-                ValueInformation->DataLength);
-            ExFreePool(ValueInformation);
-
-            return STATUS_SUCCESS;
-        }
-
-    case DevicePropertyBootConfiguration:
-        Length = 0;
-        if (DeviceNode->BootResources->Count != 0)
-        {
-            Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
-        }
-        Data = &DeviceNode->BootResources;
-        break;
-
-        /* FIXME: use a translated boot configuration instead */
-    case DevicePropertyBootConfigurationTranslated:
-        Length = 0;
-        if (DeviceNode->BootResources->Count != 0)
-        {
-            Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
-        }
-        Data = &DeviceNode->BootResources;
-        break;
-
-    case DevicePropertyEnumeratorName:
-        /* A buffer overflow can't happen here, since InstancePath
-        * always contains the enumerator name followed by \\ */
-        Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
-        ASSERT(Ptr);
-        Length = (Ptr - DeviceNode->InstancePath.Buffer + 1) * sizeof(WCHAR);
-        Data = DeviceNode->InstancePath.Buffer;
-        break;
-
-    case DevicePropertyPhysicalDeviceObjectName:
-        /* InstancePath buffer is NULL terminated, so we can do this */
-        Length = DeviceNode->InstancePath.MaximumLength;
-        Data = DeviceNode->InstancePath.Buffer;
-        break;
-
-    default:
-        return STATUS_INVALID_PARAMETER_2;
-    }
-
-    /* Prepare returned values */
-    *ResultLength = Length;
-    if (BufferLength < Length)
-        return STATUS_BUFFER_TOO_SMALL;
-    RtlCopyMemory(PropertyBuffer, Data, Length);
-
-    /* NULL terminate the string (if required) */
-    if (DeviceProperty == DevicePropertyEnumeratorName)
-        ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
-
-    return STATUS_SUCCESS;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
-{
-    UNIMPLEMENTED;
-}
-
-/**
- * @name IoOpenDeviceRegistryKey
- *
- * Open a registry key unique for a specified driver or device instance.
- *
- * @param DeviceObject   Device to get the registry key for.
- * @param DevInstKeyType Type of the key to return.
- * @param DesiredAccess  Access mask (eg. KEY_READ | KEY_WRITE).
- * @param DevInstRegKey  Handle to the opened registry key on
- *                       successful return.
- *
- * @return Status.
- *
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject,
-                        IN ULONG DevInstKeyType,
-                        IN ACCESS_MASK DesiredAccess,
-                        OUT PHANDLE DevInstRegKey)
-{
-   static WCHAR RootKeyName[] =
-      L"\\Registry\\Machine\\System\\CurrentControlSet\\";
-   static WCHAR ProfileKeyName[] =
-      L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
-   static WCHAR ClassKeyName[] = L"Control\\Class\\";
-   static WCHAR EnumKeyName[] = L"Enum\\";
-   static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
-   ULONG KeyNameLength;
-   LPWSTR KeyNameBuffer;
-   UNICODE_STRING KeyName;
-   ULONG DriverKeyLength;
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   PDEVICE_NODE DeviceNode = NULL;
-   NTSTATUS Status;
-
-   DPRINT("IoOpenDeviceRegistryKey() called\n");
-
-   if ((DevInstKeyType & (PLUGPLAY_REGKEY_DEVICE | PLUGPLAY_REGKEY_DRIVER)) == 0)
-   {
-       DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
-       return STATUS_INVALID_PARAMETER;
-   }
-
-   /*
-    * Calculate the length of the base key name. This is the full
-    * name for driver key or the name excluding "Device Parameters"
-    * subkey for device key.
-    */
-
-   KeyNameLength = sizeof(RootKeyName);
-   if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
-      KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
-   if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
-   {
-      KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
-      Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
-                                   0, NULL, &DriverKeyLength);
-      if (Status != STATUS_BUFFER_TOO_SMALL)
-         return Status;
-      KeyNameLength += DriverKeyLength;
-   }
-   else
-   {
-      DeviceNode = IopGetDeviceNode(DeviceObject);
-      KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
-                       DeviceNode->InstancePath.Length;
-   }
-
-   /*
-    * Now allocate the buffer for the key name...
-    */
-
-   KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
-   if (KeyNameBuffer == NULL)
-      return STATUS_INSUFFICIENT_RESOURCES;
-
-   KeyName.Length = 0;
-   KeyName.MaximumLength = (USHORT)KeyNameLength;
-   KeyName.Buffer = KeyNameBuffer;
-
-   /*
-    * ...and build the key name.
-    */
-
-   KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
-   RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
-
-   if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
-      RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
-
-   if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
-   {
-      RtlAppendUnicodeToString(&KeyName, ClassKeyName);
-      Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
-                                   DriverKeyLength, KeyNameBuffer +
-                                   (KeyName.Length / sizeof(WCHAR)),
-                                   &DriverKeyLength);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
-         ExFreePool(KeyNameBuffer);
-         return Status;
-      }
-      KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
-   }
-   else
-   {
-      RtlAppendUnicodeToString(&KeyName, EnumKeyName);
-      Status = RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->InstancePath);
-      if (DeviceNode->InstancePath.Length == 0)
-      {
-         ExFreePool(KeyNameBuffer);
-         return Status;
-      }
-   }
-
-   /*
-    * Open the base key.
-    */
-   Status = IopOpenRegistryKeyEx(DevInstRegKey, NULL, &KeyName, DesiredAccess);
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
-      ExFreePool(KeyNameBuffer);
-      return Status;
-   }
-   ExFreePool(KeyNameBuffer);
-
-   /*
-    * For driver key we're done now.
-    */
-
-   if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
-      return Status;
-
-   /*
-    * Let's go further. For device key we must open "Device Parameters"
-    * subkey and create it if it doesn't exist yet.
-    */
-
-   RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
-   InitializeObjectAttributes(&ObjectAttributes, &KeyName,
-                              OBJ_CASE_INSENSITIVE, *DevInstRegKey, NULL);
-   Status = ZwCreateKey(DevInstRegKey, DesiredAccess, &ObjectAttributes,
-                        0, NULL, REG_OPTION_NON_VOLATILE, NULL);
-   ZwClose(ObjectAttributes.RootDirectory);
-
-   return Status;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-IoRequestDeviceEject(IN PDEVICE_OBJECT PhysicalDeviceObject)
-{
-   UNIMPLEMENTED;
-}
-
-
 NTSTATUS
 IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject)
 {
@@ -743,7 +281,7 @@
 }
 
 USHORT
-STDCALL
+NTAPI
 IopGetBusTypeGuidIndex(LPGUID BusTypeGuid)
 {
    USHORT i = 0, FoundIndex = 0xFFFF;
@@ -2137,158 +1675,6 @@
 }
 
 /*
- * @implemented
- */
-VOID
-NTAPI
-IoSynchronousInvalidateDeviceRelations(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN DEVICE_RELATION_TYPE Type)
-{
-    PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
-    DEVICETREE_TRAVERSE_CONTEXT Context;
-    PDEVICE_RELATIONS DeviceRelations;
-    IO_STATUS_BLOCK IoStatusBlock;
-    PDEVICE_NODE ChildDeviceNode;
-    IO_STACK_LOCATION Stack;
-    BOOLEAN BootDrivers;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
-    HANDLE Handle;
-    NTSTATUS Status;
-    ULONG i;
-
-    DPRINT("DeviceObject 0x%p\n", DeviceObject);
-
-    DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
-
-    Stack.Parameters.QueryDeviceRelations.Type = Type;
-
-    Status = IopInitiatePnpIrp(
-        DeviceObject,
-        &IoStatusBlock,
-        IRP_MN_QUERY_DEVICE_RELATIONS,
-        &Stack);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
-        return;
-    }
-
-    DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
-
-    if (!DeviceRelations || DeviceRelations->Count <= 0)
-    {
-        DPRINT("No PDOs\n");
-        if (DeviceRelations)
-        {
-            ExFreePool(DeviceRelations);
-        }
-        return;
-    }
-
-    DPRINT("Got %d PDOs\n", DeviceRelations->Count);
-
-    /*
-     * Create device nodes for all discovered devices
-     */
-    for (i = 0; i < DeviceRelations->Count; i++)
-    {
-        if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL)
-        {
-            ObDereferenceObject(DeviceRelations->Objects[i]);
-            continue;
-        }
-        Status = IopCreateDeviceNode(
-            DeviceNode,
-            DeviceRelations->Objects[i],
-            NULL,
-            &ChildDeviceNode);
-        DeviceNode->Flags |= DNF_ENUMERATED;
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT("No resources\n");
-            for (i = 0; i < DeviceRelations->Count; i++)
-                ObDereferenceObject(DeviceRelations->Objects[i]);
-            ExFreePool(DeviceRelations);
-            return;
-        }
-    }
-    ExFreePool(DeviceRelations);
-
-    /*
-     * Retrieve information about all discovered children from the bus driver
-     */
-    IopInitDeviceTreeTraverseContext(
-        &Context,
-        DeviceNode,
-        IopActionInterrogateDeviceStack,
-        DeviceNode);
-
-    Status = IopTraverseDeviceTree(&Context);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
-        return;
-    }
-
-    /*
-     * Retrieve configuration from the registry for discovered children
-     */
-    IopInitDeviceTreeTraverseContext(
-        &Context,
-        DeviceNode,
-        IopActionConfigureChildServices,
-        DeviceNode);
-
-    Status = IopTraverseDeviceTree(&Context);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
-        return;
-    }
-
-    /*
-     * Get the state of the system boot. If the \\SystemRoot link isn't
-     * created yet, we will assume that it's possible to load only boot
-     * drivers.
-     */
-    InitializeObjectAttributes(
-        &ObjectAttributes,
-        &LinkName,
-        0,
-        NULL,
-        NULL);
-    Status = ZwOpenFile(
-        &Handle,
-        FILE_ALL_ACCESS,
-        &ObjectAttributes,
-        &IoStatusBlock,
-        0,
-        0);
-     if (NT_SUCCESS(Status))
-     {
-         BootDrivers = FALSE;
-         ZwClose(Handle);
-     }
-     else
-         BootDrivers = TRUE;
-
-    /*
-     * Initialize services for discovered children. Only boot drivers will
-     * be loaded from boot driver!
-     */
-    Status = IopInitializePnpServices(DeviceNode, BootDrivers);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
-        return;
-    }
-
-    DPRINT("IopInvalidateDeviceRelations() finished\n");
-}
-
-/*
  * IopActionConfigureChildServices
  *
  * Retrieve configuration for all (direct) child nodes of a parent node.
@@ -3476,4 +2862,615 @@
     }
 }
 
-/* EOF */
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject,
+                    IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
+                    IN ULONG BufferLength,
+                    OUT PVOID PropertyBuffer,
+                    OUT PULONG ResultLength)
+{
+    PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+    DEVICE_CAPABILITIES DeviceCaps;
+    ULONG Length;
+    PVOID Data = NULL;
+    PWSTR Ptr;
+    NTSTATUS Status;
+
+    DPRINT("IoGetDeviceProperty(0x%p %d)\n", DeviceObject, DeviceProperty);
+
+    *ResultLength = 0;
+
+    if (DeviceNode == NULL)
+        return STATUS_INVALID_DEVICE_REQUEST;
+
+    switch (DeviceProperty)
+    {
+    case DevicePropertyBusNumber:
+        Length = sizeof(ULONG);
+        Data = &DeviceNode->ChildBusNumber;
+        break;
+
+        /* Complete, untested */
+    case DevicePropertyBusTypeGuid:
+        /* Sanity check */
+        if ((DeviceNode->ChildBusTypeIndex != 0xFFFF) &&
+            (DeviceNode->ChildBusTypeIndex < IopBusTypeGuidList->GuidCount))
+        {
+            /* Return the GUID */
+            *ResultLength = sizeof(GUID);
+
+            /* Check if the buffer given was large enough */
+            if (BufferLength < *ResultLength)
+            {
+                return STATUS_BUFFER_TOO_SMALL;
+            }
+
+            /* Copy the GUID */
+            RtlCopyMemory(PropertyBuffer,
+                &(IopBusTypeGuidList->Guids[DeviceNode->ChildBusTypeIndex]),
+                sizeof(GUID));
+            return STATUS_SUCCESS;
+        }
+        else
+        {
+            return STATUS_OBJECT_NAME_NOT_FOUND;
+        }
+        break;
+
+    case DevicePropertyLegacyBusType:
+        Length = sizeof(INTERFACE_TYPE);
+        Data = &DeviceNode->ChildInterfaceType;
+        break;
+
+    case DevicePropertyAddress:
+        /* Query the device caps */
+        Status = IopQueryDeviceCapabilities(DeviceNode, &DeviceCaps);
+        if (NT_SUCCESS(Status) && (DeviceCaps.Address != (ULONG)-1))
+        {
+            /* Return length */
+            *ResultLength = sizeof(ULONG);
+
+            /* Check if the buffer given was large enough */
+            if (BufferLength < *ResultLength)
+            {
+                return STATUS_BUFFER_TOO_SMALL;
+            }
+
+            /* Return address */
+            *(PULONG)PropertyBuffer = DeviceCaps.Address;
+            return STATUS_SUCCESS;
+        }
+        else
+        {
+            return STATUS_OBJECT_NAME_NOT_FOUND;
+        }
+        break;
+
+//    case DevicePropertyUINumber:
+//      if (DeviceNode->CapabilityFlags == NULL)
+//         return STATUS_INVALID_DEVICE_REQUEST;
+//      Length = sizeof(ULONG);
+//      Data = &DeviceNode->CapabilityFlags->UINumber;
+//      break;
+
+    case DevicePropertyClassName:
+    case DevicePropertyClassGuid:
+    case DevicePropertyDriverKeyName:
+    case DevicePropertyManufacturer:
+    case DevicePropertyFriendlyName:
+    case DevicePropertyHardwareID:
+    case DevicePropertyCompatibleIDs:
+    case DevicePropertyDeviceDescription:
+    case DevicePropertyLocationInformation:
+    case DevicePropertyUINumber:
+        {
+            LPCWSTR RegistryPropertyName;
+            UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
+            UNICODE_STRING ValueName;
+            KEY_VALUE_PARTIAL_INFORMATION *ValueInformation;
+            ULONG ValueInformationLength;
+            HANDLE KeyHandle, EnumRootHandle;
+            NTSTATUS Status;
+
+            switch (DeviceProperty)
+            {
+            case DevicePropertyClassName:
+                RegistryPropertyName = L"Class"; break;
+            case DevicePropertyClassGuid:
+                RegistryPropertyName = L"ClassGuid"; break;
+            case DevicePropertyDriverKeyName:
+                RegistryPropertyName = L"Driver"; break;
+            case DevicePropertyManufacturer:
+                RegistryPropertyName = L"Mfg"; break;
+            case DevicePropertyFriendlyName:
+                RegistryPropertyName = L"FriendlyName"; break;
+            case DevicePropertyHardwareID:
+                RegistryPropertyName = L"HardwareID"; break;
+            case DevicePropertyCompatibleIDs:
+                RegistryPropertyName = L"CompatibleIDs"; break;
+            case DevicePropertyDeviceDescription:
+                RegistryPropertyName = L"DeviceDesc"; break;
+            case DevicePropertyLocationInformation:
+                RegistryPropertyName = L"LocationInformation"; break;
+            case DevicePropertyUINumber:
+                RegistryPropertyName = L"UINumber"; break;
+            default:
+                /* Should not happen */
+                ASSERT(FALSE);
+                return STATUS_UNSUCCESSFUL;
+            }
+
+            DPRINT("Registry property %S\n", RegistryPropertyName);
+
+            /* Open Enum key */
+            Status = IopOpenRegistryKeyEx(&EnumRootHandle, NULL,
+                &EnumRoot, KEY_READ);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Error opening ENUM_ROOT, Status=0x%08x\n", Status);
+                return Status;
+            }
+
+            /* Open instance key */
+            Status = IopOpenRegistryKeyEx(&KeyHandle, EnumRootHandle,
+                &DeviceNode->InstancePath, KEY_READ);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Error opening InstancePath, Status=0x%08x\n", Status);
+                ZwClose(EnumRootHandle);
+                return Status;
+            }
+
+            /* Allocate buffer to read as much data as required by the caller */
+            ValueInformationLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,
+                Data[0]) + BufferLength;
+            ValueInformation = ExAllocatePool(PagedPool, ValueInformationLength);
+            if (!ValueInformation)
+            {
+                ZwClose(KeyHandle);
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+
+            /* Read the value */
+            RtlInitUnicodeString(&ValueName, RegistryPropertyName);
+            Status = ZwQueryValueKey(KeyHandle, &ValueName,
+                KeyValuePartialInformation, ValueInformation,
+                ValueInformationLength,
+                &ValueInformationLength);
+            ZwClose(KeyHandle);
+
+            /* Return data */
+            *ResultLength = ValueInformation->DataLength;
+
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Problem: Status=0x%08x, ResultLength = %d\n", Status, *ResultLength);
+                ExFreePool(ValueInformation);
+                if (Status == STATUS_BUFFER_OVERFLOW)
+                    return STATUS_BUFFER_TOO_SMALL;
+                else
+                    return Status;
+            }
+
+            /* FIXME: Verify the value (NULL-terminated, correct format). */
+            RtlCopyMemory(PropertyBuffer, ValueInformation->Data,
+                ValueInformation->DataLength);
+            ExFreePool(ValueInformation);
+
+            return STATUS_SUCCESS;
+        }
+
+    case DevicePropertyBootConfiguration:
+        Length = 0;
+        if (DeviceNode->BootResources->Count != 0)
+        {
+            Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
+        }
+        Data = &DeviceNode->BootResources;
+        break;
+
+        /* FIXME: use a translated boot configuration instead */
+    case DevicePropertyBootConfigurationTranslated:
+        Length = 0;
+        if (DeviceNode->BootResources->Count != 0)
+        {
+            Length = CM_RESOURCE_LIST_SIZE(DeviceNode->BootResources);
+        }
+        Data = &DeviceNode->BootResources;
+        break;
+
+    case DevicePropertyEnumeratorName:
+        /* A buffer overflow can't happen here, since InstancePath
+        * always contains the enumerator name followed by \\ */
+        Ptr = wcschr(DeviceNode->InstancePath.Buffer, L'\\');
+        ASSERT(Ptr);
+        Length = (Ptr - DeviceNode->InstancePath.Buffer + 1) * sizeof(WCHAR);
+        Data = DeviceNode->InstancePath.Buffer;
+        break;
+
+    case DevicePropertyPhysicalDeviceObjectName:
+        /* InstancePath buffer is NULL terminated, so we can do this */
+        Length = DeviceNode->InstancePath.MaximumLength;
+        Data = DeviceNode->InstancePath.Buffer;
+        break;
+
+    default:
+        return STATUS_INVALID_PARAMETER_2;
+    }
+
+    /* Prepare returned values */
+    *ResultLength = Length;
+    if (BufferLength < Length)
+        return STATUS_BUFFER_TOO_SMALL;
+    RtlCopyMemory(PropertyBuffer, Data, Length);
+
+    /* NULL terminate the string (if required) */
+    if (DeviceProperty == DevicePropertyEnumeratorName)
+        ((LPWSTR)PropertyBuffer)[Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+    return STATUS_SUCCESS;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    UNIMPLEMENTED;
+}
+
+/**
+ * @name IoOpenDeviceRegistryKey
+ *
+ * Open a registry key unique for a specified driver or device instance.
+ *
+ * @param DeviceObject   Device to get the registry key for.
+ * @param DevInstKeyType Type of the key to return.
+ * @param DesiredAccess  Access mask (eg. KEY_READ | KEY_WRITE).
+ * @param DevInstRegKey  Handle to the opened registry key on
+ *                       successful return.
+ *
+ * @return Status.
+ *
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject,
+                        IN ULONG DevInstKeyType,
+                        IN ACCESS_MASK DesiredAccess,
+                        OUT PHANDLE DevInstRegKey)
+{
+   static WCHAR RootKeyName[] =
+      L"\\Registry\\Machine\\System\\CurrentControlSet\\";
+   static WCHAR ProfileKeyName[] =
+      L"Hardware Profiles\\Current\\System\\CurrentControlSet\\";
+   static WCHAR ClassKeyName[] = L"Control\\Class\\";
+   static WCHAR EnumKeyName[] = L"Enum\\";
+   static WCHAR DeviceParametersKeyName[] = L"Device Parameters";
+   ULONG KeyNameLength;
+   LPWSTR KeyNameBuffer;
+   UNICODE_STRING KeyName;
+   ULONG DriverKeyLength;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   PDEVICE_NODE DeviceNode = NULL;
+   NTSTATUS Status;
+
+   DPRINT("IoOpenDeviceRegistryKey() called\n");
+
+   if ((DevInstKeyType & (PLUGPLAY_REGKEY_DEVICE | PLUGPLAY_REGKEY_DRIVER)) == 0)
+   {
+       DPRINT1("IoOpenDeviceRegistryKey(): got wrong params, exiting... \n");
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   /*
+    * Calculate the length of the base key name. This is the full
+    * name for driver key or the name excluding "Device Parameters"
+    * subkey for device key.
+    */
+
+   KeyNameLength = sizeof(RootKeyName);
+   if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
+      KeyNameLength += sizeof(ProfileKeyName) - sizeof(UNICODE_NULL);
+   if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
+   {
+      KeyNameLength += sizeof(ClassKeyName) - sizeof(UNICODE_NULL);
+      Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
+                                   0, NULL, &DriverKeyLength);
+      if (Status != STATUS_BUFFER_TOO_SMALL)
+         return Status;
+      KeyNameLength += DriverKeyLength;
+   }
+   else
+   {
+      DeviceNode = IopGetDeviceNode(DeviceObject);
+      KeyNameLength += sizeof(EnumKeyName) - sizeof(UNICODE_NULL) +
+                       DeviceNode->InstancePath.Length;
+   }
+
+   /*
+    * Now allocate the buffer for the key name...
+    */
+
+   KeyNameBuffer = ExAllocatePool(PagedPool, KeyNameLength);
+   if (KeyNameBuffer == NULL)
+      return STATUS_INSUFFICIENT_RESOURCES;
+
+   KeyName.Length = 0;
+   KeyName.MaximumLength = (USHORT)KeyNameLength;
+   KeyName.Buffer = KeyNameBuffer;
+
+   /*
+    * ...and build the key name.
+    */
+
+   KeyName.Length += sizeof(RootKeyName) - sizeof(UNICODE_NULL);
+   RtlCopyMemory(KeyNameBuffer, RootKeyName, KeyName.Length);
+
+   if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
+      RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
+
+   if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
+   {
+      RtlAppendUnicodeToString(&KeyName, ClassKeyName);
+      Status = IoGetDeviceProperty(DeviceObject, DevicePropertyDriverKeyName,
+                                   DriverKeyLength, KeyNameBuffer +
+                                   (KeyName.Length / sizeof(WCHAR)),
+                                   &DriverKeyLength);
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT1("Call to IoGetDeviceProperty() failed with Status 0x%08lx\n", Status);
+         ExFreePool(KeyNameBuffer);
+         return Status;
+      }
+      KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
+   }
+   else
+   {
+      RtlAppendUnicodeToString(&KeyName, EnumKeyName);
+      Status = RtlAppendUnicodeStringToString(&KeyName, &DeviceNode->InstancePath);
+      if (DeviceNode->InstancePath.Length == 0)
+      {
+         ExFreePool(KeyNameBuffer);
+         return Status;
+      }
+   }
+
+   /*
+    * Open the base key.
+    */
+   Status = IopOpenRegistryKeyEx(DevInstRegKey, NULL, &KeyName, DesiredAccess);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT1("IoOpenDeviceRegistryKey(%wZ): Base key doesn't exist, exiting... (Status 0x%08lx)\n", &KeyName, Status);
+      ExFreePool(KeyNameBuffer);
+      return Status;
+   }
+   ExFreePool(KeyNameBuffer);
+
+   /*
+    * For driver key we're done now.
+    */
+
+   if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
+      return Status;
+
+   /*
+    * Let's go further. For device key we must open "Device Parameters"
+    * subkey and create it if it doesn't exist yet.
+    */
+
+   RtlInitUnicodeString(&KeyName, DeviceParametersKeyName);
+   InitializeObjectAttributes(&ObjectAttributes, &KeyName,
+                              OBJ_CASE_INSENSITIVE, *DevInstRegKey, NULL);
+   Status = ZwCreateKey(DevInstRegKey, DesiredAccess, &ObjectAttributes,
+                        0, NULL, REG_OPTION_NON_VOLATILE, NULL);
+   ZwClose(ObjectAttributes.RootDirectory);
+
+   return Status;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+IoRequestDeviceEject(IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+   UNIMPLEMENTED;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+IoInvalidateDeviceRelations(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN DEVICE_RELATION_TYPE Type)
+{
+    PIO_WORKITEM WorkItem;
+    PINVALIDATE_DEVICE_RELATION_DATA Data;
+
+    Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
+    if (!Data)
+        return;
+    WorkItem = IoAllocateWorkItem(DeviceObject);
+    if (!WorkItem)
+    {
+        ExFreePool(Data);
+        return;
+    }
+
+    ObReferenceObject(DeviceObject);
+    Data->DeviceObject = DeviceObject;
+    Data->Type = Type;
+    Data->WorkItem = WorkItem;
+
+    IoQueueWorkItem(
+        WorkItem,
+        IopAsynchronousInvalidateDeviceRelations,
+        DelayedWorkQueue,
+        Data);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+IoSynchronousInvalidateDeviceRelations(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN DEVICE_RELATION_TYPE Type)
+{
+    PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject);
+    DEVICETREE_TRAVERSE_CONTEXT Context;
+    PDEVICE_RELATIONS DeviceRelations;
+    IO_STATUS_BLOCK IoStatusBlock;
+    PDEVICE_NODE ChildDeviceNode;
+    IO_STACK_LOCATION Stack;
+    BOOLEAN BootDrivers;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
+    HANDLE Handle;
+    NTSTATUS Status;
+    ULONG i;
+
+    DPRINT("DeviceObject 0x%p\n", DeviceObject);
+
+    DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
+
+    Stack.Parameters.QueryDeviceRelations.Type = Type;
+
+    Status = IopInitiatePnpIrp(
+        DeviceObject,
+        &IoStatusBlock,
+        IRP_MN_QUERY_DEVICE_RELATIONS,
+        &Stack);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status);
+        return;
+    }
+
+    DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
+
+    if (!DeviceRelations || DeviceRelations->Count <= 0)
+    {
+        DPRINT("No PDOs\n");
+        if (DeviceRelations)
+        {
+            ExFreePool(DeviceRelations);
+        }
+        return;
+    }
+
+    DPRINT("Got %d PDOs\n", DeviceRelations->Count);
+
+    /*
+     * Create device nodes for all discovered devices
+     */
+    for (i = 0; i < DeviceRelations->Count; i++)
+    {
+        if (IopGetDeviceNode(DeviceRelations->Objects[i]) != NULL)
+        {
+            ObDereferenceObject(DeviceRelations->Objects[i]);
+            continue;
+        }
+        Status = IopCreateDeviceNode(
+            DeviceNode,
+            DeviceRelations->Objects[i],
+            NULL,
+            &ChildDeviceNode);
+        DeviceNode->Flags |= DNF_ENUMERATED;
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("No resources\n");
+            for (i = 0; i < DeviceRelations->Count; i++)
+                ObDereferenceObject(DeviceRelations->Objects[i]);
+            ExFreePool(DeviceRelations);
+            return;
+        }
+    }
+    ExFreePool(DeviceRelations);
+
+    /*
+     * Retrieve information about all discovered children from the bus driver
+     */
+    IopInitDeviceTreeTraverseContext(
+        &Context,
+        DeviceNode,
+        IopActionInterrogateDeviceStack,
+        DeviceNode);
+
+    Status = IopTraverseDeviceTree(&Context);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
+        return;
+    }
+
+    /*
+     * Retrieve configuration from the registry for discovered children
+     */
+    IopInitDeviceTreeTraverseContext(
+        &Context,
+        DeviceNode,
+        IopActionConfigureChildServices,
+        DeviceNode);
+
+    Status = IopTraverseDeviceTree(&Context);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status);
+        return;
+    }
+
+    /*
+     * Get the state of the system boot. If the \\SystemRoot link isn't
+     * created yet, we will assume that it's possible to load only boot
+     * drivers.
+     */
+    InitializeObjectAttributes(
+        &ObjectAttributes,
+        &LinkName,
+        0,
+        NULL,
+        NULL);
+    Status = ZwOpenFile(
+        &Handle,
+        FILE_ALL_ACCESS,
+        &ObjectAttributes,
+        &IoStatusBlock,
+        0,
+        0);
+     if (NT_SUCCESS(Status))
+     {
+         BootDrivers = FALSE;
+         ZwClose(Handle);
+     }
+     else
+         BootDrivers = TRUE;
+
+    /*
+     * Initialize services for discovered children. Only boot drivers will
+     * be loaded from boot driver!
+     */
+    Status = IopInitializePnpServices(DeviceNode, BootDrivers);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status);
+        return;
+    }
+
+    DPRINT("IopInvalidateDeviceRelations() finished\n");
+}

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c?rev=35427&r1=35426&r2=35427&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpnotify.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/pnpnotify.c
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnpnotify.c
  * PURPOSE:         Plug & Play notification functions
- *
  * PROGRAMMERS:     Filip Navara (xnavara at volny.cz)
  *                  Hervé Poussineau (hpoussin at reactos.org)
  */
@@ -14,184 +13,22 @@
 #define NDEBUG
 #include <debug.h>
 
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, IopInitPnpNotificationImplementation)
-#endif
-
-
 /* TYPES *******************************************************************/
 
 typedef struct _PNP_NOTIFY_ENTRY
 {
-	LIST_ENTRY PnpNotifyList;
-	IO_NOTIFICATION_EVENT_CATEGORY EventCategory;
-	PVOID Context;
-	UNICODE_STRING Guid;
-	PFILE_OBJECT FileObject;
-	PDRIVER_NOTIFICATION_CALLBACK_ROUTINE PnpNotificationProc;
+    LIST_ENTRY PnpNotifyList;
+    IO_NOTIFICATION_EVENT_CATEGORY EventCategory;
+    PVOID Context;
+    UNICODE_STRING Guid;
+    PFILE_OBJECT FileObject;
+    PDRIVER_NOTIFICATION_CALLBACK_ROUTINE PnpNotificationProc;
 } PNP_NOTIFY_ENTRY, *PPNP_NOTIFY_ENTRY;
 
 KGUARDED_MUTEX PnpNotifyListLock;
 LIST_ENTRY PnpNotifyListHead;
 
 /* FUNCTIONS *****************************************************************/
-
-/*
- * @unimplemented
- */
-ULONG
-STDCALL
-IoPnPDeliverServicePowerNotification(
-	ULONG		VetoedPowerOperation OPTIONAL,
-	ULONG		PowerNotification,
-	ULONG		Unknown OPTIONAL,
-	BOOLEAN  	Synchronous
-	)
-{
-	UNIMPLEMENTED;
-	return 0;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoRegisterPlugPlayNotification(
-	IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
-	IN ULONG EventCategoryFlags,
-	IN PVOID EventCategoryData OPTIONAL,
-	IN PDRIVER_OBJECT DriverObject,
-	IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine,
-	IN PVOID Context,
-	OUT PVOID *NotificationEntry)
-{
-	PPNP_NOTIFY_ENTRY Entry;
-	PWSTR SymbolicLinkList;
-	NTSTATUS Status;
-
-	PAGED_CODE();
-
-	DPRINT("IoRegisterPlugPlayNotification(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject %p) called.\n",
-		EventCategory,
-		EventCategoryFlags,
-		DriverObject);
-
-	ObReferenceObject(DriverObject);
-
-	/* Try to allocate entry for notification before sending any notification */
-	Entry = ExAllocatePoolWithTag(
-		NonPagedPool,
-		sizeof(PNP_NOTIFY_ENTRY),
-		TAG_PNP_NOTIFY);
-	if (!Entry)
-	{
-		DPRINT("ExAllocatePool() failed\n");
-		ObDereferenceObject(DriverObject);
-		return STATUS_INSUFFICIENT_RESOURCES;
-	}
-
-	if (EventCategory == EventCategoryDeviceInterfaceChange
-		&& EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
-	{
-		DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
-		UNICODE_STRING SymbolicLinkU;
-		PWSTR SymbolicLink;
-
-		Status = IoGetDeviceInterfaces(
-			(LPGUID)EventCategoryData,
-			NULL, /* PhysicalDeviceObject OPTIONAL */
-			0, /* Flags */
-			&SymbolicLinkList);
-		if (!NT_SUCCESS(Status))
-		{
-			DPRINT("IoGetDeviceInterfaces() failed with status 0x%08lx\n", Status);
-			ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
-			ObDereferenceObject(DriverObject);
-			return Status;
-		}
-		/* Enumerate SymbolicLinkList */
-		NotificationInfos.Version = 1;
-		NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
-		RtlCopyMemory(&NotificationInfos.Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID));
-		RtlCopyMemory(&NotificationInfos.InterfaceClassGuid, EventCategoryData, sizeof(GUID));
-		NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
-		for (SymbolicLink = SymbolicLinkList; *SymbolicLink; SymbolicLink += wcslen(SymbolicLink) + 1)
-		{
-			RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
-			DPRINT("Calling callback routine for %S\n", SymbolicLink);
-			(*CallbackRoutine)(&NotificationInfos, Context);
-		}
-		ExFreePool(SymbolicLinkList);
-	}
-
-	Entry->PnpNotificationProc = CallbackRoutine;
-	Entry->EventCategory = EventCategory;
-	Entry->Context = Context;
-	switch (EventCategory)
-	{
-		case EventCategoryDeviceInterfaceChange:
-		{
-			Status = RtlStringFromGUID(EventCategoryData, &Entry->Guid);
-			if (!NT_SUCCESS(Status))
-			{
-				ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
-				ObDereferenceObject(DriverObject);
-				return Status;
-			}
-			break;
-		}
-		case EventCategoryHardwareProfileChange:
-		{
-			/* nothing to do */
-			break;
-		}
-		case EventCategoryTargetDeviceChange:
-		{
-			Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
-			break;
-		}
-		default:
-		{
-			DPRINT1("IoRegisterPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
-			break;
-		}
-	}
-
-	KeAcquireGuardedMutex(&PnpNotifyListLock);
-	InsertHeadList(&PnpNotifyListHead,
-		&Entry->PnpNotifyList);
-	KeReleaseGuardedMutex(&PnpNotifyListLock);
-
-	DPRINT("IoRegisterPlugPlayNotification() returns NotificationEntry %p\n",
-		Entry);
-	*NotificationEntry = Entry;
-	return STATUS_SUCCESS;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-IoUnregisterPlugPlayNotification(
-	IN PVOID NotificationEntry)
-{
-	PPNP_NOTIFY_ENTRY Entry;
-
-	PAGED_CODE();
-
-	Entry = (PPNP_NOTIFY_ENTRY)NotificationEntry;
-	DPRINT("IoUnregisterPlugPlayNotification(NotificationEntry %p) called\n",
-		Entry);
-
-	KeAcquireGuardedMutex(&PnpNotifyListLock);
-	RtlFreeUnicodeString(&Entry->Guid);
-	RemoveEntryList(&Entry->PnpNotifyList);
-	KeReleaseGuardedMutex(&PnpNotifyListLock);
-
-	return STATUS_SUCCESS;
-}
 
 VOID
 IopNotifyPlugPlayNotification(
@@ -323,4 +160,166 @@
 	ExFreePoolWithTag(NotificationStructure, TAG_PNP_NOTIFY);
 }
 
-/* EOF */
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @unimplemented
+ */
+ULONG
+NTAPI
+IoPnPDeliverServicePowerNotification(ULONG VetoedPowerOperation OPTIONAL,
+                                     ULONG PowerNotification,
+                                     ULONG Unknown OPTIONAL,
+                                     BOOLEAN Synchronous)
+{
+    UNIMPLEMENTED;
+    return 0;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoRegisterPlugPlayNotification(IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
+                               IN ULONG EventCategoryFlags,
+                               IN PVOID EventCategoryData OPTIONAL,
+                               IN PDRIVER_OBJECT DriverObject,
+                               IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine,
+                               IN PVOID Context,
+                               OUT PVOID *NotificationEntry)
+{
+    PPNP_NOTIFY_ENTRY Entry;
+    PWSTR SymbolicLinkList;
+    NTSTATUS Status;
+    PAGED_CODE();
+
+    DPRINT("__FUNCTION__(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject %p) called.\n",
+        EventCategory,
+        EventCategoryFlags,
+        DriverObject);
+
+    ObReferenceObject(DriverObject);
+
+    /* Try to allocate entry for notification before sending any notification */
+    Entry = ExAllocatePoolWithTag(NonPagedPool,
+                                  sizeof(PNP_NOTIFY_ENTRY),
+                                  TAG_PNP_NOTIFY);
+
+    if (!Entry)
+    {
+        DPRINT("ExAllocatePool() failed\n");
+        ObDereferenceObject(DriverObject);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    if (EventCategory == EventCategoryDeviceInterfaceChange	&&
+        EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
+    {
+        DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
+        UNICODE_STRING SymbolicLinkU;
+        PWSTR SymbolicLink;
+
+        Status = IoGetDeviceInterfaces((LPGUID)EventCategoryData,
+                                       NULL, /* PhysicalDeviceObject OPTIONAL */
+                                       0, /* Flags */
+                                       &SymbolicLinkList);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IoGetDeviceInterfaces() failed with status 0x%08lx\n",
+              Status);
+            ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
+            ObDereferenceObject(DriverObject);
+            return Status;
+        }
+
+        /* Enumerate SymbolicLinkList */
+        NotificationInfos.Version = 1;
+        NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
+        RtlCopyMemory(&NotificationInfos.Event,
+                      &GUID_DEVICE_INTERFACE_ARRIVAL,
+                      sizeof(GUID));
+        RtlCopyMemory(&NotificationInfos.InterfaceClassGuid,
+                      EventCategoryData,
+                      sizeof(GUID));
+        NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
+
+        for (SymbolicLink = SymbolicLinkList;
+             *SymbolicLink;
+             SymbolicLink += wcslen(SymbolicLink) + 1)
+        {
+            RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
+            DPRINT("Calling callback routine for %S\n", SymbolicLink);
+            (*CallbackRoutine)(&NotificationInfos, Context);
+        }
+
+        ExFreePool(SymbolicLinkList);
+    }
+
+    Entry->PnpNotificationProc = CallbackRoutine;
+    Entry->EventCategory = EventCategory;
+    Entry->Context = Context;
+    switch (EventCategory)
+    {
+        case EventCategoryDeviceInterfaceChange:
+        {
+            Status = RtlStringFromGUID(EventCategoryData, &Entry->Guid);
+            if (!NT_SUCCESS(Status))
+            {
+                ExFreePoolWithTag(Entry, TAG_PNP_NOTIFY);
+                ObDereferenceObject(DriverObject);
+                return Status;
+            }
+            break;
+        }
+        case EventCategoryHardwareProfileChange:
+        {
+            /* nothing to do */
+           break;
+        }
+        case EventCategoryTargetDeviceChange:
+        {
+            Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
+            break;
+        }
+        default:
+        {
+            DPRINT1("__FUNCTION__(): unknown EventCategory 0x%x UNIMPLEMENTED\n",
+              EventCategory);
+            break;
+        }
+    }
+
+    KeAcquireGuardedMutex(&PnpNotifyListLock);
+	InsertHeadList(&PnpNotifyListHead,
+                   &Entry->PnpNotifyList);
+    KeReleaseGuardedMutex(&PnpNotifyListLock);
+
+    DPRINT("IoRegisterPlugPlayNotification() returns NotificationEntry %p\n",
+        Entry);
+
+    *NotificationEntry = Entry;
+
+    return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
+{
+    PPNP_NOTIFY_ENTRY Entry;
+    PAGED_CODE();
+
+    Entry = (PPNP_NOTIFY_ENTRY)NotificationEntry;
+    DPRINT("__FUNCTION__(NotificationEntry %p) called\n", Entry);
+
+    KeAcquireGuardedMutex(&PnpNotifyListLock);
+    RtlFreeUnicodeString(&Entry->Guid);
+    RemoveEntryList(&Entry->PnpNotifyList);
+    KeReleaseGuardedMutex(&PnpNotifyListLock);
+
+    return STATUS_SUCCESS;
+}

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c?rev=35427&r1=35426&r2=35427&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/pnpreport.c
- * PURPOSE:         Device Changes Reporting functions
- *
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnpreport.c
+ * PURPOSE:         Device Changes Reporting Functions
  * PROGRAMMERS:     Filip Navara (xnavara at volny.cz)
  */
 
@@ -13,116 +12,127 @@
 #define NDEBUG
 #include <debug.h>
 
-/* FUNCTIONS *****************************************************************/
+/* PUBLIC FUNCTIONS **********************************************************/
 
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
-IoReportDetectedDevice(
-  IN PDRIVER_OBJECT DriverObject,
-  IN INTERFACE_TYPE LegacyBusType,
-  IN ULONG BusNumber,
-  IN ULONG SlotNumber,
-  IN PCM_RESOURCE_LIST ResourceList,
-  IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements  OPTIONAL,
-  IN BOOLEAN ResourceAssigned,
-  IN OUT PDEVICE_OBJECT *DeviceObject)
+NTAPI
+IoReportDetectedDevice(IN PDRIVER_OBJECT DriverObject,
+                       IN INTERFACE_TYPE LegacyBusType,
+                       IN ULONG BusNumber,
+                       IN ULONG SlotNumber,
+                       IN PCM_RESOURCE_LIST ResourceList,
+                       IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements OPTIONAL,
+                       IN BOOLEAN ResourceAssigned,
+                       IN OUT PDEVICE_OBJECT *DeviceObject OPTIONAL)
 {
-  PDEVICE_NODE DeviceNode;
-  PDEVICE_OBJECT Pdo;
-  NTSTATUS Status = STATUS_SUCCESS;
+    PDEVICE_NODE DeviceNode;
+    PDEVICE_OBJECT Pdo;
+    NTSTATUS Status = STATUS_SUCCESS;
 
-  DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n",
-    DeviceObject, DeviceObject ? *DeviceObject : NULL);
+    DPRINT("__FUNCTION__ (DeviceObject %p, *DeviceObject %p)\n",
+      DeviceObject, DeviceObject ? *DeviceObject : NULL);
 
-  /* if *DeviceObject is not NULL, we must use it as a PDO,
-   * and don't create a new one.
-   */
-  if (DeviceObject && *DeviceObject)
-    Pdo = *DeviceObject;
-  else
-  {
-    UNICODE_STRING ServiceName;
-    ServiceName.Buffer = DriverObject->DriverName.Buffer + sizeof(DRIVER_ROOT_NAME) / sizeof(WCHAR) - 1;
-    ServiceName.Length = ServiceName.MaximumLength = DriverObject->DriverName.Length - sizeof(DRIVER_ROOT_NAME) + sizeof(WCHAR);
+    /* if *DeviceObject is not NULL, we must use it as a PDO, and don't create a new one */
+    if (DeviceObject && *DeviceObject)
+    {
+        Pdo = *DeviceObject;
+    }
+    else
+    {
+        UNICODE_STRING ServiceName;
+        ServiceName.Buffer = DriverObject->DriverName.Buffer +
+          sizeof(DRIVER_ROOT_NAME) / sizeof(WCHAR) - 1;
+        ServiceName.Length = DriverObject->DriverName.Length -
+          sizeof(DRIVER_ROOT_NAME) + sizeof(WCHAR);
+        ServiceName.MaximumLength = ServiceName.Length;
 
-    /* create a new PDO and return it in *DeviceObject */
-    Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &ServiceName, &DeviceNode);
-    if (!NT_SUCCESS(Status))
-    {
-      DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
-      return Status;
-    }
-    Pdo = DeviceNode->PhysicalDeviceObject;
-    if (DeviceObject)
-      *DeviceObject = Pdo;
+        /* create a new PDO and return it in *DeviceObject */
+        Status = IopCreateDeviceNode(IopRootDeviceNode,
+                                     NULL,
+                                     &ServiceName,
+                                     &DeviceNode);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
+            return Status;
+        }
+
+        Pdo = DeviceNode->PhysicalDeviceObject;
+        if (DeviceObject) *DeviceObject = Pdo;
   }
 
-  /* we don't need to call AddDevice and send IRP_MN_START_DEVICE */
-
-  return Status;
+    /* we don't need to call AddDevice and send IRP_MN_START_DEVICE */
+    return Status;
 }
 
 /*
  * @unimplemented
  */
 NTSTATUS
-STDCALL
-IoReportResourceForDetection(
-  IN PDRIVER_OBJECT DriverObject,
-  IN PCM_RESOURCE_LIST DriverList   OPTIONAL,
-  IN ULONG DriverListSize    OPTIONAL,
-  IN PDEVICE_OBJECT DeviceObject    OPTIONAL,
-  IN PCM_RESOURCE_LIST DeviceList   OPTIONAL,
-  IN ULONG DeviceListSize   OPTIONAL,
-  OUT PBOOLEAN ConflictDetected)
+NTAPI
+IoReportResourceForDetection(IN PDRIVER_OBJECT DriverObject,
+                             IN PCM_RESOURCE_LIST DriverList OPTIONAL,
+                             IN ULONG DriverListSize OPTIONAL,
+                             IN PDEVICE_OBJECT DeviceObject OPTIONAL,
+                             IN PCM_RESOURCE_LIST DeviceList OPTIONAL,
+                             IN ULONG DeviceListSize OPTIONAL,
+                             OUT PBOOLEAN ConflictDetected)
 {
-  static int warned = 0;
-  if (!warned)
-  {
-    DPRINT1("IoReportResourceForDetection partly implemented\n");
-    warned = 1;
-  }
+    static int warned = 0;
+    if (!warned)
+    {
+        DPRINT1("IoReportResourceForDetection partly implemented\n");
+        warned = 1;
+    }
 
-  *ConflictDetected = FALSE;
+    *ConflictDetected = FALSE;
 
-  if (PopSystemPowerDeviceNode != NULL && DriverListSize > 0)
-  {
-    /* We hope legacy devices will be enumerated by ACPI */
-    *ConflictDetected = TRUE;
-    return STATUS_CONFLICTING_ADDRESSES;
-  }
-  return STATUS_SUCCESS;
+    if (PopSystemPowerDeviceNode && DriverListSize > 0)
+    {
+        /* We hope legacy devices will be enumerated by ACPI */
+        *ConflictDetected = TRUE;
+        return STATUS_CONFLICTING_ADDRESSES;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+IopSetEvent(IN PVOID Context)
+{
+    PKEVENT Event = Context;
+
+    /* Set the event */
+    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
 }
 
 /*
  * @unimplemented
  */
 NTSTATUS
-STDCALL
-IoReportTargetDeviceChange(
-  IN PDEVICE_OBJECT PhysicalDeviceObject,
-  IN PVOID NotificationStructure)
+NTAPI
+IoReportTargetDeviceChange(IN PDEVICE_OBJECT PhysicalDeviceObject,
+                           IN PVOID NotificationStructure)
 {
-  DPRINT1("IoReportTargetDeviceChange called (UNIMPLEMENTED)\n");
-  return STATUS_NOT_IMPLEMENTED;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 /*
  * @unimplemented
  */
 NTSTATUS
-STDCALL
-IoReportTargetDeviceChangeAsynchronous(
-  IN PDEVICE_OBJECT PhysicalDeviceObject,
-  IN PVOID NotificationStructure,
-  IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback  OPTIONAL,
-  IN PVOID Context  OPTIONAL)
+NTAPI
+IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject,
+                                       IN PVOID NotificationStructure,
+                                       IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
+                                       IN PVOID Context OPTIONAL)
 {
-  DPRINT1("IoReportTargetDeviceChangeAsynchronous called (UNIMPLEMENTED)\n");
-  return STATUS_NOT_IMPLEMENTED;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
-
-/* EOF */

Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c?rev=35427&r1=35426&r2=35427&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c [iso-8859-1] Mon Aug 18 08:30:17 2008
@@ -1,9 +1,8 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/pnproot.c
+ * PROJECT:         ReactOS Kernel
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/io/pnpmgr/pnproot.c
  * PURPOSE:         PnP manager root device
- *
  * PROGRAMMERS:     Casper S. Hornstrup (chorns at users.sourceforge.net)
  *                  Copyright 2007 Hervé Poussineau (hpoussin at reactos.org)
  */
@@ -1135,5 +1134,3 @@
 
     return STATUS_SUCCESS;
 }
-
-/* EOF */



More information about the Ros-diffs mailing list