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/cmbatt.c
5 * PURPOSE: Main Initialization Code and IRP Handling
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
13 /* GLOBALS ********************************************************************/
16 PCALLBACK_OBJECT CmBattPowerCallBackObject
;
17 PVOID CmBattPowerCallBackRegistration
;
18 UNICODE_STRING GlobalRegistryPath
;
19 KTIMER CmBattWakeDpcTimerObject
;
20 KDPC CmBattWakeDpcObject
;
22 /* FUNCTIONS ******************************************************************/
26 CmBattPowerCallBack(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
35 CmBattWakeDpc(PKDPC Dpc
,
36 PCMBATT_DEVICE_EXTENSION FdoExtension
,
37 PVOID SystemArgument1
,
38 PVOID SystemArgument2
)
45 CmBattNotifyHandler(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
53 CmBattUnload(IN PDRIVER_OBJECT DriverObject
)
55 if (CmBattDebug
& CMBATT_GENERIC_INFO
) DPRINT("CmBattUnload: \n");
57 /* Check if we have a registered power callback */
58 if (CmBattPowerCallBackObject
)
61 ExUnregisterCallback(CmBattPowerCallBackRegistration
);
62 ObfDereferenceObject(CmBattPowerCallBackObject
);
65 /* Free the registry buffer if it exists */
66 if (GlobalRegistryPath
.Buffer
) ExFreePool(GlobalRegistryPath
.Buffer
);
68 /* Make sure we don't still have references to the DO */
69 if ((DriverObject
->DeviceObject
) && (CmBattDebug
& CMBATT_GENERIC_WARNING
))
71 DbgPrint("Unload called before all devices removed.\n");
77 CmBattVerifyStaticInfo(ULONG StaData
,
81 return STATUS_NOT_IMPLEMENTED
;
86 CmBattOpenClose(IN PDEVICE_OBJECT DeviceObject
,
89 NTSTATUS Status
= STATUS_SUCCESS
;
90 PIO_STACK_LOCATION IoStackLocation
;
93 PCMBATT_DEVICE_EXTENSION DeviceExtension
;
95 if (CmBattDebug
& CMBATT_GENERIC_INFO
) DPRINT("CmBattOpenClose\n");
97 /* Grab the device extension and lock it */
98 DeviceExtension
= DeviceObject
->DeviceExtension
;
99 ExAcquireFastMutex(&DeviceExtension
->FastMutex
);
101 /* Check if someone is trying to open a device that doesn't exist yet */
102 Count
= DeviceExtension
->HandleCount
;
103 if (Count
== 0xFFFFFFFF)
105 /* Fail the request */
106 Status
= STATUS_NO_SUCH_DEVICE
;
107 if (CmBattDebug
& CMBATT_PNP_INFO
)
109 DbgPrint("CmBattOpenClose: Failed (UID = %x)(device being removed).\n",
110 DeviceExtension
->Tag
);
115 /* Check if this is an open or close */
116 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
117 Major
= IoStackLocation
->MajorFunction
;
118 if (Major
== IRP_MJ_CREATE
)
120 /* Increment the open count */
121 DeviceExtension
->HandleCount
= Count
+ 1;
122 if (CmBattDebug
& CMBATT_PNP_INFO
)
124 DbgPrint("CmBattOpenClose: Open (DeviceNumber = %x)(count = %x).\n",
125 DeviceExtension
->DeviceId
, Count
+ 1);
128 else if (Major
== IRP_MJ_CLOSE
)
130 /* Decrement the open count */
131 DeviceExtension
->HandleCount
= Count
- 1;
132 if (CmBattDebug
& CMBATT_PNP_INFO
)
134 DbgPrint("CmBattOpenClose: Close (DeviceNumber = %x)(count = %x).\n",
135 DeviceExtension
->DeviceId
, Count
+ 1);
140 /* Release lock and complete request */
141 ExReleaseFastMutex(&DeviceExtension
->FastMutex
);
142 Irp
->IoStatus
.Status
= Status
;
143 IofCompleteRequest(Irp
, IO_NO_INCREMENT
);
149 CmBattIoctl(PDEVICE_OBJECT DeviceObject
,
153 return STATUS_NOT_IMPLEMENTED
;
158 CmBattQueryTag(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
162 return STATUS_NOT_IMPLEMENTED
;
167 CmBattDisableStatusNotify(PCMBATT_DEVICE_EXTENSION DeviceExtension
)
170 return STATUS_NOT_IMPLEMENTED
;
175 CmBattSetStatusNotify(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
177 PBATTERY_NOTIFY BatteryNotify
)
180 return STATUS_NOT_IMPLEMENTED
;
185 CmBattGetBatteryStatus(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
189 return STATUS_NOT_IMPLEMENTED
;
194 CmBattQueryInformation(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
196 BATTERY_QUERY_INFORMATION_LEVEL Level
,
197 OPTIONAL LONG AtRate
,
200 PULONG ReturnedLength
)
203 return STATUS_NOT_IMPLEMENTED
;
208 CmBattQueryStatus(PCMBATT_DEVICE_EXTENSION DeviceExtension
,
210 PBATTERY_STATUS BatteryStatus
)
213 return STATUS_NOT_IMPLEMENTED
;
218 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
219 IN PUNICODE_STRING RegistryPath
)
222 PDRIVER_EXTENSION DriverExtension
;
223 OBJECT_ATTRIBUTES ObjectAttributes
;
224 UNICODE_STRING CallbackName
;
226 /* Allocate registry path */
227 GlobalRegistryPath
.MaximumLength
= RegistryPath
->Length
+ sizeof(UNICODE_NULL
);
228 GlobalRegistryPath
.Length
= RegistryPath
->Length
;
229 GlobalRegistryPath
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
230 GlobalRegistryPath
.MaximumLength
,
232 if (!GlobalRegistryPath
.Buffer
)
234 /* Fail if we're out of memory this early */
235 if (CmBattDebug
& CMBATT_GENERIC_WARNING
)
237 DbgPrint("CmBatt: Couldn't allocate pool for registry path.");
239 return STATUS_INSUFFICIENT_RESOURCES
;
242 /* Buffer allocated, copy the string */
243 RtlCopyUnicodeString(&GlobalRegistryPath
, RegistryPath
);
244 if (CmBattDebug
& CMBATT_GENERIC_INFO
)
246 DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%ws\"\n",
248 RegistryPath
->Buffer
);
251 /* Setup the major dispatchers */
252 DriverObject
->MajorFunction
[0] = CmBattOpenClose
;
253 DriverObject
->MajorFunction
[2] = CmBattOpenClose
;
254 DriverObject
->MajorFunction
[14] = CmBattIoctl
;
255 DriverObject
->MajorFunction
[22] = CmBattPowerDispatch
;
256 DriverObject
->MajorFunction
[27] = CmBattPnpDispatch
;
257 DriverObject
->MajorFunction
[23] = CmBattSystemControl
;
259 /* And the unload routine */
260 DriverObject
->DriverUnload
= CmBattUnload
;
262 /* And the add device routine */
263 DriverExtension
= DriverObject
->DriverExtension
;
264 DriverExtension
->AddDevice
= CmBattAddDevice
;
266 /* Create a power callback */
267 RtlInitUnicodeString(&CallbackName
, L
"\\Callback\\PowerState");
268 InitializeObjectAttributes(&ObjectAttributes
,
273 Status
= ExCreateCallback(&CmBattPowerCallBackObject
, &ObjectAttributes
, 0, TRUE
);
274 if (!NT_SUCCESS(Status
))
276 /* No callback, fail */
277 CmBattPowerCallBackObject
= 0;
278 if (CmBattDebug
& CMBATT_GENERIC_WARNING
)
280 DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n", Status
);
285 /* Register the power callback now */
286 CmBattPowerCallBackRegistration
= ExRegisterCallback(CmBattPowerCallBackObject
,
287 (PVOID
)CmBattPowerCallBack
,
289 if (CmBattPowerCallBackRegistration
)
291 /* Last thing: setup our DPC and timer for battery wake */
292 KeInitializeDpc(&CmBattWakeDpcObject
, (PVOID
)CmBattWakeDpc
, DriverObject
);
293 KeInitializeTimer(&CmBattWakeDpcTimerObject
);
297 ObfDereferenceObject(CmBattPowerCallBackObject
);
298 if (CmBattDebug
& CMBATT_GENERIC_WARNING
)
300 DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback failed.\n");
305 Status
= STATUS_SUCCESS
;
308 /* Return failure or success */