[UMPNPMGR][ADVAPI32][SERVICES] Pass PNP events to the service manager

- umpnpmgr.dll: Call I_ScSendPnPMessage to report pnp events to the service manager.
- adavpi32.dll: Implement I_ScSendPnPMessage which calls the service managers RI_ScSendPnPMessage function.
- services.exe: Add a debug message to RI_ScSendPnPMessage.
This commit is contained in:
Eric Kohl 2025-05-11 14:25:15 +02:00
parent 00b5dc8b49
commit d32fd58722
7 changed files with 99 additions and 28 deletions

View file

@ -121,8 +121,9 @@ ProcessDeviceClassChangeEvent(
RPC_STATUS RpcStatus; RPC_STATUS RpcStatus;
PLIST_ENTRY Current; PLIST_ENTRY Current;
PNOTIFY_ENTRY pNotifyData; PNOTIFY_ENTRY pNotifyData;
PDEV_BROADCAST_DEVICEINTERFACE_W pData; PDEV_BROADCAST_DEVICEINTERFACE_W pEventData;
DWORD dwSize; DWORD dwSize;
DWORD dwEventType;
DPRINT("ProcessDeviceClassChangeEvent(%p)\n", PnpEvent); DPRINT("ProcessDeviceClassChangeEvent(%p)\n", PnpEvent);
DPRINT("SymbolicLink: %S\n", PnpEvent->DeviceClass.SymbolicLinkName); DPRINT("SymbolicLink: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
@ -142,33 +143,45 @@ ProcessDeviceClassChangeEvent(
((pNotifyData->ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) || ((pNotifyData->ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) ||
(UuidEqual(&PnpEvent->DeviceClass.ClassGuid, &pNotifyData->ClassGuid, &RpcStatus)))) (UuidEqual(&PnpEvent->DeviceClass.ClassGuid, &pNotifyData->ClassGuid, &RpcStatus))))
{ {
if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_ARRIVAL, &RpcStatus))
{
DPRINT("Interface arrival: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
dwEventType = DBT_DEVICEARRIVAL;
}
else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_REMOVAL, &RpcStatus))
{
DPRINT("Interface removal: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
dwEventType = DBT_DEVICEREMOVECOMPLETE;
}
else
{
dwEventType = 0;
}
dwSize = sizeof(DEV_BROADCAST_DEVICEINTERFACE_W) + wcslen(PnpEvent->DeviceClass.SymbolicLinkName) * sizeof(WCHAR);
pEventData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if (pEventData)
{
pEventData->dbcc_size = dwSize;
pEventData->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
CopyMemory(&pEventData->dbcc_classguid, &PnpEvent->DeviceClass.ClassGuid, sizeof(GUID));
wcscpy(pEventData->dbcc_name, PnpEvent->DeviceClass.SymbolicLinkName);
}
if ((pNotifyData->ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE) if ((pNotifyData->ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
{ {
dwSize = sizeof(DEV_BROADCAST_DEVICEINTERFACE_W) + wcslen(PnpEvent->DeviceClass.SymbolicLinkName) * sizeof(WCHAR); SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, (WPARAM)dwEventType, (LPARAM)pEventData);
pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
pData->dbcc_size = dwSize;
pData->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
CopyMemory(&pData->dbcc_classguid, &PnpEvent->DeviceClass.ClassGuid, sizeof(GUID));
wcscpy(pData->dbcc_name, PnpEvent->DeviceClass.SymbolicLinkName);
if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_ARRIVAL, &RpcStatus))
{
DPRINT("Interface arrival: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, DBT_DEVICEARRIVAL, (LPARAM)pData);
}
else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_REMOVAL, &RpcStatus))
{
DPRINT("Interface removal: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, DBT_DEVICEREMOVECOMPLETE, (LPARAM)pData);
}
HeapFree(GetProcessHeap(), 0, pData);
} }
else if ((pNotifyData->ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE) else if ((pNotifyData->ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE)
{ {
DPRINT1("Service notification is not implemented yet!\n"); I_ScSendPnPMessage((SERVICE_STATUS_HANDLE)pNotifyData->hRecipient,
SERVICE_CONTROL_DEVICEEVENT,
dwEventType,
pEventData);
} }
if (pEventData)
HeapFree(GetProcessHeap(), 0, pEventData);
} }
Current = Current->Flink; Current = Current->Flink;

View file

@ -6715,10 +6715,16 @@ RControlServiceExW(
/* Function 52 */ /* Function 52 */
DWORD DWORD
WINAPI WINAPI
RSendPnPMessage( RI_ScSendPnPMessage(
handle_t BindingHandle) /* FIXME */ _In_ RPC_SERVICE_STATUS_HANDLE hServiceStatus,
_In_ DWORD dwControl,
_In_ DWORD dwEventType,
_In_ DWORD dwEventSize,
_In_ LPBYTE pEventData)
{ {
UNIMPLEMENTED; DPRINT1("RI_ScSendPnPMessage(%p %lx %lu %lu %p)\n",
hServiceStatus, dwControl, dwEventType, dwEventSize, pEventData);
return ERROR_CALL_NOT_IMPLEMENTED; return ERROR_CALL_NOT_IMPLEMENTED;
} }

View file

@ -39,6 +39,8 @@
#include <seclogon_c.h> #include <seclogon_c.h>
#include <svcctl_c.h> #include <svcctl_c.h>
#include <winreg_c.h> #include <winreg_c.h>
#include <dbt.h>
// #include <winsvc_undoc.h>
#include <wine/debug.h> #include <wine/debug.h>
#include <wine/unicode.h> #include <wine/unicode.h>

View file

@ -306,6 +306,7 @@
@ stdcall I_QueryTagInformation(ptr long ptr) @ stdcall I_QueryTagInformation(ptr long ptr)
@ stdcall I_ScIsSecurityProcess() @ stdcall I_ScIsSecurityProcess()
@ stdcall I_ScPnPGetServiceName(ptr wstr long) @ stdcall I_ScPnPGetServiceName(ptr wstr long)
@ stdcall I_ScSendPnPMessage(ptr long long ptr)
@ stub I_ScSendTSMessage @ stub I_ScSendTSMessage
@ stdcall I_ScSetServiceBitsA(ptr long long long str) @ stdcall I_ScSetServiceBitsA(ptr long long long str)
@ stdcall I_ScSetServiceBitsW(ptr long long long wstr) @ stdcall I_ScSetServiceBitsW(ptr long long long wstr)

View file

@ -1617,6 +1617,45 @@ EnumServicesStatusExW(SC_HANDLE hSCManager,
} }
/**********************************************************************
* I_ScSendPnPMessage
*
* Undocumented
*
* @unimplemented
*/
BOOL
WINAPI
I_ScSendPnPMessage(
_In_ SERVICE_STATUS_HANDLE hServiceStatus,
_In_ DWORD dwControlCode,
_In_ DWORD dwEventType,
_In_ PVOID pEventData)
{
BOOL bResult;
TRACE("I_ScSendPnPMessage(%p %lu %lu %p)\n",
hServiceStatus, dwControlCode, dwEventType, pEventData);
RpcTryExcept
{
bResult = RI_ScSendPnPMessage((RPC_SERVICE_STATUS_HANDLE)hServiceStatus,
dwControlCode,
dwEventType,
((PDEV_BROADCAST_HDR)pEventData)->dbch_size,
pEventData);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError(ScmRpcStatusToWinError(RpcExceptionCode()));
bResult = FALSE;
}
RpcEndExcept;
return bResult;
}
/********************************************************************** /**********************************************************************
* GetServiceDisplayNameA * GetServiceDisplayNameA
* *

View file

@ -876,8 +876,12 @@ interface svcctl
/* Function 52 */ /* Function 52 */
DWORD DWORD
__stdcall __stdcall
RSendPnPMessage( RI_ScSendPnPMessage(
[in] handle_t BindingHandle); /* FIXME */ [in] RPC_SERVICE_STATUS_HANDLE hServiceStatus,
[in] DWORD dwControl,
[in] DWORD dwEventType,
[in] DWORD dwEventSize,
[in, size_is(dwEventSize)] LPBYTE pEventData);
/* Function 53 */ /* Function 53 */
DWORD DWORD

View file

@ -60,7 +60,13 @@ I_ScPnPGetServiceName(
_Out_ LPWSTR lpServiceName, _Out_ LPWSTR lpServiceName,
_In_ DWORD cchServiceName); _In_ DWORD cchServiceName);
/* I_ScSendPnPMessage */ DWORD
WINAPI
I_ScSendPnPMessage(
_In_ SERVICE_STATUS_HANDLE hServiceStatus,
_In_ DWORD dwControlCode,
_In_ DWORD dwEventType,
_In_ PVOID pEventData);
/* I_ScSendTSMessage */ /* I_ScSendTSMessage */