b58c097eed228a39b87d68c2210b7a7cc178fd9e
[reactos.git] / drivers / bus / acpi / main.c
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 default:
316 DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
317 break;
318 }
319 }
320 else
321 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
322
323 if (status != STATUS_PENDING)
324 {
325 Irp->IoStatus.Status = status;
326 IoCompleteRequest(Irp, IO_NO_INCREMENT);
327 }
328 else
329 IoMarkIrpPending(Irp);
330
331 return status;
332 }
333
334 static
335 NTSTATUS
336 AcpiRegOpenKey(IN HANDLE ParentKeyHandle,
337 IN LPCWSTR KeyName,
338 IN ACCESS_MASK DesiredAccess,
339 OUT HANDLE KeyHandle)
340 {
341 OBJECT_ATTRIBUTES ObjectAttributes;
342 UNICODE_STRING Name;
343
344 RtlInitUnicodeString(&Name, KeyName);
345
346 InitializeObjectAttributes(&ObjectAttributes,
347 &Name,
348 OBJ_CASE_INSENSITIVE,
349 ParentKeyHandle,
350 NULL);
351
352 return ZwOpenKey(KeyHandle,
353 DesiredAccess,
354 &ObjectAttributes);
355 }
356
357 static
358 NTSTATUS
359 AcpiRegQueryValue(IN HANDLE KeyHandle,
360 IN LPWSTR ValueName,
361 OUT PULONG Type OPTIONAL,
362 OUT PVOID Data OPTIONAL,
363 IN OUT PULONG DataLength OPTIONAL)
364 {
365 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
366 UNICODE_STRING Name;
367 ULONG BufferLength = 0;
368 NTSTATUS Status;
369
370 RtlInitUnicodeString(&Name, ValueName);
371
372 if (DataLength != NULL)
373 BufferLength = *DataLength;
374
375 /* Check if the caller provided a valid buffer */
376 if ((Data != NULL) && (BufferLength != 0))
377 {
378 BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
379
380 /* Allocate memory for the value */
381 ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferLength, 'MpcA');
382 if (ValueInfo == NULL)
383 return STATUS_NO_MEMORY;
384 }
385 else
386 {
387 /* Caller didn't provide a valid buffer, assume he wants the size only */
388 ValueInfo = NULL;
389 BufferLength = 0;
390 }
391
392 /* Query the value */
393 Status = ZwQueryValueKey(KeyHandle,
394 &Name,
395 KeyValuePartialInformation,
396 ValueInfo,
397 BufferLength,
398 &BufferLength);
399
400 if (DataLength != NULL)
401 *DataLength = BufferLength;
402
403 /* Check if we have the size only */
404 if (ValueInfo == NULL)
405 {
406 /* Check for unexpected status */
407 if ((Status != STATUS_BUFFER_OVERFLOW) &&
408 (Status != STATUS_BUFFER_TOO_SMALL))
409 {
410 return Status;
411 }
412
413 /* All is well */
414 Status = STATUS_SUCCESS;
415 }
416 /* Otherwise the caller wanted data back, check if we got it */
417 else if (NT_SUCCESS(Status))
418 {
419 if (Type != NULL)
420 *Type = ValueInfo->Type;
421
422 /* Copy it */
423 RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
424
425 /* if the type is REG_SZ and data is not 0-terminated
426 * and there is enough space in the buffer NT appends a \0 */
427 if (((ValueInfo->Type == REG_SZ) ||
428 (ValueInfo->Type == REG_EXPAND_SZ) ||
429 (ValueInfo->Type == REG_MULTI_SZ)) &&
430 (ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)))
431 {
432 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
433 if ((ptr > (WCHAR *)Data) && ptr[-1])
434 *ptr = 0;
435 }
436 }
437
438 /* Free the memory and return status */
439 if (ValueInfo != NULL)
440 {
441 ExFreePoolWithTag(ValueInfo, 'MpcA');
442 }
443
444 return Status;
445 }
446
447 static
448 NTSTATUS
449 GetProcessorInformation(VOID)
450 {
451 LPWSTR ProcessorIdentifier = NULL;
452 LPWSTR ProcessorVendorIdentifier = NULL;
453 LPWSTR HardwareIdsBuffer = NULL;
454 HANDLE ProcessorHandle = NULL;
455 ULONG Length = 0, Level1Length = 0, Level2Length = 0, Level3Length = 0;
456 SIZE_T HardwareIdsLength = 0;
457 SIZE_T VendorIdentifierLength;
458 ULONG i;
459 PWCHAR Ptr;
460 NTSTATUS Status;
461
462 DPRINT("GetProcessorInformation()\n");
463
464 /* Open the key for CPU 0 */
465 Status = AcpiRegOpenKey(NULL,
466 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
467 KEY_READ,
468 &ProcessorHandle);
469 if (!NT_SUCCESS(Status))
470 {
471 DPRINT1("Failed to open CentralProcessor registry key: 0x%lx\n", Status);
472 goto done;
473 }
474
475 /* Query the processor identifier length */
476 Status = AcpiRegQueryValue(ProcessorHandle,
477 L"Identifier",
478 NULL,
479 NULL,
480 &Length);
481 if (!NT_SUCCESS(Status))
482 {
483 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
484 goto done;
485 }
486
487 /* Remember the length as fallback for level 1-3 length */
488 Level1Length = Level2Length = Level3Length = Length;
489
490 /* Allocate a buffer large enough to be zero terminated */
491 Length += sizeof(UNICODE_NULL);
492 ProcessorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
493 if (ProcessorIdentifier == NULL)
494 {
495 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
496 Status = STATUS_INSUFFICIENT_RESOURCES;
497 goto done;
498 }
499
500 /* Query the processor identifier string */
501 Status = AcpiRegQueryValue(ProcessorHandle,
502 L"Identifier",
503 NULL,
504 ProcessorIdentifier,
505 &Length);
506 if (!NT_SUCCESS(Status))
507 {
508 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
509 goto done;
510 }
511
512 /* Query the processor name length */
513 Length = 0;
514 Status = AcpiRegQueryValue(ProcessorHandle,
515 L"ProcessorNameString",
516 NULL,
517 NULL,
518 &Length);
519 if (!NT_SUCCESS(Status))
520 {
521 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
522 goto done;
523 }
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 /* Query the vendor identifier length */
548 Length = 0;
549 Status = AcpiRegQueryValue(ProcessorHandle,
550 L"VendorIdentifier",
551 NULL,
552 NULL,
553 &Length);
554 if (!NT_SUCCESS(Status) || (Length == 0))
555 {
556 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
557 goto done;
558 }
559
560 /* Allocate a buffer large enough to be zero terminated */
561 Length += sizeof(UNICODE_NULL);
562 ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
563 if (ProcessorVendorIdentifier == NULL)
564 {
565 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
566 Status = STATUS_INSUFFICIENT_RESOURCES;
567 goto done;
568 }
569
570 /* Query the vendor identifier string */
571 Status = AcpiRegQueryValue(ProcessorHandle,
572 L"VendorIdentifier",
573 NULL,
574 ProcessorVendorIdentifier,
575 &Length);
576 if (!NT_SUCCESS(Status))
577 {
578 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
579 goto done;
580 }
581
582 /* Change spaces to underscores */
583 for (i = 0; i < wcslen(ProcessorIdentifier); i++)
584 {
585 if (ProcessorIdentifier[i] == L' ')
586 ProcessorIdentifier[i] = L'_';
587 }
588
589 Ptr = wcsstr(ProcessorIdentifier, L"Stepping");
590 if (Ptr != NULL)
591 {
592 Ptr--;
593 Level1Length = (ULONG)(Ptr - ProcessorIdentifier);
594 }
595
596 Ptr = wcsstr(ProcessorIdentifier, L"Model");
597 if (Ptr != NULL)
598 {
599 Ptr--;
600 Level2Length = (ULONG)(Ptr - ProcessorIdentifier);
601 }
602
603 Ptr = wcsstr(ProcessorIdentifier, L"Family");
604 if (Ptr != NULL)
605 {
606 Ptr--;
607 Level3Length = (ULONG)(Ptr - ProcessorIdentifier);
608 }
609
610 VendorIdentifierLength = (USHORT)wcslen(ProcessorVendorIdentifier);
611
612 /* Calculate the size of the full REG_MULTI_SZ data (see swprintf below) */
613 HardwareIdsLength = (5 + VendorIdentifierLength + 3 + Level1Length + 1 +
614 1 + VendorIdentifierLength + 3 + Level1Length + 1 +
615 5 + VendorIdentifierLength + 3 + Level2Length + 1 +
616 1 + VendorIdentifierLength + 3 + Level2Length + 1 +
617 5 + VendorIdentifierLength + 3 + Level3Length + 1 +
618 1 + VendorIdentifierLength + 3 + Level3Length + 1 +
619 1) * sizeof(WCHAR);
620
621 /* Allocate a buffer to the data */
622 HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength, 'IpcA');
623 if (HardwareIdsBuffer == NULL)
624 {
625 Status = STATUS_INSUFFICIENT_RESOURCES;
626 goto done;
627 }
628
629 Length = 0;
630 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
631 HardwareIdsBuffer[Length++] = UNICODE_NULL;
632
633 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
634 HardwareIdsBuffer[Length++] = UNICODE_NULL;
635
636 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
637 HardwareIdsBuffer[Length++] = UNICODE_NULL;
638
639 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
640 HardwareIdsBuffer[Length++] = UNICODE_NULL;
641
642 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
643 HardwareIdsBuffer[Length++] = UNICODE_NULL;
644
645 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
646 HardwareIdsBuffer[Length++] = UNICODE_NULL;
647 HardwareIdsBuffer[Length++] = UNICODE_NULL;
648
649 /* Make sure we counted correctly */
650 NT_ASSERT(Length * sizeof(WCHAR) == HardwareIdsLength);
651
652 ProcessorHardwareIds.Length = (SHORT)HardwareIdsLength;
653 ProcessorHardwareIds.MaximumLength = ProcessorHardwareIds.Length;
654 ProcessorHardwareIds.Buffer = HardwareIdsBuffer;
655
656 Length = (5 + VendorIdentifierLength + 3 + Level1Length + 1) * sizeof(WCHAR);
657 ProcessorIdString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
658 if (ProcessorIdString != NULL)
659 {
660 Length = swprintf(ProcessorIdString, L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
661 ProcessorIdString[Length++] = UNICODE_NULL;
662 DPRINT("ProcessorIdString: %S\n", ProcessorIdString);
663 }
664
665 done:
666 if (ProcessorHandle != NULL)
667 ZwClose(ProcessorHandle);
668
669 if (ProcessorIdentifier != NULL)
670 ExFreePoolWithTag(ProcessorIdentifier, 'IpcA');
671
672 if (ProcessorVendorIdentifier != NULL)
673 ExFreePoolWithTag(ProcessorVendorIdentifier, 'IpcA');
674
675 if (!NT_SUCCESS(Status))
676 {
677 if (HardwareIdsBuffer != NULL)
678 ExFreePoolWithTag(HardwareIdsBuffer, 'IpcA');
679 }
680
681 return Status;
682 }
683
684 NTSTATUS
685 NTAPI
686 DriverEntry (
687 PDRIVER_OBJECT DriverObject,
688 PUNICODE_STRING RegistryPath
689 )
690 {
691 NTSTATUS Status;
692 DPRINT("Driver Entry \n");
693
694 Status = GetProcessorInformation();
695 if (!NT_SUCCESS(Status))
696 {
697 NT_ASSERT(FALSE);
698 return Status;
699 }
700
701 //
702 // Set entry points into the driver
703 //
704 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
705 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
706 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
707 DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
708 DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
709
710 DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
711
712 return STATUS_SUCCESS;
713 }