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
Bus_AddDevice(PDRIVER_OBJECT DriverObject,PDEVICE_OBJECT PhysicalDeviceObject)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
ACPIDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)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
ButtonWaitThread(PVOID Context)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
ACPIDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)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
AcpiRegOpenKey(IN HANDLE ParentKeyHandle,IN LPCWSTR KeyName,IN ACCESS_MASK DesiredAccess,OUT HANDLE KeyHandle)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
AcpiRegQueryValue(IN HANDLE KeyHandle,IN LPWSTR ValueName,OUT PULONG Type OPTIONAL,OUT PVOID Data OPTIONAL,IN OUT PULONG DataLength OPTIONAL)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
GetProcessorInformation(VOID)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
DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)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