xref: /reactos/drivers/bus/acpi/compbatt/compbatt.c (revision 34593d93)
1 /*
2  * PROJECT:         ReactOS Composite Battery Driver
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * FILE:            boot/drivers/bus/acpi/compbatt/compbatt.c
5  * PURPOSE:         Main Initialization Code and IRP Handling
6  * PROGRAMMERS:     ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "compbatt.h"
12 
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
17 ULONG CompBattDebug;
18 
19 /* FUNCTIONS ******************************************************************/
20 
21 NTSTATUS
22 NTAPI
CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)23 CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject,
24                   IN PIRP Irp)
25 {
26     PAGED_CODE();
27     if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING OpenClose\n");
28 
29     /* Complete the IRP with success */
30     Irp->IoStatus.Status = STATUS_SUCCESS;
31     Irp->IoStatus.Information = 0;
32     IoCompleteRequest(Irp, IO_NO_INCREMENT);
33 
34     /* Return success */
35     if (CompBattDebug & 0x100) DbgPrint("CompBatt: Exiting OpenClose\n");
36     return STATUS_SUCCESS;
37 }
38 
39 NTSTATUS
40 NTAPI
CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)41 CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject,
42                       IN PIRP Irp)
43 {
44     PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
45     NTSTATUS Status;
46     PAGED_CODE();
47     if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING System Control\n");
48 
49     /* Are we attached yet? */
50     if (DeviceExtension->AttachedDevice)
51     {
52         /* Send it up the stack */
53         IoSkipCurrentIrpStackLocation(Irp);
54         Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
55     }
56     else
57     {
58         /* We don't support WMI */
59         Status = STATUS_NOT_SUPPORTED;
60         Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
61         IoCompleteRequest(Irp, IO_NO_INCREMENT);
62     }
63 
64     /* Return status */
65     return Status;
66 }
67 
68 NTSTATUS
69 NTAPI
CompBattMonitorIrpComplete(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PKEVENT Event)70 CompBattMonitorIrpComplete(IN PDEVICE_OBJECT DeviceObject,
71                            IN PIRP Irp,
72                            IN PKEVENT Event)
73 {
74     UNIMPLEMENTED;
75     return STATUS_NOT_IMPLEMENTED;
76 }
77 
78 NTSTATUS
79 NTAPI
CompBattMonitorIrpCompleteWorker(IN PCOMPBATT_BATTERY_DATA BatteryData)80 CompBattMonitorIrpCompleteWorker(IN PCOMPBATT_BATTERY_DATA BatteryData)
81 {
82     UNIMPLEMENTED;
83     return STATUS_NOT_IMPLEMENTED;
84 }
85 
86 VOID
87 NTAPI
CompBattRecalculateTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)88 CompBattRecalculateTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
89 {
90     PCOMPBATT_BATTERY_DATA BatteryData;
91     ULONG Tag;
92     PLIST_ENTRY ListHead, NextEntry;
93     if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING CompBattRecalculateTag\n");
94 
95     /* Loop the battery list */
96     ExAcquireFastMutex(&DeviceExtension->Lock);
97     ListHead = &DeviceExtension->BatteryList;
98     NextEntry = ListHead->Flink;
99     while (NextEntry != ListHead)
100     {
101         /* Get the battery information and check if it has a tag */
102         BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
103         if (BatteryData->Flags & COMPBATT_TAG_ASSIGNED)
104         {
105             /* Generate the next tag and exit */
106             Tag = DeviceExtension->NextTag;
107             DeviceExtension->Flags |= COMPBATT_TAG_ASSIGNED;
108             DeviceExtension->Tag = Tag;
109             DeviceExtension->NextTag = Tag + 1;
110             break;
111        }
112 
113        /* No tag for this device extension, clear it */
114        DeviceExtension->Tag = 0;
115        NextEntry = NextEntry->Flink;
116     }
117 
118     /* We're done */
119     ExReleaseFastMutex(&DeviceExtension->Lock);
120     if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING CompBattRecalculateTag\n");
121 }
122 
123 NTSTATUS
124 NTAPI
CompBattIoctl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)125 CompBattIoctl(IN PDEVICE_OBJECT DeviceObject,
126               IN PIRP Irp)
127 {
128     PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
129     NTSTATUS Status;
130     if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING Ioctl\n");
131 
132     /* Let the class driver handle it */
133     Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp);
134     if (Status == STATUS_NOT_SUPPORTED)
135     {
136         /* It failed, try the next driver up the stack */
137         Irp->IoStatus.Status = Status;
138         IoSkipCurrentIrpStackLocation(Irp);
139         Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
140     }
141 
142     /* Return status */
143     if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING Ioctl\n");
144     return Status;
145 }
146 
147 NTSTATUS
148 NTAPI
CompBattQueryTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,OUT PULONG Tag)149 CompBattQueryTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
150                  OUT PULONG Tag)
151 {
152     NTSTATUS Status;
153     PAGED_CODE();
154     if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING QueryTag\n");
155 
156     /* Was a tag assigned? */
157     if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED))
158     {
159         /* Assign one */
160         CompBattRecalculateTag(DeviceExtension);
161     }
162 
163     /* Do we have a tag now? */
164     if ((DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) && (DeviceExtension->Tag))
165     {
166         /* Return the tag */
167         *Tag = DeviceExtension->Tag;
168         Status = STATUS_SUCCESS;
169     }
170     else
171     {
172         /* No tag */
173         *Tag = 0;
174         Status = STATUS_NO_SUCH_DEVICE;
175     }
176 
177     /* Return status */
178     if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING QueryTag\n");
179     return Status;
180 }
181 
182 NTSTATUS
183 NTAPI
CompBattDisableStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)184 CompBattDisableStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
185 {
186     PCOMPBATT_BATTERY_DATA BatteryData;
187     PLIST_ENTRY ListHead, NextEntry;
188     if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING DisableStatusNotify\n");
189 
190     /* Loop the battery list */
191     ExAcquireFastMutex(&DeviceExtension->Lock);
192     ListHead = &DeviceExtension->BatteryList;
193     NextEntry = ListHead->Flink;
194     while (NextEntry != ListHead)
195     {
196         /* Get the battery information and clear capacity data */
197         BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
198         BatteryData->WaitStatus.LowCapacity = 0;
199         BatteryData->WaitStatus.HighCapacity = 0x7FFFFFFF;
200         NextEntry = NextEntry->Flink;
201     }
202 
203     /* Done */
204     ExReleaseFastMutex(&DeviceExtension->Lock);
205     if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING DisableStatusNotify\n");
206     return STATUS_SUCCESS;
207 }
208 
209 NTSTATUS
210 NTAPI
CompBattSetStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,IN ULONG BatteryTag,IN PBATTERY_NOTIFY BatteryNotify)211 CompBattSetStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
212                         IN ULONG BatteryTag,
213                         IN PBATTERY_NOTIFY BatteryNotify)
214 {
215     UNIMPLEMENTED;
216     return STATUS_NOT_IMPLEMENTED;
217 }
218 
219 NTSTATUS
220 NTAPI
CompBattQueryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,IN ULONG Tag,IN PBATTERY_STATUS BatteryStatus)221 CompBattQueryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
222                     IN ULONG Tag,
223                     IN PBATTERY_STATUS BatteryStatus)
224 {
225     UNIMPLEMENTED;
226     return STATUS_NOT_IMPLEMENTED;
227 }
228 
229 NTSTATUS
230 NTAPI
CompBattGetBatteryInformation(OUT PBATTERY_INFORMATION BatteryInfo,IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)231 CompBattGetBatteryInformation(OUT PBATTERY_INFORMATION BatteryInfo,
232                               IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
233 {
234     NTSTATUS Status = STATUS_SUCCESS;
235     BATTERY_QUERY_INFORMATION InputBuffer;
236     PCOMPBATT_BATTERY_DATA BatteryData;
237     PLIST_ENTRY ListHead, NextEntry;
238     if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteryInformation\n");
239 
240     /* Set defaults */
241     BatteryInfo->DefaultAlert1 = 0;
242     BatteryInfo->DefaultAlert2 = 0;
243     BatteryInfo->CriticalBias = 0;
244 
245     /* Loop the battery list */
246     ExAcquireFastMutex(&DeviceExtension->Lock);
247     ListHead = &DeviceExtension->BatteryList;
248     NextEntry = ListHead->Flink;
249     while (NextEntry != ListHead)
250     {
251         /* Try to acquire the remove lock */
252         BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
253         if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, 0)))
254         {
255             /* Now release the device lock since the battery can't go away */
256             ExReleaseFastMutex(&DeviceExtension->Lock);
257 
258             /* Build the query */
259             InputBuffer.BatteryTag = BatteryData->Tag;
260             InputBuffer.InformationLevel = BatteryInformation;
261             InputBuffer.AtRate = 0;
262 
263             /* Make sure the battery has a tag */
264             if (BatteryData->Tag)
265             {
266                 /* Do we already have the data? */
267                 if (!(BatteryData->Flags & COMPBATT_BATTERY_INFORMATION_PRESENT))
268                 {
269                     /* Send the IOCTL to query the information */
270                     RtlZeroMemory(&BatteryData->BatteryInformation,
271                                   sizeof(BatteryData->BatteryInformation));
272                     Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION,
273                                           BatteryData->DeviceObject,
274                                           &InputBuffer,
275                                           sizeof(InputBuffer),
276                                           &BatteryData->BatteryInformation,
277                                           sizeof(BatteryData->BatteryInformation),
278                                           0);
279                     if (!NT_SUCCESS(Status))
280                     {
281                         /* Fail if the query had a problem */
282                         if (Status == STATUS_DEVICE_REMOVED) Status = STATUS_NO_SUCH_DEVICE;
283                         ExAcquireFastMutex(&DeviceExtension->Lock);
284                         IoReleaseRemoveLock(&BatteryData->RemoveLock, 0);
285                         break;
286                     }
287 
288                     /* Next time we can use the static copy */
289                     BatteryData->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT;
290                     if (CompBattDebug & 2)
291                         DbgPrint("CompBattGetBatteryInformation: Read individual BATTERY_INFORMATION\n"
292                                  "--------  Capabilities = %x\n--------  Technology = %x\n"
293                                  "--------  Chemistry[4] = %x\n--------  DesignedCapacity = %x\n"
294                                  "--------  FullChargedCapacity = %x\n--------  DefaultAlert1 = %x\n"
295                                  "--------  DefaultAlert2 = %x\n--------  CriticalBias = %x\n"
296                                  "--------  CycleCount = %x\n",
297                                  BatteryData->BatteryInformation.Capabilities,
298                                  BatteryData->BatteryInformation.Technology,
299                                  BatteryData->BatteryInformation.Chemistry,
300                                  BatteryData->BatteryInformation.DesignedCapacity,
301                                  BatteryData->BatteryInformation.FullChargedCapacity,
302                                  BatteryData->BatteryInformation.DefaultAlert1,
303                                  BatteryData->BatteryInformation.DefaultAlert2,
304                                  BatteryData->BatteryInformation.CriticalBias,
305                                  BatteryData->BatteryInformation.CycleCount);
306                 }
307 
308                 /* Combine capabilities */
309                 BatteryInfo->Capabilities |= BatteryData->BatteryInformation.Capabilities;
310 
311                 /* Add-on capacity */
312                 if (BatteryData->BatteryInformation.DesignedCapacity != BATTERY_UNKNOWN_CAPACITY)
313                 {
314                     BatteryInfo->DesignedCapacity += BatteryData->BatteryInformation.DesignedCapacity;
315                 }
316 
317                 /* Add on fully charged capacity */
318                 if (BatteryData->BatteryInformation.FullChargedCapacity != BATTERY_UNKNOWN_CAPACITY)
319                 {
320                     BatteryInfo->FullChargedCapacity += BatteryData->BatteryInformation.FullChargedCapacity;
321                 }
322 
323                 /* Choose the highest alert */
324                 BatteryInfo->DefaultAlert1 = max(BatteryInfo->DefaultAlert1,
325                                                  BatteryData->BatteryInformation.DefaultAlert1);
326 
327                 /* Choose the highest alert */
328                 BatteryInfo->DefaultAlert2 = max(BatteryInfo->DefaultAlert2,
329                                                  BatteryData->BatteryInformation.DefaultAlert2);
330 
331                 /* Choose the highest critical bias */
332                 BatteryInfo->CriticalBias = max(BatteryInfo->CriticalBias,
333                                                 BatteryData->BatteryInformation.CriticalBias);
334             }
335 
336             /* Re-acquire the device extension lock and release the remove lock */
337             ExAcquireFastMutex(&DeviceExtension->Lock);
338             IoReleaseRemoveLock(&BatteryData->RemoveLock, 0);
339         }
340 
341         /* Next entry */
342         NextEntry = NextEntry->Flink;
343     }
344 
345     /* We are done with the list, check if the information was queried okay */
346     ExReleaseFastMutex(&DeviceExtension->Lock);
347     if (NT_SUCCESS(Status))
348     {
349         /* If there's no fully charged capacity, use the design capacity */
350         if (!BatteryInfo->FullChargedCapacity)
351         {
352             BatteryInfo->FullChargedCapacity = BatteryInfo->DesignedCapacity;
353         }
354 
355         /* Print out final combined data */
356         if (CompBattDebug & 2)
357             DbgPrint("CompBattGetBatteryInformation: Returning BATTERY_INFORMATION\n"
358                      "--------  Capabilities = %x\n--------  Technology = %x\n"
359                      "--------  Chemistry[4] = %x\n--------  DesignedCapacity = %x\n"
360                      "--------  FullChargedCapacity = %x\n--------  DefaultAlert1 = %x\n"
361                      "--------  DefaultAlert2 = %x\n--------  CriticalBias = %x\n"
362                      "--------  CycleCount = %x\n",
363                      BatteryInfo->Capabilities,
364                      BatteryInfo->Technology,
365                      BatteryInfo->Chemistry,
366                      BatteryInfo->DesignedCapacity,
367                      BatteryInfo->FullChargedCapacity,
368                      BatteryInfo->DefaultAlert1,
369                      BatteryInfo->DefaultAlert2,
370                      BatteryInfo->CriticalBias,
371                      BatteryInfo->CycleCount);
372 
373         /* Copy the data into the device extension */
374         RtlCopyMemory(&DeviceExtension->BatteryInformation,
375                       BatteryInfo,
376                       sizeof(DeviceExtension->BatteryInformation));
377         DeviceExtension->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT;
378     }
379 
380     /* We are done */
381     if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteryInformation\n");
382     return Status;
383 }
384 
385 NTSTATUS
386 NTAPI
CompBattGetBatteryGranularity(OUT PBATTERY_REPORTING_SCALE ReportingScale,IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)387 CompBattGetBatteryGranularity(OUT PBATTERY_REPORTING_SCALE ReportingScale,
388                               IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
389 {
390     NTSTATUS Status = STATUS_SUCCESS;
391     BATTERY_QUERY_INFORMATION InputBuffer;
392     PCOMPBATT_BATTERY_DATA BatteryData;
393     BATTERY_REPORTING_SCALE BatteryScale[4];
394     PLIST_ENTRY ListHead, NextEntry;
395     ULONG i;
396     if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteryGranularity\n");
397 
398     /* Set defaults */
399     ReportingScale[0].Granularity = -1;
400     ReportingScale[1].Granularity = -1;
401     ReportingScale[2].Granularity = -1;
402     ReportingScale[3].Granularity = -1;
403 
404     /* Loop the battery list */
405     ExAcquireFastMutex(&DeviceExtension->Lock);
406     ListHead = &DeviceExtension->BatteryList;
407     NextEntry = ListHead->Flink;
408     while (NextEntry != ListHead)
409     {
410         /* Try to acquire the remove lock */
411         BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink);
412         if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, 0)))
413         {
414             /* Now release the device lock since the battery can't go away */
415             ExReleaseFastMutex(&DeviceExtension->Lock);
416 
417             /* Build the query */
418             InputBuffer.BatteryTag = BatteryData->Tag;
419             InputBuffer.InformationLevel = BatteryGranularityInformation;
420 
421             /* Make sure the battery has a tag */
422             if (BatteryData->Tag)
423             {
424                 /* Send the IOCTL to query the information */
425                 RtlZeroMemory(&BatteryData->BatteryInformation,
426                               sizeof(BatteryData->BatteryInformation));
427                 Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION,
428                                       BatteryData->DeviceObject,
429                                       &InputBuffer,
430                                       sizeof(InputBuffer),
431                                       &BatteryScale,
432                                       sizeof(BatteryScale),
433                                       0);
434                 if (!NT_SUCCESS(Status))
435                 {
436                     /* Fail if the query had a problem */
437                     ExAcquireFastMutex(&DeviceExtension->Lock);
438                     IoReleaseRemoveLock(&BatteryData->RemoveLock, 0);
439                     break;
440                 }
441 
442                 /* Loop all 4 scales */
443                 for (i = 0; i < 4; i++)
444                 {
445                     /* Check for valid granularity */
446                     if (BatteryScale[i].Granularity)
447                     {
448                         /* If it's smaller, use it instead */
449                         ReportingScale[i].Granularity = min(BatteryScale[i].Granularity,
450                                                             ReportingScale[i].Granularity);
451                     }
452 
453                 }
454             }
455 
456             /* Re-acquire the device extension lock and release the remove lock */
457             ExAcquireFastMutex(&DeviceExtension->Lock);
458             IoReleaseRemoveLock(&BatteryData->RemoveLock, 0);
459         }
460 
461         /* Next entry */
462         NextEntry = NextEntry->Flink;
463     }
464 
465     /* All done */
466     ExReleaseFastMutex(&DeviceExtension->Lock);
467     if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteryGranularity\n");
468     return STATUS_SUCCESS;
469 }
470 
471 NTSTATUS
472 NTAPI
CompBattGetEstimatedTime(OUT PULONG Time,IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)473 CompBattGetEstimatedTime(OUT PULONG Time,
474                          IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension)
475 {
476     UNIMPLEMENTED;
477     return STATUS_NOT_IMPLEMENTED;
478 }
479 
480 NTSTATUS
481 NTAPI
CompBattQueryInformation(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,IN ULONG Tag,IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel,IN OPTIONAL LONG AtRate,IN PVOID Buffer,IN ULONG BufferLength,OUT PULONG ReturnedLength)482 CompBattQueryInformation(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
483                          IN ULONG Tag,
484                          IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel,
485                          IN OPTIONAL LONG AtRate,
486                          IN PVOID Buffer,
487                          IN ULONG BufferLength,
488                          OUT PULONG ReturnedLength)
489 {
490     BATTERY_INFORMATION BatteryInfo;
491     BATTERY_REPORTING_SCALE BatteryGranularity[4];
492     PWCHAR BatteryName = L"Composite Battery";
493     //BATTERY_MANUFACTURE_DATE Date;
494     ULONG Dummy, Time;
495     PVOID QueryData = NULL;
496     ULONG QueryLength = 0;
497     NTSTATUS Status = STATUS_SUCCESS;
498     PAGED_CODE();
499     if (CompBattDebug & 1)  DbgPrint("CompBatt: ENTERING QueryInformation\n");
500 
501     /* Check for valid/correct tag */
502     if ((Tag != DeviceExtension->Tag) ||
503         (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED)))
504     {
505         /* Not right, so fail */
506         return STATUS_NO_SUCH_DEVICE;
507     }
508 
509     /* Check what caller wants */
510     switch (InfoLevel)
511     {
512         case BatteryInformation:
513 
514             /* Query combined battery information */
515             RtlZeroMemory(&BatteryInfo, sizeof(BatteryInfo));
516             Status = CompBattGetBatteryInformation(&BatteryInfo, DeviceExtension);
517             if (NT_SUCCESS(Status))
518             {
519                 /* Return the data if successful */
520                 QueryData = &BatteryInfo;
521                 QueryLength = sizeof(BatteryInfo);
522             }
523             break;
524 
525         case BatteryGranularityInformation:
526 
527             /* Query combined granularity information */
528             RtlZeroMemory(&BatteryGranularity, sizeof(BatteryGranularity));
529             Status = CompBattGetBatteryGranularity(BatteryGranularity, DeviceExtension);
530             if (NT_SUCCESS(Status))
531             {
532                 /* Return the data if successful */
533                 QueryLength = sizeof(BatteryGranularity);
534                 QueryData = &BatteryGranularity;
535             }
536             break;
537 
538         case BatteryEstimatedTime:
539 
540             /* Query combined time estimate information */
541             RtlZeroMemory(&Time, sizeof(Time));
542             Status = CompBattGetEstimatedTime(&Time, DeviceExtension);
543             if (NT_SUCCESS(Status))
544             {
545                 /* Return the data if successful */
546                 QueryLength = sizeof(Time);
547                 QueryData = &Time;
548             }
549             break;
550 
551         case BatteryManufactureName:
552         case BatteryDeviceName:
553 
554             /* Return the static buffer */
555             QueryData = BatteryName;
556             QueryLength = sizeof(L"Composite Battery");
557             break;
558 
559         case BatteryManufactureDate:
560 
561             /* Static data */
562             //Date.Day = 26;
563             //Date.Month = 06;
564             //Date.Year = 1997;
565             break;
566 
567         case BatteryTemperature:
568         case BatteryUniqueID:
569 
570             /* Return zero */
571             Dummy = 0;
572             QueryData = &Dummy;
573             QueryLength = sizeof(Dummy);
574             break;
575 
576         default:
577             /* Everything else is unknown */
578             Status = STATUS_INVALID_PARAMETER;
579             break;
580     }
581 
582     /* Return the required length and check if the caller supplied enough */
583     *ReturnedLength = QueryLength;
584     if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL;
585 
586     /* Copy the data if there's enough space and it exists */
587     if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength);
588 
589     /* Return function result */
590     if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING QueryInformation\n");
591     return Status;
592 }
593 
594 NTSTATUS
595 NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)596 DriverEntry(IN PDRIVER_OBJECT DriverObject,
597             IN PUNICODE_STRING RegistryPath)
598 {
599     /* Register add device routine */
600     DriverObject->DriverExtension->AddDevice = CompBattAddDevice;
601 
602     /* Register other handlers */
603     DriverObject->MajorFunction[IRP_MJ_CREATE] = CompBattOpenClose;
604     DriverObject->MajorFunction[IRP_MJ_CLOSE] = CompBattOpenClose;
605     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CompBattIoctl;
606     DriverObject->MajorFunction[IRP_MJ_POWER] = CompBattPowerDispatch;
607     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CompBattSystemControl;
608     DriverObject->MajorFunction[IRP_MJ_PNP] = CompBattPnpDispatch;
609     return STATUS_SUCCESS;
610 }
611 
612 /* EOF */
613