ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

battc.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            drivers/battery/battc/battc.c
00005  * PURPOSE:         Battery Class Driver
00006  * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
00007  */
00008 
00009 #include <battc.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 NTSTATUS
00015 NTAPI
00016 DriverEntry(PDRIVER_OBJECT DriverObject,
00017             PUNICODE_STRING RegistryPath)
00018 {
00019   DPRINT("Battery class driver initialized\n");
00020 
00021   return STATUS_SUCCESS;
00022 }
00023 
00024 BCLASSAPI
00025 NTSTATUS
00026 NTAPI
00027 BatteryClassUnload(PVOID ClassData)
00028 {
00029   PBATTERY_CLASS_DATA BattClass = ClassData;
00030 
00031   DPRINT("Battery 0x%x is being unloaded\n");
00032 
00033   if (BattClass->InterfaceName.Length != 0)
00034   {
00035       IoSetDeviceInterfaceState(&BattClass->InterfaceName, FALSE);
00036       RtlFreeUnicodeString(&BattClass->InterfaceName);
00037   }
00038 
00039   ExFreePoolWithTag(BattClass,
00040                     BATTERY_CLASS_DATA_TAG);
00041 
00042   return STATUS_SUCCESS;
00043 }
00044 
00045 BCLASSAPI
00046 NTSTATUS
00047 NTAPI
00048 BatteryClassSystemControl(PVOID ClassData,
00049                           PVOID WmiLibContext,
00050                           PDEVICE_OBJECT DeviceObject,
00051                           PIRP Irp,
00052                           PVOID Disposition)
00053 {
00054   UNIMPLEMENTED
00055 
00056   return STATUS_WMI_GUID_NOT_FOUND;
00057 }
00058 
00059 BCLASSAPI
00060 NTSTATUS
00061 NTAPI
00062 BatteryClassQueryWmiDataBlock(PVOID ClassData,
00063                               PDEVICE_OBJECT DeviceObject,
00064                               PIRP Irp,
00065                               ULONG GuidIndex,
00066                               PULONG InstanceLengthArray,
00067                               ULONG OutBufferSize,
00068                               PUCHAR Buffer)
00069 {
00070   UNIMPLEMENTED
00071 
00072   return STATUS_WMI_GUID_NOT_FOUND;
00073 }
00074 
00075 BCLASSAPI
00076 NTSTATUS
00077 NTAPI
00078 BatteryClassStatusNotify(PVOID ClassData)
00079 {
00080   PBATTERY_CLASS_DATA BattClass = ClassData;
00081   PBATTERY_WAIT_STATUS BattWait = BattClass->EventTriggerContext;
00082   BATTERY_STATUS BattStatus;
00083   NTSTATUS Status;
00084 
00085   DPRINT("Received battery status notification from 0x%x\n", ClassData);
00086 
00087   ExAcquireFastMutex(&BattClass->Mutex);
00088   if (!BattClass->Waiting)
00089   {
00090       ExReleaseFastMutex(&BattClass->Mutex);
00091       return STATUS_SUCCESS;
00092   }
00093 
00094   switch (BattClass->EventTrigger)
00095   {
00096      case EVENT_BATTERY_TAG:
00097        ExReleaseFastMutex(&BattClass->Mutex);
00098        DPRINT1("Waiting for battery is UNIMPLEMENTED!\n");
00099        break;
00100 
00101      case EVENT_BATTERY_STATUS:
00102        ExReleaseFastMutex(&BattClass->Mutex);
00103        Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
00104                                                     BattWait->BatteryTag,
00105                                                     &BattStatus);
00106        if (!NT_SUCCESS(Status))
00107            return Status;
00108 
00109        ExAcquireFastMutex(&BattClass->Mutex);
00110 
00111        if (!(BattWait->PowerState & BattStatus.PowerState) ||
00112            (BattWait->HighCapacity > BattStatus.Capacity) ||
00113            (BattWait->LowCapacity < BattStatus.Capacity))
00114        {
00115            KeSetEvent(&BattClass->WaitEvent, IO_NO_INCREMENT, FALSE);
00116        }
00117 
00118        ExReleaseFastMutex(&BattClass->Mutex);
00119        break;
00120 
00121      default:
00122        ExReleaseFastMutex(&BattClass->Mutex);
00123        ASSERT(FALSE);
00124        break;
00125   }
00126 
00127   return STATUS_SUCCESS;
00128 }
00129 
00130 BCLASSAPI
00131 NTSTATUS
00132 NTAPI
00133 BatteryClassInitializeDevice(PBATTERY_MINIPORT_INFO MiniportInfo,
00134                              PVOID *ClassData)
00135 {
00136   NTSTATUS Status;
00137   PBATTERY_CLASS_DATA BattClass = ExAllocatePoolWithTag(NonPagedPool,
00138                                                         sizeof(BATTERY_CLASS_DATA),
00139                                                         BATTERY_CLASS_DATA_TAG);
00140 
00141   if (!BattClass)
00142       return STATUS_INSUFFICIENT_RESOURCES;
00143 
00144   RtlZeroMemory(BattClass, sizeof(BATTERY_CLASS_DATA));
00145 
00146   RtlCopyMemory(&BattClass->MiniportInfo,
00147                 MiniportInfo,
00148                 sizeof(BattClass->MiniportInfo));
00149 
00150   KeInitializeEvent(&BattClass->WaitEvent, SynchronizationEvent, FALSE);
00151 
00152   ExInitializeFastMutex(&BattClass->Mutex);
00153 
00154   Status = IoRegisterDeviceInterface(MiniportInfo->Pdo,
00155                                      &GUID_DEVICE_BATTERY,
00156                                      NULL,
00157                                      &BattClass->InterfaceName);
00158   if (NT_SUCCESS(Status))
00159   {
00160       DPRINT("Initialized battery interface: %wZ\n", &BattClass->InterfaceName);
00161       IoSetDeviceInterfaceState(&BattClass->InterfaceName, TRUE);
00162   }
00163   else
00164   {
00165       DPRINT1("IoRegisterDeviceInterface failed (0x%x)\n", Status);
00166   }
00167 
00168   *ClassData = BattClass;
00169 
00170   return STATUS_SUCCESS;
00171 }
00172 
00173 BCLASSAPI
00174 NTSTATUS
00175 NTAPI
00176 BatteryClassIoctl(PVOID ClassData,
00177                   PIRP Irp)
00178 {
00179   PBATTERY_CLASS_DATA BattClass = ClassData;
00180   PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
00181   NTSTATUS Status;
00182   ULONG WaitTime;
00183   PBATTERY_WAIT_STATUS BattWait;
00184   PBATTERY_QUERY_INFORMATION BattQueryInfo;
00185   PBATTERY_SET_INFORMATION BattSetInfo;
00186   LARGE_INTEGER Timeout;
00187   PBATTERY_STATUS BattStatus;
00188   BATTERY_NOTIFY BattNotify;
00189   ULONG ReturnedLength;
00190 
00191   Irp->IoStatus.Information = 0;
00192 
00193   DPRINT("Received IOCTL %x for 0x%x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode,
00194          ClassData);
00195 
00196   switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
00197   {
00198     case IOCTL_BATTERY_QUERY_TAG:
00199       if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
00200           IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
00201       {
00202           Status = STATUS_BUFFER_TOO_SMALL;
00203           break;
00204       }
00205 
00206       WaitTime = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
00207 
00208       Timeout.QuadPart = Int32x32To64(WaitTime, -1000);
00209 
00210       Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
00211                                                 (PULONG)Irp->AssociatedIrp.SystemBuffer);
00212       if (!NT_SUCCESS(Status))
00213       {
00214           ExAcquireFastMutex(&BattClass->Mutex);
00215           BattClass->EventTrigger = EVENT_BATTERY_TAG;
00216           BattClass->Waiting = TRUE;
00217           ExReleaseFastMutex(&BattClass->Mutex);
00218 
00219           Status = KeWaitForSingleObject(&BattClass->WaitEvent,
00220                                          Executive,
00221                                          KernelMode,
00222                                          FALSE,
00223                                          WaitTime != -1 ? &Timeout : NULL);
00224 
00225           ExAcquireFastMutex(&BattClass->Mutex);
00226           BattClass->Waiting = FALSE;
00227           ExReleaseFastMutex(&BattClass->Mutex);
00228 
00229           if (Status == STATUS_SUCCESS)
00230           {
00231               Status = BattClass->MiniportInfo.QueryTag(BattClass->MiniportInfo.Context,
00232                                                         (PULONG)Irp->AssociatedIrp.SystemBuffer);
00233               if (NT_SUCCESS(Status))
00234                   Irp->IoStatus.Information = sizeof(ULONG);
00235           }
00236           else
00237           {
00238               Status = STATUS_NO_SUCH_DEVICE;
00239           }
00240       }
00241       else
00242           Irp->IoStatus.Information = sizeof(ULONG);
00243       break;
00244 
00245     case IOCTL_BATTERY_QUERY_STATUS:
00246       if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattWait) ||
00247           IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BATTERY_STATUS))
00248       {
00249           Status = STATUS_BUFFER_TOO_SMALL;
00250           break;
00251       }
00252 
00253       BattWait = Irp->AssociatedIrp.SystemBuffer;
00254 
00255       Timeout.QuadPart = Int32x32To64(BattWait->Timeout, -1000);
00256 
00257       Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
00258                                                    BattWait->BatteryTag,
00259                                                    (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
00260 
00261       BattStatus = Irp->AssociatedIrp.SystemBuffer;
00262 
00263       if (!NT_SUCCESS(Status) ||
00264           ((BattWait->PowerState & BattStatus->PowerState) &&
00265            (BattWait->HighCapacity <= BattStatus->Capacity) &&
00266            (BattWait->LowCapacity >= BattStatus->Capacity)))
00267       {
00268           BattNotify.PowerState = BattWait->PowerState;
00269           BattNotify.HighCapacity = BattWait->HighCapacity;
00270           BattNotify.LowCapacity = BattWait->LowCapacity;
00271 
00272           BattClass->MiniportInfo.SetStatusNotify(BattClass->MiniportInfo.Context,
00273                                                   BattWait->BatteryTag,
00274                                                   &BattNotify);
00275 
00276           ExAcquireFastMutex(&BattClass->Mutex);
00277           BattClass->EventTrigger = EVENT_BATTERY_STATUS;
00278           BattClass->EventTriggerContext = BattWait;
00279           BattClass->Waiting = TRUE;
00280           ExReleaseFastMutex(&BattClass->Mutex);
00281 
00282           Status = KeWaitForSingleObject(&BattClass->WaitEvent,
00283                                          Executive,
00284                                          KernelMode,
00285                                          FALSE,
00286                                          BattWait->Timeout != -1 ? &Timeout : NULL);
00287 
00288           ExAcquireFastMutex(&BattClass->Mutex);
00289           BattClass->Waiting = FALSE;
00290           ExReleaseFastMutex(&BattClass->Mutex);
00291 
00292           BattClass->MiniportInfo.DisableStatusNotify(BattClass->MiniportInfo.Context);
00293 
00294           if (Status == STATUS_SUCCESS)
00295           {
00296               Status = BattClass->MiniportInfo.QueryStatus(BattClass->MiniportInfo.Context,
00297                                                            BattWait->BatteryTag,
00298                                                            (PBATTERY_STATUS)Irp->AssociatedIrp.SystemBuffer);
00299               if (NT_SUCCESS(Status))
00300                   Irp->IoStatus.Information = sizeof(ULONG);
00301           }
00302           else
00303           {
00304               Status = STATUS_NO_SUCH_DEVICE;
00305           }
00306       }
00307       else
00308           Irp->IoStatus.Information = sizeof(BATTERY_STATUS);
00309       break;
00310 
00311     case IOCTL_BATTERY_QUERY_INFORMATION:
00312       if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattQueryInfo))
00313       {
00314           Status = STATUS_BUFFER_TOO_SMALL;
00315           break;
00316       }
00317 
00318       BattQueryInfo = Irp->AssociatedIrp.SystemBuffer;
00319 
00320       Status = BattClass->MiniportInfo.QueryInformation(BattClass->MiniportInfo.Context,
00321                                                         BattQueryInfo->BatteryTag,
00322                                                         BattQueryInfo->InformationLevel,
00323                                                         BattQueryInfo->AtRate,
00324                                                         Irp->AssociatedIrp.SystemBuffer,
00325                                                         IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
00326                                                         &ReturnedLength);
00327       Irp->IoStatus.Information = ReturnedLength;
00328       if (!NT_SUCCESS(Status))
00329           DPRINT1("QueryInformation failed (0x%x)\n", Status);
00330       break;
00331     case IOCTL_BATTERY_SET_INFORMATION:
00332       if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(*BattSetInfo))
00333       {
00334           Status = STATUS_BUFFER_TOO_SMALL;
00335           break;
00336       }
00337 
00338       BattSetInfo = Irp->AssociatedIrp.SystemBuffer;
00339 
00340       Status = BattClass->MiniportInfo.SetInformation(BattClass->MiniportInfo.Context,
00341                                                       BattSetInfo->BatteryTag,
00342                                                       BattSetInfo->InformationLevel,
00343                                                       BattSetInfo->Buffer);
00344       if (!NT_SUCCESS(Status))
00345           DPRINT1("SetInformation failed (0x%x)\n", Status);
00346       break;
00347 
00348     default:
00349       DPRINT1("Received unsupported IRP %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
00350       /* Do NOT complete the irp */
00351       return STATUS_NOT_SUPPORTED;
00352   }
00353 
00354   Irp->IoStatus.Status = Status;
00355   IoCompleteRequest(Irp, IO_NO_INCREMENT);
00356 
00357   return Status;
00358 }

Generated on Sat May 26 2012 04:25:43 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.