Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbattc.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
1.7.6.1
|