ReactOS 0.4.16-dev-122-g325d74c
battc.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: drivers/battery/battc/battc.c
5 * PURPOSE: Battery Class Driver
6 * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
7 */
8
9#include <battc.h>
10
11#define NDEBUG
12#include <debug.h>
13
18{
19 DPRINT("Battery class driver initialized\n");
20
21 return STATUS_SUCCESS;
22}
23
28{
29 PBATTERY_CLASS_DATA BattClass;
30
31 DPRINT("Battery %p is being unloaded\n", ClassData);
32
33 BattClass = ClassData;
34 if (BattClass->InterfaceName.Length != 0)
35 {
38 }
39
40 ExFreePoolWithTag(BattClass,
42
43 return STATUS_SUCCESS;
44}
45
52 PIRP Irp,
54{
56
58}
59
65 PIRP Irp,
67 PULONG InstanceLengthArray,
70{
72
74}
75
80{
81 PBATTERY_CLASS_DATA BattClass;
82 PBATTERY_WAIT_STATUS BattWait;
83 BATTERY_STATUS BattStatus;
85
86 DPRINT("Received battery status notification from %p\n", ClassData);
87
88 BattClass = ClassData;
89 BattWait = BattClass->EventTriggerContext;
90
91 ExAcquireFastMutex(&BattClass->Mutex);
92 if (!BattClass->Waiting)
93 {
94 ExReleaseFastMutex(&BattClass->Mutex);
95 return STATUS_SUCCESS;
96 }
97
98 switch (BattClass->EventTrigger)
99 {
101 ExReleaseFastMutex(&BattClass->Mutex);
102 DPRINT1("Waiting for battery is UNIMPLEMENTED!\n");
103 break;
104
106 ExReleaseFastMutex(&BattClass->Mutex);
107 Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
108 BattWait->BatteryTag,
109 &BattStatus);
110 if (!NT_SUCCESS(Status))
111 return Status;
112
113 ExAcquireFastMutex(&BattClass->Mutex);
114
115 if (!(BattWait->PowerState & BattStatus.PowerState) ||
116 (BattWait->HighCapacity > BattStatus.Capacity) ||
117 (BattWait->LowCapacity < BattStatus.Capacity))
118 {
120 }
121
122 ExReleaseFastMutex(&BattClass->Mutex);
123 break;
124
125 default:
126 ExReleaseFastMutex(&BattClass->Mutex);
127 ASSERT(FALSE);
128 break;
129 }
130
131 return STATUS_SUCCESS;
132}
133
136NTAPI
139{
141 PBATTERY_CLASS_DATA BattClass;
142
144 sizeof(BATTERY_CLASS_DATA),
146 if (BattClass == NULL)
148
149 RtlZeroMemory(BattClass, sizeof(BATTERY_CLASS_DATA));
150
151 RtlCopyMemory(&BattClass->MiniportInfo,
152 MiniportInfo,
153 sizeof(BattClass->MiniportInfo));
154
156
157 ExInitializeFastMutex(&BattClass->Mutex);
158
159 if (MiniportInfo->Pdo != NULL)
160 {
161 Status = IoRegisterDeviceInterface(MiniportInfo->Pdo,
162 &GUID_DEVICE_BATTERY,
163 NULL,
164 &BattClass->InterfaceName);
165 if (NT_SUCCESS(Status))
166 {
167 DPRINT("Initialized battery interface: %wZ\n", &BattClass->InterfaceName);
170 {
171 DPRINT1("Got STATUS_OBJECT_NAME_EXISTS for SetDeviceInterfaceState\n");
173 }
174 }
175 else
176 {
177 DPRINT1("IoRegisterDeviceInterface failed (0x%x)\n", Status);
178 }
179 }
180
181 *ClassData = BattClass;
182
183 return STATUS_SUCCESS;
184}
185
188NTAPI
190 PIRP Irp)
191{
192 PBATTERY_CLASS_DATA BattClass;
195 ULONG WaitTime;
196 BATTERY_WAIT_STATUS BattWait;
197 PBATTERY_QUERY_INFORMATION BattQueryInfo;
198 PBATTERY_SET_INFORMATION BattSetInfo;
200 PBATTERY_STATUS BattStatus;
201 BATTERY_NOTIFY BattNotify;
203
204 DPRINT("BatteryClassIoctl(%p %p)\n", ClassData, Irp);
205
206 BattClass = ClassData;
207
209 Irp->IoStatus.Information = 0;
210
211 DPRINT("Received IOCTL %x for %p\n", IrpSp->Parameters.DeviceIoControl.IoControlCode,
212 ClassData);
213
214 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
215 {
217 if ((IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(ULONG) && IrpSp->Parameters.DeviceIoControl.InputBufferLength != 0) ||
218 IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
219 {
221 break;
222 }
223
224 WaitTime = IrpSp->Parameters.DeviceIoControl.InputBufferLength == sizeof(ULONG) ? *(PULONG)Irp->AssociatedIrp.SystemBuffer : 0;
225
226 Timeout.QuadPart = Int32x32To64(WaitTime, -1000);
227
228 Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
229 (PULONG)Irp->AssociatedIrp.SystemBuffer);
230 if (!NT_SUCCESS(Status))
231 {
232 ExAcquireFastMutex(&BattClass->Mutex);
233 BattClass->EventTrigger = EVENT_BATTERY_TAG;
234 BattClass->Waiting = TRUE;
235 ExReleaseFastMutex(&BattClass->Mutex);
236
238 Executive,
240 FALSE,
241 WaitTime != -1 ? &Timeout : NULL);
242
243 ExAcquireFastMutex(&BattClass->Mutex);
244 BattClass->Waiting = FALSE;
245 ExReleaseFastMutex(&BattClass->Mutex);
246
247 if (Status == STATUS_SUCCESS)
248 {
249 Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
250 (PULONG)Irp->AssociatedIrp.SystemBuffer);
251 if (NT_SUCCESS(Status))
252 Irp->IoStatus.Information = sizeof(ULONG);
253 }
254 else
255 {
257 }
258 }
259 else
260 {
261 Irp->IoStatus.Information = sizeof(ULONG);
262 }
263 break;
264
266 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BattWait) ||
267 IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BATTERY_STATUS))
268 {
270 break;
271 }
272
273 BattWait = *(PBATTERY_WAIT_STATUS)Irp->AssociatedIrp.SystemBuffer;
274
275 Timeout.QuadPart = Int32x32To64(BattWait.Timeout, -1000);
276
277 Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
278 BattWait.BatteryTag,
279 (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
280
281 BattStatus = Irp->AssociatedIrp.SystemBuffer;
282
283 if (!NT_SUCCESS(Status) ||
284 ((BattWait.PowerState & BattStatus->PowerState) &&
285 (BattWait.HighCapacity <= BattStatus->Capacity) &&
286 (BattWait.LowCapacity >= BattStatus->Capacity)))
287 {
288 BattNotify.PowerState = BattWait.PowerState;
289 BattNotify.HighCapacity = BattWait.HighCapacity;
290 BattNotify.LowCapacity = BattWait.LowCapacity;
291
292 BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
293 BattWait.BatteryTag,
294 &BattNotify);
295
296 ExAcquireFastMutex(&BattClass->Mutex);
298 BattClass->EventTriggerContext = &BattWait;
299 BattClass->Waiting = TRUE;
300 ExReleaseFastMutex(&BattClass->Mutex);
301
303 Executive,
305 FALSE,
306 BattWait.Timeout != -1 ? &Timeout : NULL);
307
308 ExAcquireFastMutex(&BattClass->Mutex);
309 BattClass->Waiting = FALSE;
310 ExReleaseFastMutex(&BattClass->Mutex);
311
313
314 if (Status == STATUS_SUCCESS)
315 {
316 Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
317 BattWait.BatteryTag,
318 (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
319 if (NT_SUCCESS(Status))
320 Irp->IoStatus.Information = sizeof(ULONG);
321 }
322 else
323 {
325 }
326 }
327 else
328 {
329 Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
330 }
331 break;
332
334 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattQueryInfo))
335 {
337 break;
338 }
339
340 BattQueryInfo = Irp->AssociatedIrp.SystemBuffer;
341
343 BattQueryInfo->BatteryTag,
344 BattQueryInfo->InformationLevel,
345 BattQueryInfo->AtRate,
346 Irp->AssociatedIrp.SystemBuffer,
347 IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
349 Irp->IoStatus.Information = ReturnedLength;
350 if (!NT_SUCCESS(Status))
351 {
352 DPRINT1("QueryInformation failed (0x%x)\n", Status);
353 }
354 break;
355
357 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattSetInfo))
358 {
360 break;
361 }
362
363 BattSetInfo = Irp->AssociatedIrp.SystemBuffer;
364
365 Status = BattClass->MiniportInfo.SetInformation(BattClass->MiniportInfo.Context,
366 BattSetInfo->BatteryTag,
367 BattSetInfo->InformationLevel,
368 BattSetInfo->Buffer);
369 if (!NT_SUCCESS(Status))
370 {
371 DPRINT1("SetInformation failed (0x%x)\n", Status);
372 }
373 break;
374
375 default:
376 DPRINT1("Received unsupported IRP %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
377 /* Do NOT complete the irp */
379 }
380
381 Irp->IoStatus.Status = Status;
383
384 return Status;
385}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
struct _BATTERY_WAIT_STATUS * PBATTERY_WAIT_STATUS
_Out_ PVOID * ClassData
Definition: batclass.h:336
_In_ PVOID WmiLibContext
Definition: batclass.h:377
#define IOCTL_BATTERY_QUERY_TAG
Definition: batclass.h:84
#define IOCTL_BATTERY_SET_INFORMATION
Definition: batclass.h:88
#define BCLASSAPI
Definition: batclass.h:326
#define IOCTL_BATTERY_QUERY_INFORMATION
Definition: batclass.h:86
struct _BATTERY_STATUS BATTERY_STATUS
#define IOCTL_BATTERY_QUERY_STATUS
Definition: batclass.h:90
BCLASSAPI NTSTATUS NTAPI BatteryClassQueryWmiDataBlock(PVOID ClassData, PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, PULONG InstanceLengthArray, ULONG OutBufferSize, PUCHAR Buffer)
Definition: battc.c:63
BCLASSAPI NTSTATUS NTAPI BatteryClassStatusNotify(PVOID ClassData)
Definition: battc.c:79
BCLASSAPI NTSTATUS NTAPI BatteryClassInitializeDevice(PBATTERY_MINIPORT_INFO MiniportInfo, PVOID *ClassData)
Definition: battc.c:137
BCLASSAPI NTSTATUS NTAPI BatteryClassIoctl(PVOID ClassData, PIRP Irp)
Definition: battc.c:189
BCLASSAPI NTSTATUS NTAPI BatteryClassSystemControl(PVOID ClassData, PVOID WmiLibContext, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Disposition)
Definition: battc.c:49
BCLASSAPI NTSTATUS NTAPI BatteryClassUnload(PVOID ClassData)
Definition: battc.c:27
#define EVENT_BATTERY_STATUS
Definition: battc.h:32
#define BATTERY_CLASS_DATA_TAG
Definition: battc.h:28
#define EVENT_BATTERY_TAG
Definition: battc.h:31
#define UNIMPLEMENTED
Definition: debug.h:118
Definition: bufpool.h:45
_In_ PIRP _In_ ULONG GuidIndex
Definition: classpnp.h:419
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:34
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define Int32x32To64(a, b)
@ SynchronizationEvent
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:776
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
static ULONG Timeout
Definition: ping.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
UNICODE_STRING InterfaceName
Definition: battc.h:24
KEVENT WaitEvent
Definition: battc.h:19
UCHAR EventTrigger
Definition: battc.h:22
PVOID EventTriggerContext
Definition: battc.h:23
FAST_MUTEX Mutex
Definition: battc.h:21
BATTERY_MINIPORT_INFO MiniportInfo
Definition: battc.h:18
BOOLEAN Waiting
Definition: battc.h:20
BCLASS_QUERY_INFORMATION QueryInformation
Definition: batclass.h:252
PDEVICE_OBJECT Pdo
Definition: batclass.h:257
BCLASS_SET_STATUS_NOTIFY SetStatusNotify
Definition: batclass.h:255
BCLASS_SET_INFORMATION SetInformation
Definition: batclass.h:253
BCLASS_DISABLE_STATUS_NOTIFY DisableStatusNotify
Definition: batclass.h:256
BCLASS_QUERY_STATUS QueryStatus
Definition: batclass.h:254
BCLASS_QUERY_TAG QueryTag
Definition: batclass.h:251
ULONG LowCapacity
Definition: batclass.h:204
ULONG HighCapacity
Definition: batclass.h:205
ULONG PowerState
Definition: batclass.h:203
BATTERY_QUERY_INFORMATION_LEVEL InformationLevel
Definition: batclass.h:110
BATTERY_SET_INFORMATION_LEVEL InformationLevel
Definition: batclass.h:141
ULONG PowerState
Definition: batclass.h:154
ULONG Capacity
Definition: batclass.h:155
struct _IO_STACK_LOCATION::@1575::@1576 DeviceIoControl
union _IO_STACK_LOCATION::@1575 Parameters
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ ULONG OutBufferSize
Definition: wdfwmi.h:87
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:415