From: Vibhav Pant vibhavp@gmail.com
--- dlls/ntoskrnl.exe/pnp.c | 51 ++++++++++++++++++++++++++-- dlls/ntoskrnl.exe/tests/driver_pnp.c | 2 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 8 ++--- 3 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index b330a0eacc6..13e6005c239 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -1001,10 +1001,55 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla return status; }
-NTSTATUS WINAPI IoReportTargetDeviceChange( DEVICE_OBJECT *pdo, void *notification ) +/*********************************************************************** + * IoReportTargetDeviceChange (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI IoReportTargetDeviceChange( DEVICE_OBJECT *pdo, VOID *n ) { - FIXME( "(%p, %p) stub!\n", pdo, notification ); - return STATUS_NOT_SUPPORTED; + OBJECT_NAME_INFORMATION *name_info; + DEV_BROADCAST_HANDLE *event_handle; + DWORD data_size; + TARGET_DEVICE_CUSTOM_NOTIFICATION *notification = n; + ULONG size; + NTSTATUS ret; + + TRACE( "(%p, %p)\n", pdo, n ); + + if (notification->Version != 1) + return STATUS_INVALID_PARAMETER; + + ret = ObQueryNameString( pdo, NULL, 0, &size ); + if (ret != STATUS_INFO_LENGTH_MISMATCH) + return ret; + + name_info = heap_alloc( size ); + if (!name_info) + return STATUS_NO_MEMORY; + + ret = ObQueryNameString( pdo, name_info, size, &size ); + if (ret != STATUS_SUCCESS) return ret; + + data_size = notification->Size - offsetof(TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer); + if (notification->NameBufferOffset != -1 && notification->CustomDataBuffer[data_size - 1] != '\0') + data_size++; + event_handle = heap_alloc_zero( offsetof( DEV_BROADCAST_HANDLE, dbch_data[data_size] ) ); + if (!event_handle) + { + heap_free( name_info ); + return STATUS_NO_MEMORY; + } + event_handle->dbch_size = offsetof( DEV_BROADCAST_HANDLE, dbch_data[data_size] ); + event_handle->dbch_devicetype = DBT_DEVTYP_HANDLE; + event_handle->dbch_eventguid = notification->Event; + event_handle->dbch_nameoffset = notification->NameBufferOffset; + memcpy( event_handle->dbch_data, notification->CustomDataBuffer, + notification->Size - + offsetof( TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer[1] ) ); + send_devicechange( DBT_CUSTOMEVENT, name_info->Name.Buffer, (BYTE *)event_handle, event_handle->dbch_size ); + heap_free( event_handle ); + heap_free( name_info ); + + return STATUS_SUCCESS; }
/*********************************************************************** diff --git a/dlls/ntoskrnl.exe/tests/driver_pnp.c b/dlls/ntoskrnl.exe/tests/driver_pnp.c index e79edae7125..210da969bfc 100644 --- a/dlls/ntoskrnl.exe/tests/driver_pnp.c +++ b/dlls/ntoskrnl.exe/tests/driver_pnp.c @@ -722,7 +722,7 @@ static void test_devicechange( DEVICE_OBJECT *obj ) notif->NameBufferOffset = -1;
status = IoReportTargetDeviceChange( obj, notif ); - todo_wine ok( status == STATUS_SUCCESS, "IoReportTargetDeviceChange failed, status %#lx size %d,\n", status, notif->Size ); + ok( status == STATUS_SUCCESS, "IoReportTargetDeviceChange failed, status %#lx size %d,\n", status, notif->Size ); ExFreePool( notif ); winetest_pop_context(); } diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index ea011e9e397..ff707186c15 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1587,15 +1587,15 @@ static void test_pnp_devices(void)
filter_handle.dbch_handle = bus; notify_handle_custom = RegisterDeviceNotificationA(window, &filter_handle, 0); - todo_wine ok(!!notify_handle_custom, "failed to register for device notifications, error %lu\n", GetLastError()); + ok(!!notify_handle_custom, "failed to register for device notifications, error %lu\n", GetLastError());
ret = DeviceIoControl(bus, IOCTL_WINETEST_BUS_MAIN, NULL, 0, NULL, 0, &size, NULL); ok(ret, "got error %lu\n", GetLastError()); for (i = 0; i < ARRAY_SIZE(custom_events); i++) pump_messages(); - todo_wine ok(got_custom_event == ARRAY_SIZE(custom_events), - "got %u custom event messages, expected %d\n", got_custom_event, - (int)ARRAY_SIZE(custom_events)); + ok(got_custom_event == ARRAY_SIZE(custom_events), + "got %u custom event messages, expected %d\n", got_custom_event, + (int)ARRAY_SIZE(custom_events));
/* Test IoRegisterDeviceInterface() and IoSetDeviceInterfaceState(). */