mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:52:57 +00:00
Better support of GUID_DEVICE_SYS_BUTTON interface.
Now, the kernel can receive power events from the keyboard, but only reacts by displaying a message svn path=/trunk/; revision=27407
This commit is contained in:
parent
802891c598
commit
e8c10e466d
1 changed files with 184 additions and 21 deletions
|
@ -8,12 +8,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
PKWIN32_POWEREVENT_CALLOUT PopEventCallout;
|
PKWIN32_POWEREVENT_CALLOUT PopEventCallout;
|
||||||
extern PCALLBACK_OBJECT SetSystemTimeCallback;
|
extern PCALLBACK_OBJECT SetSystemTimeCallback;
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
NTAPI
|
||||||
|
PopGetSysButton(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PVOID Context);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PoNotifySystemTimeSet(VOID)
|
PoNotifySystemTimeSet(VOID)
|
||||||
|
@ -34,6 +40,101 @@ PoNotifySystemTimeSet(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _SYS_BUTTON_CONTEXT
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PIO_WORKITEM WorkItem;
|
||||||
|
KEVENT Event;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
ULONG SysButton;
|
||||||
|
} SYS_BUTTON_CONTEXT, *PSYS_BUTTON_CONTEXT;
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PopGetSysButtonCompletion(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
PSYS_BUTTON_CONTEXT SysButtonContext = Context;
|
||||||
|
ULONG SysButton;
|
||||||
|
|
||||||
|
if (Irp->PendingReturned)
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
|
|
||||||
|
/* The DeviceObject can be NULL, so use the one we stored */
|
||||||
|
DeviceObject = SysButtonContext->DeviceObject;
|
||||||
|
|
||||||
|
/* FIXME: What do do with the sys button event? */
|
||||||
|
SysButton = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
{
|
||||||
|
DPRINT1("A device reported the event 0x%x (", SysButton);
|
||||||
|
if (SysButton & SYS_BUTTON_POWER) DbgPrint(" POWER");
|
||||||
|
if (SysButton & SYS_BUTTON_SLEEP) DbgPrint(" SLEEP");
|
||||||
|
if (SysButton & SYS_BUTTON_LID) DbgPrint(" LID");
|
||||||
|
if (SysButton == 0) DbgPrint(" WAKE");
|
||||||
|
DbgPrint(" )\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new workitem to send the next IOCTL_GET_SYS_BUTTON_EVENT */
|
||||||
|
SysButtonContext->WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||||
|
if (!SysButtonContext->WorkItem)
|
||||||
|
{
|
||||||
|
DPRINT("IoAllocateWorkItem() failed\n");
|
||||||
|
ExFreePool(SysButtonContext);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
IoQueueWorkItem(
|
||||||
|
SysButtonContext->WorkItem,
|
||||||
|
PopGetSysButton,
|
||||||
|
DelayedWorkQueue,
|
||||||
|
SysButtonContext);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS /* STATUS_CONTINUE_COMPLETION */;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
NTAPI
|
||||||
|
PopGetSysButton(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
PSYS_BUTTON_CONTEXT SysButtonContext = Context;
|
||||||
|
PIO_WORKITEM CurrentWorkItem = SysButtonContext->WorkItem;;
|
||||||
|
PIRP Irp;
|
||||||
|
|
||||||
|
/* Get button pressed (IOCTL_GET_SYS_BUTTON_EVENT) */
|
||||||
|
KeInitializeEvent(&SysButtonContext->Event, NotificationEvent, FALSE);
|
||||||
|
Irp = IoBuildDeviceIoControlRequest(
|
||||||
|
IOCTL_GET_SYS_BUTTON_EVENT,
|
||||||
|
DeviceObject,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&SysButtonContext->SysButton,
|
||||||
|
sizeof(SysButtonContext->SysButton),
|
||||||
|
FALSE,
|
||||||
|
&SysButtonContext->Event,
|
||||||
|
&SysButtonContext->IoStatusBlock);
|
||||||
|
if (Irp)
|
||||||
|
{
|
||||||
|
IoSetCompletionRoutine(
|
||||||
|
Irp,
|
||||||
|
PopGetSysButtonCompletion,
|
||||||
|
SysButtonContext,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
FALSE);
|
||||||
|
IoCallDriver(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
|
||||||
|
ExFreePool(SysButtonContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
IoFreeWorkItem(CurrentWorkItem);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
PopAddRemoveSysCapsCallback(
|
PopAddRemoveSysCapsCallback(
|
||||||
|
@ -41,9 +142,14 @@ PopAddRemoveSysCapsCallback(
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification;
|
PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification;
|
||||||
|
PSYS_BUTTON_CONTEXT SysButtonContext;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
HANDLE DeviceHandle;
|
HANDLE FileHandle;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
|
PIRP Irp;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
KEVENT Event;
|
||||||
BOOLEAN Arrival;
|
BOOLEAN Arrival;
|
||||||
ULONG Caps;
|
ULONG Caps;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -67,7 +173,7 @@ PopAddRemoveSysCapsCallback(
|
||||||
{
|
{
|
||||||
DPRINT("Arrival of %wZ\n", Notification->SymbolicLinkName);
|
DPRINT("Arrival of %wZ\n", Notification->SymbolicLinkName);
|
||||||
|
|
||||||
/* Open device */
|
/* Open the device */
|
||||||
InitializeObjectAttributes(
|
InitializeObjectAttributes(
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
Notification->SymbolicLinkName,
|
Notification->SymbolicLinkName,
|
||||||
|
@ -75,7 +181,7 @@ PopAddRemoveSysCapsCallback(
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
Status = ZwOpenFile(
|
Status = ZwOpenFile(
|
||||||
&DeviceHandle,
|
&FileHandle,
|
||||||
FILE_READ_DATA,
|
FILE_READ_DATA,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
|
@ -86,32 +192,89 @@ PopAddRemoveSysCapsCallback(
|
||||||
DPRINT("ZwOpenFile() failed with status 0x%08lx\n", Status);
|
DPRINT("ZwOpenFile() failed with status 0x%08lx\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
Status = ObReferenceObjectByHandle(
|
||||||
|
FileHandle,
|
||||||
|
FILE_READ_DATA,
|
||||||
|
IoFileObjectType,
|
||||||
|
ExGetPreviousMode(),
|
||||||
|
(PVOID*)&FileObject,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ObReferenceObjectByHandle() failed with status 0x%08lx\n", Status);
|
||||||
|
ZwClose(FileHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Send IOCTL_GET_SYS_BUTTON_CAPS to get new caps */
|
/* Get capabilities (IOCTL_GET_SYS_BUTTON_CAPS) */
|
||||||
Status = ZwDeviceIoControlFile(
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
DeviceHandle,
|
Irp = IoBuildDeviceIoControlRequest(
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
&IoStatusBlock,
|
|
||||||
IOCTL_GET_SYS_BUTTON_CAPS,
|
IOCTL_GET_SYS_BUTTON_CAPS,
|
||||||
|
DeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&Caps,
|
&Caps,
|
||||||
sizeof(Caps));
|
sizeof(Caps),
|
||||||
|
FALSE,
|
||||||
|
&Event,
|
||||||
|
&IoStatusBlock);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
DPRINT("IoBuildDeviceIoControlRequest() failed\n");
|
||||||
|
ZwClose(FileHandle);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
DPRINT("IOCTL_GET_SYS_BUTTON_CAPS pending\n");
|
||||||
|
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||||
|
Status = IoStatusBlock.Status;
|
||||||
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ZwDeviceIoControlFile(IOCTL_GET_SYS_BUTTON_CAPS) failed with status 0x%08lx\n", Status);
|
DPRINT("Sending IOCTL_GET_SYS_BUTTON_CAPS failed with status 0x%08x\n", Status);
|
||||||
ZwClose(DeviceHandle);
|
ZwClose(FileHandle);
|
||||||
return Status;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
/* FIXME: What do do with this? */
|
|
||||||
DPRINT1("Device capabilities: 0x%lx\n", Caps);
|
|
||||||
|
|
||||||
/* Send IOCTL_GET_SYS_BUTTON_CAPS to get current caps */
|
/* FIXME: What do do with the capabilities? */
|
||||||
/* FIXME: Set a IO completion routine on it to be able to send a new one */
|
{
|
||||||
DPRINT1("Send a IOCTL_GET_SYS_BUTTON_EVENT\n");
|
DPRINT1("Device capabilities: 0x%x (", Caps);
|
||||||
return ZwClose(DeviceHandle);
|
if (Caps & SYS_BUTTON_POWER) DbgPrint(" POWER");
|
||||||
|
if (Caps & SYS_BUTTON_SLEEP) DbgPrint(" SLEEP");
|
||||||
|
if (Caps & SYS_BUTTON_LID) DbgPrint(" LID");
|
||||||
|
DbgPrint(" )\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
SysButtonContext = ExAllocatePool(NonPagedPool, sizeof(SYS_BUTTON_CONTEXT));
|
||||||
|
if (!SysButtonContext)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePool() failed\n");
|
||||||
|
ZwClose(FileHandle);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Queue a work item to get sys button event */
|
||||||
|
SysButtonContext->WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||||
|
SysButtonContext->DeviceObject = DeviceObject;
|
||||||
|
if (!SysButtonContext->WorkItem)
|
||||||
|
{
|
||||||
|
DPRINT("IoAllocateWorkItem() failed\n");
|
||||||
|
ZwClose(FileHandle);
|
||||||
|
ExFreePool(SysButtonContext);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
IoQueueWorkItem(
|
||||||
|
SysButtonContext->WorkItem,
|
||||||
|
PopGetSysButton,
|
||||||
|
DelayedWorkQueue,
|
||||||
|
SysButtonContext);
|
||||||
|
|
||||||
|
ZwClose(FileHandle);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue