[ros-diffs] [pschweitzer] 44288: Implemented IoReportTargetDeviceChangeAsynchronous and IoReportTargetDeviceChange

pschweitzer at svn.reactos.org pschweitzer at svn.reactos.org
Thu Nov 26 11:31:19 CET 2009


Author: pschweitzer
Date: Thu Nov 26 11:31:19 2009
New Revision: 44288

URL: http://svn.reactos.org/svn/reactos?rev=44288&view=rev
Log:
Implemented IoReportTargetDeviceChangeAsynchronous and IoReportTargetDeviceChange

Modified:
    branches/arty-newcc/ntoskrnl/include/internal/io.h
    branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpreport.c

Modified: branches/arty-newcc/ntoskrnl/include/internal/io.h
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/include/internal/io.h?rev=44288&r1=44287&r2=44288&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/include/internal/io.h [iso-8859-1] Thu Nov 26 11:31:19 2009
@@ -490,6 +490,18 @@
 } DEVICETREE_TRAVERSE_CONTEXT, *PDEVICETREE_TRAVERSE_CONTEXT;
 
 //
+// Internal structure for notifications
+//
+typedef struct _INTERNAL_WORK_QUEUE_ITEM
+{
+  WORK_QUEUE_ITEM WorkItem;
+  PDEVICE_OBJECT PhysicalDeviceObject;
+  PDEVICE_CHANGE_COMPLETE_CALLBACK Callback;
+  PVOID Context;
+  PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure;
+} INTERNAL_WORK_QUEUE_ITEM, *PINTERNAL_WORK_QUEUE_ITEM;
+
+//
 // PNP Routines
 //
 VOID
@@ -506,6 +518,16 @@
 VOID
 PnpInit2(
     VOID
+);
+
+NTSTATUS
+PpSetCustomTargetEvent(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN OUT PKEVENT NotifyEvent,
+    IN OUT PNTSTATUS NotifyStatus,
+    IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback,
+    IN PVOID Context,
+    IN PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure
 );
 
 VOID
@@ -613,6 +635,9 @@
 IopGetRegistryValue(IN HANDLE Handle,
                     IN PWSTR ValueName,
                     OUT PKEY_VALUE_FULL_INFORMATION *Information);
+
+VOID
+IopReportTargetDeviceChangeAsyncWorker(PVOID Context);
 
 
 //

Modified: branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpreport.c
URL: http://svn.reactos.org/svn/reactos/branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpreport.c?rev=44288&r1=44287&r2=44288&view=diff
==============================================================================
--- branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] (original)
+++ branches/arty-newcc/ntoskrnl/io/pnpmgr/pnpreport.c [iso-8859-1] Thu Nov 26 11:31:19 2009
@@ -4,6 +4,7 @@
  * FILE:            ntoskrnl/io/pnpmgr/pnpreport.c
  * PURPOSE:         Device Changes Reporting Functions
  * PROGRAMMERS:     Filip Navara (xnavara at volny.cz)
+ *                  Pierre Schweitzer
  */
 
 /* INCLUDES ******************************************************************/
@@ -11,6 +12,34 @@
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <debug.h>
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+NTSTATUS
+PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
+                       IN OUT PKEVENT NotifyEvent,
+                       IN OUT PNTSTATUS NotifyStatus,
+                       IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback,
+                       IN PVOID Context,
+                       IN PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationStructure)
+{
+  ASSERT(NotificationStructure);
+  ASSERT(DeviceObject);
+
+  UNIMPLEMENTED;
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+VOID
+IopReportTargetDeviceChangeAsyncWorker(PVOID Context)
+{
+  PINTERNAL_WORK_QUEUE_ITEM Item;
+
+  Item = (PINTERNAL_WORK_QUEUE_ITEM)Context;
+  PpSetCustomTargetEvent(Item->PhysicalDeviceObject, NULL, NULL, Item->Callback, Item->Context, Item->NotificationStructure);
+  ObDereferenceObject(Item->PhysicalDeviceObject);
+  ExFreePoolWithTag(Context, '  pP');
+}
 
 /* PUBLIC FUNCTIONS **********************************************************/
 
@@ -112,35 +141,54 @@
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 NTAPI
 IoReportTargetDeviceChange(IN PDEVICE_OBJECT PhysicalDeviceObject,
                            IN PVOID NotificationStructure)
 {
-	PTARGET_DEVICE_CUSTOM_NOTIFICATION IntNotificationStructure;
- 
-	ASSERT(NotificationStructure);
- 
-	if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject))
-	{
-		KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0);
-	}
- 
-	IntNotificationStructure = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure;
-	if ((RtlCompareMemory(&(IntNotificationStructure->Event), &(GUID_TARGET_DEVICE_QUERY_REMOVE), sizeof(GUID))) ||
-		(RtlCompareMemory(&(IntNotificationStructure->Event), &(GUID_TARGET_DEVICE_REMOVE_CANCELLED), sizeof(GUID))) ||
-		(RtlCompareMemory(&(IntNotificationStructure->Event), &(GUID_TARGET_DEVICE_REMOVE_COMPLETE), sizeof(GUID))))
-	{
-		return STATUS_INVALID_DEVICE_REQUEST;
-	}
- 
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-/*
- * @unimplemented
+  KEVENT NotifyEvent;
+  NTSTATUS Status, NotifyStatus;
+  PTARGET_DEVICE_CUSTOM_NOTIFICATION notifyStruct = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure;
+
+  ASSERT(notifyStruct);
+
+  /* Check for valid PDO */
+  if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject))
+  {
+    KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0);
+  }
+
+  /* FileObject must be null. PnP will fill in it */
+  ASSERT(notifyStruct->FileObject == NULL);
+
+  /* Do not handle system PnP events */
+  if ((RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_QUERY_REMOVE), sizeof(GUID)) != sizeof(GUID)) ||
+      (RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_CANCELLED), sizeof(GUID)) != sizeof(GUID)) ||
+      (RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_COMPLETE), sizeof(GUID)) != sizeof(GUID)))
+  {
+    return STATUS_INVALID_DEVICE_REQUEST;
+  }
+
+  /* FIXME: Other checks to do on notify struct */
+
+  /* Initialize even that will let us know when PnP will have finished notify */
+  KeInitializeEvent(&NotifyEvent, NotificationEvent, FALSE);
+
+  Status = PpSetCustomTargetEvent(PhysicalDeviceObject, &NotifyEvent, &NotifyStatus, NULL, NULL, notifyStruct);
+  /* If no error, wait for the notify to end and return the status of the notify and not of the event */
+  if (NT_SUCCESS(Status))
+  {
+    KeWaitForSingleObject(&NotifyEvent, Executive, KernelMode, FALSE, NULL);
+    Status = NotifyStatus;
+  }
+
+  return Status;
+}
+
+/*
+ * @implemented
  */
 NTSTATUS
 NTAPI
@@ -149,6 +197,47 @@
                                        IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL,
                                        IN PVOID Context OPTIONAL)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
+  PINTERNAL_WORK_QUEUE_ITEM Item = NULL;
+  PTARGET_DEVICE_CUSTOM_NOTIFICATION notifyStruct = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)NotificationStructure;
+
+  ASSERT(notifyStruct);
+
+  /* Check for valid PDO */
+  if (!IopIsValidPhysicalDeviceObject(PhysicalDeviceObject))
+  {
+    KeBugCheckEx(PNP_DETECTED_FATAL_ERROR, 0x2, (ULONG)PhysicalDeviceObject, 0, 0);
+  }
+
+  /* FileObject must be null. PnP will fill in it */
+  ASSERT(notifyStruct->FileObject == NULL);
+
+  /* Do not handle system PnP events */
+  if ((RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_QUERY_REMOVE), sizeof(GUID)) != sizeof(GUID)) ||
+      (RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_CANCELLED), sizeof(GUID)) != sizeof(GUID)) ||
+      (RtlCompareMemory(&(notifyStruct->Event), &(GUID_TARGET_DEVICE_REMOVE_COMPLETE), sizeof(GUID)) != sizeof(GUID)))
+  {
+    return STATUS_INVALID_DEVICE_REQUEST;
+  }
+
+  /* FIXME: Other checks to do on notify struct */
+
+  /* We need to store all the data given by the caller with the WorkItem, so use our own struct */
+  Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(INTERNAL_WORK_QUEUE_ITEM), '  pP');
+  if (!Item)
+  {
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
+
+  /* Initialize all stuff */
+  ObReferenceObject(PhysicalDeviceObject);
+  Item->NotificationStructure = notifyStruct;
+  Item->PhysicalDeviceObject = PhysicalDeviceObject;
+  Item->Callback = Callback;
+  Item->Context = Context;
+  ExInitializeWorkItem(&(Item->WorkItem), (PWORKER_THREAD_ROUTINE)IopReportTargetDeviceChangeAsyncWorker, Item);
+
+  /* Finally, queue the item, our work here is done */
+  ExQueueWorkItem(&(Item->WorkItem), DelayedWorkQueue);
+
+  return STATUS_PENDING;
+}




More information about the Ros-diffs mailing list