[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, ¬ification->entry );
+ if (EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
+ {
+ LIST_FOR_EACH_ENTRY( interf, &Interfaces, struct InterfaceInstance, entry )
+ {
+ if (interf->active && !memcmp( ¬ification->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