1 #include "precomp.h" 2 3 #include <poclass.h> 4 5 #define NDEBUG 6 #include <debug.h> 7 8 NTSTATUS 9 NTAPI 10 DriverEntry ( 11 PDRIVER_OBJECT DriverObject, 12 PUNICODE_STRING RegistryPath 13 ); 14 15 #ifdef ALLOC_PRAGMA 16 #pragma alloc_text (INIT, DriverEntry) 17 #pragma alloc_text (PAGE, Bus_AddDevice) 18 19 #endif 20 21 extern struct acpi_device *sleep_button; 22 extern struct acpi_device *power_button; 23 24 UNICODE_STRING ProcessorHardwareIds = {0, 0, NULL}; 25 LPWSTR ProcessorIdString = NULL; 26 LPWSTR ProcessorNameString = NULL; 27 28 29 NTSTATUS 30 NTAPI 31 Bus_AddDevice( 32 PDRIVER_OBJECT DriverObject, 33 PDEVICE_OBJECT PhysicalDeviceObject 34 ) 35 36 { 37 NTSTATUS status; 38 PDEVICE_OBJECT deviceObject = NULL; 39 PFDO_DEVICE_DATA deviceData = NULL; 40 #ifndef NDEBUG 41 PWCHAR deviceName = NULL; 42 ULONG nameLength; 43 #endif 44 45 PAGED_CODE (); 46 47 DPRINT("Add Device: 0x%p\n", PhysicalDeviceObject); 48 49 DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n"); 50 status = IoCreateDevice(DriverObject, 51 sizeof(FDO_DEVICE_DATA), 52 NULL, 53 FILE_DEVICE_ACPI, 54 FILE_DEVICE_SECURE_OPEN, 55 TRUE, 56 &deviceObject); 57 if (!NT_SUCCESS(status)) 58 { 59 DPRINT1("IoCreateDevice() failed with status 0x%X\n", status); 60 goto End; 61 } 62 63 deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension; 64 RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA)); 65 66 // 67 // Set the initial state of the FDO 68 // 69 70 INITIALIZE_PNP_STATE(deviceData->Common); 71 72 deviceData->Common.IsFDO = TRUE; 73 74 deviceData->Common.Self = deviceObject; 75 76 ExInitializeFastMutex (&deviceData->Mutex); 77 78 InitializeListHead (&deviceData->ListOfPDOs); 79 80 // Set the PDO for use with PlugPlay functions 81 82 deviceData->UnderlyingPDO = PhysicalDeviceObject; 83 84 // 85 // Set the initial powerstate of the FDO 86 // 87 88 deviceData->Common.DevicePowerState = PowerDeviceUnspecified; 89 deviceData->Common.SystemPowerState = PowerSystemWorking; 90 91 deviceObject->Flags |= DO_POWER_PAGABLE; 92 93 // 94 // Attach our FDO to the device stack. 95 // The return value of IoAttachDeviceToDeviceStack is the top of the 96 // attachment chain. This is where all the IRPs should be routed. 97 // 98 99 deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack ( 100 deviceObject, 101 PhysicalDeviceObject); 102 103 if (NULL == deviceData->NextLowerDriver) { 104 105 status = STATUS_NO_SUCH_DEVICE; 106 goto End; 107 } 108 109 110 #ifndef NDEBUG 111 // 112 // We will demonstrate here the step to retrieve the name of the PDO 113 // 114 115 status = IoGetDeviceProperty (PhysicalDeviceObject, 116 DevicePropertyPhysicalDeviceObjectName, 117 0, 118 NULL, 119 &nameLength); 120 121 if (status != STATUS_BUFFER_TOO_SMALL) 122 { 123 DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status); 124 goto End; 125 } 126 127 deviceName = ExAllocatePoolWithTag(NonPagedPool, nameLength, 'MpcA'); 128 129 if (NULL == deviceName) { 130 DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength); 131 status = STATUS_INSUFFICIENT_RESOURCES; 132 goto End; 133 } 134 135 status = IoGetDeviceProperty (PhysicalDeviceObject, 136 DevicePropertyPhysicalDeviceObjectName, 137 nameLength, 138 deviceName, 139 &nameLength); 140 141 if (!NT_SUCCESS (status)) { 142 143 DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status); 144 goto End; 145 } 146 147 DPRINT("AddDevice: %p to %p->%p (%ws) \n", 148 deviceObject, 149 deviceData->NextLowerDriver, 150 PhysicalDeviceObject, 151 deviceName); 152 153 #endif 154 155 // 156 // We are done with initializing, so let's indicate that and return. 157 // This should be the final step in the AddDevice process. 158 // 159 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 160 161 End: 162 #ifndef NDEBUG 163 if (deviceName){ 164 ExFreePoolWithTag(deviceName, 'MpcA'); 165 } 166 #endif 167 if (!NT_SUCCESS(status) && deviceObject){ 168 if (deviceData && deviceData->NextLowerDriver){ 169 IoDetachDevice (deviceData->NextLowerDriver); 170 } 171 IoDeleteDevice (deviceObject); 172 } 173 return status; 174 175 } 176 177 NTSTATUS 178 NTAPI 179 ACPIDispatchCreateClose( 180 IN PDEVICE_OBJECT DeviceObject, 181 IN PIRP Irp) 182 { 183 Irp->IoStatus.Status = STATUS_SUCCESS; 184 Irp->IoStatus.Information = 0; 185 186 IoCompleteRequest(Irp, IO_NO_INCREMENT); 187 188 return STATUS_SUCCESS; 189 } 190 191 VOID 192 NTAPI 193 ButtonWaitThread(PVOID Context) 194 { 195 PIRP Irp = Context; 196 int result; 197 struct acpi_bus_event event; 198 ULONG ButtonEvent; 199 200 while (ACPI_SUCCESS(result = acpi_bus_receive_event(&event)) && 201 event.type != ACPI_BUTTON_NOTIFY_STATUS); 202 203 if (!ACPI_SUCCESS(result)) 204 { 205 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 206 } 207 else 208 { 209 if (strstr(event.bus_id, "PWRF")) 210 ButtonEvent = SYS_BUTTON_POWER; 211 else if (strstr(event.bus_id, "SLPF")) 212 ButtonEvent = SYS_BUTTON_SLEEP; 213 else 214 ButtonEvent = 0; 215 216 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &ButtonEvent, sizeof(ButtonEvent)); 217 Irp->IoStatus.Status = STATUS_SUCCESS; 218 Irp->IoStatus.Information = sizeof(ULONG); 219 } 220 221 IoCompleteRequest(Irp, IO_NO_INCREMENT); 222 } 223 224 225 NTSTATUS 226 NTAPI 227 ACPIDispatchDeviceControl( 228 IN PDEVICE_OBJECT DeviceObject, 229 IN PIRP Irp) 230 { 231 PIO_STACK_LOCATION irpStack; 232 NTSTATUS status = STATUS_NOT_SUPPORTED; 233 PCOMMON_DEVICE_DATA commonData; 234 ULONG Caps = 0; 235 HANDLE ThreadHandle; 236 237 PAGED_CODE (); 238 239 irpStack = IoGetCurrentIrpStackLocation (Irp); 240 ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction); 241 242 commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; 243 244 Irp->IoStatus.Information = 0; 245 246 if (!commonData->IsFDO) 247 { 248 switch (irpStack->Parameters.DeviceIoControl.IoControlCode) 249 { 250 case IOCTL_ACPI_EVAL_METHOD: 251 status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData, 252 Irp); 253 break; 254 255 case IOCTL_GET_SYS_BUTTON_CAPS: 256 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) 257 { 258 status = STATUS_BUFFER_TOO_SMALL; 259 break; 260 } 261 262 if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D")) 263 { 264 DPRINT1("Lid button reported to power manager\n"); 265 Caps |= SYS_BUTTON_LID; 266 } 267 else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL) 268 { 269 /* We have to return both at the same time because since we 270 * have a NULL handle we are the fixed feature DO and we will 271 * only be called once (not once per device) 272 */ 273 if (power_button) 274 { 275 DPRINT("Fixed power button reported to power manager\n"); 276 Caps |= SYS_BUTTON_POWER; 277 } 278 if (sleep_button) 279 { 280 DPRINT("Fixed sleep button reported to power manager\n"); 281 Caps |= SYS_BUTTON_SLEEP; 282 } 283 } 284 else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C")) 285 { 286 DPRINT("Control method power button reported to power manager\n"); 287 Caps |= SYS_BUTTON_POWER; 288 } 289 else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E")) 290 { 291 DPRINT("Control method sleep reported to power manager\n"); 292 Caps |= SYS_BUTTON_SLEEP; 293 } 294 else 295 { 296 DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n"); 297 status = STATUS_INVALID_PARAMETER; 298 } 299 300 if (Caps != 0) 301 { 302 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps)); 303 Irp->IoStatus.Information = sizeof(Caps); 304 status = STATUS_SUCCESS; 305 } 306 break; 307 308 case IOCTL_GET_SYS_BUTTON_EVENT: 309 PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, ButtonWaitThread, Irp); 310 ZwClose(ThreadHandle); 311 312 status = STATUS_PENDING; 313 break; 314 315 case IOCTL_BATTERY_QUERY_TAG: 316 DPRINT("IOCTL_BATTERY_QUERY_TAG is not supported!\n"); 317 break; 318 319 default: 320 DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode); 321 break; 322 } 323 } 324 else 325 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n"); 326 327 if (status != STATUS_PENDING) 328 { 329 Irp->IoStatus.Status = status; 330 IoCompleteRequest(Irp, IO_NO_INCREMENT); 331 } 332 else 333 IoMarkIrpPending(Irp); 334 335 return status; 336 } 337 338 static 339 NTSTATUS 340 AcpiRegOpenKey(IN HANDLE ParentKeyHandle, 341 IN LPCWSTR KeyName, 342 IN ACCESS_MASK DesiredAccess, 343 OUT HANDLE KeyHandle) 344 { 345 OBJECT_ATTRIBUTES ObjectAttributes; 346 UNICODE_STRING Name; 347 348 RtlInitUnicodeString(&Name, KeyName); 349 350 InitializeObjectAttributes(&ObjectAttributes, 351 &Name, 352 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 353 ParentKeyHandle, 354 NULL); 355 356 return ZwOpenKey(KeyHandle, 357 DesiredAccess, 358 &ObjectAttributes); 359 } 360 361 static 362 NTSTATUS 363 AcpiRegQueryValue(IN HANDLE KeyHandle, 364 IN LPWSTR ValueName, 365 OUT PULONG Type OPTIONAL, 366 OUT PVOID Data OPTIONAL, 367 IN OUT PULONG DataLength OPTIONAL) 368 { 369 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; 370 UNICODE_STRING Name; 371 ULONG BufferLength = 0; 372 NTSTATUS Status; 373 374 RtlInitUnicodeString(&Name, ValueName); 375 376 if (DataLength != NULL) 377 BufferLength = *DataLength; 378 379 /* Check if the caller provided a valid buffer */ 380 if ((Data != NULL) && (BufferLength != 0)) 381 { 382 BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); 383 384 /* Allocate memory for the value */ 385 ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferLength, 'MpcA'); 386 if (ValueInfo == NULL) 387 return STATUS_NO_MEMORY; 388 } 389 else 390 { 391 /* Caller didn't provide a valid buffer, assume he wants the size only */ 392 ValueInfo = NULL; 393 BufferLength = 0; 394 } 395 396 /* Query the value */ 397 Status = ZwQueryValueKey(KeyHandle, 398 &Name, 399 KeyValuePartialInformation, 400 ValueInfo, 401 BufferLength, 402 &BufferLength); 403 404 if (DataLength != NULL) 405 *DataLength = BufferLength; 406 407 /* Check if we have the size only */ 408 if (ValueInfo == NULL) 409 { 410 /* Check for unexpected status */ 411 if ((Status != STATUS_BUFFER_OVERFLOW) && 412 (Status != STATUS_BUFFER_TOO_SMALL)) 413 { 414 return Status; 415 } 416 417 /* All is well */ 418 Status = STATUS_SUCCESS; 419 } 420 /* Otherwise the caller wanted data back, check if we got it */ 421 else if (NT_SUCCESS(Status)) 422 { 423 if (Type != NULL) 424 *Type = ValueInfo->Type; 425 426 /* Copy it */ 427 RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength); 428 429 /* if the type is REG_SZ and data is not 0-terminated 430 * and there is enough space in the buffer NT appends a \0 */ 431 if (((ValueInfo->Type == REG_SZ) || 432 (ValueInfo->Type == REG_EXPAND_SZ) || 433 (ValueInfo->Type == REG_MULTI_SZ)) && 434 (ValueInfo->DataLength <= *DataLength - sizeof(WCHAR))) 435 { 436 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength); 437 if ((ptr > (WCHAR *)Data) && ptr[-1]) 438 *ptr = 0; 439 } 440 } 441 442 /* Free the memory and return status */ 443 if (ValueInfo != NULL) 444 { 445 ExFreePoolWithTag(ValueInfo, 'MpcA'); 446 } 447 448 return Status; 449 } 450 451 static 452 NTSTATUS 453 GetProcessorInformation(VOID) 454 { 455 LPWSTR ProcessorIdentifier = NULL; 456 LPWSTR ProcessorVendorIdentifier = NULL; 457 LPWSTR HardwareIdsBuffer = NULL; 458 HANDLE ProcessorHandle = NULL; 459 ULONG Length = 0, Level1Length = 0, Level2Length = 0, Level3Length = 0; 460 SIZE_T HardwareIdsLength = 0; 461 SIZE_T VendorIdentifierLength; 462 ULONG i; 463 PWCHAR Ptr; 464 NTSTATUS Status; 465 466 DPRINT("GetProcessorInformation()\n"); 467 468 /* Open the key for CPU 0 */ 469 Status = AcpiRegOpenKey(NULL, 470 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0", 471 KEY_READ, 472 &ProcessorHandle); 473 if (!NT_SUCCESS(Status)) 474 { 475 DPRINT1("Failed to open CentralProcessor registry key: 0x%lx\n", Status); 476 goto done; 477 } 478 479 /* Query the processor identifier length */ 480 Status = AcpiRegQueryValue(ProcessorHandle, 481 L"Identifier", 482 NULL, 483 NULL, 484 &Length); 485 if (!NT_SUCCESS(Status)) 486 { 487 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status); 488 goto done; 489 } 490 491 /* Remember the length as fallback for level 1-3 length */ 492 Level1Length = Level2Length = Level3Length = Length; 493 494 /* Allocate a buffer large enough to be zero terminated */ 495 Length += sizeof(UNICODE_NULL); 496 ProcessorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA'); 497 if (ProcessorIdentifier == NULL) 498 { 499 DPRINT1("Failed to allocate 0x%lx bytes\n", Length); 500 Status = STATUS_INSUFFICIENT_RESOURCES; 501 goto done; 502 } 503 504 /* Query the processor identifier string */ 505 Status = AcpiRegQueryValue(ProcessorHandle, 506 L"Identifier", 507 NULL, 508 ProcessorIdentifier, 509 &Length); 510 if (!NT_SUCCESS(Status)) 511 { 512 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status); 513 goto done; 514 } 515 516 /* Query the processor name length */ 517 Length = 0; 518 Status = AcpiRegQueryValue(ProcessorHandle, 519 L"ProcessorNameString", 520 NULL, 521 NULL, 522 &Length); 523 if (NT_SUCCESS(Status)) 524 { 525 /* Allocate a buffer large enough to be zero terminated */ 526 Length += sizeof(UNICODE_NULL); 527 ProcessorNameString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA'); 528 if (ProcessorNameString == NULL) 529 { 530 DPRINT1("Failed to allocate 0x%lx bytes\n", Length); 531 Status = STATUS_INSUFFICIENT_RESOURCES; 532 goto done; 533 } 534 535 /* Query the processor name string */ 536 Status = AcpiRegQueryValue(ProcessorHandle, 537 L"ProcessorNameString", 538 NULL, 539 ProcessorNameString, 540 &Length); 541 if (!NT_SUCCESS(Status)) 542 { 543 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status); 544 goto done; 545 } 546 } 547 548 /* Query the vendor identifier length */ 549 Length = 0; 550 Status = AcpiRegQueryValue(ProcessorHandle, 551 L"VendorIdentifier", 552 NULL, 553 NULL, 554 &Length); 555 if (!NT_SUCCESS(Status) || (Length == 0)) 556 { 557 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status); 558 goto done; 559 } 560 561 /* Allocate a buffer large enough to be zero terminated */ 562 Length += sizeof(UNICODE_NULL); 563 ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA'); 564 if (ProcessorVendorIdentifier == NULL) 565 { 566 DPRINT1("Failed to allocate 0x%lx bytes\n", Length); 567 Status = STATUS_INSUFFICIENT_RESOURCES; 568 goto done; 569 } 570 571 /* Query the vendor identifier string */ 572 Status = AcpiRegQueryValue(ProcessorHandle, 573 L"VendorIdentifier", 574 NULL, 575 ProcessorVendorIdentifier, 576 &Length); 577 if (!NT_SUCCESS(Status)) 578 { 579 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status); 580 goto done; 581 } 582 583 /* Change spaces to underscores */ 584 for (i = 0; i < wcslen(ProcessorIdentifier); i++) 585 { 586 if (ProcessorIdentifier[i] == L' ') 587 ProcessorIdentifier[i] = L'_'; 588 } 589 590 Ptr = wcsstr(ProcessorIdentifier, L"Stepping"); 591 if (Ptr != NULL) 592 { 593 Ptr--; 594 Level1Length = (ULONG)(Ptr - ProcessorIdentifier); 595 } 596 597 Ptr = wcsstr(ProcessorIdentifier, L"Model"); 598 if (Ptr != NULL) 599 { 600 Ptr--; 601 Level2Length = (ULONG)(Ptr - ProcessorIdentifier); 602 } 603 604 Ptr = wcsstr(ProcessorIdentifier, L"Family"); 605 if (Ptr != NULL) 606 { 607 Ptr--; 608 Level3Length = (ULONG)(Ptr - ProcessorIdentifier); 609 } 610 611 VendorIdentifierLength = (USHORT)wcslen(ProcessorVendorIdentifier); 612 613 /* Calculate the size of the full REG_MULTI_SZ data (see swprintf below) */ 614 HardwareIdsLength = (5 + VendorIdentifierLength + 3 + Level1Length + 1 + 615 1 + VendorIdentifierLength + 3 + Level1Length + 1 + 616 5 + VendorIdentifierLength + 3 + Level2Length + 1 + 617 1 + VendorIdentifierLength + 3 + Level2Length + 1 + 618 5 + VendorIdentifierLength + 3 + Level3Length + 1 + 619 1 + VendorIdentifierLength + 3 + Level3Length + 1 + 620 1) * sizeof(WCHAR); 621 622 /* Allocate a buffer to the data */ 623 HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength, 'IpcA'); 624 if (HardwareIdsBuffer == NULL) 625 { 626 Status = STATUS_INSUFFICIENT_RESOURCES; 627 goto done; 628 } 629 630 Length = 0; 631 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier); 632 HardwareIdsBuffer[Length++] = UNICODE_NULL; 633 634 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier); 635 HardwareIdsBuffer[Length++] = UNICODE_NULL; 636 637 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier); 638 HardwareIdsBuffer[Length++] = UNICODE_NULL; 639 640 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier); 641 HardwareIdsBuffer[Length++] = UNICODE_NULL; 642 643 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier); 644 HardwareIdsBuffer[Length++] = UNICODE_NULL; 645 646 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier); 647 HardwareIdsBuffer[Length++] = UNICODE_NULL; 648 HardwareIdsBuffer[Length++] = UNICODE_NULL; 649 650 /* Make sure we counted correctly */ 651 NT_ASSERT(Length * sizeof(WCHAR) == HardwareIdsLength); 652 653 ProcessorHardwareIds.Length = (SHORT)HardwareIdsLength; 654 ProcessorHardwareIds.MaximumLength = ProcessorHardwareIds.Length; 655 ProcessorHardwareIds.Buffer = HardwareIdsBuffer; 656 657 Length = (5 + VendorIdentifierLength + 3 + Level1Length + 1) * sizeof(WCHAR); 658 ProcessorIdString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA'); 659 if (ProcessorIdString != NULL) 660 { 661 Length = swprintf(ProcessorIdString, L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier); 662 ProcessorIdString[Length++] = UNICODE_NULL; 663 DPRINT("ProcessorIdString: %S\n", ProcessorIdString); 664 } 665 666 done: 667 if (ProcessorHandle != NULL) 668 ZwClose(ProcessorHandle); 669 670 if (ProcessorIdentifier != NULL) 671 ExFreePoolWithTag(ProcessorIdentifier, 'IpcA'); 672 673 if (ProcessorVendorIdentifier != NULL) 674 ExFreePoolWithTag(ProcessorVendorIdentifier, 'IpcA'); 675 676 if (!NT_SUCCESS(Status)) 677 { 678 if (HardwareIdsBuffer != NULL) 679 ExFreePoolWithTag(HardwareIdsBuffer, 'IpcA'); 680 } 681 682 return Status; 683 } 684 685 NTSTATUS 686 NTAPI 687 DriverEntry ( 688 PDRIVER_OBJECT DriverObject, 689 PUNICODE_STRING RegistryPath 690 ) 691 { 692 NTSTATUS Status; 693 DPRINT("Driver Entry \n"); 694 695 Status = GetProcessorInformation(); 696 if (!NT_SUCCESS(Status)) 697 { 698 NT_ASSERT(FALSE); 699 return Status; 700 } 701 702 // 703 // Set entry points into the driver 704 // 705 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl; 706 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP; 707 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power; 708 DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose; 709 DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose; 710 711 DriverObject->DriverExtension->AddDevice = Bus_AddDevice; 712 713 return STATUS_SUCCESS; 714 } 715