[PATCH v4 4/5] ntoskrnl.exe: Send WM_DEVICECHANGE messages to handles that have registered
Micah N Gorrell
mgorrell at codeweavers.com
Thu May 30 16:41:16 CDT 2019
Signed-off-by: Micah N Gorrell <mgorrell at codeweavers.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 54 ++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index b5d89f6ee5..dad89016ab 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1712,6 +1712,45 @@ static NTSTATUS create_device_symlink( DEVICE_OBJECT *device, UNICODE_STRING *sy
return ret;
}
+/*******************************************************************
+ * list_device_notifications
+ *
+ * Build an array of windows which have been registered to receive device
+ * notifications. The array must be freed with HeapFree. Returns NULL when no
+ * registered windows are found.
+ */
+static HWND *list_device_notifications( void )
+{
+ HWND *list;
+ int i, count, size = 128;
+
+ for (;;)
+ {
+ count = 0;
+
+ if (!(list = heap_alloc( size * sizeof(HWND) ))) break;
+
+ SERVER_START_REQ( get_device_notifications )
+ {
+ wine_server_set_reply( req, list, (size-1) * sizeof(user_handle_t) );
+ if (!wine_server_call( req )) count = reply->count;
+ }
+ SERVER_END_REQ;
+ if (count && count < size)
+ {
+ /* start from the end since HWND is potentially larger than user_handle_t */
+ for (i = count - 1; i >= 0; i--)
+ list[i] = wine_server_ptr_handle( ((user_handle_t *)list)[i] );
+ list[count] = 0;
+ return list;
+ }
+ heap_free( list );
+ if (!count) break;
+ size = count + 1; /* restart with a large enough buffer */
+ }
+ return NULL;
+}
+
/***********************************************************************
* IoSetDeviceInterfaceState (NTOSKRNL.EXE.@)
*/
@@ -1739,6 +1778,8 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable
NTSTATUS ret;
GUID class;
ULONG len;
+ HWND *registrations;
+ unsigned int i;
TRACE("(%s, %d)\n", debugstr_us(name), enable);
@@ -1822,6 +1863,19 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( UNICODE_STRING *name, BOOLEAN enable
BroadcastSystemMessageW( BSF_FORCEIFHUNG | BSF_QUERY, NULL, WM_DEVICECHANGE,
enable ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, (LPARAM)broadcast );
+ if ((registrations = list_device_notifications( )))
+ {
+ for (i = 0; registrations[i]; i++)
+ {
+ TRACE("Sending WM_DEVICECHANGE to registered window %p\n", registrations[i]);
+ SendMessageTimeoutW( registrations[i], WM_DEVICECHANGE,
+ enable ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
+ (LPARAM)broadcast, SMTO_ABORTIFHUNG, 2000, NULL );
+ }
+
+ heap_free( registrations );
+ }
+
heap_free( broadcast );
}
return ret;
--
2.21.0
More information about the wine-devel
mailing list