[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;
PLIST_ENTRY Current;
PNOTIFY_ENTRY pNotifyData;
PDEV_BROADCAST_DEVICEINTERFACE_W pData;
PDEV_BROADCAST_DEVICEINTERFACE_W pEventData;
DWORD dwSize;
DWORD dwEventType;
DPRINT("ProcessDeviceClassChangeEvent(%p)\n", PnpEvent);
DPRINT("SymbolicLink: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
@ -142,33 +143,45 @@ ProcessDeviceClassChangeEvent(
((pNotifyData->ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) ||
(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)
{
dwSize = sizeof(DEV_BROADCAST_DEVICEINTERFACE_W) + wcslen(PnpEvent->DeviceClass.SymbolicLinkName) * sizeof(WCHAR);
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);
SendMessageW((HANDLE)pNotifyData->hRecipient, WM_DEVICECHANGE, (WPARAM)dwEventType, (LPARAM)pEventData);
}
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;

View file

@ -6715,10 +6715,16 @@ RControlServiceExW(
/* Function 52 */
DWORD
WINAPI
RSendPnPMessage(
handle_t BindingHandle) /* FIXME */
RI_ScSendPnPMessage(
_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;
}

View file

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

View file

@ -306,6 +306,7 @@
@ stdcall I_QueryTagInformation(ptr long ptr)
@ stdcall I_ScIsSecurityProcess()
@ stdcall I_ScPnPGetServiceName(ptr wstr long)
@ stdcall I_ScSendPnPMessage(ptr long long ptr)
@ stub I_ScSendTSMessage
@ stdcall I_ScSetServiceBitsA(ptr long long long str)
@ 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
*

View file

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

View file

@ -60,7 +60,13 @@ I_ScPnPGetServiceName(
_Out_ LPWSTR lpServiceName,
_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 */