ReactOS 0.4.17-dev-804-g023d8af
pnp.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Audio Service Plug and Play
5 * COPYRIGHT: Copyright 2007 Andrew Greenwood <silverblade@reactos.org>
6 * Copyright 2026 Vitaly Orekhov <vkvo2000@vivaldi.net>
7 */
8
9#include "audiosrv.h"
10
11#include <winreg.h>
12#include <winuser.h>
13#include <mmsystem.h>
14#include <setupapi.h>
15#include <ks.h>
16#include <ksmedia.h>
17
18#define NDEBUG
19#include <debug.h>
20
21static HDEVNOTIFY device_notification_handle = NULL;
23
24/*
25 Finds all devices within the KSCATEGORY_AUDIO category and puts them
26 in the shared device list.
27*/
28
29BOOL
31{
32 SP_DEVICE_INTERFACE_DATA interface_data;
33 SP_DEVINFO_DATA device_data;
35 HDEVINFO dev_info;
37 int index = 0;
38
39 const GUID category_guid = {STATIC_KSCATEGORY_AUDIO};
40
41 dev_info = SetupDiGetClassDevsExW(&category_guid,
42 NULL,
43 NULL,
45 NULL,
46 NULL,
47 NULL);
48
49 interface_data.cbSize = sizeof(interface_data);
50 interface_data.Reserved = 0;
51
52 /* Enumerate the devices within the category */
53 index = 0;
54
56 + (MAX_PATH * sizeof(WCHAR));
57
60 0,
61 length);
62
63 if ( ! detail_data )
64 {
65 DPRINT("failed to allocate detail_data\n");
66 return TRUE;
67 }
68
69 while (
71 NULL,
72 &category_guid,
73 index,
74 &interface_data) )
75 {
76 PnP_AudioDevice* list_node;
77
79
80 /* NOTE: We don't actually use device_data... */
82 device_data.cbSize = sizeof(device_data);
83 device_data.Reserved = 0;
85 &interface_data,
87 length,
88 NULL,
89 &device_data);
90
91 list_node = CreateDeviceDescriptor(detail_data->DevicePath, TRUE);
92 AppendAudioDeviceToList(list_node);
93 DestroyDeviceDescriptor(list_node);
94
95 /* TODO: Cleanup the device we enumerated? */
96
97 index ++;
98 };
99
101
103
104 uWinMMDeviceChange = RegisterWindowMessageW(L"winmm_devicechange");
105
106 if (uWinMMDeviceChange == 0)
107 DPRINT1("Failed to register winmm_devicechange window message: GetLastError %u\n", GetLastError());
108
109 return TRUE;
110}
111
112
113/*
114 Add new devices to the list as they arrive.
115*/
116
117DWORD
119{
120 PnP_AudioDevice* list_node;
121 list_node = CreateDeviceDescriptor(device->dbcc_name, TRUE);
122 AppendAudioDeviceToList(list_node);
123 DestroyDeviceDescriptor(list_node);
124
127
128 return NO_ERROR;
129}
130
131DWORD
133{
134 /* TODO: clean up appended audio devices */
137
138 return NO_ERROR;
139}
140
141
142/*
143 Request notification of device additions/removals.
144*/
145
146BOOL
148{
149 DEV_BROADCAST_DEVICEINTERFACE notification_filter;
150
151 const GUID wdmaud_guid = {STATIC_KSCATEGORY_AUDIO};
152
153 ZeroMemory(&notification_filter, sizeof(notification_filter));
154 notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
155 notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
156 notification_filter.dbcc_classguid = wdmaud_guid;
157
160 &notification_filter,
161 DEVICE_NOTIFY_SERVICE_HANDLE);
163 {
164 DPRINT("failed with error %d\n", GetLastError());
165 }
166
167 return ( device_notification_handle != NULL );
168}
169
170
171/*
172 When we're not interested in device notifications any more, this gets
173 called.
174*/
175
176VOID
178{
180 {
183 }
184}
185
186
187/*
188 Device events from the main service handler get passed to this.
189*/
190
191DWORD
193 DWORD dwEventType,
194 LPVOID lpEventData)
195{
196 switch (dwEventType)
197 {
199 {
200 DEV_BROADCAST_DEVICEINTERFACE* incoming_device =
201 (DEV_BROADCAST_DEVICEINTERFACE*)lpEventData;
202
203 return ProcessDeviceArrival(incoming_device);
204 }
205
207 {
208 DEV_BROADCAST_DEVICEINTERFACE* removed_device =
209 (DEV_BROADCAST_DEVICEINTERFACE*)lpEventData;
210
211 return ProcessDeviceRemovalComplete(removed_device);
212 }
213
214 default:
215 {
216 break;
217 }
218 }
219
220 return NO_ERROR;
221}
#define DPRINT1
Definition: precomp.h:8
BOOL AppendAudioDeviceToList(PnP_AudioDevice *device)
SERVICE_STATUS_HANDLE service_status_handle
Definition: main.c:13
#define DestroyDeviceDescriptor(descriptor)
Definition: audiosrv.h:30
VOID * CreateDeviceDescriptor(WCHAR *path, BOOL is_enabled)
BOOL RegisterForDeviceNotifications(VOID)
Definition: pnp.c:147
VOID UnregisterDeviceNotifications(VOID)
Definition: pnp.c:177
static HDEVNOTIFY device_notification_handle
Definition: pnp.c:21
DWORD ProcessDeviceRemovalComplete(DEV_BROADCAST_DEVICEINTERFACE *device)
Definition: pnp.c:132
DWORD ProcessDeviceArrival(DEV_BROADCAST_DEVICEINTERFACE *device)
Definition: pnp.c:118
DWORD HandleDeviceEvent(DWORD dwEventType, LPVOID lpEventData)
Definition: pnp.c:192
static UINT uWinMMDeviceChange
Definition: pnp.c:22
BOOL ProcessExistingDevices(VOID)
Definition: pnp.c:30
#define BSF_POSTMESSAGE
Definition: dbt.h:58
#define BSM_APPLICATIONS
Definition: dbt.h:48
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define DBT_DEVTYP_DEVICEINTERFACE
Definition: dbt.h:24
#define DBT_DEVICEREMOVECOMPLETE
Definition: dbt.h:16
#define BSM_ALLDESKTOPS
Definition: dbt.h:49
DEV_BROADCAST_DEVICEINTERFACE_A DEV_BROADCAST_DEVICEINTERFACE
Definition: dbt.h:137
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:3069
HDEVINFO WINAPI SetupDiGetClassDevsExW(CONST GUID *class, PCWSTR enumstr, HWND parent, DWORD flags, HDEVINFO deviceset, PCWSTR machine, PVOID reserved)
Definition: devinst.c:2548
BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:3300
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:3182
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint index
Definition: glext.h:6031
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
unsigned int UINT
Definition: sysinfo.c:13
#define STATIC_KSCATEGORY_AUDIO
Definition: ksmedia.h:169
#define ZeroMemory
Definition: minwinbase.h:31
short WCHAR
Definition: pedump.c:58
SP_DEVICE_INTERFACE_DETAIL_DATA_A SP_DEVICE_INTERFACE_DETAIL_DATA
Definition: setupapi.h:1152
#define DIGCF_DEVICEINTERFACE
Definition: setupapi.h:177
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA_W
#define DIGCF_PRESENT
Definition: setupapi.h:174
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W * PSP_DEVICE_INTERFACE_DETAIL_DATA_W
#define DPRINT
Definition: sndvol32.h:73
ULONG_PTR Reserved
Definition: setupapi.h:841
Definition: devices.h:37
BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY Handle)
Definition: resources.c:162
HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecipient, LPVOID NotificationFilter, DWORD Flags)
Definition: resources.c:111
LONG WINAPI BroadcastSystemMessageW(DWORD dwFlags, LPDWORD lpdwRecipients, UINT uiMessage, WPARAM wParam, LPARAM lParam)
Definition: message.c:3408
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
UINT WINAPI RegisterWindowMessageW(_In_ LPCWSTR)