ReactOS  0.4.14-dev-114-gc8cbd56
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 
17 typedef struct _SYS_BUTTON_CONTEXT
18 {
25 
26 static VOID
27 NTAPI
30  IN PVOID Context);
31 
34 
35 /* FUNCTIONS *****************************************************************/
36 
37 VOID
38 NTAPI
40 {
41  KIRQL OldIrql;
42 
43  /* Check if Win32k registered a notification callback */
44  if (PopEventCallout)
45  {
46  /* Raise to dispatch */
48 
49  /* Notify the callback */
51 
52  /* Lower IRQL back */
54  }
55 }
56 
57 static NTSTATUS
58 NTAPI
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 
105 static VOID
106 NTAPI
109  IN PVOID Context)
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);
118  DeviceObject,
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 
145 NTSTATUS
146 NTAPI
148  IN PVOID Context)
149 {
151  PSYS_BUTTON_CONTEXT SysButtonContext;
156  PIRP Irp;
158  KEVENT Event;
159  BOOLEAN Arrival;
160  ULONG Caps;
162 
163  DPRINT("PopAddRemoveSysCapsCallback(%p %p)\n",
165 
167  if (Notification->Version != 1)
169  if (Notification->Size != sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION))
171  if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID))
172  Arrival = TRUE;
173  else if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID))
174  Arrival = FALSE;
175  else
177 
178  if (Arrival)
179  {
180  DPRINT("Arrival of %wZ\n", Notification->SymbolicLinkName);
181 
182  /* Open the device */
184  Notification->SymbolicLinkName,
186  NULL,
187  NULL);
191  &IoStatusBlock,
193  0);
194  if (!NT_SUCCESS(Status))
195  {
196  DPRINT1("ZwOpenFile() failed with status 0x%08lx\n", Status);
197  return Status;
198  }
202  KernelMode,
203  (PVOID*)&FileObject,
204  NULL);
205  if (!NT_SUCCESS(Status))
206  {
207  DPRINT1("ObReferenceObjectByHandle() failed with status 0x%08lx\n", Status);
209  return Status;
210  }
213 
214  /* Get capabilities (IOCTL_GET_SYS_BUTTON_CAPS) */
217  DeviceObject,
218  NULL,
219  0,
220  &Caps,
221  sizeof(Caps),
222  FALSE,
223  &Event,
224  &IoStatusBlock);
225  if (!Irp)
226  {
227  DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
230  }
232  if (Status == STATUS_PENDING)
233  {
234  DPRINT("IOCTL_GET_SYS_BUTTON_CAPS pending\n");
237  }
238  if (!NT_SUCCESS(Status))
239  {
240  DPRINT1("Sending IOCTL_GET_SYS_BUTTON_CAPS failed with status 0x%08x\n", Status);
243  }
244 
245  DPRINT("Device capabilities: 0x%x\n", Caps);
246  if (Caps & SYS_BUTTON_POWER)
247  {
248  DPRINT("POWER button present\n");
250  }
251 
252  if (Caps & SYS_BUTTON_SLEEP)
253  {
254  DPRINT("SLEEP button present\n");
256  }
257 
258  if (Caps & SYS_BUTTON_LID)
259  {
260  DPRINT("LID present\n");
262  }
263 
264  SysButtonContext = ExAllocatePoolWithTag(NonPagedPool,
265  sizeof(SYS_BUTTON_CONTEXT),
266  'IWOP');
267  if (!SysButtonContext)
268  {
269  DPRINT1("ExAllocatePoolWithTag() failed\n");
272  }
273 
274  /* Queue a work item to get sys button event */
275  SysButtonContext->WorkItem = IoAllocateWorkItem(DeviceObject);
276  SysButtonContext->DeviceObject = DeviceObject;
277  if (!SysButtonContext->WorkItem)
278  {
279  DPRINT1("IoAllocateWorkItem() failed\n");
281  ExFreePoolWithTag(SysButtonContext, 'IWOP');
283  }
284  IoQueueWorkItem(SysButtonContext->WorkItem,
287  SysButtonContext);
288 
290  return STATUS_SUCCESS;
291  }
292  else
293  {
294  DPRINT1("Removal of a power capable device not implemented\n");
295  return STATUS_NOT_IMPLEMENTED;
296  }
297 }
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:311
#define IOCTL_GET_SYS_BUTTON_CAPS
Definition: poclass.h:57
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION * PDEVICE_INTERFACE_CHANGE_NOTIFICATION
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define DbgPrint
Definition: loader.c:25
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define SYS_BUTTON_SLEEP
Definition: poclass.h:82
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define FILE_SHARE_READ
Definition: compat.h:125
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
PCALLBACK_OBJECT SetSystemTimeCallback
Definition: callback.c:27
#define SYS_BUTTON_LID
Definition: poclass.h:83
UCHAR KIRQL
Definition: env_spec_w32.h:591
HANDLE FileHandle
Definition: stats.c:38
PKWIN32_POWEREVENT_CALLOUT PopEventCallout
Definition: events.c:32
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:496
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID NTAPI PoNotifySystemTimeSet(VOID)
Definition: events.c:39
#define FILE_READ_DATA
Definition: nt_native.h:628
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define IOCTL_GET_SYS_BUTTON_EVENT
Definition: poclass.h:60
NTSYSAPI NTSTATUS NTAPI ZwShutdownSystem(_In_ SHUTDOWN_ACTION Action)
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
VOID NTAPI ExNotifyCallback(IN PCALLBACK_OBJECT CallbackObject, IN PVOID Argument1, IN PVOID Argument2)
Definition: callback.c:467
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS(NTAPI * PKWIN32_POWEREVENT_CALLOUT)(_In_ struct _WIN32_POWEREVENT_PARAMETERS *Parameters)
Definition: pstypes.h:528
* PFILE_OBJECT
Definition: iotypes.h:1955
struct _SYS_BUTTON_CONTEXT * PSYS_BUTTON_CONTEXT
NTSTATUS NTAPI PopAddRemoveSysCapsCallback(IN PVOID NotificationStructure, IN PVOID Context)
Definition: events.c:147
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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)
static VOID NTAPI PopGetSysButton(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: events.c:107
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define SYS_BUTTON_POWER
Definition: poclass.h:81
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
struct _GUID GUID
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PDEVICE_OBJECT DeviceObject
Definition: events.c:19
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
struct _SYS_BUTTON_CONTEXT SYS_BUTTON_CONTEXT
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 DPRINT1
Definition: precomp.h:8
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
SYSTEM_POWER_CAPABILITIES PopCapabilities
Definition: power.c:29
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
IO_STATUS_BLOCK IoStatusBlock
Definition: events.c:22
return STATUS_SUCCESS
Definition: btrfs.c:2966
static NTSTATUS NTAPI PopGetSysButtonCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: events.c:59
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
PIO_WORKITEM WorkItem
Definition: events.c:20