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