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