[BUS][ACPI] Silence DPRINT1 in the special case of IOCTL_BATTERY_QUERY_TAG (#427)
[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 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,
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 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
526 goto done;
527 }
528
529 /* Allocate a buffer large enough to be zero terminated */
530 Length += sizeof(UNICODE_NULL);
531 ProcessorNameString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
532 if (ProcessorNameString == NULL)
533 {
534 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
535 Status = STATUS_INSUFFICIENT_RESOURCES;
536 goto done;
537 }
538
539 /* Query the processor name string */
540 Status = AcpiRegQueryValue(ProcessorHandle,
541 L"ProcessorNameString",
542 NULL,
543 ProcessorNameString,
544 &Length);
545 if (!NT_SUCCESS(Status))
546 {
547 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
548 goto done;
549 }
550
551 /* Query the vendor identifier length */
552 Length = 0;
553 Status = AcpiRegQueryValue(ProcessorHandle,
554 L"VendorIdentifier",
555 NULL,
556 NULL,
557 &Length);
558 if (!NT_SUCCESS(Status) || (Length == 0))
559 {
560 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
561 goto done;
562 }
563
564 /* Allocate a buffer large enough to be zero terminated */
565 Length += sizeof(UNICODE_NULL);
566 ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
567 if (ProcessorVendorIdentifier == NULL)
568 {
569 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
570 Status = STATUS_INSUFFICIENT_RESOURCES;
571 goto done;
572 }
573
574 /* Query the vendor identifier string */
575 Status = AcpiRegQueryValue(ProcessorHandle,
576 L"VendorIdentifier",
577 NULL,
578 ProcessorVendorIdentifier,
579 &Length);
580 if (!NT_SUCCESS(Status))
581 {
582 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
583 goto done;
584 }
585
586 /* Change spaces to underscores */
587 for (i = 0; i < wcslen(ProcessorIdentifier); i++)
588 {
589 if (ProcessorIdentifier[i] == L' ')
590 ProcessorIdentifier[i] = L'_';
591 }
592
593 Ptr = wcsstr(ProcessorIdentifier, L"Stepping");
594 if (Ptr != NULL)
595 {
596 Ptr--;
597 Level1Length = (ULONG)(Ptr - ProcessorIdentifier);
598 }
599
600 Ptr = wcsstr(ProcessorIdentifier, L"Model");
601 if (Ptr != NULL)
602 {
603 Ptr--;
604 Level2Length = (ULONG)(Ptr - ProcessorIdentifier);
605 }
606
607 Ptr = wcsstr(ProcessorIdentifier, L"Family");
608 if (Ptr != NULL)
609 {
610 Ptr--;
611 Level3Length = (ULONG)(Ptr - ProcessorIdentifier);
612 }
613
614 VendorIdentifierLength = (USHORT)wcslen(ProcessorVendorIdentifier);
615
616 /* Calculate the size of the full REG_MULTI_SZ data (see swprintf below) */
617 HardwareIdsLength = (5 + VendorIdentifierLength + 3 + Level1Length + 1 +
618 1 + VendorIdentifierLength + 3 + Level1Length + 1 +
619 5 + VendorIdentifierLength + 3 + Level2Length + 1 +
620 1 + VendorIdentifierLength + 3 + Level2Length + 1 +
621 5 + VendorIdentifierLength + 3 + Level3Length + 1 +
622 1 + VendorIdentifierLength + 3 + Level3Length + 1 +
623 1) * sizeof(WCHAR);
624
625 /* Allocate a buffer to the data */
626 HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength, 'IpcA');
627 if (HardwareIdsBuffer == NULL)
628 {
629 Status = STATUS_INSUFFICIENT_RESOURCES;
630 goto done;
631 }
632
633 Length = 0;
634 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
635 HardwareIdsBuffer[Length++] = UNICODE_NULL;
636
637 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
638 HardwareIdsBuffer[Length++] = UNICODE_NULL;
639
640 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
641 HardwareIdsBuffer[Length++] = UNICODE_NULL;
642
643 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
644 HardwareIdsBuffer[Length++] = UNICODE_NULL;
645
646 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
647 HardwareIdsBuffer[Length++] = UNICODE_NULL;
648
649 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
650 HardwareIdsBuffer[Length++] = UNICODE_NULL;
651 HardwareIdsBuffer[Length++] = UNICODE_NULL;
652
653 /* Make sure we counted correctly */
654 NT_ASSERT(Length * sizeof(WCHAR) == HardwareIdsLength);
655
656 ProcessorHardwareIds.Length = (SHORT)HardwareIdsLength;
657 ProcessorHardwareIds.MaximumLength = ProcessorHardwareIds.Length;
658 ProcessorHardwareIds.Buffer = HardwareIdsBuffer;
659
660 Length = (5 + VendorIdentifierLength + 3 + Level1Length + 1) * sizeof(WCHAR);
661 ProcessorIdString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
662 if (ProcessorIdString != NULL)
663 {
664 Length = swprintf(ProcessorIdString, L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
665 ProcessorIdString[Length++] = UNICODE_NULL;
666 DPRINT("ProcessorIdString: %S\n", ProcessorIdString);
667 }
668
669 done:
670 if (ProcessorHandle != NULL)
671 ZwClose(ProcessorHandle);
672
673 if (ProcessorIdentifier != NULL)
674 ExFreePoolWithTag(ProcessorIdentifier, 'IpcA');
675
676 if (ProcessorVendorIdentifier != NULL)
677 ExFreePoolWithTag(ProcessorVendorIdentifier, 'IpcA');
678
679 if (!NT_SUCCESS(Status))
680 {
681 if (HardwareIdsBuffer != NULL)
682 ExFreePoolWithTag(HardwareIdsBuffer, 'IpcA');
683 }
684
685 return Status;
686 }
687
688 NTSTATUS
689 NTAPI
690 DriverEntry (
691 PDRIVER_OBJECT DriverObject,
692 PUNICODE_STRING RegistryPath
693 )
694 {
695 NTSTATUS Status;
696 DPRINT("Driver Entry \n");
697
698 Status = GetProcessorInformation();
699 if (!NT_SUCCESS(Status))
700 {
701 NT_ASSERT(FALSE);
702 return Status;
703 }
704
705 //
706 // Set entry points into the driver
707 //
708 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
709 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
710 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
711 DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
712 DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
713
714 DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
715
716 return STATUS_SUCCESS;
717 }