ReactOS 0.4.15-dev-7788-g1ad9096
events.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/po/events.c
5 * PURPOSE: Power Manager
6 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS *******************************************************************/
16
17typedef struct _SYS_BUTTON_CONTEXT
18{
25
26static VOID
31
34
35/* FUNCTIONS *****************************************************************/
36
37VOID
40{
42
43 /* Check if Win32k registered a notification callback */
45 {
46 /* Raise to dispatch */
48
49 /* Notify the callback */
51
52 /* Lower IRQL back */
54 }
55}
56
57static NTSTATUS
61 IN PIRP Irp,
63{
64 PSYS_BUTTON_CONTEXT SysButtonContext = Context;
65 ULONG SysButton;
66
67 /* The DeviceObject can be NULL, so use the one we stored */
68 DeviceObject = SysButtonContext->DeviceObject;
69
70 /* FIXME: What do do with the sys button event? */
71 SysButton = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
72 {
73 DPRINT1("A device reported the event 0x%x (", SysButton);
74 if (SysButton & SYS_BUTTON_POWER) DbgPrint(" POWER");
75 if (SysButton & SYS_BUTTON_SLEEP) DbgPrint(" SLEEP");
76 if (SysButton & SYS_BUTTON_LID) DbgPrint(" LID");
77 if (SysButton == 0) DbgPrint(" WAKE");
78 DbgPrint(" )\n");
79
80 if (SysButton & SYS_BUTTON_POWER)
81 {
82 /* FIXME: Read registry for the action we should perform here */
83 DPRINT1("Initiating shutdown after power button event\n");
84
86 }
87 }
88
89 /* Allocate a new workitem to send the next IOCTL_GET_SYS_BUTTON_EVENT */
90 SysButtonContext->WorkItem = IoAllocateWorkItem(DeviceObject);
91 if (!SysButtonContext->WorkItem)
92 {
93 DPRINT("IoAllocateWorkItem() failed\n");
94 ExFreePoolWithTag(SysButtonContext, 'IWOP');
95 return STATUS_SUCCESS;
96 }
97 IoQueueWorkItem(SysButtonContext->WorkItem,
100 SysButtonContext);
101
102 return STATUS_SUCCESS /* STATUS_CONTINUE_COMPLETION */;
103}
104
105static VOID
106NTAPI
110{
111 PSYS_BUTTON_CONTEXT SysButtonContext = Context;
112 PIO_WORKITEM CurrentWorkItem = SysButtonContext->WorkItem;
113 PIRP Irp;
114
115 /* Get button pressed (IOCTL_GET_SYS_BUTTON_EVENT) */
116 KeInitializeEvent(&SysButtonContext->Event, NotificationEvent, FALSE);
119 NULL,
120 0,
121 &SysButtonContext->SysButton,
122 sizeof(SysButtonContext->SysButton),
123 FALSE,
124 &SysButtonContext->Event,
125 &SysButtonContext->IoStatusBlock);
126 if (Irp)
127 {
130 SysButtonContext,
131 TRUE,
132 FALSE,
133 FALSE);
135 }
136 else
137 {
138 DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
139 ExFreePoolWithTag(SysButtonContext, 'IWOP');
140 }
141
142 IoFreeWorkItem(CurrentWorkItem);
143}
144
146NTAPI
149{
151 PSYS_BUTTON_CONTEXT SysButtonContext;
156 PIRP Irp;
159 BOOLEAN Arrival;
160 ULONG Caps;
163
164 DPRINT("PopAddRemoveSysCapsCallback(%p %p)\n",
166
168 if (Notification->Version != 1)
172 if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
173 Arrival = TRUE;
174 else if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
175 Arrival = FALSE;
176 else
178
179 if (Arrival && DeviceType == PolicyDeviceBattery)
180 {
182 return STATUS_SUCCESS;
183 }
184
185 if (Arrival)
186 {
187 DPRINT("Arrival of %wZ\n", Notification->SymbolicLinkName);
188
189 /* Open the device */
191 Notification->SymbolicLinkName,
193 NULL,
194 NULL);
200 0);
201 if (!NT_SUCCESS(Status))
202 {
203 DPRINT1("ZwOpenFile() failed with status 0x%08lx\n", Status);
204 return Status;
205 }
210 (PVOID*)&FileObject,
211 NULL);
212 if (!NT_SUCCESS(Status))
213 {
214 DPRINT1("ObReferenceObjectByHandle() failed with status 0x%08lx\n", Status);
216 return Status;
217 }
220
221 /* Get capabilities (IOCTL_GET_SYS_BUTTON_CAPS) */
225 NULL,
226 0,
227 &Caps,
228 sizeof(Caps),
229 FALSE,
230 &Event,
232 if (!Irp)
233 {
234 DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
237 }
239 if (Status == STATUS_PENDING)
240 {
241 DPRINT("IOCTL_GET_SYS_BUTTON_CAPS pending\n");
244 }
245 if (!NT_SUCCESS(Status))
246 {
247 DPRINT1("Sending IOCTL_GET_SYS_BUTTON_CAPS failed with status 0x%08x\n", Status);
250 }
251
252 DPRINT("Device capabilities: 0x%x\n", Caps);
253 if (Caps & SYS_BUTTON_POWER)
254 {
255 DPRINT("POWER button present\n");
257 }
258
259 if (Caps & SYS_BUTTON_SLEEP)
260 {
261 DPRINT("SLEEP button present\n");
263 }
264
265 if (Caps & SYS_BUTTON_LID)
266 {
267 DPRINT("LID present\n");
269 }
270
271 SysButtonContext = ExAllocatePoolWithTag(NonPagedPool,
272 sizeof(SYS_BUTTON_CONTEXT),
273 'IWOP');
274 if (!SysButtonContext)
275 {
276 DPRINT1("ExAllocatePoolWithTag() failed\n");
279 }
280
281 /* Queue a work item to get sys button event */
282 SysButtonContext->WorkItem = IoAllocateWorkItem(DeviceObject);
283 SysButtonContext->DeviceObject = DeviceObject;
284 if (!SysButtonContext->WorkItem)
285 {
286 DPRINT1("IoAllocateWorkItem() failed\n");
288 ExFreePoolWithTag(SysButtonContext, 'IWOP');
290 }
291 IoQueueWorkItem(SysButtonContext->WorkItem,
294 SysButtonContext);
295
297 return STATUS_SUCCESS;
298 }
299 else
300 {
301 DPRINT1("Removal of a power capable device not implemented\n");
303 }
304}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_SHARE_READ
Definition: compat.h:136
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
NTSTATUS(NTAPI * PKWIN32_POWEREVENT_CALLOUT)(_In_ struct _WIN32_POWEREVENT_PARAMETERS *Parameters)
Definition: pstypes.h:544
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
DeviceType
Definition: mmdrv.h:42
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwShutdownSystem(_In_ SHUTDOWN_ACTION Action)
@ ShutdownNoReboot
Definition: extypes.h:176
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_READ_DATA
Definition: nt_native.h:628
@ NotificationEvent
VOID NTAPI ExNotifyCallback(IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2)
Definition: callback.c:467
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
struct _SYS_BUTTON_CONTEXT SYS_BUTTON_CONTEXT
struct _SYS_BUTTON_CONTEXT * PSYS_BUTTON_CONTEXT
static VOID NTAPI PopGetSysButton(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: events.c:107
PCALLBACK_OBJECT SetSystemTimeCallback
Definition: callback.c:27
NTSTATUS NTAPI PopAddRemoveSysCapsCallback(IN PVOID NotificationStructure, IN PVOID Context)
Definition: events.c:147
static NTSTATUS NTAPI PopGetSysButtonCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: events.c:59
PKWIN32_POWEREVENT_CALLOUT PopEventCallout
Definition: events.c:32
VOID NTAPI PoNotifySystemTimeSet(VOID)
Definition: events.c:39
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
@ PolicyDeviceBattery
Definition: po.h:40
enum _POP_POLICY_DEVICE_TYPE POP_POLICY_DEVICE_TYPE
SYSTEM_POWER_CAPABILITIES PopCapabilities
Definition: power.c:29
#define SYS_BUTTON_SLEEP
Definition: poclass.h:82
#define SYS_BUTTON_POWER
Definition: poclass.h:81
#define IOCTL_GET_SYS_BUTTON_CAPS
Definition: poclass.h:57
#define IOCTL_GET_SYS_BUTTON_EVENT
Definition: poclass.h:60
#define SYS_BUTTON_LID
Definition: poclass.h:83
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN SystemBatteriesPresent
Definition: ntpoapi.h:374
PIO_WORKITEM WorkItem
Definition: events.c:20
IO_STATUS_BLOCK IoStatusBlock
Definition: events.c:22
PDEVICE_OBJECT DeviceObject
Definition: events.c:19
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
@ DelayedWorkQueue
Definition: extypes.h:190
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION * PDEVICE_INTERFACE_CHANGE_NOTIFICATION
* PFILE_OBJECT
Definition: iotypes.h:1998
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Suspended
Definition: ketypes.h:420
#define ObDereferenceObject
Definition: obfuncs.h:203