xref: /reactos/drivers/bus/acpi/cmbatt/cmbwmi.c (revision 8a978a17)
1 /*
2  * PROJECT:         ReactOS ACPI-Compliant Control Method Battery
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * FILE:            boot/drivers/bus/acpi/cmbatt/cmbwmi.c
5  * PURPOSE:         WMI Interface
6  * PROGRAMMERS:     ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "cmbatt.h"
12 
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
17 WMIGUIDREGINFO CmBattWmiGuidList[1] =
18 {
19     {&GUID_POWER_DEVICE_WAKE_ENABLE, 1, 0}
20 };
21 
22 /* FUNCTIONS ******************************************************************/
23 
24 PCHAR
25 NTAPI
26 WMIMinorFunctionString(IN UCHAR MinorFunction)
27 {
28     switch (MinorFunction)
29     {
30         case IRP_MN_CHANGE_SINGLE_INSTANCE:
31             return "IRP_MN_CHANGE_SINGLE_INSTANCE";
32         case IRP_MN_CHANGE_SINGLE_ITEM:
33             return "IRP_MN_CHANGE_SINGLE_ITEM";
34         case IRP_MN_DISABLE_COLLECTION:
35             return "IRP_MN_DISABLE_COLLECTION";
36         case IRP_MN_DISABLE_EVENTS:
37             return "IRP_MN_DISABLE_EVENTS";
38         case IRP_MN_ENABLE_COLLECTION:
39             return "IRP_MN_ENABLE_COLLECTION";
40         case IRP_MN_ENABLE_EVENTS:
41             return "IRP_MN_ENABLE_EVENTS";
42         case IRP_MN_EXECUTE_METHOD:
43             return "IRP_MN_EXECUTE_METHOD";
44         case IRP_MN_QUERY_ALL_DATA:
45             return "IRP_MN_QUERY_ALL_DATA";
46         case IRP_MN_QUERY_SINGLE_INSTANCE:
47             return "IRP_MN_QUERY_SINGLE_INSTANCE";
48         case IRP_MN_REGINFO:
49             return "IRP_MN_REGINFO";
50         default:
51             return "IRP_MN_?????";
52     }
53 }
54 
55 NTSTATUS
56 NTAPI
57 CmBattQueryWmiRegInfo(PDEVICE_OBJECT DeviceObject,
58                       PULONG RegFlags,
59                       PUNICODE_STRING InstanceName,
60                       PUNICODE_STRING *RegistryPath,
61                       PUNICODE_STRING MofResourceName,
62                       PDEVICE_OBJECT *Pdo)
63 {
64     UNIMPLEMENTED;
65     return STATUS_NOT_IMPLEMENTED;
66 }
67 
68 NTSTATUS
69 NTAPI
70 CmBattQueryWmiDataBlock(PDEVICE_OBJECT DeviceObject,
71                         PIRP Irp,
72                         ULONG GuidIndex,
73                         ULONG InstanceIndex,
74                         ULONG InstanceCount,
75                         PULONG InstanceLengthArray,
76                         ULONG BufferAvail,
77                         PUCHAR Buffer)
78 {
79     UNIMPLEMENTED;
80     return STATUS_NOT_IMPLEMENTED;
81 }
82 
83 NTSTATUS
84 NTAPI
85 CmBattSetWmiDataBlock(PDEVICE_OBJECT DeviceObject,
86                       PIRP Irp,
87                       ULONG GuidIndex,
88                       ULONG InstanceIndex,
89                       ULONG BufferSize,
90                       PUCHAR Buffer)
91 {
92     UNIMPLEMENTED;
93     return STATUS_NOT_IMPLEMENTED;
94 }
95 
96 NTSTATUS
97 NTAPI
98 CmBattSetWmiDataItem(PDEVICE_OBJECT DeviceObject,
99                      PIRP Irp,
100                      ULONG GuidIndex,
101                      ULONG InstanceIndex,
102                      ULONG DataItemId,
103                      ULONG BufferSize,
104                      PUCHAR Buffer)
105 {
106     UNIMPLEMENTED;
107     return STATUS_NOT_IMPLEMENTED;
108 }
109 
110 NTSTATUS
111 NTAPI
112 CmBattWmiDeRegistration(IN PCMBATT_DEVICE_EXTENSION DeviceExtension)
113 {
114     PAGED_CODE();
115 
116     /* De-register */
117     return IoWMIRegistrationControl(DeviceExtension->FdoDeviceObject,
118                                     WMIREG_ACTION_DEREGISTER);
119 }
120 
121 NTSTATUS
122 NTAPI
123 CmBattWmiRegistration(IN PCMBATT_DEVICE_EXTENSION DeviceExtension)
124 {
125     PAGED_CODE();
126 
127     /* GUID information */
128     DeviceExtension->WmiLibInfo.GuidCount = sizeof(CmBattWmiGuidList) /
129                                             sizeof(WMIGUIDREGINFO);
130     DeviceExtension->WmiLibInfo.GuidList = CmBattWmiGuidList;
131 
132     /* Callbacks */
133     DeviceExtension->WmiLibInfo.QueryWmiRegInfo = CmBattQueryWmiRegInfo;
134     DeviceExtension->WmiLibInfo.QueryWmiDataBlock = CmBattQueryWmiDataBlock;
135     DeviceExtension->WmiLibInfo.SetWmiDataBlock = CmBattSetWmiDataBlock;
136     DeviceExtension->WmiLibInfo.SetWmiDataItem = CmBattSetWmiDataItem;
137     DeviceExtension->WmiLibInfo.ExecuteWmiMethod = NULL;
138     DeviceExtension->WmiLibInfo.WmiFunctionControl = NULL;
139 
140     /* Register */
141     return IoWMIRegistrationControl(DeviceExtension->FdoDeviceObject,
142                                     WMIREG_ACTION_REGISTER);
143 }
144 
145 NTSTATUS
146 NTAPI
147 CmBattSystemControl(IN PDEVICE_OBJECT DeviceObject,
148                     IN PIRP Irp)
149 {
150     NTSTATUS Status;
151     PCMBATT_DEVICE_EXTENSION DeviceExtension;
152     PWMILIB_CONTEXT WmiLibContext;
153     SYSCTL_IRP_DISPOSITION Disposition = IrpForward;
154     PAGED_CODE();
155     if (CmBattDebug & 2)
156         DbgPrint("CmBatt: SystemControl: %s\n",
157                  WMIMinorFunctionString(IoGetCurrentIrpStackLocation(Irp)->MinorFunction));
158 
159     /* Acquire the remove lock */
160     DeviceExtension = DeviceObject->DeviceExtension;
161     Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, 0);
162     if (!NT_SUCCESS(Status))
163     {
164         /* It's too late, fail */
165         Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
166         IoCompleteRequest(Irp, IO_NO_INCREMENT);
167         return STATUS_DEVICE_REMOVED;
168     }
169 
170     /* What kind of device is this? */
171     WmiLibContext = &DeviceExtension->WmiLibInfo;
172     if (DeviceExtension->FdoType == CmBattBattery)
173     {
174         /* For batteries, let the class driver handle it */
175         Status = BatteryClassSystemControl(DeviceExtension->ClassData,
176                                            WmiLibContext,
177                                            DeviceObject,
178                                            Irp,
179                                            &Disposition);
180     }
181     else
182     {
183         /* Otherwise, call the wmi library directly */
184         Status = WmiSystemControl(WmiLibContext,
185                                   DeviceObject,
186                                   Irp,
187                                   &Disposition);
188     }
189 
190     /* Check what happened */
191     switch (Disposition)
192     {
193         case IrpNotCompleted:
194 
195             /* Complete it here */
196             if (CmBattDebug & 2) DbgPrint("CmBatt: SystemControl: Irp Not Completed.\n");
197             IoCompleteRequest(Irp, IO_NO_INCREMENT);
198             break;
199 
200         case IrpForward:
201 
202             /* Forward it to ACPI */
203             if (CmBattDebug & 2) DbgPrint("CmBatt: SystemControl: Irp Forward.\n");
204             IoSkipCurrentIrpStackLocation(Irp);
205             Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
206             break;
207 
208         case IrpProcessed:
209 
210             /* Nothing to do */
211             if (CmBattDebug & 2) DbgPrint("CmBatt: SystemControl: Irp Processed.\n");
212             break;
213 
214         default:
215             ASSERT(FALSE);
216     }
217 
218     /* Release the lock and return */
219     IoReleaseRemoveLock(&DeviceExtension->RemoveLock, 0);
220     return Status;
221 }
222 
223 /* EOF */
224