From: Vibhav Pant vibhavp@gmail.com
--- dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- dlls/ntoskrnl.exe/pnp.c | 60 +++++++++++++++++++++++++++++ include/ddk/wdm.h | 10 +++++ 3 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index e9ad2aa7e74..690b4e166c3 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -465,7 +465,7 @@ @ stub IoReportHalResourceUsage @ stdcall IoReportResourceForDetection(ptr ptr long ptr ptr long ptr) @ stdcall IoReportResourceUsage(ptr ptr ptr long ptr ptr long long ptr) -@ stub IoReportTargetDeviceChange +@ stdcall IoReportTargetDeviceChange(ptr ptr) @ stub IoReportTargetDeviceChangeAsynchronous @ stub IoRequestDeviceEject @ stdcall IoReuseIrp(ptr long) diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index cbd5cf6ff2a..16837c9cd57 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -1001,6 +1001,66 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(DEVICE_OBJECT *device, const GUID *cla return status; }
+/*********************************************************************** + * IoReportTargetDeviceChange (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI IoReportTargetDeviceChange( DEVICE_OBJECT *pdo, VOID *n ) +{ + OBJECT_NAME_INFORMATION *name_info; + DEV_BROADCAST_HANDLE *event_handle; + DWORD custom_buf_size, 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; + + custom_buf_size = notification->Size - offsetof(TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer) + 1; + data_size = custom_buf_size + name_info->Name.Length * sizeof( WCHAR ) + 1; + if (notification->NameBufferOffset != -1 && notification->CustomDataBuffer[custom_buf_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, custom_buf_size ); + if (notification->NameBufferOffset != -1 && notification->CustomDataBuffer[custom_buf_size - 1] != '\0') + notification->CustomDataBuffer[custom_buf_size++] = '\0'; + + memcpy( &event_handle->dbch_data[custom_buf_size], name_info->Name.Buffer, + name_info->Name.Length * sizeof( WCHAR ) + 1); + event_handle->dbch_reserved = custom_buf_size; + heap_free( name_info ); + + /* TODO: Note that this is not really synchronous. This will merely queue up an event in the + * plugplay service, which will be asynchronously broadcast to all listeners. */ + send_devicechange( DBT_CUSTOMEVENT, (BYTE *)event_handle, event_handle->dbch_size ); + heap_free( event_handle ); + + return STATUS_SUCCESS; +} + /*********************************************************************** * IoOpenDeviceRegistryKey (NTOSKRNL.EXE.@) */ diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index e0c21d0ccfd..23ac13018e7 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1613,6 +1613,15 @@ typedef enum _DIRECTORY_NOTIFY_INFORMATION_CLASS { DirectoryNotifyExtendedInformation } DIRECTORY_NOTIFY_INFORMATION_CLASS, *PDIRECTORY_NOTIFY_INFORMATION_CLASS;
+typedef struct _TARGET_DEVICE_CUSTOM_NOTIFICATION { + USHORT Version; + USHORT Size; + GUID Event; + FILE_OBJECT *FileObject; + LONG NameBufferOffset; + UCHAR CustomDataBuffer[1]; +} TARGET_DEVICE_CUSTOM_NOTIFICATION, *PTARGET_DEVICE_CUSTOM_NOTIFICATION; + typedef enum _WORK_QUEUE_TYPE { CriticalWorkQueue, DelayedWorkQueue, @@ -1781,6 +1790,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface(PDEVICE_OBJECT,const GUID*,PUNICODE_S void WINAPI IoReleaseCancelSpinLock(KIRQL); void WINAPI IoReleaseRemoveLockAndWaitEx(IO_REMOVE_LOCK*,void*,ULONG); void WINAPI IoReleaseRemoveLockEx(IO_REMOVE_LOCK*,void*,ULONG); +NTSTATUS WINAPI IoReportTargetDeviceChange(DEVICE_OBJECT *, VOID *); void WINAPI IoReuseIrp(IRP*,NTSTATUS); NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN); NTSTATUS WINAPI IoSetDevicePropertyData(DEVICE_OBJECT*,const DEVPROPKEY*,LCID,ULONG,DEVPROPTYPE,ULONG,void*);