From 48b9dc33d5f139a95070b84bfbae0b793de441f0 Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sat, 27 Mar 2010 21:34:06 +0000 Subject: [PATCH] [COMPBATT]: Main driver skeleton: CompBattAddDevice, DriverEntry, CompBattSystemControl, CompBattIoct, CompBattOpenClose, CompBattPowerDispatch, CompBattPnpDispatch. svn path=/trunk/; revision=46498 --- reactos/drivers/bus/acpi/compbatt/compbatt.c | 70 +++++++- reactos/drivers/bus/acpi/compbatt/compbatt.h | 64 ++++++- reactos/drivers/bus/acpi/compbatt/comppnp.c | 179 ++++++++++++++++++- 3 files changed, 298 insertions(+), 15 deletions(-) diff --git a/reactos/drivers/bus/acpi/compbatt/compbatt.c b/reactos/drivers/bus/acpi/compbatt/compbatt.c index 03d587c46ad..d8f8920cc0a 100644 --- a/reactos/drivers/bus/acpi/compbatt/compbatt.c +++ b/reactos/drivers/bus/acpi/compbatt/compbatt.c @@ -21,8 +21,17 @@ NTAPI CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PAGED_CODE(); + if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING OpenClose\n"); + + /* Complete the IRP with success */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IofCompleteRequest(Irp, IO_NO_INCREMENT); + + /* Return success */ + if (CompBattDebug & 0x100) DbgPrint("CompBatt: Exiting OpenClose\n"); + return STATUS_SUCCESS; } NTSTATUS @@ -30,8 +39,28 @@ NTAPI CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + NTSTATUS Status; + PAGED_CODE(); + if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING System Control\n"); + + /* Are we attached yet? */ + if (DeviceExtension->AttachedDevice) + { + /* Send it up the stack */ + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); + } + else + { + /* We don't support WMI */ + Status = STATUS_NOT_SUPPORTED; + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + + /* Return status */ + return Status; } NTSTATUS @@ -65,8 +94,23 @@ NTAPI CompBattIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + NTSTATUS Status; + if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING Ioctl\n"); + + /* Let the class driver handle it */ + Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp); + if (Status == STATUS_NOT_SUPPORTED) + { + /* It failed, try the next driver up the stack */ + Irp->IoStatus.Status = Status; + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); + } + + /* Return status */ + if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING Ioctl\n"); + return Status; } NTSTATUS @@ -161,8 +205,18 @@ NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + /* Register add device routine */ + DriverObject->DriverExtension->AddDevice = CompBattAddDevice; + + /* Register other handlers */ + DriverObject->MajorFunction[0] = CompBattOpenClose; + DriverObject->MajorFunction[2] = CompBattOpenClose; + DriverObject->MajorFunction[14] = CompBattIoctl; + DriverObject->MajorFunction[22] = CompBattPowerDispatch; + DriverObject->MajorFunction[23] = CompBattSystemControl; + DriverObject->MajorFunction[27] = CompBattPnpDispatch; + + return STATUS_SUCCESS; } /* EOF */ diff --git a/reactos/drivers/bus/acpi/compbatt/compbatt.h b/reactos/drivers/bus/acpi/compbatt/compbatt.h index 701f1362641..015195bafe2 100644 --- a/reactos/drivers/bus/acpi/compbatt/compbatt.h +++ b/reactos/drivers/bus/acpi/compbatt/compbatt.h @@ -52,6 +52,68 @@ typedef struct _COMPBATT_DEVICE_EXTENSION PVOID NotificationEntry; } COMPBATT_DEVICE_EXTENSION, *PCOMPBATT_DEVICE_EXTENSION; -extern ULONG CmBattDebug; +NTSTATUS +NTAPI +CompBattAddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PdoDeviceObject +); + +NTSTATUS +NTAPI +CompBattPowerDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +); + +NTSTATUS +NTAPI +CompBattPnpDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp +); + +NTSTATUS +NTAPI +CompBattQueryInformation( + IN PCOMPBATT_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 +); + +NTSTATUS +NTAPI +CompBattQueryStatus( + IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + IN ULONG Tag, + IN PBATTERY_STATUS BatteryStatus +); + +NTSTATUS +NTAPI +CompBattSetStatusNotify( + IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + IN ULONG BatteryTag, + IN PBATTERY_NOTIFY BatteryNotify +); + +NTSTATUS +NTAPI +CompBattDisableStatusNotify( + IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension +); + +NTSTATUS +NTAPI +CompBattQueryTag( + IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, + OUT PULONG Tag +); + +extern ULONG CompBattDebug; /* EOF */ diff --git a/reactos/drivers/bus/acpi/compbatt/comppnp.c b/reactos/drivers/bus/acpi/compbatt/comppnp.c index a767c18ab80..156ee3fd81f 100644 --- a/reactos/drivers/bus/acpi/compbatt/comppnp.c +++ b/reactos/drivers/bus/acpi/compbatt/comppnp.c @@ -17,8 +17,15 @@ NTAPI CompBattPowerDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + if (CompBattDebug & 1) DbgPrint("CompBatt: PowerDispatch recieved power IRP.\n"); + + /* Start the next IRP */ + PoStartNextPowerIrp(Irp); + + /* Call the next driver in the stack */ + IoSkipCurrentIrpStackLocation(Irp); + return PoCallDriver(DeviceExtension->AttachedDevice, Irp); } PCOMPBATT_BATTERY_ENTRY @@ -79,8 +86,82 @@ NTAPI CompBattAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PdoDeviceObject) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + UNICODE_STRING DeviceName; + PCOMPBATT_DEVICE_EXTENSION DeviceExtension; + PDEVICE_OBJECT DeviceObject; + UNICODE_STRING SymbolicLinkName; + BATTERY_MINIPORT_INFO MiniportInfo; + if (CompBattDebug & 2) DbgPrint("CompBatt: Got an AddDevice - %x\n", PdoDeviceObject); + + /* Create the device */ + RtlInitUnicodeString(&DeviceName, L"\\Device\\CompositeBattery"); + Status = IoCreateDevice(DriverObject, + sizeof(COMPBATT_DEVICE_EXTENSION), + &DeviceName, + FILE_DEVICE_BATTERY, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) return Status; + + /* Setup symbolic link for Win32 access */ + RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\CompositeBattery"); + IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName); + + /* Initialize the device extension */ + DeviceExtension = DeviceObject->DeviceExtension; + RtlZeroMemory(DeviceExtension, 0x1B0u); + + /* Attach to device stack and set DO pointers */ + DeviceExtension->AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject, + PdoDeviceObject); + DeviceExtension->DeviceObject = DeviceObject; + if (!DeviceExtension->AttachedDevice) + { + /* Fail */ + if (CompBattDebug & 8) + DbgPrint("CompBattAddDevice: Could not attach to LowerDevice.\n"); + IoDeleteDevice(DeviceObject); + return STATUS_UNSUCCESSFUL; + } + + /* Set device object flags */ + DeviceObject->Flags |= (DO_POWER_PAGABLE | DO_BUFFERED_IO); + DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + /* Setup the device extension */ + ExInitializeFastMutex(&DeviceExtension->Lock); + InitializeListHead(&DeviceExtension->BatteryList); + DeviceExtension->Flags = 0; + DeviceExtension->NextTag = 1; + + /* Setup the miniport data */ + RtlZeroMemory(&MiniportInfo, sizeof(MiniportInfo)); + MiniportInfo.MajorVersion = BATTERY_CLASS_MAJOR_VERSION; + MiniportInfo.MinorVersion = BATTERY_CLASS_MINOR_VERSION; + MiniportInfo.Context = DeviceExtension; + MiniportInfo.DeviceName = &DeviceName; + MiniportInfo.QueryTag = (BCLASS_QUERY_TAG)CompBattQueryTag; + MiniportInfo.QueryInformation = (BCLASS_QUERY_INFORMATION)CompBattQueryInformation; + MiniportInfo.SetInformation = NULL; + MiniportInfo.QueryStatus = (BCLASS_QUERY_STATUS)CompBattQueryStatus; + MiniportInfo.SetStatusNotify = (BCLASS_SET_STATUS_NOTIFY)CompBattSetStatusNotify; + MiniportInfo.DisableStatusNotify = (BCLASS_DISABLE_STATUS_NOTIFY)CompBattDisableStatusNotify; + MiniportInfo.Pdo = NULL; + + /* Register with the class driver */ + Status = BatteryClassInitializeDevice(&MiniportInfo, + &DeviceExtension->ClassData); + if (!NT_SUCCESS(Status)) + { + /* Undo everything */ + IoDetachDevice(DeviceExtension->AttachedDevice); + IoDeleteDevice(DeviceObject); + } + + /* Return status */ + return Status; } NTSTATUS @@ -88,8 +169,94 @@ NTAPI CompBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status; + PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING PnpDispatch\n"); + + /* Set default error */ + Status = STATUS_NOT_SUPPORTED; + + /* Check what kind of PnP function this is */ + switch (IoStackLocation->MinorFunction) + { + case IRP_MN_START_DEVICE: + + /* Device is starting, register for new batteries and pick up current ones */ + Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, + 0, + (PVOID)&GUID_DEVICE_BATTERY, + DeviceObject->DriverObject, + (PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)CompBattPnpEventHandler, + DeviceExtension, + &DeviceExtension->NotificationEntry); + if (NT_SUCCESS(Status)) + { + /* Now go get the batteries */ + if (CompBattDebug & 2) + DbgPrint("CompBatt: Successfully registered for PnP notification\n"); + Status = CompBattGetBatteries(DeviceExtension); + } + else + { + /* We failed */ + if (CompBattDebug & 8) + DbgPrint("CompBatt: Couldn't register for PnP notification - %x\n", + Status); + } + + case IRP_MN_CANCEL_STOP_DEVICE: + + /* Explicitly say ok */ + Status = STATUS_SUCCESS; + break; + + case IRP_MN_CANCEL_REMOVE_DEVICE: + + /* Explicitly say ok */ + Status = STATUS_SUCCESS; + break; + + case IRP_MN_SURPRISE_REMOVAL: + + /* Explicitly say ok */ + Status = STATUS_SUCCESS; + break; + + case IRP_MN_QUERY_PNP_DEVICE_STATE: + + /* Add this in */ + Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; + Status = STATUS_SUCCESS; + break; + + default: + + /* Not supported */ + Status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + /* Set IRP status if we have one */ + if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status; + + /* Did someone pick it up? */ + if ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED)) + { + /* Still unsupported, try ACPI */ + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); + } + else + { + /* Complete the request */ + Status = Irp->IoStatus.Status; + IofCompleteRequest(Irp, IO_NO_INCREMENT); + } + + /* Release the remove lock and return status */ + if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING PnpDispatch\n"); + return Status; } /* EOF */