[ACPI]
[reactos.git] / reactos / drivers / bus / acpi / main.c
index c4f2c22..4cbdfda 100644 (file)
@@ -7,6 +7,7 @@
 #include <acpi_drivers.h>
 
 #include <acpiioct.h>
+#include <poclass.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -17,7 +18,8 @@
 
 #endif
 
-
+extern struct acpi_device *sleep_button;
+extern struct acpi_device *power_button;
 
 NTSTATUS
 NTAPI
@@ -166,6 +168,20 @@ End:
 
 }
 
+NTSTATUS
+NTAPI
+ACPIDispatchCreateClose(
+   IN PDEVICE_OBJECT DeviceObject,
+   IN PIRP Irp)
+{
+   Irp->IoStatus.Status = STATUS_SUCCESS;
+   Irp->IoStatus.Information = 0;
+
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+   return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 ACPIDispatchDeviceControl(
@@ -175,6 +191,7 @@ ACPIDispatchDeviceControl(
     PIO_STACK_LOCATION      irpStack;
     NTSTATUS                status = STATUS_NOT_SUPPORTED;
     PCOMMON_DEVICE_DATA     commonData;
+    ULONG Caps = 0;
 
     PAGED_CODE ();
 
@@ -194,6 +211,59 @@ ACPIDispatchDeviceControl(
                                           Irp);
               break;
 
+           case IOCTL_GET_SYS_BUTTON_CAPS:
+              if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+              {
+                  status = STATUS_BUFFER_TOO_SMALL;
+                  break;
+              }
+
+              if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
+              {
+                  DPRINT1("Lid button reported to power manager\n");
+                  Caps |= SYS_BUTTON_LID;
+              }
+              else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
+              {
+                  /* We have to return both at the same time because since we
+                   * have a NULL handle we are the fixed feature DO and we will
+                   * only be called once (not once per device)
+                   */
+                  if (power_button)
+                  {
+                      DPRINT1("Fixed power button reported to power manager\n");
+                      Caps |= SYS_BUTTON_POWER;
+                  }
+                  if (sleep_button)
+                  {
+                      DPRINT1("Fixed sleep button reported to power manager\n");
+                      Caps |= SYS_BUTTON_SLEEP;
+                  }
+              }
+              if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
+              {
+                  DPRINT1("Control method power button reported to power manager\n");
+                  Caps |= SYS_BUTTON_POWER;
+              }
+              else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
+              {
+                  DPRINT1("Control method sleep reported to power manager\n");
+                  Caps |= SYS_BUTTON_SLEEP;
+              }
+              else
+              {
+                  DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
+                  status = STATUS_INVALID_PARAMETER;
+              }
+
+              if (Caps != 0)
+              {
+                  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps));
+                  Irp->IoStatus.Information = sizeof(Caps);
+                  status = STATUS_SUCCESS;
+              }
+              break;
+
            /* TODO: Implement other IOCTLs */
 
            default:
@@ -228,6 +298,8 @@ DriverEntry (
     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
     DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
     DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
+    DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
+    DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
 
     DriverObject->DriverExtension->AddDevice = Bus_AddDevice;