First attempt at implementing NtGetPlugPlayEvent.
Modified: trunk/reactos/include/ntos/zw.h
Modified: trunk/reactos/ntoskrnl/include/internal/io.h
Modified: trunk/reactos/ntoskrnl/io/plugplay.c
Modified: trunk/reactos/ntoskrnl/io/pnpmgr.c

Modified: trunk/reactos/include/ntos/zw.h
--- trunk/reactos/include/ntos/zw.h	2005-02-01 16:15:24 UTC (rev 13376)
+++ trunk/reactos/include/ntos/zw.h	2005-02-01 16:24:10 UTC (rev 13377)
@@ -2702,7 +2702,7 @@
 	  FileNamesInformation			FILE_NAMES_INFORMATION
 	  FileDispositionInformation		FILE_DISPOSITION_INFORMATION
 	  FilePositionInformation		FILE_POSITION_INFORMATION
-	  FileFullEaInformation			FILE_FULL_EA_INFORMATION		
+	  FileFullEaInformation			FILE_FULL_EA_INFORMATION
 	  FileModeInformation			FILE_MODE_INFORMATION
 	  FileAlignmentInformation		FILE_ALIGNMENT_INFORMATION
 	  FileAllInformation			FILE_ALL_INFORMATION
@@ -2715,7 +2715,7 @@
 	  FilePipeRemoteInformation		
 	  FileMailslotQueryInformation		
 	  FileMailslotSetInformation		
-	  FileCompressionInformation		FILE_COMPRESSION_INFORMATION		
+	  FileCompressionInformation		FILE_COMPRESSION_INFORMATION
 	  FileCopyOnWriteInformation		
 	  FileCompletionInformation 		IO_COMPLETION_CONTEXT
 	  FileMoveClusterInformation		
@@ -2728,7 +2728,7 @@
 	  FileContentIndexInformation		
 	  FileInheritContentIndexInformation	
 	  FileOleInformation			
-	  FileMaximumInformation			
+	  FileMaximumInformation		
 
  * REMARK:
  *	  This procedure maps to the win32 GetShortPathName, GetLongPathName,
@@ -4933,16 +4933,16 @@
 
 NTSTATUS
 STDCALL
-NtPlugPlayControl (DWORD Unknown1,
-                   DWORD Unknown2,
-                   DWORD Unknown3);
+NtPlugPlayControl(IN ULONG ControlCode,
+                  IN OUT PVOID Buffer,
+                  IN ULONG BufferLength);
 
 NTSTATUS
 STDCALL
-NtGetPlugPlayEvent (ULONG Reserved1,
-                    ULONG Reserved2,
-                    PVOID Buffer,
-                    ULONG BufferLength);
+NtGetPlugPlayEvent(IN ULONG Reserved1,
+                   IN ULONG Reserved2,
+                   OUT PVOID Buffer,
+                   IN ULONG BufferLength);
 
 /* --- POWER MANAGEMENT --- */
 
@@ -5027,12 +5027,6 @@
 		 ULONG Selector2,
 		 LDT_ENTRY LdtEntry2);
 
-NTSTATUS
-STDCALL
-NtQueryOleDirectoryFile (
-	VOID
-	);
-
 /*
  * FUNCTION: Checks a clients access rights to a object
  * ARGUMENTS: 

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
--- trunk/reactos/ntoskrnl/include/internal/io.h	2005-02-01 16:15:24 UTC (rev 13376)
+++ trunk/reactos/ntoskrnl/include/internal/io.h	2005-02-01 16:24:10 UTC (rev 13377)
@@ -500,6 +500,13 @@
 VOID FASTCALL
 IopReinitializeDrivers(VOID);
 
+
+/* pnpevent.c */
+
+NTSTATUS INIT_FUNCTION
+IopInitPlugPlayEvents(VOID);
+
+
 /* pnpmgr.c */
 
 NTSTATUS

Modified: trunk/reactos/ntoskrnl/io/plugplay.c
--- trunk/reactos/ntoskrnl/io/plugplay.c	2005-02-01 16:15:24 UTC (rev 13376)
+++ trunk/reactos/ntoskrnl/io/plugplay.c	2005-02-01 16:24:10 UTC (rev 13377)
@@ -1,9 +1,9 @@
-/* $Id:$
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/plugplay.c
- * PURPOSE:         Mysterious nt4 support for plug-and-play
+ * PURPOSE:         Plug-and-play interface routines
  * 
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  */
@@ -11,27 +11,129 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+
+#define NDEBUG
 #include <internal/debug.h>
 
+
+/* GLOBALS *******************************************************************/
+
+static LIST_ENTRY IopPnpEventListHead;
+static KEVENT IopPnpNotifyEvent;
+
+
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS
-STDCALL
-NtPlugPlayControl (DWORD Unknown1,
-                   DWORD Unknown2,
-                   DWORD Unknown3)
+NTSTATUS INIT_FUNCTION
+IopInitPlugPlayEvents(VOID)
 {
-   UNIMPLEMENTED;
-   return(STATUS_NOT_IMPLEMENTED);
+
+  InitializeListHead(&IopPnpEventListHead);
+
+  KeInitializeEvent(&IopPnpNotifyEvent,
+		    NotificationEvent,
+		    FALSE);
+
+  return STATUS_SUCCESS;
 }
 
-NTSTATUS
-STDCALL
-NtGetPlugPlayEvent (ULONG Reserved1,
-                    ULONG Reserved2,
-                    PVOID Buffer,
-                    ULONG BufferLength)
+
+#if 0
+/* Insert a new pnp event at the head of the event queue */
+VOID
+IopEnqueuePlugPlayEvent(VOID)
 {
-   UNIMPLEMENTED;
-   return(STATUS_NOT_IMPLEMENTED);
+
 }
+#endif
+
+
+#if 0
+/*
+ * Remove the current PnP event from the tail of the event queue
+ * and signal IopPnpNotifyEvent if there is yet another event in the queue.
+ */
+VOID
+IopDequeuePlugPlayEvent(VOID)
+{
+
+}
+#endif
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtGetPlugPlayEvent(IN ULONG Reserved1,
+                   IN ULONG Reserved2,
+                   OUT PVOID Buffer,
+                   IN ULONG BufferLength)
+{
+  NTSTATUS Status;
+
+  DPRINT("NtGetPlugPlayEvent() called\n");
+
+  /* Function can only be called from user-mode */
+  if (KeGetPreviousMode() != UserMode)
+  {
+    DPRINT1("NtGetPlugPlayEvent cannot be called from kernel mode!\n");
+    return STATUS_ACCESS_DENIED;
+  }
+
+  /* Check for Tcb privilege */
+  if (!SeSinglePrivilegeCheck(SeTcbPrivilege,
+                              UserMode))
+  {
+    DPRINT1("NtGetPlugPlayEvent: Caller requires 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))
+  {
+    DPRINT("Waiting done\n");
+
+#if 0
+    /* Get entry from the tail of the list */
+    Entry = IopPnpEventListHead.Blink;
+
+    /* Check the buffer size */
+    if (BufferLength < Entry->Event.Size)
+    {
+      DPRINT1("Buffer is too small for the pnp-event\n");
+      return STATUS_BUFFER_TOO_SMALL;
+    }
+
+    /* Copy event data to user buffer */
+    memcpy(Buffer,
+           &Entry->Event,
+           &Entry->Event.Size);
+#endif
+  }
+
+  DPRINT("NtGetPlugPlayEvent() done\n");
+
+  return Status;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtPlugPlayControl(IN ULONG ControlCode,
+                  IN OUT PVOID Buffer,
+                  IN ULONG BufferLength)
+{
+  UNIMPLEMENTED;
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+/* EOF */

Modified: trunk/reactos/ntoskrnl/io/pnpmgr.c
--- trunk/reactos/ntoskrnl/io/pnpmgr.c	2005-02-01 16:15:24 UTC (rev 13376)
+++ trunk/reactos/ntoskrnl/io/pnpmgr.c	2005-02-01 16:24:10 UTC (rev 13377)
@@ -481,7 +481,7 @@
   return STATUS_UNSUCCESSFUL;
 }
 
-/**********************************************************************
+/*
  * DESCRIPTION
  * 	Creates a device node
  *
@@ -1556,7 +1556,6 @@
  * parent node. This function just calls IopActionInitChildServices with
  * BootDrivers = TRUE.
  */
-
 NTSTATUS
 IopActionInitBootServices(
    PDEVICE_NODE DeviceNode,
@@ -1581,7 +1580,6 @@
  * Return Value
  *    Status
  */
-
 NTSTATUS
 IopInitializePnpServices(
    IN PDEVICE_NODE DeviceNode,
@@ -1768,6 +1766,14 @@
 
    KeInitializeSpinLock(&IopDeviceTreeLock);
 
+   /* Initialize PnP-Event notification support */
+   Status = IopInitPlugPlayEvents();
+   if (!NT_SUCCESS(Status))
+   {
+      CPRINT("IopInitPlugPlayEvents() failed\n");
+      KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+   }
+
    /*
     * Create root device node
     */