ReactOS  0.4.14-dev-608-gd495a4f
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 
15 NTAPI
18 {
19  DPRINT("Battery class driver initialized\n");
20 
21  return STATUS_SUCCESS;
22 }
23 
26 NTAPI
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 
48 NTAPI
52  PIRP Irp,
54 {
56 
58 }
59 
62 NTAPI
65  PIRP Irp,
67  PULONG InstanceLengthArray,
69  PUCHAR Buffer)
70 {
72 
74 }
75 
78 NTAPI
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  {
100  case EVENT_BATTERY_TAG:
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  {
119  KeSetEvent(&BattClass->WaitEvent, IO_NO_INCREMENT, FALSE);
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 
134 BCLASSAPI
135 NTSTATUS
136 NTAPI
138  PVOID *ClassData)
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 
186 BCLASSAPI
187 NTSTATUS
188 NTAPI
190  PIRP Irp)
191 {
192  PBATTERY_CLASS_DATA BattClass;
195  ULONG WaitTime;
196  PBATTERY_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) ||
218  IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
219  {
221  break;
222  }
223 
224  WaitTime = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
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 
237  Status = KeWaitForSingleObject(&BattClass->WaitEvent,
238  Executive,
239  KernelMode,
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 = 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);
297  BattClass->EventTrigger = EVENT_BATTERY_STATUS;
298  BattClass->EventTriggerContext = BattWait;
299  BattClass->Waiting = TRUE;
300  ExReleaseFastMutex(&BattClass->Mutex);
301 
302  Status = KeWaitForSingleObject(&BattClass->WaitEvent,
303  Executive,
304  KernelMode,
305  FALSE,
306  BattWait->Timeout != -1 ? &Timeout : NULL);
307 
308  ExAcquireFastMutex(&BattClass->Mutex);
309  BattClass->Waiting = FALSE;
310  ExReleaseFastMutex(&BattClass->Mutex);
311 
312  BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
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 
342  Status = BattClass->MiniportInfo.QueryInformation(BattClass->MiniportInfo.Context,
343  BattQueryInfo->BatteryTag,
344  BattQueryInfo->InformationLevel,
345  BattQueryInfo->AtRate,
346  Irp->AssociatedIrp.SystemBuffer,
347  IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
348  &ReturnedLength);
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 */
378  return STATUS_NOT_SUPPORTED;
379  }
380 
381  Irp->IoStatus.Status = Status;
383 
384  return Status;
385 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
BCLASSAPI NTSTATUS NTAPI BatteryClassInitializeDevice(PBATTERY_MINIPORT_INFO MiniportInfo, PVOID *ClassData)
Definition: battc.c:137
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:762
#define EVENT_BATTERY_STATUS
Definition: battc.h:32
_In_ PVOID WmiLibContext
Definition: batclass.h:377
#define IOCTL_BATTERY_QUERY_INFORMATION
Definition: batclass.h:86
_In_ PIRP Irp
Definition: csq.h:116
ULONG PowerState
Definition: batclass.h:154
unsigned char * PUCHAR
Definition: retypes.h:3
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING InterfaceName
Definition: battc.h:24
_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG OutBufferSize
Definition: classpnp.h:429
BCLASSAPI NTSTATUS NTAPI BatteryClassIoctl(PVOID ClassData, PIRP Irp)
Definition: battc.c:189
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
BCLASSAPI NTSTATUS NTAPI BatteryClassUnload(PVOID ClassData)
Definition: battc.c:27
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: battc.c:16
KEVENT WaitEvent
Definition: battc.h:19
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
BCLASS_DISABLE_STATUS_NOTIFY DisableStatusNotify
Definition: batclass.h:256
BATTERY_SET_INFORMATION_LEVEL InformationLevel
Definition: batclass.h:141
#define BCLASSAPI
Definition: batclass.h:326
smooth NULL
Definition: ftsmooth.c:416
BCLASSAPI NTSTATUS NTAPI BatteryClassStatusNotify(PVOID ClassData)
Definition: battc.c:79
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
_In_ PIRP _In_ ULONG GuidIndex
Definition: classpnp.h:401
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
BATTERY_QUERY_INFORMATION_LEVEL InformationLevel
Definition: batclass.h:110
ULONG HighCapacity
Definition: batclass.h:205
#define BATTERY_CLASS_DATA_TAG
Definition: battc.h:28
ULONG PowerState
Definition: batclass.h:203
#define IOCTL_BATTERY_SET_INFORMATION
Definition: batclass.h:88
FAST_MUTEX Mutex
Definition: battc.h:21
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
PDEVICE_OBJECT Pdo
Definition: batclass.h:257
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define IOCTL_BATTERY_QUERY_TAG
Definition: batclass.h:84
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PVOID EventTriggerContext
Definition: battc.h:23
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
BCLASSAPI NTSTATUS NTAPI BatteryClassSystemControl(PVOID ClassData, PVOID WmiLibContext, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Disposition)
Definition: battc.c:49
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
BCLASS_QUERY_INFORMATION QueryInformation
Definition: batclass.h:252
UCHAR EventTrigger
Definition: battc.h:22
ULONG Capacity
Definition: batclass.h:155
#define IOCTL_BATTERY_QUERY_STATUS
Definition: batclass.h:90
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
BCLASSAPI NTSTATUS NTAPI BatteryClassQueryWmiDataBlock(PVOID ClassData, PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, PULONG InstanceLengthArray, ULONG OutBufferSize, PUCHAR Buffer)
Definition: battc.c:63
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
ULONG LowCapacity
Definition: batclass.h:204
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
static ULONG Timeout
Definition: ping.c:61
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
#define EVENT_BATTERY_TAG
Definition: battc.h:31
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
BCLASS_SET_INFORMATION SetInformation
Definition: batclass.h:253
unsigned int * PULONG
Definition: retypes.h:1
BOOLEAN Waiting
Definition: battc.h:20
#define DPRINT1
Definition: precomp.h:8
BATTERY_MINIPORT_INFO MiniportInfo
Definition: battc.h:18
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
BCLASS_SET_STATUS_NOTIFY SetStatusNotify
Definition: batclass.h:255
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
BCLASS_QUERY_TAG QueryTag
Definition: batclass.h:251
BCLASS_QUERY_STATUS QueryStatus
Definition: batclass.h:254
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define Int32x32To64(a, b)
struct _BATTERY_STATUS BATTERY_STATUS
_Out_ PVOID * ClassData
Definition: batclass.h:336