[Wine-patches] [eterhack 09/12] ntoskrnl.exe: Add support for PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Чт Май 21 17:53:45 MSD 2009


---
 dlls/ntoskrnl.exe/ntoskrnl.c |   38 ++++++++++++++++++++++++++++++++++++++
 include/ddk/wdm.h            |    2 ++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index b79ddba..638f335 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -104,6 +104,7 @@ struct InterfaceInstance
     WCHAR *link;
     UNICODE_STRING target;
     GUID guid;
+    int active;
 };
 
 static struct list InterfaceChangeNotifications = LIST_INIT(InterfaceChangeNotifications);
@@ -1529,6 +1530,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
                 {
                     RtlInitUnicodeString( &interf->target, target );
                     interf->guid = *InterfaceClassGuid;
+                    interf->active = 0;
                     EnterCriticalSection( &cs );
                     if (!get_registered_interface( interf->link,
                             strlenW(interf->link) ))
@@ -1688,6 +1690,7 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( PUNICODE_STRING SymbolicLinkName,
         }
         LeaveCriticalSection( &cs );
         if (status != STATUS_SUCCESS) return status;
+        interf->active = 1;
         call_interface_change_callbacks( &guid, SymbolicLinkName );
         return STATUS_SUCCESS;
     }
@@ -1900,14 +1903,49 @@ NTSTATUS WINAPI IoRegisterPlugPlayNotification( IO_NOTIFICATION_EVENT_CATEGORY
     {
         struct InterfaceChangeNotification *notification =
                 HeapAlloc( GetProcessHeap(), 0, sizeof(*notification) );
+        struct list interfs = LIST_INIT(interfs);
+        struct InterfaceInstance *interf, *interf2;
+        UNICODE_STRING link;
 
         if (notification == NULL) return STATUS_NO_MEMORY;
         notification->interface_class = *(GUID *)EventCategoryData;
         notification->callback = CallbackRoutine;
         notification->context = Context;
+
         EnterCriticalSection( &cs );
         list_add_tail( &InterfaceChangeNotifications, &notification->entry );
+        if (EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
+        {
+            LIST_FOR_EACH_ENTRY( interf, &Interfaces, struct InterfaceInstance, entry )
+            {
+                if (interf->active && !memcmp( &notification->interface_class,
+                        &interf->guid, sizeof(GUID) ))
+                {
+                    interf2 = HeapAlloc( GetProcessHeap(), 0, sizeof(*interf2) );
+                    if (interf2 == NULL) break;
+                    interf2->link = HeapAlloc( GetProcessHeap(), 0,
+                            (strlenW(interf->link) + 1) * sizeof(WCHAR) );
+                    if (interf2->link == NULL) break;
+                    strcpyW( interf2->link, interf->link );
+                    interf2->guid = interf->guid;
+                    list_add_tail( &interfs, &interf2->entry );
+                }
+            }
+        }
         LeaveCriticalSection( &cs );
+
+        LIST_FOR_EACH_ENTRY_SAFE( interf, interf2, &interfs,
+                struct InterfaceInstance, entry )
+        {
+            list_remove( &interf->entry );
+            if (interf->link)
+            {
+                RtlInitUnicodeString( &link, interf->link );
+                call_interface_change_callbacks( &interf->guid, &link );
+                HeapFree( GetProcessHeap(), 0, interf->link );
+            }
+            HeapFree( GetProcessHeap(), 0, interf );
+        }
         *NotificationEntry = notification;
         return STATUS_SUCCESS;
     }
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index ce530b9..c8608fe 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1096,6 +1096,8 @@ typedef enum _IO_NOTIFICATION_EVENT_CATEGORY {
     EventCategoryTargetDeviceChange
 } IO_NOTIFICATION_EVENT_CATEGORY;
 
+#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES 0x00000001
+
 typedef struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION {
     USHORT Version;
     USHORT Size;
-- 
1.6.2.5



Подробная информация о списке рассылки Wine-patches