ReactOS 0.4.16-dev-1056-gbe87e00
event.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: base/services/umpnpmgr/event.c
23 * PURPOSE: PNP Event thread
24 * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
25 * Hervé Poussineau (hpoussin@reactos.org)
26 * Colin Finck (colin@reactos.org)
27 */
28
29/* INCLUDES *****************************************************************/
30
31#include "precomp.h"
32
33#define NDEBUG
34#include <debug.h>
35
36/* FUNCTIONS *****************************************************************/
37
38static
39VOID
42{
43 RPC_STATUS RpcStatus;
44
45 DPRINT("ProcessTargetDeviceEvent(%p)\n", PnpEvent);
46
47 if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
48 {
49// DWORD dwRecipient;
50
51 DPRINT("Device arrival: %S\n", PnpEvent->TargetDevice.DeviceIds);
52
53// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
54// BroadcastSystemMessageW(BSF_POSTMESSAGE,
55// &dwRecipient,
56// WM_DEVICECHANGE,
57// DBT_DEVNODES_CHANGED,
58// 0);
60 }
61 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_EJECT_VETOED, &RpcStatus))
62 {
63 DPRINT1("Eject vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds);
64 }
65 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_KERNEL_INITIATED_EJECT, &RpcStatus))
66 {
67 DPRINT1("Kernel initiated eject: %S\n", PnpEvent->TargetDevice.DeviceIds);
68 }
69 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SAFE_REMOVAL, &RpcStatus))
70 {
71// DWORD dwRecipient;
72
73 DPRINT1("Safe removal: %S\n", PnpEvent->TargetDevice.DeviceIds);
74
75// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
76// BroadcastSystemMessageW(BSF_POSTMESSAGE,
77// &dwRecipient,
78// WM_DEVICECHANGE,
79// DBT_DEVNODES_CHANGED,
80// 0);
82 }
83 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_SURPRISE_REMOVAL, &RpcStatus))
84 {
85// DWORD dwRecipient;
86
87 DPRINT1("Surprise removal: %S\n", PnpEvent->TargetDevice.DeviceIds);
88
89// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
90// BroadcastSystemMessageW(BSF_POSTMESSAGE,
91// &dwRecipient,
92// WM_DEVICECHANGE,
93// DBT_DEVNODES_CHANGED,
94// 0);
96 }
97 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVAL_VETOED, &RpcStatus))
98 {
99 DPRINT1("Removal vetoed: %S\n", PnpEvent->TargetDevice.DeviceIds);
100 }
101 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_REMOVE_PENDING, &RpcStatus))
102 {
103 DPRINT1("Removal pending: %S\n", PnpEvent->TargetDevice.DeviceIds);
104 }
105 else
106 {
107 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
108 PnpEvent->EventGuid.Data1, PnpEvent->EventGuid.Data2, PnpEvent->EventGuid.Data3,
109 PnpEvent->EventGuid.Data4[0], PnpEvent->EventGuid.Data4[1], PnpEvent->EventGuid.Data4[2],
110 PnpEvent->EventGuid.Data4[3], PnpEvent->EventGuid.Data4[4], PnpEvent->EventGuid.Data4[5],
111 PnpEvent->EventGuid.Data4[6], PnpEvent->EventGuid.Data4[7]);
112 }
113}
114
115
116static
117VOID
120{
121 RPC_STATUS RpcStatus;
122 PLIST_ENTRY Current;
123 PNOTIFY_ENTRY pNotifyData;
126
127 DPRINT("ProcessDeviceClassChangeEvent(%p)\n", PnpEvent);
128 DPRINT("SymbolicLink: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
129 DPRINT("ClassGuid: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
130 PnpEvent->DeviceClass.ClassGuid.Data1, PnpEvent->DeviceClass.ClassGuid.Data2, PnpEvent->DeviceClass.ClassGuid.Data3,
131 PnpEvent->DeviceClass.ClassGuid.Data4[0], PnpEvent->DeviceClass.ClassGuid.Data4[1], PnpEvent->DeviceClass.ClassGuid.Data4[2],
132 PnpEvent->DeviceClass.ClassGuid.Data4[3], PnpEvent->DeviceClass.ClassGuid.Data4[4], PnpEvent->DeviceClass.ClassGuid.Data4[5],
133 PnpEvent->DeviceClass.ClassGuid.Data4[6], PnpEvent->DeviceClass.ClassGuid.Data4[7]);
134
136
137 Current = NotificationListHead.Flink;
138 while (Current != &NotificationListHead)
139 {
140 pNotifyData = CONTAINING_RECORD(Current, NOTIFY_ENTRY, ListEntry);
141 if ((pNotifyData->dwType == CLASS_NOTIFICATION) &&
142 ((pNotifyData->ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES) ||
143 (UuidEqual(&PnpEvent->DeviceClass.ClassGuid, &pNotifyData->ClassGuid, &RpcStatus))))
144 {
145 if ((pNotifyData->ulFlags & DEVICE_NOTIFY_WINDOW_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
146 {
147 dwSize = sizeof(DEV_BROADCAST_DEVICEINTERFACE_W) + wcslen(PnpEvent->DeviceClass.SymbolicLinkName) * sizeof(WCHAR);
149
150 pData->dbcc_size = dwSize;
151 pData->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
152 CopyMemory(&pData->dbcc_classguid, &PnpEvent->DeviceClass.ClassGuid, sizeof(GUID));
153 wcscpy(pData->dbcc_name, PnpEvent->DeviceClass.SymbolicLinkName);
154
155 if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_ARRIVAL, &RpcStatus))
156 {
157 DPRINT("Interface arrival: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
159 }
160 else if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_INTERFACE_REMOVAL, &RpcStatus))
161 {
162 DPRINT("Interface removal: %S\n", PnpEvent->DeviceClass.SymbolicLinkName);
164 }
165
167 }
168 else
169 {
170 DPRINT1("Service notification is not implemented yet!\n");
171 }
172 }
173
174 Current = Current->Flink;
175 }
176
178}
179
180
181static
182VOID
185{
187 DWORD len;
188 DWORD DeviceIdLength;
189// DWORD dwRecipient;
190
191 DPRINT("ProcessDeviceInstallEvent(%p)\n", PnpEvent);
192 DPRINT("Device enumerated: %S\n", PnpEvent->InstallDevice.DeviceId);
193
194 DeviceIdLength = lstrlenW(PnpEvent->InstallDevice.DeviceId);
195 if (DeviceIdLength)
196 {
197 /* Allocate a new device-install event */
198 len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
200 if (Params)
201 {
202 wcscpy(Params->DeviceIds, PnpEvent->InstallDevice.DeviceId);
203
204 /* Queue the event (will be dequeued by DeviceInstallThread) */
208
210
211// dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
212// BroadcastSystemMessageW(BSF_POSTMESSAGE,
213// &dwRecipient,
214// WM_DEVICECHANGE,
215// DBT_DEVNODES_CHANGED,
216// 0);
218 }
219 }
220}
221
222
223DWORD
224WINAPI
226 _In_ LPVOID lpParameter)
227{
228 PLUGPLAY_CONTROL_USER_RESPONSE_DATA ResponseData = {0, 0, 0, 0};
229 DWORD dwRet = ERROR_SUCCESS;
231 PPLUGPLAY_EVENT_BLOCK PnpEvent, NewPnpEvent;
232 ULONG PnpEventSize;
233
234 UNREFERENCED_PARAMETER(lpParameter);
235
236 PnpEventSize = 0x1000;
237 PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
238 if (PnpEvent == NULL)
239 return ERROR_OUTOFMEMORY;
240
241 for (;;)
242 {
243 DPRINT("Calling NtGetPlugPlayEvent()\n");
244
245 /* Wait for the next PnP event */
246 Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);
247
248 /* Resize the buffer for the PnP event if it's too small */
250 {
251 PnpEventSize += 0x400;
252 NewPnpEvent = HeapReAlloc(GetProcessHeap(), 0, PnpEvent, PnpEventSize);
253 if (NewPnpEvent == NULL)
254 {
255 dwRet = ERROR_OUTOFMEMORY;
256 break;
257 }
258 PnpEvent = NewPnpEvent;
259 continue;
260 }
261
262 if (!NT_SUCCESS(Status))
263 {
264 DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status);
265 break;
266 }
267
268 /* Process the PnP event */
269 DPRINT("Received PnP Event\n");
270 switch (PnpEvent->EventCategory)
271 {
272// case HardwareProfileChangeEvent:
273
275 ProcessTargetDeviceEvent(PnpEvent);
276 break;
277
280 break;
281
282// case CustomDeviceEvent:
283
286 break;
287
288// case DeviceArrivalEvent:
289// case PowerEvent:
290// case VetoEvent:
291// case BlockedDriverEvent:
292
293 default:
294 DPRINT1("Unsupported Event Category: %lu\n", PnpEvent->EventCategory);
295 break;
296 }
297
298 /* Dequeue the current PnP event and signal the next one */
300 &ResponseData,
301 sizeof(ResponseData));
302 if (!NT_SUCCESS(Status))
303 {
304 DPRINT1("NtPlugPlayControl(PlugPlayControlUserResponse) failed (Status 0x%08lx)\n", Status);
305 break;
306 }
307 }
308
309 HeapFree(GetProcessHeap(), 0, PnpEvent);
310
311 return dwRet;
312}
313
314/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static VOID ProcessDeviceClassChangeEvent(_In_ PPLUGPLAY_EVENT_BLOCK PnpEvent)
Definition: event.c:118
DWORD WINAPI PnpEventThread(_In_ LPVOID lpParameter)
Definition: event.c:225
static VOID ProcessTargetDeviceEvent(_In_ PPLUGPLAY_EVENT_BLOCK PnpEvent)
Definition: event.c:40
static VOID ProcessDeviceInstallEvent(_In_ PPLUGPLAY_EVENT_BLOCK PnpEvent)
Definition: event.c:183
HANDLE hDeviceInstallListNotEmpty
Definition: install.c:46
HANDLE hDeviceInstallListMutex
Definition: install.c:44
LIST_ENTRY DeviceInstallListHead
Definition: install.c:45
@ CLASS_NOTIFICATION
Definition: precomp.h:47
LIST_ENTRY NotificationListHead
Definition: rpcserver.c:42
RTL_RESOURCE NotificationListLock
Definition: rpcserver.c:43
wcscpy
struct _DEV_BROADCAST_DEVICEINTERFACE_W DEV_BROADCAST_DEVICEINTERFACE_W
#define DBT_DEVNODES_CHANGED
Definition: dbt.h:28
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define DBT_DEVTYP_DEVICEINTERFACE
Definition: dbt.h:24
#define DBT_DEVICEREMOVECOMPLETE
Definition: dbt.h:16
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrlenW
Definition: compat.h:750
#define INFINITE
Definition: serial.h:102
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
#define InsertTailList(ListHead, Entry)
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
@ TargetDeviceChangeEvent
Definition: cmtypes.h:257
@ DeviceClassChangeEvent
Definition: cmtypes.h:258
@ DeviceInstallEvent
Definition: cmtypes.h:260
@ PlugPlayControlUserResponse
Definition: cmtypes.h:216
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
#define _In_
Definition: no_sal2.h:158
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
NTSTATUS NTAPI NtGetPlugPlayEvent(IN ULONG Reserved1, IN ULONG Reserved2, OUT PPLUGPLAY_EVENT_BLOCK Buffer, IN ULONG BufferSize)
Definition: plugplay.c:1364
NTSTATUS NTAPI NtPlugPlayControl(IN PLUGPLAY_CONTROL_CLASS PlugPlayControlClass, IN OUT PVOID Buffer, IN ULONG BufferLength)
Definition: plugplay.c:1494
int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status)
Definition: rpcrt4_main.c:252
long RPC_STATUS
Definition: rpc.h:48
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
Definition: precomp.h:53
NOTIFICATION_TYPE dwType
Definition: precomp.h:55
DWORD ulFlags
Definition: precomp.h:58
DWORD_PTR hRecipient
Definition: precomp.h:57
GUID ClassGuid
Definition: precomp.h:59
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PLUGPLAY_EVENT_CATEGORY EventCategory
Definition: cmtypes.h:406
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
#define CopyMemory
Definition: winbase.h:1741
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define HWND_BROADCAST
Definition: winuser.h:1215
#define WM_DEVICECHANGE
Definition: winuser.h:1822
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180