DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
- DPRINT("Battery class driver initialized\n");
+ DPRINT("Battery class driver initialized\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
BCLASSAPI
NTAPI
BatteryClassUnload(PVOID ClassData)
{
- PBATTERY_CLASS_DATA BattClass = ClassData;
+ PBATTERY_CLASS_DATA BattClass = ClassData;
- DPRINT("Battery 0x%x is being unloaded\n");
+ DPRINT("Battery 0x%x is being unloaded\n");
- if (BattClass->InterfaceName.Length != 0)
- {
- IoSetDeviceInterfaceState(&BattClass->InterfaceName, FALSE);
- RtlFreeUnicodeString(&BattClass->InterfaceName);
- }
+ if (BattClass->InterfaceName.Length != 0)
+ {
+ IoSetDeviceInterfaceState(&BattClass->InterfaceName, FALSE);
+ RtlFreeUnicodeString(&BattClass->InterfaceName);
+ }
- ExFreePoolWithTag(BattClass,
- BATTERY_CLASS_DATA_TAG);
+ ExFreePoolWithTag(BattClass,
+ BATTERY_CLASS_DATA_TAG);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
BCLASSAPI
PIRP Irp,
PVOID Disposition)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
- return STATUS_WMI_GUID_NOT_FOUND;
+ return STATUS_WMI_GUID_NOT_FOUND;
}
BCLASSAPI
ULONG OutBufferSize,
PUCHAR Buffer)
{
- UNIMPLEMENTED;
+ UNIMPLEMENTED;
- return STATUS_WMI_GUID_NOT_FOUND;
+ return STATUS_WMI_GUID_NOT_FOUND;
}
BCLASSAPI
NTAPI
BatteryClassStatusNotify(PVOID ClassData)
{
- PBATTERY_CLASS_DATA BattClass = ClassData;
- PBATTERY_WAIT_STATUS BattWait = BattClass->EventTriggerContext;
- BATTERY_STATUS BattStatus;
- NTSTATUS Status;
-
- DPRINT("Received battery status notification from 0x%x\n", ClassData);
-
- ExAcquireFastMutex(&BattClass->Mutex);
- if (!BattClass->Waiting)
- {
- ExReleaseFastMutex(&BattClass->Mutex);
- return STATUS_SUCCESS;
- }
-
- switch (BattClass->EventTrigger)
- {
- case EVENT_BATTERY_TAG:
- ExReleaseFastMutex(&BattClass->Mutex);
- DPRINT1("Waiting for battery is UNIMPLEMENTED!\n");
- break;
-
- case EVENT_BATTERY_STATUS:
- ExReleaseFastMutex(&BattClass->Mutex);
- Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
- BattWait->BatteryTag,
- &BattStatus);
- if (!NT_SUCCESS(Status))
- return Status;
-
- ExAcquireFastMutex(&BattClass->Mutex);
-
- if (!(BattWait->PowerState & BattStatus.PowerState) ||
- (BattWait->HighCapacity > BattStatus.Capacity) ||
- (BattWait->LowCapacity < BattStatus.Capacity))
- {
- KeSetEvent(&BattClass->WaitEvent, IO_NO_INCREMENT, FALSE);
- }
-
- ExReleaseFastMutex(&BattClass->Mutex);
- break;
-
- default:
- ExReleaseFastMutex(&BattClass->Mutex);
- ASSERT(FALSE);
- break;
- }
-
- return STATUS_SUCCESS;
+ PBATTERY_CLASS_DATA BattClass = ClassData;
+ PBATTERY_WAIT_STATUS BattWait = BattClass->EventTriggerContext;
+ BATTERY_STATUS BattStatus;
+ NTSTATUS Status;
+
+ DPRINT("Received battery status notification from 0x%x\n", ClassData);
+
+ ExAcquireFastMutex(&BattClass->Mutex);
+ if (!BattClass->Waiting)
+ {
+ ExReleaseFastMutex(&BattClass->Mutex);
+ return STATUS_SUCCESS;
+ }
+
+ switch (BattClass->EventTrigger)
+ {
+ case EVENT_BATTERY_TAG:
+ ExReleaseFastMutex(&BattClass->Mutex);
+ DPRINT1("Waiting for battery is UNIMPLEMENTED!\n");
+ break;
+
+ case EVENT_BATTERY_STATUS:
+ ExReleaseFastMutex(&BattClass->Mutex);
+ Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
+ BattWait->BatteryTag,
+ &BattStatus);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ ExAcquireFastMutex(&BattClass->Mutex);
+
+ if (!(BattWait->PowerState & BattStatus.PowerState) ||
+ (BattWait->HighCapacity > BattStatus.Capacity) ||
+ (BattWait->LowCapacity < BattStatus.Capacity))
+ {
+ KeSetEvent(&BattClass->WaitEvent, IO_NO_INCREMENT, FALSE);
+ }
+
+ ExReleaseFastMutex(&BattClass->Mutex);
+ break;
+
+ default:
+ ExReleaseFastMutex(&BattClass->Mutex);
+ ASSERT(FALSE);
+ break;
+ }
+
+ return STATUS_SUCCESS;
}
BCLASSAPI
BatteryClassInitializeDevice(PBATTERY_MINIPORT_INFO MiniportInfo,
PVOID *ClassData)
{
- NTSTATUS Status;
- PBATTERY_CLASS_DATA BattClass = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(BATTERY_CLASS_DATA),
- BATTERY_CLASS_DATA_TAG);
+ NTSTATUS Status;
+ PBATTERY_CLASS_DATA BattClass = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(BATTERY_CLASS_DATA),
+ BATTERY_CLASS_DATA_TAG);
- if (!BattClass)
- return STATUS_INSUFFICIENT_RESOURCES;
+ if (!BattClass)
+ return STATUS_INSUFFICIENT_RESOURCES;
- RtlZeroMemory(BattClass, sizeof(BATTERY_CLASS_DATA));
+ RtlZeroMemory(BattClass, sizeof(BATTERY_CLASS_DATA));
- RtlCopyMemory(&BattClass->MiniportInfo,
- MiniportInfo,
- sizeof(BattClass->MiniportInfo));
+ RtlCopyMemory(&BattClass->MiniportInfo,
+ MiniportInfo,
+ sizeof(BattClass->MiniportInfo));
- KeInitializeEvent(&BattClass->WaitEvent, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&BattClass->WaitEvent, SynchronizationEvent, FALSE);
- ExInitializeFastMutex(&BattClass->Mutex);
+ ExInitializeFastMutex(&BattClass->Mutex);
- if (MiniportInfo->Pdo != NULL)
- {
- Status = IoRegisterDeviceInterface(MiniportInfo->Pdo,
- &GUID_DEVICE_BATTERY,
- NULL,
- &BattClass->InterfaceName);
- if (NT_SUCCESS(Status))
+ if (MiniportInfo->Pdo != NULL)
{
- DPRINT("Initialized battery interface: %wZ\n", &BattClass->InterfaceName);
- Status = IoSetDeviceInterfaceState(&BattClass->InterfaceName, TRUE);
- if (Status == STATUS_OBJECT_NAME_EXISTS)
+ Status = IoRegisterDeviceInterface(MiniportInfo->Pdo,
+ &GUID_DEVICE_BATTERY,
+ NULL,
+ &BattClass->InterfaceName);
+ if (NT_SUCCESS(Status))
{
- DPRINT1("Got STATUS_OBJECT_NAME_EXISTS for SetDeviceInterfaceState\n");
- Status = STATUS_SUCCESS;
+ DPRINT("Initialized battery interface: %wZ\n", &BattClass->InterfaceName);
+ Status = IoSetDeviceInterfaceState(&BattClass->InterfaceName, TRUE);
+ if (Status == STATUS_OBJECT_NAME_EXISTS)
+ {
+ DPRINT1("Got STATUS_OBJECT_NAME_EXISTS for SetDeviceInterfaceState\n");
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ DPRINT1("IoRegisterDeviceInterface failed (0x%x)\n", Status);
}
}
- else
- {
- DPRINT1("IoRegisterDeviceInterface failed (0x%x)\n", Status);
- }
- }
- *ClassData = BattClass;
+ *ClassData = BattClass;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
BCLASSAPI
BatteryClassIoctl(PVOID ClassData,
PIRP Irp)
{
- PBATTERY_CLASS_DATA BattClass = ClassData;
- PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
- NTSTATUS Status;
- ULONG WaitTime;
- PBATTERY_WAIT_STATUS BattWait;
- PBATTERY_QUERY_INFORMATION BattQueryInfo;
- PBATTERY_SET_INFORMATION BattSetInfo;
- LARGE_INTEGER Timeout;
- PBATTERY_STATUS BattStatus;
- BATTERY_NOTIFY BattNotify;
- ULONG ReturnedLength;
-
- Irp->IoStatus.Information = 0;
-
- DPRINT("Received IOCTL %x for 0x%x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode,
- ClassData);
-
- switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_BATTERY_QUERY_TAG:
- if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
- IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- WaitTime = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
-
- Timeout.QuadPart = Int32x32To64(WaitTime, -1000);
-
- Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
- (PULONG)Irp->AssociatedIrp.SystemBuffer);
- if (!NT_SUCCESS(Status))
- {
- ExAcquireFastMutex(&BattClass->Mutex);
- BattClass->EventTrigger = EVENT_BATTERY_TAG;
- BattClass->Waiting = TRUE;
- ExReleaseFastMutex(&BattClass->Mutex);
-
- Status = KeWaitForSingleObject(&BattClass->WaitEvent,
- Executive,
- KernelMode,
- FALSE,
- WaitTime != -1 ? &Timeout : NULL);
-
- ExAcquireFastMutex(&BattClass->Mutex);
- BattClass->Waiting = FALSE;
- ExReleaseFastMutex(&BattClass->Mutex);
-
- if (Status == STATUS_SUCCESS)
- {
- Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
- (PULONG)Irp->AssociatedIrp.SystemBuffer);
- if (NT_SUCCESS(Status))
- Irp->IoStatus.Information = sizeof(ULONG);
- }
- else
- {
- Status = STATUS_NO_SUCH_DEVICE;
- }
- }
- else
- Irp->IoStatus.Information = sizeof(ULONG);
- break;
-
- case IOCTL_BATTERY_QUERY_STATUS:
- if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattWait) ||
- IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BATTERY_STATUS))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- BattWait = Irp->AssociatedIrp.SystemBuffer;
-
- Timeout.QuadPart = Int32x32To64(BattWait->Timeout, -1000);
-
- Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
- BattWait->BatteryTag,
- (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
-
- BattStatus = Irp->AssociatedIrp.SystemBuffer;
-
- if (!NT_SUCCESS(Status) ||
- ((BattWait->PowerState & BattStatus->PowerState) &&
- (BattWait->HighCapacity <= BattStatus->Capacity) &&
- (BattWait->LowCapacity >= BattStatus->Capacity)))
- {
- BattNotify.PowerState = BattWait->PowerState;
- BattNotify.HighCapacity = BattWait->HighCapacity;
- BattNotify.LowCapacity = BattWait->LowCapacity;
-
- BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
- BattWait->BatteryTag,
- &BattNotify);
-
- ExAcquireFastMutex(&BattClass->Mutex);
- BattClass->EventTrigger = EVENT_BATTERY_STATUS;
- BattClass->EventTriggerContext = BattWait;
- BattClass->Waiting = TRUE;
- ExReleaseFastMutex(&BattClass->Mutex);
-
- Status = KeWaitForSingleObject(&BattClass->WaitEvent,
- Executive,
- KernelMode,
- FALSE,
- BattWait->Timeout != -1 ? &Timeout : NULL);
-
- ExAcquireFastMutex(&BattClass->Mutex);
- BattClass->Waiting = FALSE;
- ExReleaseFastMutex(&BattClass->Mutex);
-
- BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
-
- if (Status == STATUS_SUCCESS)
- {
- Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
- BattWait->BatteryTag,
- (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
- if (NT_SUCCESS(Status))
- Irp->IoStatus.Information = sizeof(ULONG);
- }
- else
- {
- Status = STATUS_NO_SUCH_DEVICE;
- }
- }
- else
- Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
- break;
-
- case IOCTL_BATTERY_QUERY_INFORMATION:
- if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattQueryInfo))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- BattQueryInfo = Irp->AssociatedIrp.SystemBuffer;
-
- Status = BattClass->MiniportInfo.QueryInformation(BattClass->MiniportInfo.Context,
- BattQueryInfo->BatteryTag,
- BattQueryInfo->InformationLevel,
- BattQueryInfo->AtRate,
- Irp->AssociatedIrp.SystemBuffer,
- IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
- &ReturnedLength);
- Irp->IoStatus.Information = ReturnedLength;
- if (!NT_SUCCESS(Status))
- DPRINT1("QueryInformation failed (0x%x)\n", Status);
- break;
- case IOCTL_BATTERY_SET_INFORMATION:
- if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattSetInfo))
- {
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- BattSetInfo = Irp->AssociatedIrp.SystemBuffer;
-
- Status = BattClass->MiniportInfo.SetInformation(BattClass->MiniportInfo.Context,
- BattSetInfo->BatteryTag,
- BattSetInfo->InformationLevel,
- BattSetInfo->Buffer);
- if (!NT_SUCCESS(Status))
- DPRINT1("SetInformation failed (0x%x)\n", Status);
- break;
-
- default:
- DPRINT1("Received unsupported IRP %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
- /* Do NOT complete the irp */
- return STATUS_NOT_SUPPORTED;
- }
-
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
+ PBATTERY_CLASS_DATA BattClass = ClassData;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ NTSTATUS Status;
+ ULONG WaitTime;
+ PBATTERY_WAIT_STATUS BattWait;
+ PBATTERY_QUERY_INFORMATION BattQueryInfo;
+ PBATTERY_SET_INFORMATION BattSetInfo;
+ LARGE_INTEGER Timeout;
+ PBATTERY_STATUS BattStatus;
+ BATTERY_NOTIFY BattNotify;
+ ULONG ReturnedLength;
+
+ Irp->IoStatus.Information = 0;
+
+ DPRINT("Received IOCTL %x for 0x%x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode,
+ ClassData);
+
+ switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_BATTERY_QUERY_TAG:
+ if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
+ IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ WaitTime = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
+
+ Timeout.QuadPart = Int32x32To64(WaitTime, -1000);
+
+ Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
+ (PULONG)Irp->AssociatedIrp.SystemBuffer);
+ if (!NT_SUCCESS(Status))
+ {
+ ExAcquireFastMutex(&BattClass->Mutex);
+ BattClass->EventTrigger = EVENT_BATTERY_TAG;
+ BattClass->Waiting = TRUE;
+ ExReleaseFastMutex(&BattClass->Mutex);
+
+ Status = KeWaitForSingleObject(&BattClass->WaitEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ WaitTime != -1 ? &Timeout : NULL);
+
+ ExAcquireFastMutex(&BattClass->Mutex);
+ BattClass->Waiting = FALSE;
+ ExReleaseFastMutex(&BattClass->Mutex);
+
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
+ (PULONG)Irp->AssociatedIrp.SystemBuffer);
+ if (NT_SUCCESS(Status))
+ Irp->IoStatus.Information = sizeof(ULONG);
+ }
+ else
+ {
+ Status = STATUS_NO_SUCH_DEVICE;
+ }
+ }
+ else
+ Irp->IoStatus.Information = sizeof(ULONG);
+ break;
+
+ case IOCTL_BATTERY_QUERY_STATUS:
+ if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattWait) ||
+ IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BATTERY_STATUS))
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ BattWait = Irp->AssociatedIrp.SystemBuffer;
+
+ Timeout.QuadPart = Int32x32To64(BattWait->Timeout, -1000);
+
+ Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
+ BattWait->BatteryTag,
+ (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
+
+ BattStatus = Irp->AssociatedIrp.SystemBuffer;
+
+ if (!NT_SUCCESS(Status) ||
+ ((BattWait->PowerState & BattStatus->PowerState) &&
+ (BattWait->HighCapacity <= BattStatus->Capacity) &&
+ (BattWait->LowCapacity >= BattStatus->Capacity)))
+ {
+ BattNotify.PowerState = BattWait->PowerState;
+ BattNotify.HighCapacity = BattWait->HighCapacity;
+ BattNotify.LowCapacity = BattWait->LowCapacity;
+
+ BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
+ BattWait->BatteryTag,
+ &BattNotify);
+
+ ExAcquireFastMutex(&BattClass->Mutex);
+ BattClass->EventTrigger = EVENT_BATTERY_STATUS;
+ BattClass->EventTriggerContext = BattWait;
+ BattClass->Waiting = TRUE;
+ ExReleaseFastMutex(&BattClass->Mutex);
+
+ Status = KeWaitForSingleObject(&BattClass->WaitEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ BattWait->Timeout != -1 ? &Timeout : NULL);
+
+ ExAcquireFastMutex(&BattClass->Mutex);
+ BattClass->Waiting = FALSE;
+ ExReleaseFastMutex(&BattClass->Mutex);
+
+ BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
+
+ if (Status == STATUS_SUCCESS)
+ {
+ Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
+ BattWait->BatteryTag,
+ (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
+ if (NT_SUCCESS(Status))
+ Irp->IoStatus.Information = sizeof(ULONG);
+ }
+ else
+ {
+ Status = STATUS_NO_SUCH_DEVICE;
+ }
+ }
+ else
+ Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
+ break;
+
+ case IOCTL_BATTERY_QUERY_INFORMATION:
+ if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattQueryInfo))
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ BattQueryInfo = Irp->AssociatedIrp.SystemBuffer;
+
+ Status = BattClass->MiniportInfo.QueryInformation(BattClass->MiniportInfo.Context,
+ BattQueryInfo->BatteryTag,
+ BattQueryInfo->InformationLevel,
+ BattQueryInfo->AtRate,
+ Irp->AssociatedIrp.SystemBuffer,
+ IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
+ &ReturnedLength);
+ Irp->IoStatus.Information = ReturnedLength;
+ if (!NT_SUCCESS(Status))
+ DPRINT1("QueryInformation failed (0x%x)\n", Status);
+ break;
+
+ case IOCTL_BATTERY_SET_INFORMATION:
+ if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattSetInfo))
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ BattSetInfo = Irp->AssociatedIrp.SystemBuffer;
+
+ Status = BattClass->MiniportInfo.SetInformation(BattClass->MiniportInfo.Context,
+ BattSetInfo->BatteryTag,
+ BattSetInfo->InformationLevel,
+ BattSetInfo->Buffer);
+ if (!NT_SUCCESS(Status))
+ DPRINT1("SetInformation failed (0x%x)\n", Status);
+ break;
+
+ default:
+ DPRINT1("Received unsupported IRP %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
+ /* Do NOT complete the irp */
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
}