Implement IoRegisterPlugPlayNotification, IoUnregisterPlugPlayNotification
Implement IoSetDeviceInterfaceState
Fix IoRegisterDeviceInterface
Add prototype for ExFreePoolWithTag

namespc.c: change STATUS_UNSUCCESSFUL to STATUS_OBJECT_NAME_INVALID

SVN maintenance in ntoskrnl/kd/wrappers/
Modified: trunk/reactos/include/ddk/exfuncs.h
Modified: trunk/reactos/include/ddk/pnptypes.h
Modified: trunk/reactos/include/ntos/ntpnp.h
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
Modified: trunk/reactos/ntoskrnl/io/deviface.c
Modified: trunk/reactos/ntoskrnl/io/iomgr.c
Modified: trunk/reactos/ntoskrnl/io/pnpnotify.c
Modified: trunk/reactos/ntoskrnl/io/pnproot.c
Modified: trunk/reactos/ntoskrnl/ob/namespc.c

Modified: trunk/reactos/include/ddk/exfuncs.h
--- trunk/reactos/include/ddk/exfuncs.h	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/include/ddk/exfuncs.h	2005-04-30 09:39:09 UTC (rev 14866)
@@ -215,6 +215,13 @@
 	PVOID	block
 	);
 
+void
+STDCALL
+ExFreePoolWithTag (
+	PVOID	block,
+	ULONG	tag
+	);
+
 /*
  * PVOID
  * ExFreeToZone (

Modified: trunk/reactos/include/ddk/pnptypes.h
--- trunk/reactos/include/ddk/pnptypes.h	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/include/ddk/pnptypes.h	2005-04-30 09:39:09 UTC (rev 14866)
@@ -147,6 +147,9 @@
   EventCategoryTargetDeviceChange
 } IO_NOTIFICATION_EVENT_CATEGORY;
 
+/* EventCategoryFlags for IoRegisterPlugPlayNotification */
+#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES 0x00000001
+
 /* CallbackRoutine for IoRegisterPlugPlayNotification */
 typedef NTSTATUS STDCALL_FUNC
 (*PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)(

Modified: trunk/reactos/include/ntos/ntpnp.h
--- trunk/reactos/include/ntos/ntpnp.h	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/include/ntos/ntpnp.h	2005-04-30 09:39:09 UTC (rev 14866)
@@ -38,8 +38,8 @@
 DEFINE_GUID(GUID_DEVICE_HIBERNATE_VETOED, 0x61173AD9, 0x194F, 0x11D3, 0x97, 0xDC, 0x00, 0xA0, 0xC9, 0x40, 0x52, 0x2E);
 DEFINE_GUID(GUID_DEVICE_BATTERY, 0x72631E54, 0x78A4, 0x11D0, 0xBC, 0xF7, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A);
 DEFINE_GUID(GUID_DEVICE_SAFE_REMOVAL, 0x8FBEF967, 0xD6C5, 0x11D2, 0x97, 0xB5, 0x00, 0xA0, 0xC9, 0x40, 0x52, 0x2E);
-/* DEFINE_GUID(GUID_DEVICE_INTERFACE_ARRIVAL, 0xCB3A4004, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F); */
-/* DEFINE_GUID(GUID_DEVICE_INTERFACE_REMOVAL, 0xCB3A4005, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F); */
+DEFINE_GUID(GUID_DEVICE_INTERFACE_ARRIVAL, 0xCB3A4004, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F);
+DEFINE_GUID(GUID_DEVICE_INTERFACE_REMOVAL, 0xCB3A4005, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F);
 DEFINE_GUID(GUID_DEVICE_ARRIVAL, 0xCB3A4009, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F);
 DEFINE_GUID(GUID_DEVICE_ENUMERATED, 0xCB3A400A, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F);
 DEFINE_GUID(GUID_DEVICE_ENUMERATE_REQUEST, 0xCB3A400B, 0x46F0, 0x11D0, 0xB0, 0x8F, 0x00, 0x60, 0x97, 0x13, 0x05, 0x3F);

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
--- trunk/reactos/ntoskrnl/include/internal/io.h	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/ntoskrnl/include/internal/io.h	2005-04-30 09:39:09 UTC (rev 14866)
@@ -330,6 +330,17 @@
 VOID
 IopInitDriverImplementation(VOID);
 
+VOID
+IopInitPnpNotificationImplementation(VOID);
+
+VOID
+IopNotifyPlugPlayNotification(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
+	IN GUID* Event,
+	IN PVOID EventCategoryData1,
+	IN PVOID EventCategoryData2);
+
 NTSTATUS
 IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject);
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/io/deviface.c
--- trunk/reactos/ntoskrnl/io/deviface.c	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/ntoskrnl/io/deviface.c	2005-04-30 09:39:09 UTC (rev 14866)
@@ -7,6 +7,7 @@
  * 
  * PROGRAMMERS:     Filip Navara (xnavara@volny.cz)
  *                  Matthew Brace (ismarc@austin.rr.com)
+ *                  HervÚ Poussineau (hpoussin@reactos.com)
  */
 
 /* INCLUDES ******************************************************************/
@@ -573,6 +574,8 @@
    UNICODE_STRING GuidString;
    UNICODE_STRING SubKeyName;
    UNICODE_STRING BaseKeyName;
+   UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
+   POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
    UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance");
    UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
    HANDLE InterfaceKey;
@@ -589,6 +592,19 @@
       return Status;
    }
    
+   /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
+   Status = ObQueryNameString(
+      PhysicalDeviceObject,
+      PdoNameInfo,
+      sizeof(PdoNameInfoBuffer),
+      &i);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
+      return Status;
+   }
+   ASSERT(PdoNameInfo->Name.Length);
+   
    /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\DeviceClasses\{GUID}\##?#ACPI#PNP0501#1#{GUID} */
    InstancePath = &PhysicalDeviceObject->DeviceObjectExtension->DeviceNode->InstancePath;
    BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
@@ -703,10 +719,10 @@
       return Status;
    }
    
-   /* Create symbolic link name: \\?\ACPI#PNP0501#1#{GUID}\ReferenceString */
+   /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
    SymbolicLinkName->Length = 0;
    SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
-      + 4 * sizeof(WCHAR) /* 5 = size of \\??\ */
+      + 4 * sizeof(WCHAR) /* 4 = size of \??\ */
       + InstancePath->Length
       + sizeof(WCHAR)     /* 1  = size of # */
       + GuidString.Length
@@ -725,7 +741,7 @@
       ExFreePool(BaseKeyName.Buffer);
       return STATUS_INSUFFICIENT_RESOURCES;
    }
-   RtlAppendUnicodeToString(SymbolicLinkName, L"\\\\??\\");
+   RtlAppendUnicodeToString(SymbolicLinkName, L"\\??\\");
    StartIndex = SymbolicLinkName->Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
@@ -743,7 +759,8 @@
    SymbolicLinkName->Buffer[SymbolicLinkName->Length] = '\0';
    
    /* Create symbolic link */
-   Status = IoCreateSymbolicLink(SymbolicLinkName, InstancePath);
+   DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
+   Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
    if (!NT_SUCCESS(Status))
    {
       DPRINT("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
@@ -778,7 +795,7 @@
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 
 NTSTATUS STDCALL
@@ -786,7 +803,40 @@
    IN PUNICODE_STRING SymbolicLinkName,
    IN BOOLEAN Enable)
 {
-   DPRINT("IoSetDeviceInterfaceState called (UNIMPLEMENTED)\n");
+   PDEVICE_OBJECT PhysicalDeviceObject;
+   PFILE_OBJECT FileObject;
+   UNICODE_STRING GuidString;
+   PWCHAR StartPosition;
+   PWCHAR EndPosition;
+   NTSTATUS Status;
+   
+   if (SymbolicLinkName == NULL)
+      return STATUS_INVALID_PARAMETER_1;
+   
+   DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable);
+   Status = IoGetDeviceObjectPointer(SymbolicLinkName,
+      0, /* DesiredAccess */
+      &FileObject,
+      &PhysicalDeviceObject);
+   if (!NT_SUCCESS(Status))
+      return Status;
+   
+   /* Symbolic link name is \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
+   /* Get GUID from SymbolicLinkName */
+   StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
+   EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
+   if (!StartPosition ||!EndPosition || StartPosition > EndPosition)
+      return STATUS_INVALID_PARAMETER_1;
+   GuidString.Buffer = StartPosition;
+   GuidString.MaximumLength = GuidString.Length = (ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition;
+   
+   IopNotifyPlugPlayNotification(
+      PhysicalDeviceObject,
+      EventCategoryDeviceInterfaceChange,
+      Enable ? (LPGUID)&GUID_DEVICE_INTERFACE_ARRIVAL : (LPGUID)&GUID_DEVICE_INTERFACE_REMOVAL,
+      &GuidString,
+      (PVOID)SymbolicLinkName);
+   
    return STATUS_SUCCESS;
 }
 

Modified: trunk/reactos/ntoskrnl/io/iomgr.c
--- trunk/reactos/ntoskrnl/io/iomgr.c	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/ntoskrnl/io/iomgr.c	2005-04-30 09:39:09 UTC (rev 14866)
@@ -216,6 +216,7 @@
   IoInitFileSystemImplementation();
   IoInitVpbImplementation();
   IoInitShutdownNotification();
+  IopInitPnpNotificationImplementation();
   IopInitErrorLog();
   IopInitTimerImplementation();
   IopInitIoCompletionImplementation();

Modified: trunk/reactos/ntoskrnl/io/pnpnotify.c
--- trunk/reactos/ntoskrnl/io/pnpnotify.c	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/ntoskrnl/io/pnpnotify.c	2005-04-30 09:39:09 UTC (rev 14866)
@@ -6,13 +6,32 @@
  * PURPOSE:         Plug & Play notification functions
  * 
  * PROGRAMMERS:     Filip Navara (xnavara@volny.cz)
+ *                  HervÚ Poussineau (hpoussin@reactos.com)
  */
 
 /* INCLUDES ******************************************************************/
 
+#define NDEBUG
 #include <ntoskrnl.h>
 #include <internal/debug.h>
 
+/* 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;
+} PNP_NOTIFY_ENTRY, *PPNP_NOTIFY_ENTRY;
+
+static KGUARDED_MUTEX PnpNotifyListLock;
+static LIST_ENTRY PnpNotifyListHead;
+
+#define TAG_PNP_NOTIFY  TAG('P', 'n', 'P', 'N')
+
 /* FUNCTIONS *****************************************************************/
 
 /*
@@ -32,33 +51,262 @@
 }
 
 /*
- * @unimplemented
+ * @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)
+	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)
 {
-  DPRINT("IoRegisterPlugPlayNotification called (UNIMPLEMENTED)\n");
-  return STATUS_NOT_IMPLEMENTED;
+	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 == EventCategoryTargetDeviceChange
+		&& EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
+	{
+		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;
+		}
+		/* FIXME: enumerate SymbolicLinkList */
+		DPRINT1("IoRegisterPlugPlayNotification(): need to send notifications for existing interfaces!\n");
+		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;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 STDCALL
 IoUnregisterPlugPlayNotification(
-  IN PVOID NotificationEntry)
+	IN PVOID NotificationEntry)
 {
-  DPRINT("IoUnregisterPlugPlayNotification called (UNIMPLEMENTED)\n");
-  return STATUS_NOT_IMPLEMENTED;
+	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(
+	IN PDEVICE_OBJECT DeviceObject,
+	IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory,
+	IN GUID* Event,
+	IN PVOID EventCategoryData1,
+	IN PVOID EventCategoryData2)
+{
+	PPNP_NOTIFY_ENTRY ChangeEntry;
+	PLIST_ENTRY Entry;
+	PVOID NotificationStructure;
+	BOOLEAN CallCurrentEntry;
+	
+	ASSERT(DeviceObject);
+	
+	KeAcquireGuardedMutex(&PnpNotifyListLock);
+	if (IsListEmpty(&PnpNotifyListHead))
+	{
+		KeReleaseGuardedMutex(&PnpNotifyListLock);
+		return;
+	}
+	
+	switch (EventCategory)
+	{
+		case EventCategoryDeviceInterfaceChange:
+		{
+			PDEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
+			NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
+				PagedPool,
+				sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION),
+				TAG_PNP_NOTIFY);
+			NotificationInfos->Version = 1;
+			NotificationInfos->Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
+			RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
+			RtlCopyMemory(&NotificationInfos->InterfaceClassGuid, EventCategoryData1, sizeof(GUID));
+			NotificationInfos->SymbolicLinkName = (PUNICODE_STRING)EventCategoryData2;
+			break;
+		}
+		case EventCategoryHardwareProfileChange:
+		{
+			PHWPROFILE_CHANGE_NOTIFICATION NotificationInfos;
+			NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
+				PagedPool,
+				sizeof(HWPROFILE_CHANGE_NOTIFICATION),
+				TAG_PNP_NOTIFY);
+			NotificationInfos->Version = 1;
+			NotificationInfos->Size = sizeof(HWPROFILE_CHANGE_NOTIFICATION);
+			RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
+			break;
+		}
+		case EventCategoryTargetDeviceChange:
+		{
+			PTARGET_DEVICE_REMOVAL_NOTIFICATION NotificationInfos;
+			NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
+				PagedPool,
+				sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION),
+				TAG_PNP_NOTIFY);
+			NotificationInfos->Version = 1;
+			NotificationInfos->Size = sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION);
+			RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
+			NotificationInfos->FileObject = (PFILE_OBJECT)EventCategoryData1;
+			break;
+		}
+		default:
+		{
+			DPRINT1("IopNotifyPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
+			return;
+		}
+	}
+	
+	/* Loop through procedures registred in PnpNotifyListHead
+	 * list to find those that meet some criteria.
+	 */
+	
+	Entry = PnpNotifyListHead.Flink;
+	while (Entry != &PnpNotifyListHead)
+	{
+		ChangeEntry = CONTAINING_RECORD(Entry, PNP_NOTIFY_ENTRY, PnpNotifyList);
+		CallCurrentEntry = FALSE;
+		
+		switch (EventCategory)
+		{
+			case EventCategoryDeviceInterfaceChange:
+			{
+				if (ChangeEntry->EventCategory == EventCategory
+					&& RtlCompareUnicodeString(&ChangeEntry->Guid, (PUNICODE_STRING)EventCategoryData1, FALSE) == 0)
+				{
+					CallCurrentEntry = TRUE;
+				}
+				break;
+			}
+			case EventCategoryHardwareProfileChange:
+			{
+				CallCurrentEntry = TRUE;
+				break;
+			}
+			case EventCategoryTargetDeviceChange:
+			{
+				if (ChangeEntry->FileObject == (PFILE_OBJECT)EventCategoryData1)
+					CallCurrentEntry = TRUE;
+			}
+			default:
+			{
+				DPRINT1("IopNotifyPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
+				break;
+			}
+		}
+		
+		if (CallCurrentEntry)
+		{
+			/* Call entry into new allocated memory */
+			DPRINT("IopNotifyPlugPlayNotification(): found suitable callback %p\n",
+				ChangeEntry);
+			
+			(ChangeEntry->PnpNotificationProc)(
+				NotificationStructure,
+				ChangeEntry->Context);
+		}
+		
+		Entry = Entry->Flink;
+	}
+	KeReleaseGuardedMutex(&PnpNotifyListLock);
+	ExFreePoolWithTag(NotificationStructure, TAG_PNP_NOTIFY);
+}
+
+VOID INIT_FUNCTION
+IopInitPnpNotificationImplementation(VOID)
+{
+	KeInitializeGuardedMutex(&PnpNotifyListLock);
+	InitializeListHead(&PnpNotifyListHead);
+}
+
 /* EOF */

Modified: trunk/reactos/ntoskrnl/io/pnproot.c
--- trunk/reactos/ntoskrnl/io/pnproot.c	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/ntoskrnl/io/pnproot.c	2005-04-30 09:39:09 UTC (rev 14866)
@@ -634,7 +634,7 @@
         sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
         NULL,
         FILE_DEVICE_CONTROLLER,
-        0,
+        FILE_AUTOGENERATED_DEVICE_NAME,
         FALSE,
         &Device->Pdo);
       if (!NT_SUCCESS(Status))
Property changes on: trunk/reactos/ntoskrnl/kd/wrappers
___________________________________________________________________
Name: svn:ignore
   + *.d

Modified: trunk/reactos/ntoskrnl/ob/namespc.c
--- trunk/reactos/ntoskrnl/ob/namespc.c	2005-04-30 05:08:13 UTC (rev 14865)
+++ trunk/reactos/ntoskrnl/ob/namespc.c	2005-04-30 09:39:09 UTC (rev 14866)
@@ -147,7 +147,7 @@
        Object == NULL)
      {
 	RtlFreeUnicodeString(&RemainingPath);
-	return STATUS_UNSUCCESSFUL;
+	return STATUS_OBJECT_NAME_INVALID;
      }
 
    Status = ObCreateHandle(PsGetCurrentProcess(),