ReactOS 0.4.16-dev-306-g647d351
cmbpnp.c
Go to the documentation of this file.
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/cmbpnp.c
5 * PURPOSE: Plug-and-Play IOCTL/IRP Handling
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "cmbatt.h"
12
13/* FUNCTIONS ******************************************************************/
14
15VOID
22{
24 PCMBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
25 if (CmBattDebug & 0x20) DbgPrint("CmBattWaitWakeLoop: Entered.\n");
26
27 /* Check for success */
28 if ((NT_SUCCESS(IoStatusBlock->Status)) && (DeviceExtension->WaitWakeEnable))
29 {
30 /* Request a new power IRP */
31 if (CmBattDebug & 2) DbgPrint("CmBattWaitWakeLoop: completed successfully\n");
36 Context,
37 &DeviceExtension->PowerIrp);
38 if (CmBattDebug & 2)
39 DbgPrint("CmBattWaitWakeLoop: PoRequestPowerIrp: status = 0x%08x.\n",
40 Status);
41 }
42 else
43 {
44 /* Clear the power IRP, we failed */
45 if (CmBattDebug & 0xC)
46 DbgPrint("CmBattWaitWakeLoop: failed: status = 0x%08x.\n",
48 DeviceExtension->PowerIrp = NULL;
49 }
50}
51
55 IN PIRP Irp,
57{
58 if (CmBattDebug & 2) DbgPrint("CmBattIoCompletion: Event (%x)\n", Event);
59
60 /* Set the completion event */
63}
64
68 IN OUT PACPI_INTERFACE_STANDARD AcpiInterface)
69{
70 PIRP Irp;
72 PIO_STACK_LOCATION IoStackLocation;
74
75 /* Allocate the IRP */
76 Irp = IoAllocateIrp(DeviceObject->StackSize, 0);
77 if (!Irp)
78 {
79 /* Fail */
80 if (CmBattDebug & 0xC)
81 DbgPrint("CmBattGetAcpiInterfaces: Failed to allocate Irp\n");
83 }
84
85 /* Set default error code */
86 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
87
88 /* Build the query */
89 IoStackLocation = IoGetNextIrpStackLocation(Irp);
90 IoStackLocation->MajorFunction = IRP_MJ_PNP;
91 IoStackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
92 IoStackLocation->Parameters.QueryInterface.InterfaceType = &GUID_ACPI_INTERFACE_STANDARD;
93 IoStackLocation->Parameters.QueryInterface.Size = sizeof(ACPI_INTERFACE_STANDARD);
94 IoStackLocation->Parameters.QueryInterface.Version = 1;
95 IoStackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)AcpiInterface;
96 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData = NULL;
97
98 /* Set default ACPI interface data */
99 AcpiInterface->Size = sizeof(ACPI_INTERFACE_STANDARD);
100 AcpiInterface->Version = 1;
101
102 /* Initialize our wait event */
104
105 /* Set the completion routine */
108 &Event,
109 TRUE,
110 TRUE,
111 TRUE);
112
113 /* Now call ACPI */
115 if (Status == STATUS_PENDING)
116 {
117 /* Wait for completion */
119 Executive,
121 FALSE,
122 NULL);
123 Status = Irp->IoStatus.Status;
124 }
125
126 /* Free the IRP */
127 IoFreeIrp(Irp);
128
129 /* Return status */
130 if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0xC))
131 DbgPrint("CmBattGetAcpiInterfaces: Could not get ACPI driver interfaces, status = %x\n", Status);
132 return Status;
133}
134
135VOID
136NTAPI
138{
139 PAGED_CODE();
140 if (CmBattDebug & 0x220) DbgPrint("CmBattDestroyFdo, Battery.\n");
141
142 /* Delete the device */
144 if (CmBattDebug & 0x220) DbgPrint("CmBattDestroyFdo: done.\n");
145}
146
148NTAPI
150 IN PIRP Irp)
151{
152 PCMBATT_DEVICE_EXTENSION DeviceExtension;
154 DeviceExtension = DeviceObject->DeviceExtension;
155 if (CmBattDebug & 2)
156 DbgPrint("CmBattRemoveDevice: CmBatt (%x), Type %d, _UID %d\n",
157 DeviceExtension,
158 DeviceExtension->FdoType,
159 DeviceExtension->DeviceId);
160
161 /* Make sure it's safe to go ahead */
162 IoReleaseRemoveLockAndWait(&DeviceExtension->RemoveLock, 0);
163
164 /* Check for pending power IRP */
165 if (DeviceExtension->PowerIrp)
166 {
167 /* Cancel and clear */
168 IoCancelIrp(DeviceExtension->PowerIrp);
169 DeviceExtension->PowerIrp = NULL;
170 }
171
172 /* Check what type of FDO is being removed */
173 Context = DeviceExtension->AcpiInterface.Context;
174 if (DeviceExtension->FdoType == CmBattBattery)
175 {
176 /* Unregister battery FDO */
179 CmBattWmiDeRegistration(DeviceExtension);
180 if (!NT_SUCCESS(BatteryClassUnload(DeviceExtension->ClassData))) ASSERT(FALSE);
181 }
182 else
183 {
184 /* Unregister AC adapter FDO */
187 CmBattWmiDeRegistration(DeviceExtension);
189 }
190
191 /* Detach and delete */
192 IoDetachDevice(DeviceExtension->AttachedDevice);
193 IoDeleteDevice(DeviceExtension->DeviceObject);
194 return STATUS_SUCCESS;
195}
196
198NTAPI
200 IN PIRP Irp)
201{
202 PIO_STACK_LOCATION IoStackLocation;
203 PCMBATT_DEVICE_EXTENSION DeviceExtension;
205 if (CmBattDebug & 0x210) DbgPrint("CmBattPowerDispatch\n");
206
207 /* Get stack location and device extension */
208 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
209 DeviceExtension = DeviceObject->DeviceExtension;
210 switch (IoStackLocation->MinorFunction)
211 {
212 case IRP_MN_WAIT_WAKE:
213 if (CmBattDebug & 0x10)
214 DbgPrint("CmBattPowerDispatch: IRP_MN_WAIT_WAKE\n");
215 break;
216
218 if (CmBattDebug & 0x10)
219 DbgPrint("CmBattPowerDispatch: IRP_MN_POWER_SEQUENCE\n");
220 break;
221
223 if (CmBattDebug & 0x10)
224 DbgPrint("CmBattPowerDispatch: IRP_MN_WAIT_WAKE\n");
225 break;
226
227 case IRP_MN_SET_POWER:
228 if (CmBattDebug & 0x10)
229 DbgPrint("CmBattPowerDispatch: IRP_MN_SET_POWER type: %d, State: %d \n",
230 IoStackLocation->Parameters.Power.Type,
231 IoStackLocation->Parameters.Power.State);
232 break;
233
234 default:
235
236 if (CmBattDebug & 1)
237 DbgPrint("CmBattPowerDispatch: minor %d\n", IoStackLocation->MinorFunction);
238 break;
239 }
240
241 /* Start the next IRP and see if we're attached */
243 if (DeviceExtension->AttachedDevice)
244 {
245 /* Call ACPI */
247 Status = PoCallDriver(DeviceExtension->AttachedDevice, Irp);
248 }
249 else
250 {
251 /* Complete the request here */
252 Status = Irp->IoStatus.Status;
254 }
255
256 /* Return status */
257 return Status;
258}
259
261NTAPI
263 IN PIRP Irp)
264{
265 PIO_STACK_LOCATION IoStackLocation;
266 PCMBATT_DEVICE_EXTENSION DeviceExtension;
269 PAGED_CODE();
270
271 /* Get stack location and device extension */
272 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
273 DeviceExtension = DeviceObject->DeviceExtension;
274
275 /* Set default error */
277
278 /* Try to acquire the lock before doing anything */
279 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
280 if (!NT_SUCCESS(Status))
281 {
282 /* Complete the request */
283 Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
286 }
287
288 /* What's the operation? */
289 switch (IoStackLocation->MinorFunction)
290 {
292
293 /* Initialize our wait event */
295
296 /* Set the completion routine */
300 &Event,
301 TRUE,
302 TRUE,
303 TRUE);
304
305 /* Now call ACPI to inherit its PnP Device State */
306 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
307 if (Status == STATUS_PENDING)
308 {
309 /* Wait for completion */
311 Executive,
313 FALSE,
314 NULL);
315 Status = Irp->IoStatus.Status;
316 }
317
318 /* However, a battery CAN be disabled */
319 Irp->IoStatus.Information &= ~PNP_DEVICE_NOT_DISABLEABLE;
320
321 /* Release the remove lock and complete the request */
323 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
324 return Status;
325
327 if (CmBattDebug & 0x20)
328 DbgPrint("CmBattPnpDispatch: IRP_MN_SURPRISE_REMOVAL\n");
329
330 /* Lock the device extension and set the handle count to invalid */
331 ExAcquireFastMutex(&DeviceExtension->FastMutex);
332 DeviceExtension->HandleCount = -1;
333 ExReleaseFastMutex(&DeviceExtension->FastMutex);
335 break;
336
338 if (CmBattDebug & 0x20)
339 DbgPrint("CmBattPnpDispatch: IRP_MN_START_DEVICE\n");
340
341 /* Mark the extension as started */
342 if (DeviceExtension->FdoType == CmBattBattery) DeviceExtension->Started = TRUE;
344 break;
345
347 if (CmBattDebug & 0x20)
348 DbgPrint("CmBattPnpDispatch: IRP_MN_STOP_DEVICE\n");
349
350 /* Mark the extension as stopped */
351 if (DeviceExtension->FdoType == CmBattBattery) DeviceExtension->Started = FALSE;
353 break;
354
356 if (CmBattDebug & 0x20)
357 DbgPrint("CmBattPnpDispatch: IRP_MN_QUERY_REMOVE_DEVICE\n");
358
359 /* Lock the extension and get the current handle count */
360 ExAcquireFastMutex(&DeviceExtension->FastMutex);
361 if (DeviceExtension->HandleCount == 0)
362 {
363 /* No handles. Mark it as invalid since it'll be removed */
364 DeviceExtension->HandleCount = -1;
366 }
367 else if (DeviceExtension->HandleCount == -1)
368 {
369 /* Don't do anything, but this is strange since it's already removed */
371 if (CmBattDebug & 4)
372 DbgPrint("CmBattPnpDispatch: Received two consecutive QUERY_REMOVE requests.\n");
373 }
374 else
375 {
376 /* Fail because there's still open handles */
378 }
379
380 /* Release the lock and return */
381 ExReleaseFastMutex(&DeviceExtension->FastMutex);
382 break;
383
385 if (CmBattDebug & 0x20)
386 DbgPrint("CmBattPnpDispatch: IRP_MN_REMOVE_DEVICE\n");
387
388 /* Call the remove code */
390 break;
391
393 if (CmBattDebug & 0x20)
394 DbgPrint("CmBattPnpDispatch: IRP_MN_CANCEL_REMOVE_DEVICE\n");
395
396 /* Lock the extension and get the handle count */
397 ExAcquireFastMutex(&DeviceExtension->FastMutex);
398 if (DeviceExtension->HandleCount == -1)
399 {
400 /* A remove was in progress, set the handle count back to 0 */
401 DeviceExtension->HandleCount = 0;
402 }
403 else if (CmBattDebug & 2)
404 {
405 /* Nop, but warn about it */
406 DbgPrint("CmBattPnpDispatch: Received CANCEL_REMOVE when OpenCount == %x\n",
407 DeviceExtension->HandleCount);
408 }
409
410 /* Return success in all cases, and release the lock */
412 ExReleaseFastMutex(&DeviceExtension->FastMutex);
413 break;
414
416 if (CmBattDebug & 0x20)
417 DbgPrint("CmBattPnpDispatch: IRP_MN_QUERY_STOP_DEVICE\n");
418
419 /* There's no real support for this */
421 break;
422
424 if (CmBattDebug & 0x20)
425 DbgPrint("CmBattPnpDispatch: IRP_MN_CANCEL_STOP_DEVICE\n");
426
427 /* There's no real support for this */
429 break;
430
432
433 /* Initialize our wait event */
435
436 /* Set the completion routine */
440 &Event,
441 TRUE,
442 TRUE,
443 TRUE);
444
445 /* Now call ACPI */
446 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
447 if (Status == STATUS_PENDING)
448 {
449 /* Wait for completion */
451 Executive,
453 FALSE,
454 NULL);
455 Status = Irp->IoStatus.Status;
456 }
457
458 /* Get the wake power state */
459 DeviceExtension->PowerState.SystemState = IoStackLocation->Parameters.DeviceCapabilities.Capabilities->SystemWake;
460 if (CmBattDebug & 0x20)
461 DbgPrint("CmBattPnpDispatch: IRP_MN_QUERY_CAPABILITIES %d Capabilities->SystemWake = %x\n",
462 DeviceExtension->FdoType,
463 DeviceExtension->PowerState);
464
465 /* Check if it's invalid */
466 if (DeviceExtension->PowerState.SystemState == PowerSystemUnspecified)
467 {
468 /* Wait wake is not supported in this scenario */
469 DeviceExtension->WaitWakeEnable = FALSE;
470 if (CmBattDebug & 0x20)
471 DbgPrint("CmBattPnpDispatch: IRP_MN_QUERY_CAPABILITIES Wake not supported.\n");
472 }
473 else if (!(DeviceExtension->PowerIrp) &&
474 (DeviceExtension->WaitWakeEnable))
475 {
476 /* If it was requested in the registry, request the power IRP for it */
477 PoRequestPowerIrp(DeviceExtension->DeviceObject,
478 0,
479 DeviceExtension->PowerState,
481 0,
482 &DeviceExtension->PowerIrp);
483 if (CmBattDebug & 0x20)
484 DbgPrint("CmBattPnpDispatch: IRP_MN_QUERY_CAPABILITIES wait/Wake irp sent.\n");
485 }
486
487 /* Release the remove lock and complete the request */
489 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
490 return Status;
491
492 default:
493 /* Unsupported */
494 if (CmBattDebug & 0x20)
495 DbgPrint("CmBattPnpDispatch: Unimplemented minor %0x\n",
496 IoStackLocation->MinorFunction);
497 break;
498 }
499
500 /* Release the remove lock */
501 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
502
503 /* Set IRP status if we have one */
504 if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;
505
506 /* Did someone pick it up? */
508 {
509 /* Still unsupported, try ACPI */
511 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
512 }
513 else
514 {
515 /* Complete the request */
516 Status = Irp->IoStatus.Status;
518 }
519
520 /* Release the remove lock and return status */
521 return Status;
522}
523
525NTAPI
528 IN ULONG DeviceExtensionSize,
529 IN PDEVICE_OBJECT *NewDeviceObject)
530{
531 PDEVICE_OBJECT FdoDeviceObject;
537 UNICODE_STRING KeyString;
538 ULONG UniqueId;
540 PAGED_CODE();
541 if (CmBattDebug & 0x220) DbgPrint("CmBattCreateFdo: Entered\n");
542
543 /* Get unique ID */
545 if (!NT_SUCCESS(Status))
546 {
547 /* Assume 0 */
548 UniqueId = 0;
549 if (CmBattDebug & 2)
550 DbgPrint("CmBattCreateFdo: Error %x from _UID, assuming unit #0\n", Status);
551 }
552
553 /* Create the FDO */
555 DeviceExtensionSize,
556 0,
559 0,
560 &FdoDeviceObject);
561 if (!NT_SUCCESS(Status))
562 {
563 /* Fail */
564 if (CmBattDebug & 0xC)
565 DbgPrint("CmBattCreateFdo: error (0x%x) creating device object\n", Status);
566 return Status;
567 }
568
569 /* Set FDO flags */
570 FdoDeviceObject->Flags |= (DO_POWER_PAGABLE | DO_BUFFERED_IO);
571 FdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
572
573 /* Initialize the extension */
574 FdoExtension = FdoDeviceObject->DeviceExtension;
575 RtlZeroMemory(FdoExtension, DeviceExtensionSize);
576 FdoExtension->DeviceObject = FdoDeviceObject;
577 FdoExtension->FdoDeviceObject = FdoDeviceObject;
578 FdoExtension->PdoDeviceObject = DeviceObject;
579
580 /* Attach to ACPI */
581 FdoExtension->AttachedDevice = IoAttachDeviceToDeviceStack(FdoDeviceObject,
583 if (!FdoExtension->AttachedDevice)
584 {
585 /* Destroy and fail */
586 CmBattDestroyFdo(FdoExtension->FdoDeviceObject);
587 if (CmBattDebug & 0xC)
588 DbgPrint("CmBattCreateFdo: IoAttachDeviceToDeviceStack failed.\n");
589 return STATUS_UNSUCCESSFUL;
590 }
591
592 /* Get ACPI interface for EVAL */
594 &FdoExtension->AcpiInterface);
595 if (!FdoExtension->AttachedDevice)
596 {
597 /* Detach, destroy, and fail */
598 IoDetachDevice(FdoExtension->AttachedDevice);
599 CmBattDestroyFdo(FdoExtension->FdoDeviceObject);
600 if (CmBattDebug & 0xC)
601 DbgPrint("CmBattCreateFdo: Could not get ACPI interfaces: %x\n", Status);
602 return STATUS_UNSUCCESSFUL;
603 }
604
605 /* Setup the rest of the extension */
607 IoInitializeRemoveLock(&FdoExtension->RemoveLock, 'RbmC', 0, 0);
608 FdoExtension->HandleCount = 0;
609 FdoExtension->WaitWakeEnable = FALSE;
610 FdoExtension->DeviceId = UniqueId;
611 FdoExtension->DeviceName = NULL;
612 FdoExtension->DelayNotification = FALSE;
613 FdoExtension->ArFlag = 0;
614
615 /* Open the device key */
618 KEY_READ,
619 &KeyHandle);
620 if (NT_SUCCESS(Status))
621 {
622 /* Read wait wake value */
623 RtlInitUnicodeString(&KeyString, L"WaitWakeEnabled");
624 Status = ZwQueryValueKey(KeyHandle,
625 &KeyString,
627 PartialInfo,
628 sizeof(Buffer),
629 &ResultLength);
630 if (NT_SUCCESS(Status))
631 {
632 /* Set value */
633 FdoExtension->WaitWakeEnable = ((*(PULONG)PartialInfo->Data) != 0);
634 }
635
636 /* Close the handle */
638 }
639
640 /* Return success and the new FDO */
641 *NewDeviceObject = FdoDeviceObject;
642 if (CmBattDebug & 0x220)
643 DbgPrint("CmBattCreateFdo: Created FDO %x\n", FdoDeviceObject);
644 return STATUS_SUCCESS;
645}
646
648NTAPI
651{
652 BATTERY_MINIPORT_INFO MiniportInfo;
654 PDEVICE_OBJECT FdoDeviceObject;
656 PAGED_CODE();
657 if (CmBattDebug & 0x220)
658 DbgPrint("CmBattAddBattery: pdo %x\n", DeviceObject);
659
660 /* Create the FDO */
664 &FdoDeviceObject);
665 if (!NT_SUCCESS(Status))
666 {
667 if (CmBattDebug & 0xC)
668 DbgPrint("CmBattAddBattery: error (0x%x) creating Fdo\n", Status);
669 return Status;
670 }
671
672 /* Build the FDO extension, check if we support trip points */
673 FdoExtension = FdoDeviceObject->DeviceExtension;
674 FdoExtension->FdoType = CmBattBattery;
675 FdoExtension->Started = 0;
676 FdoExtension->NotifySent = TRUE;
677 InterlockedExchange(&FdoExtension->ArLockValue, 0);
678 FdoExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
679 FdoExtension->Tag = 0;
680 FdoExtension->InterruptTime = KeQueryInterruptTime();
681 FdoExtension->TripPointSet = CmBattSetTripPpoint(FdoExtension, 0) !=
683
684 /* Setup the battery miniport information structure */
685 RtlZeroMemory(&MiniportInfo, sizeof(MiniportInfo));
686 MiniportInfo.Pdo = DeviceObject;
689 MiniportInfo.Context = FdoExtension;
690 MiniportInfo.QueryTag = (PVOID)CmBattQueryTag;
692 MiniportInfo.SetInformation = NULL;
693 MiniportInfo.QueryStatus = (PVOID)CmBattQueryStatus;
696 MiniportInfo.DeviceName = FdoExtension->DeviceName;
697
698 /* Register with the class driver */
699 Status = BatteryClassInitializeDevice(&MiniportInfo, &FdoExtension->ClassData);
700 if (!NT_SUCCESS(Status))
701 {
702 IoDetachDevice(FdoExtension->AttachedDevice);
703 CmBattDestroyFdo(FdoExtension->FdoDeviceObject);
704 if (CmBattDebug & 0xC)
705 DbgPrint("CmBattAddBattery: error (0x%x) registering with class\n", Status);
706 return Status;
707 }
708
709 /* Register WMI */
711 if (!NT_SUCCESS(Status))
712 {
713 if (CmBattDebug & 0xC)
714 DbgPrint("CmBattAddBattery: Could not register as a WMI provider, status = %Lx\n", Status);
715 return Status;
716 }
717
718 /* Register ACPI */
719 Status = FdoExtension->AcpiInterface.RegisterForDeviceNotifications(FdoExtension->AcpiInterface.Context,
722 if (!NT_SUCCESS(Status))
723 {
726 IoDetachDevice(FdoExtension->AttachedDevice);
727 CmBattDestroyFdo(FdoExtension->FdoDeviceObject);
728 if (CmBattDebug & 0xC)
729 DbgPrint("CmBattAddBattery: Could not register for battery notify, status = %Lx\n", Status);
730 }
731
732 /* Return status */
733 return Status;
734}
735
737NTAPI
740{
741 PDEVICE_OBJECT FdoDeviceObject;
743 PCMBATT_DEVICE_EXTENSION DeviceExtension;
744 PAGED_CODE();
745 if (CmBattDebug & 0x220)
746 DbgPrint("CmBattAddAcAdapter: pdo %x\n", PdoDeviceObject);
747
748 /* Check if we already have an AC adapter */
749 if (AcAdapterPdo)
750 {
751 /* Don't do anything */
752 if (CmBattDebug & 0xC)
753 DbgPrint("CmBatt: Second AC adapter found. Current version of driver only supports 1 adapter.\n");
754 }
755 else
756 {
757 /* Set this as the AC adapter's PDO */
759 }
760
761 /* Create the FDO for the adapter */
765 &FdoDeviceObject);
766 if (!NT_SUCCESS(Status))
767 {
768 /* Fail */
769 if (CmBattDebug & 0xC)
770 DbgPrint("CmBattAddAcAdapter: error (0x%x) creating Fdo\n", Status);
771 return Status;
772 }
773
774 /* Set the type and do WMI registration */
775 DeviceExtension = FdoDeviceObject->DeviceExtension;
776 DeviceExtension->FdoType = CmBattAcAdapter;
777 Status = CmBattWmiRegistration(DeviceExtension);
778 if (!NT_SUCCESS(Status))
779 {
780 /* We can go on without WMI */
781 if (CmBattDebug & 0xC)
782 DbgPrint("CmBattAddBattery: Could not register as a WMI provider, status = %Lx\n", Status);
783 }
784
785 /* Register with ACPI */
786 Status = DeviceExtension->AcpiInterface.RegisterForDeviceNotifications(DeviceExtension->AcpiInterface.Context,
788 DeviceExtension);
789 if (!(NT_SUCCESS(Status)) && (CmBattDebug & 0xC))
790 DbgPrint("CmBattAddAcAdapter: Could not register for power notify, status = %Lx\n", Status);
791
792 /* Send the first manual notification */
794 return STATUS_SUCCESS;
795}
796
798NTAPI
801{
805 UNICODE_STRING KeyString;
808 ULONG PowerSourceType;
809 PAGED_CODE();
810 if (CmBattDebug & 0x220)
811 DbgPrint("CmBattAddDevice: Entered with pdo %x\n", PdoDeviceObject);
812
813 /* Make sure we have a PDO */
814 if (!PdoDeviceObject)
815 {
816 /* Should not be having as one */
817 if (CmBattDebug & 0x24) DbgPrint("CmBattAddDevice: Asked to do detection\n");
819 }
820
821 /* Open the driver key */
824 KEY_READ,
825 &KeyHandle);
826 if (!NT_SUCCESS(Status))
827 {
828 if (CmBattDebug & 0xC)
829 DbgPrint("CmBattAddDevice: Could not get the software branch: %x\n", Status);
830 return Status;
831 }
832
833 /* Read the power source type */
834 RtlInitUnicodeString(&KeyString, L"PowerSourceType");
835 Status = ZwQueryValueKey(KeyHandle,
836 &KeyString,
838 PartialInfo,
839 sizeof(Buffer),
840 &ResultLength);
842 if (!NT_SUCCESS(Status))
843 {
844 /* We need the data, fail without it */
845 if (CmBattDebug & 0xC)
846 DbgPrint("CmBattAddDevice: Could not read the power type identifier: %x\n", Status);
847 return Status;
848 }
849
850 /* Check what kind of power source this is */
851 PowerSourceType = *(PULONG)PartialInfo->Data;
852 if (PowerSourceType == 1)
853 {
854 /* Create an AC adapter */
856 }
857 else if (PowerSourceType == 0)
858 {
859 /* Create a battery */
861 }
862 else
863 {
864 /* Unknown type, fail */
865 if (CmBattDebug & 0xC)
866 DbgPrint("CmBattAddDevice: Invalid POWER_SOURCE_TYPE == %d \n", PowerSourceType);
867 return STATUS_UNSUCCESSFUL;
868 }
869
870 /* Return whatever the FDO creation routine did */
871 return Status;
872}
873
874/* EOF */
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#define InterlockedExchange
Definition: armddk.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define BATTERY_UNKNOWN_CAPACITY
Definition: batclass.h:65
#define BATTERY_CLASS_MAJOR_VERSION
Definition: batclass.h:163
#define BATTERY_CLASS_MINOR_VERSION
Definition: batclass.h:164
BCLASSAPI NTSTATUS NTAPI BatteryClassInitializeDevice(PBATTERY_MINIPORT_INFO MiniportInfo, PVOID *ClassData)
Definition: battc.c:137
BCLASSAPI NTSTATUS NTAPI BatteryClassUnload(PVOID ClassData)
Definition: battc.c:27
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
Definition: bufpool.h:45
PDEVICE_OBJECT AcAdapterPdo
Definition: cmbatt.c:23
ULONG CmBattDebug
Definition: cmbatt.c:17
NTSTATUS NTAPI CmBattDisableStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension)
Definition: cmbatt.c:624
NTSTATUS NTAPI CmBattQueryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG Tag, IN PBATTERY_STATUS BatteryStatus)
Definition: cmbatt.c:1243
NTSTATUS NTAPI CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension, IN ULONG Tag, IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, IN OPTIONAL LONG AtRate, IN PVOID Buffer, IN ULONG BufferLength, OUT PULONG ReturnedLength)
Definition: cmbatt.c:1030
VOID NTAPI CmBattNotifyHandler(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG NotifyValue)
Definition: cmbatt.c:142
NTSTATUS NTAPI CmBattQueryTag(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, OUT PULONG Tag)
Definition: cmbatt.c:566
NTSTATUS NTAPI CmBattSetStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension, IN ULONG BatteryTag, IN PBATTERY_NOTIFY BatteryNotify)
Definition: cmbatt.c:665
NTSTATUS NTAPI CmBattSetTripPpoint(PCMBATT_DEVICE_EXTENSION DeviceExtension, ULONG AlarmValue)
NTSTATUS NTAPI CmBattGetUniqueId(PDEVICE_OBJECT DeviceObject, PULONG UniqueId)
#define ACPI_BATT_NOTIFY_STATUS
Definition: cmbatt.h:60
NTSTATUS NTAPI CmBattWmiRegistration(PCMBATT_DEVICE_EXTENSION DeviceExtension)
NTSTATUS NTAPI CmBattWmiDeRegistration(PCMBATT_DEVICE_EXTENSION DeviceExtension)
@ CmBattAcAdapter
Definition: cmbatt.h:47
@ CmBattBattery
Definition: cmbatt.h:48
NTSTATUS NTAPI CmBattPowerDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbpnp.c:199
NTSTATUS NTAPI CmBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbpnp.c:262
NTSTATUS NTAPI CmBattCreateFdo(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceExtensionSize, IN PDEVICE_OBJECT *NewDeviceObject)
Definition: cmbpnp.c:526
NTSTATUS NTAPI CmBattAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PdoDeviceObject)
Definition: cmbpnp.c:799
NTSTATUS NTAPI CmBattIoCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT Event)
Definition: cmbpnp.c:54
NTSTATUS NTAPI CmBattAddAcAdapter(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PdoDeviceObject)
Definition: cmbpnp.c:738
VOID NTAPI CmBattWaitWakeLoop(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: cmbpnp.c:17
NTSTATUS NTAPI CmBattRemoveDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: cmbpnp.c:149
NTSTATUS NTAPI CmBattGetAcpiInterfaces(IN PDEVICE_OBJECT DeviceObject, IN OUT PACPI_INTERFACE_STANDARD AcpiInterface)
Definition: cmbpnp.c:67
VOID NTAPI CmBattDestroyFdo(IN PDEVICE_OBJECT DeviceObject)
Definition: cmbpnp.c:137
NTSTATUS NTAPI CmBattAddBattery(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject)
Definition: cmbpnp.c:649
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_DEVICE_REMOVED
Definition: d3dkmdt.h:39
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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
@ FdoExtension
Definition: precomp.h:48
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
#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
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 DbgPrint
Definition: hal.h:12
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT _In_ PUSB_PORT_PATH _Out_ PUSB_CD_ERROR_INFORMATION _In_ USHORT _In_ PDEVICE_OBJECT PdoDeviceObject
Definition: hubbusif.h:95
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
@ SynchronizationEvent
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
NTSTATUS NTAPI PoRequestPowerIrp(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction, _In_ POWER_STATE PowerState, _In_opt_ PREQUEST_POWER_COMPLETE CompletionFunction, _In_opt_ __drv_aliasesMem PVOID Context, _Outptr_opt_ PIRP *pIrp)
Definition: power.c:659
@ PowerSystemUnspecified
Definition: ntpoapi.h:35
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:1621
#define FILE_DEVICE_BATTERY
Definition: winioctl.h:86
struct _INTERFACE * PINTERFACE
#define KeQueryInterruptTime()
Definition: ke.h:37
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
PUNREGISTER_FOR_DEVICE_NOTIFICATIONS UnregisterForDeviceNotifications
Definition: iotypes.h:3024
PREGISTER_FOR_DEVICE_NOTIFICATIONS RegisterForDeviceNotifications
Definition: iotypes.h:3023
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
PUNICODE_STRING DeviceName
Definition: batclass.h:258
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
POWER_STATE PowerState
Definition: cmbatt.h:112
CMBATT_EXTENSION_TYPE FdoType
Definition: cmbatt.h:104
PDEVICE_OBJECT DeviceObject
Definition: cmbatt.h:105
PDEVICE_OBJECT AttachedDevice
Definition: cmbatt.h:108
IO_REMOVE_LOCK RemoveLock
Definition: cmbatt.h:115
FAST_MUTEX FastMutex
Definition: cmbatt.h:109
ACPI_INTERFACE_STANDARD AcpiInterface
Definition: cmbatt.h:118
PVOID DeviceExtension
Definition: env_spec_w32.h:418
union _IO_STACK_LOCATION::@1580 Parameters
struct _IO_STACK_LOCATION::@3979::@4005 QueryInterface
struct _IO_STACK_LOCATION::@3979::@4006 DeviceCapabilities
struct _IO_STACK_LOCATION::@3979::@4015 Power
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
SYSTEM_POWER_STATE SystemState
Definition: ntpoapi.h:57
#define PLUGPLAY_REGKEY_DRIVER
Definition: usbd.c:42
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ WDF_DEVICE_POWER_STATE PowerState
Definition: wdfdevice.h:3034
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2774
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2786
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark)
Definition: iofuncs.h:2833
#define IRP_MN_CANCEL_STOP_DEVICE
#define IRP_MN_WAIT_WAKE
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_QUERY_INTERFACE
#define IRP_MN_START_DEVICE
struct _ACPI_INTERFACE_STANDARD ACPI_INTERFACE_STANDARD
#define IRP_MN_REMOVE_DEVICE
#define DO_POWER_PAGABLE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_CAPABILITIES
#define IRP_MN_POWER_SEQUENCE
#define IRP_MN_SET_POWER
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_POWER
#define IRP_MN_QUERY_REMOVE_DEVICE
@ Executive
Definition: ketypes.h:415
unsigned char UCHAR
Definition: xmlstorage.h:181