1 /* 2 * PROJECT: ReactOS Composite Battery Driver 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: boot/drivers/bus/acpi/compbatt/compbatt.c 5 * PURPOSE: Main Initialization Code and IRP Handling 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "compbatt.h" 12 13 #include <debug.h> 14 15 /* GLOBALS ********************************************************************/ 16 17 ULONG CompBattDebug; 18 19 /* FUNCTIONS ******************************************************************/ 20 21 NTSTATUS 22 NTAPI 23 CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject, 24 IN PIRP Irp) 25 { 26 PAGED_CODE(); 27 if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING OpenClose\n"); 28 29 /* Complete the IRP with success */ 30 Irp->IoStatus.Status = STATUS_SUCCESS; 31 Irp->IoStatus.Information = 0; 32 IoCompleteRequest(Irp, IO_NO_INCREMENT); 33 34 /* Return success */ 35 if (CompBattDebug & 0x100) DbgPrint("CompBatt: Exiting OpenClose\n"); 36 return STATUS_SUCCESS; 37 } 38 39 NTSTATUS 40 NTAPI 41 CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject, 42 IN PIRP Irp) 43 { 44 PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 45 NTSTATUS Status; 46 PAGED_CODE(); 47 if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING System Control\n"); 48 49 /* Are we attached yet? */ 50 if (DeviceExtension->AttachedDevice) 51 { 52 /* Send it up the stack */ 53 IoSkipCurrentIrpStackLocation(Irp); 54 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); 55 } 56 else 57 { 58 /* We don't support WMI */ 59 Status = STATUS_NOT_SUPPORTED; 60 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 61 IoCompleteRequest(Irp, IO_NO_INCREMENT); 62 } 63 64 /* Return status */ 65 return Status; 66 } 67 68 NTSTATUS 69 NTAPI 70 CompBattMonitorIrpComplete(IN PDEVICE_OBJECT DeviceObject, 71 IN PIRP Irp, 72 IN PKEVENT Event) 73 { 74 UNIMPLEMENTED; 75 return STATUS_NOT_IMPLEMENTED; 76 } 77 78 NTSTATUS 79 NTAPI 80 CompBattMonitorIrpCompleteWorker(IN PCOMPBATT_BATTERY_DATA BatteryData) 81 { 82 UNIMPLEMENTED; 83 return STATUS_NOT_IMPLEMENTED; 84 } 85 86 VOID 87 NTAPI 88 CompBattRecalculateTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) 89 { 90 PCOMPBATT_BATTERY_DATA BatteryData; 91 ULONG Tag; 92 PLIST_ENTRY ListHead, NextEntry; 93 if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING CompBattRecalculateTag\n"); 94 95 /* Loop the battery list */ 96 ExAcquireFastMutex(&DeviceExtension->Lock); 97 ListHead = &DeviceExtension->BatteryList; 98 NextEntry = ListHead->Flink; 99 while (NextEntry != ListHead) 100 { 101 /* Get the battery information and check if it has a tag */ 102 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); 103 if (BatteryData->Flags & COMPBATT_TAG_ASSIGNED) 104 { 105 /* Generate the next tag and exit */ 106 Tag = DeviceExtension->NextTag; 107 DeviceExtension->Flags |= COMPBATT_TAG_ASSIGNED; 108 DeviceExtension->Tag = Tag; 109 DeviceExtension->NextTag = Tag + 1; 110 break; 111 } 112 113 /* No tag for this device extension, clear it */ 114 DeviceExtension->Tag = 0; 115 NextEntry = NextEntry->Flink; 116 } 117 118 /* We're done */ 119 ExReleaseFastMutex(&DeviceExtension->Lock); 120 if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING CompBattRecalculateTag\n"); 121 } 122 123 NTSTATUS 124 NTAPI 125 CompBattIoctl(IN PDEVICE_OBJECT DeviceObject, 126 IN PIRP Irp) 127 { 128 PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; 129 NTSTATUS Status; 130 if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING Ioctl\n"); 131 132 /* Let the class driver handle it */ 133 Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp); 134 if (Status == STATUS_NOT_SUPPORTED) 135 { 136 /* It failed, try the next driver up the stack */ 137 Irp->IoStatus.Status = Status; 138 IoSkipCurrentIrpStackLocation(Irp); 139 Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp); 140 } 141 142 /* Return status */ 143 if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING Ioctl\n"); 144 return Status; 145 } 146 147 NTSTATUS 148 NTAPI 149 CompBattQueryTag(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, 150 OUT PULONG Tag) 151 { 152 NTSTATUS Status; 153 PAGED_CODE(); 154 if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING QueryTag\n"); 155 156 /* Was a tag assigned? */ 157 if (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED)) 158 { 159 /* Assign one */ 160 CompBattRecalculateTag(DeviceExtension); 161 } 162 163 /* Do we have a tag now? */ 164 if ((DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED) && (DeviceExtension->Tag)) 165 { 166 /* Return the tag */ 167 *Tag = DeviceExtension->Tag; 168 Status = STATUS_SUCCESS; 169 } 170 else 171 { 172 /* No tag */ 173 *Tag = 0; 174 Status = STATUS_NO_SUCH_DEVICE; 175 } 176 177 /* Return status */ 178 if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING QueryTag\n"); 179 return Status; 180 } 181 182 NTSTATUS 183 NTAPI 184 CompBattDisableStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) 185 { 186 PCOMPBATT_BATTERY_DATA BatteryData; 187 PLIST_ENTRY ListHead, NextEntry; 188 if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING DisableStatusNotify\n"); 189 190 /* Loop the battery list */ 191 ExAcquireFastMutex(&DeviceExtension->Lock); 192 ListHead = &DeviceExtension->BatteryList; 193 NextEntry = ListHead->Flink; 194 while (NextEntry != ListHead) 195 { 196 /* Get the battery information and clear capacity data */ 197 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); 198 BatteryData->WaitStatus.LowCapacity = 0; 199 BatteryData->WaitStatus.HighCapacity = 0x7FFFFFFF; 200 NextEntry = NextEntry->Flink; 201 } 202 203 /* Done */ 204 ExReleaseFastMutex(&DeviceExtension->Lock); 205 if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING DisableStatusNotify\n"); 206 return STATUS_SUCCESS; 207 } 208 209 NTSTATUS 210 NTAPI 211 CompBattSetStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, 212 IN ULONG BatteryTag, 213 IN PBATTERY_NOTIFY BatteryNotify) 214 { 215 UNIMPLEMENTED; 216 return STATUS_NOT_IMPLEMENTED; 217 } 218 219 NTSTATUS 220 NTAPI 221 CompBattQueryStatus(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, 222 IN ULONG Tag, 223 IN PBATTERY_STATUS BatteryStatus) 224 { 225 UNIMPLEMENTED; 226 return STATUS_NOT_IMPLEMENTED; 227 } 228 229 NTSTATUS 230 NTAPI 231 CompBattGetBatteryInformation(OUT PBATTERY_INFORMATION BatteryInfo, 232 IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) 233 { 234 NTSTATUS Status = STATUS_SUCCESS; 235 BATTERY_QUERY_INFORMATION InputBuffer; 236 PCOMPBATT_BATTERY_DATA BatteryData; 237 PLIST_ENTRY ListHead, NextEntry; 238 if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteryInformation\n"); 239 240 /* Set defaults */ 241 BatteryInfo->DefaultAlert1 = 0; 242 BatteryInfo->DefaultAlert2 = 0; 243 BatteryInfo->CriticalBias = 0; 244 245 /* Loop the battery list */ 246 ExAcquireFastMutex(&DeviceExtension->Lock); 247 ListHead = &DeviceExtension->BatteryList; 248 NextEntry = ListHead->Flink; 249 while (NextEntry != ListHead) 250 { 251 /* Try to acquire the remove lock */ 252 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); 253 if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, 0))) 254 { 255 /* Now release the device lock since the battery can't go away */ 256 ExReleaseFastMutex(&DeviceExtension->Lock); 257 258 /* Build the query */ 259 InputBuffer.BatteryTag = BatteryData->Tag; 260 InputBuffer.InformationLevel = BatteryInformation; 261 InputBuffer.AtRate = 0; 262 263 /* Make sure the battery has a tag */ 264 if (BatteryData->Tag) 265 { 266 /* Do we already have the data? */ 267 if (!(BatteryData->Flags & COMPBATT_BATTERY_INFORMATION_PRESENT)) 268 { 269 /* Send the IOCTL to query the information */ 270 RtlZeroMemory(&BatteryData->BatteryInformation, 271 sizeof(BatteryData->BatteryInformation)); 272 Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, 273 BatteryData->DeviceObject, 274 &InputBuffer, 275 sizeof(InputBuffer), 276 &BatteryData->BatteryInformation, 277 sizeof(BatteryData->BatteryInformation), 278 0); 279 if (!NT_SUCCESS(Status)) 280 { 281 /* Fail if the query had a problem */ 282 if (Status == STATUS_DEVICE_REMOVED) Status = STATUS_NO_SUCH_DEVICE; 283 ExAcquireFastMutex(&DeviceExtension->Lock); 284 IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); 285 break; 286 } 287 288 /* Next time we can use the static copy */ 289 BatteryData->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT; 290 if (CompBattDebug & 2) 291 DbgPrint("CompBattGetBatteryInformation: Read individual BATTERY_INFORMATION\n" 292 "-------- Capabilities = %x\n-------- Technology = %x\n" 293 "-------- Chemistry[4] = %x\n-------- DesignedCapacity = %x\n" 294 "-------- FullChargedCapacity = %x\n-------- DefaultAlert1 = %x\n" 295 "-------- DefaultAlert2 = %x\n-------- CriticalBias = %x\n" 296 "-------- CycleCount = %x\n", 297 BatteryData->BatteryInformation.Capabilities, 298 BatteryData->BatteryInformation.Technology, 299 BatteryData->BatteryInformation.Chemistry, 300 BatteryData->BatteryInformation.DesignedCapacity, 301 BatteryData->BatteryInformation.FullChargedCapacity, 302 BatteryData->BatteryInformation.DefaultAlert1, 303 BatteryData->BatteryInformation.DefaultAlert2, 304 BatteryData->BatteryInformation.CriticalBias, 305 BatteryData->BatteryInformation.CycleCount); 306 } 307 308 /* Combine capabilities */ 309 BatteryInfo->Capabilities |= BatteryData->BatteryInformation.Capabilities; 310 311 /* Add-on capacity */ 312 if (BatteryData->BatteryInformation.DesignedCapacity != BATTERY_UNKNOWN_CAPACITY) 313 { 314 BatteryInfo->DesignedCapacity += BatteryData->BatteryInformation.DesignedCapacity; 315 } 316 317 /* Add on fully charged capacity */ 318 if (BatteryData->BatteryInformation.FullChargedCapacity != BATTERY_UNKNOWN_CAPACITY) 319 { 320 BatteryInfo->FullChargedCapacity += BatteryData->BatteryInformation.FullChargedCapacity; 321 } 322 323 /* Choose the highest alert */ 324 BatteryInfo->DefaultAlert1 = max(BatteryInfo->DefaultAlert1, 325 BatteryData->BatteryInformation.DefaultAlert1); 326 327 /* Choose the highest alert */ 328 BatteryInfo->DefaultAlert2 = max(BatteryInfo->DefaultAlert2, 329 BatteryData->BatteryInformation.DefaultAlert2); 330 331 /* Choose the highest critical bias */ 332 BatteryInfo->CriticalBias = max(BatteryInfo->CriticalBias, 333 BatteryData->BatteryInformation.CriticalBias); 334 } 335 336 /* Re-acquire the device extension lock and release the remove lock */ 337 ExAcquireFastMutex(&DeviceExtension->Lock); 338 IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); 339 } 340 341 /* Next entry */ 342 NextEntry = NextEntry->Flink; 343 } 344 345 /* We are done with the list, check if the information was queried okay */ 346 ExReleaseFastMutex(&DeviceExtension->Lock); 347 if (NT_SUCCESS(Status)) 348 { 349 /* If there's no fully charged capacity, use the design capacity */ 350 if (!BatteryInfo->FullChargedCapacity) 351 { 352 BatteryInfo->FullChargedCapacity = BatteryInfo->DesignedCapacity; 353 } 354 355 /* Print out final combined data */ 356 if (CompBattDebug & 2) 357 DbgPrint("CompBattGetBatteryInformation: Returning BATTERY_INFORMATION\n" 358 "-------- Capabilities = %x\n-------- Technology = %x\n" 359 "-------- Chemistry[4] = %x\n-------- DesignedCapacity = %x\n" 360 "-------- FullChargedCapacity = %x\n-------- DefaultAlert1 = %x\n" 361 "-------- DefaultAlert2 = %x\n-------- CriticalBias = %x\n" 362 "-------- CycleCount = %x\n", 363 BatteryInfo->Capabilities, 364 BatteryInfo->Technology, 365 BatteryInfo->Chemistry, 366 BatteryInfo->DesignedCapacity, 367 BatteryInfo->FullChargedCapacity, 368 BatteryInfo->DefaultAlert1, 369 BatteryInfo->DefaultAlert2, 370 BatteryInfo->CriticalBias, 371 BatteryInfo->CycleCount); 372 373 /* Copy the data into the device extension */ 374 RtlCopyMemory(&DeviceExtension->BatteryInformation, 375 BatteryInfo, 376 sizeof(DeviceExtension->BatteryInformation)); 377 DeviceExtension->Flags |= COMPBATT_BATTERY_INFORMATION_PRESENT; 378 } 379 380 /* We are done */ 381 if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteryInformation\n"); 382 return Status; 383 } 384 385 NTSTATUS 386 NTAPI 387 CompBattGetBatteryGranularity(OUT PBATTERY_REPORTING_SCALE ReportingScale, 388 IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) 389 { 390 NTSTATUS Status = STATUS_SUCCESS; 391 BATTERY_QUERY_INFORMATION InputBuffer; 392 PCOMPBATT_BATTERY_DATA BatteryData; 393 BATTERY_REPORTING_SCALE BatteryScale[4]; 394 PLIST_ENTRY ListHead, NextEntry; 395 ULONG i; 396 if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING GetBatteryGranularity\n"); 397 398 /* Set defaults */ 399 ReportingScale[0].Granularity = -1; 400 ReportingScale[1].Granularity = -1; 401 ReportingScale[2].Granularity = -1; 402 ReportingScale[3].Granularity = -1; 403 404 /* Loop the battery list */ 405 ExAcquireFastMutex(&DeviceExtension->Lock); 406 ListHead = &DeviceExtension->BatteryList; 407 NextEntry = ListHead->Flink; 408 while (NextEntry != ListHead) 409 { 410 /* Try to acquire the remove lock */ 411 BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); 412 if (NT_SUCCESS(IoAcquireRemoveLock(&BatteryData->RemoveLock, 0))) 413 { 414 /* Now release the device lock since the battery can't go away */ 415 ExReleaseFastMutex(&DeviceExtension->Lock); 416 417 /* Build the query */ 418 InputBuffer.BatteryTag = BatteryData->Tag; 419 InputBuffer.InformationLevel = BatteryGranularityInformation; 420 421 /* Make sure the battery has a tag */ 422 if (BatteryData->Tag) 423 { 424 /* Send the IOCTL to query the information */ 425 RtlZeroMemory(&BatteryData->BatteryInformation, 426 sizeof(BatteryData->BatteryInformation)); 427 Status = BatteryIoctl(IOCTL_BATTERY_QUERY_INFORMATION, 428 BatteryData->DeviceObject, 429 &InputBuffer, 430 sizeof(InputBuffer), 431 &BatteryScale, 432 sizeof(BatteryScale), 433 0); 434 if (!NT_SUCCESS(Status)) 435 { 436 /* Fail if the query had a problem */ 437 ExAcquireFastMutex(&DeviceExtension->Lock); 438 IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); 439 break; 440 } 441 442 /* Loop all 4 scales */ 443 for (i = 0; i < 4; i++) 444 { 445 /* Check for valid granularity */ 446 if (BatteryScale[i].Granularity) 447 { 448 /* If it's smaller, use it instead */ 449 ReportingScale[i].Granularity = min(BatteryScale[i].Granularity, 450 ReportingScale[i].Granularity); 451 } 452 453 } 454 } 455 456 /* Re-acquire the device extension lock and release the remove lock */ 457 ExAcquireFastMutex(&DeviceExtension->Lock); 458 IoReleaseRemoveLock(&BatteryData->RemoveLock, 0); 459 } 460 461 /* Next entry */ 462 NextEntry = NextEntry->Flink; 463 } 464 465 /* All done */ 466 ExReleaseFastMutex(&DeviceExtension->Lock); 467 if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING GetBatteryGranularity\n"); 468 return STATUS_SUCCESS; 469 } 470 471 NTSTATUS 472 NTAPI 473 CompBattGetEstimatedTime(OUT PULONG Time, 474 IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) 475 { 476 UNIMPLEMENTED; 477 return STATUS_NOT_IMPLEMENTED; 478 } 479 480 NTSTATUS 481 NTAPI 482 CompBattQueryInformation(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension, 483 IN ULONG Tag, 484 IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel, 485 IN OPTIONAL LONG AtRate, 486 IN PVOID Buffer, 487 IN ULONG BufferLength, 488 OUT PULONG ReturnedLength) 489 { 490 BATTERY_INFORMATION BatteryInfo; 491 BATTERY_REPORTING_SCALE BatteryGranularity[4]; 492 PWCHAR BatteryName = L"Composite Battery"; 493 //BATTERY_MANUFACTURE_DATE Date; 494 ULONG Dummy, Time; 495 PVOID QueryData = NULL; 496 ULONG QueryLength = 0; 497 NTSTATUS Status = STATUS_SUCCESS; 498 PAGED_CODE(); 499 if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING QueryInformation\n"); 500 501 /* Check for valid/correct tag */ 502 if ((Tag != DeviceExtension->Tag) || 503 (!(DeviceExtension->Flags & COMPBATT_TAG_ASSIGNED))) 504 { 505 /* Not right, so fail */ 506 return STATUS_NO_SUCH_DEVICE; 507 } 508 509 /* Check what caller wants */ 510 switch (InfoLevel) 511 { 512 case BatteryInformation: 513 514 /* Query combined battery information */ 515 RtlZeroMemory(&BatteryInfo, sizeof(BatteryInfo)); 516 Status = CompBattGetBatteryInformation(&BatteryInfo, DeviceExtension); 517 if (NT_SUCCESS(Status)) 518 { 519 /* Return the data if successful */ 520 QueryData = &BatteryInfo; 521 QueryLength = sizeof(BatteryInfo); 522 } 523 break; 524 525 case BatteryGranularityInformation: 526 527 /* Query combined granularity information */ 528 RtlZeroMemory(&BatteryGranularity, sizeof(BatteryGranularity)); 529 Status = CompBattGetBatteryGranularity(BatteryGranularity, DeviceExtension); 530 if (NT_SUCCESS(Status)) 531 { 532 /* Return the data if successful */ 533 QueryLength = sizeof(BatteryGranularity); 534 QueryData = &BatteryGranularity; 535 } 536 break; 537 538 case BatteryEstimatedTime: 539 540 /* Query combined time estimate information */ 541 RtlZeroMemory(&Time, sizeof(Time)); 542 Status = CompBattGetEstimatedTime(&Time, DeviceExtension); 543 if (NT_SUCCESS(Status)) 544 { 545 /* Return the data if successful */ 546 QueryLength = sizeof(Time); 547 QueryData = &Time; 548 } 549 break; 550 551 case BatteryManufactureName: 552 case BatteryDeviceName: 553 554 /* Return the static buffer */ 555 QueryData = BatteryName; 556 QueryLength = sizeof(L"Composite Battery"); 557 break; 558 559 case BatteryManufactureDate: 560 561 /* Static data */ 562 //Date.Day = 26; 563 //Date.Month = 06; 564 //Date.Year = 1997; 565 break; 566 567 case BatteryTemperature: 568 case BatteryUniqueID: 569 570 /* Return zero */ 571 Dummy = 0; 572 QueryData = &Dummy; 573 QueryLength = sizeof(Dummy); 574 break; 575 576 default: 577 /* Everything else is unknown */ 578 Status = STATUS_INVALID_PARAMETER; 579 break; 580 } 581 582 /* Return the required length and check if the caller supplied enough */ 583 *ReturnedLength = QueryLength; 584 if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL; 585 586 /* Copy the data if there's enough space and it exists */ 587 if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData, QueryLength); 588 589 /* Return function result */ 590 if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING QueryInformation\n"); 591 return Status; 592 } 593 594 NTSTATUS 595 NTAPI 596 DriverEntry(IN PDRIVER_OBJECT DriverObject, 597 IN PUNICODE_STRING RegistryPath) 598 { 599 /* Register add device routine */ 600 DriverObject->DriverExtension->AddDevice = CompBattAddDevice; 601 602 /* Register other handlers */ 603 DriverObject->MajorFunction[IRP_MJ_CREATE] = CompBattOpenClose; 604 DriverObject->MajorFunction[IRP_MJ_CLOSE] = CompBattOpenClose; 605 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CompBattIoctl; 606 DriverObject->MajorFunction[IRP_MJ_POWER] = CompBattPowerDispatch; 607 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CompBattSystemControl; 608 DriverObject->MajorFunction[IRP_MJ_PNP] = CompBattPnpDispatch; 609 return STATUS_SUCCESS; 610 } 611 612 /* EOF */ 613