[KERNEL32] Initial implementation for BaseCheckRunApp, calling into apphelp to check...
[reactos.git] / reactos / 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 PWCHAR deviceName = NULL;
41 #ifndef NDEBUG
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 if (deviceName){
163 ExFreePoolWithTag(deviceName, 'MpcA');
164 }
165 if (!NT_SUCCESS(status) && deviceObject){
166 if (deviceData && deviceData->NextLowerDriver){
167 IoDetachDevice (deviceData->NextLowerDriver);
168 }
169 IoDeleteDevice (deviceObject);
170 }
171 return status;
172
173 }
174
175 NTSTATUS
176 NTAPI
177 ACPIDispatchCreateClose(
178 IN PDEVICE_OBJECT DeviceObject,
179 IN PIRP Irp)
180 {
181 Irp->IoStatus.Status = STATUS_SUCCESS;
182 Irp->IoStatus.Information = 0;
183
184 IoCompleteRequest(Irp, IO_NO_INCREMENT);
185
186 return STATUS_SUCCESS;
187 }
188
189 VOID
190 NTAPI
191 ButtonWaitThread(PVOID Context)
192 {
193 PIRP Irp = Context;
194 int result;
195 struct acpi_bus_event event;
196 ULONG ButtonEvent;
197
198 while (ACPI_SUCCESS(result = acpi_bus_receive_event(&event)) &&
199 event.type != ACPI_BUTTON_NOTIFY_STATUS);
200
201 if (!ACPI_SUCCESS(result))
202 {
203 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
204 }
205 else
206 {
207 if (strstr(event.bus_id, "PWRF"))
208 ButtonEvent = SYS_BUTTON_POWER;
209 else if (strstr(event.bus_id, "SLPF"))
210 ButtonEvent = SYS_BUTTON_SLEEP;
211 else
212 ButtonEvent = 0;
213
214 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &ButtonEvent, sizeof(ButtonEvent));
215 Irp->IoStatus.Status = STATUS_SUCCESS;
216 Irp->IoStatus.Information = sizeof(ULONG);
217 }
218
219 IoCompleteRequest(Irp, IO_NO_INCREMENT);
220 }
221
222
223 NTSTATUS
224 NTAPI
225 ACPIDispatchDeviceControl(
226 IN PDEVICE_OBJECT DeviceObject,
227 IN PIRP Irp)
228 {
229 PIO_STACK_LOCATION irpStack;
230 NTSTATUS status = STATUS_NOT_SUPPORTED;
231 PCOMMON_DEVICE_DATA commonData;
232 ULONG Caps = 0;
233 HANDLE ThreadHandle;
234
235 PAGED_CODE ();
236
237 irpStack = IoGetCurrentIrpStackLocation (Irp);
238 ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction);
239
240 commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
241
242 Irp->IoStatus.Information = 0;
243
244 if (!commonData->IsFDO)
245 {
246 switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
247 {
248 case IOCTL_ACPI_EVAL_METHOD:
249 status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData,
250 Irp);
251 break;
252
253 case IOCTL_GET_SYS_BUTTON_CAPS:
254 if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
255 {
256 status = STATUS_BUFFER_TOO_SMALL;
257 break;
258 }
259
260 if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
261 {
262 DPRINT1("Lid button reported to power manager\n");
263 Caps |= SYS_BUTTON_LID;
264 }
265 else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
266 {
267 /* We have to return both at the same time because since we
268 * have a NULL handle we are the fixed feature DO and we will
269 * only be called once (not once per device)
270 */
271 if (power_button)
272 {
273 DPRINT("Fixed power button reported to power manager\n");
274 Caps |= SYS_BUTTON_POWER;
275 }
276 if (sleep_button)
277 {
278 DPRINT("Fixed sleep button reported to power manager\n");
279 Caps |= SYS_BUTTON_SLEEP;
280 }
281 }
282 else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
283 {
284 DPRINT("Control method power button reported to power manager\n");
285 Caps |= SYS_BUTTON_POWER;
286 }
287 else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
288 {
289 DPRINT("Control method sleep reported to power manager\n");
290 Caps |= SYS_BUTTON_SLEEP;
291 }
292 else
293 {
294 DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
295 status = STATUS_INVALID_PARAMETER;
296 }
297
298 if (Caps != 0)
299 {
300 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps));
301 Irp->IoStatus.Information = sizeof(Caps);
302 status = STATUS_SUCCESS;
303 }
304 break;
305
306 case IOCTL_GET_SYS_BUTTON_EVENT:
307 PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, ButtonWaitThread, Irp);
308 ZwClose(ThreadHandle);
309
310 status = STATUS_PENDING;
311 break;
312
313 default:
314 DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
315 break;
316 }
317 }
318 else
319 DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
320
321 if (status != STATUS_PENDING)
322 {
323 Irp->IoStatus.Status = status;
324 IoCompleteRequest(Irp, IO_NO_INCREMENT);
325 }
326 else
327 IoMarkIrpPending(Irp);
328
329 return status;
330 }
331
332 static
333 NTSTATUS
334 AcpiRegOpenKey(IN HANDLE ParentKeyHandle,
335 IN LPCWSTR KeyName,
336 IN ACCESS_MASK DesiredAccess,
337 OUT HANDLE KeyHandle)
338 {
339 OBJECT_ATTRIBUTES ObjectAttributes;
340 UNICODE_STRING Name;
341
342 RtlInitUnicodeString(&Name, KeyName);
343
344 InitializeObjectAttributes(&ObjectAttributes,
345 &Name,
346 OBJ_CASE_INSENSITIVE,
347 ParentKeyHandle,
348 NULL);
349
350 return ZwOpenKey(KeyHandle,
351 DesiredAccess,
352 &ObjectAttributes);
353 }
354
355 static
356 NTSTATUS
357 AcpiRegQueryValue(IN HANDLE KeyHandle,
358 IN LPWSTR ValueName,
359 OUT PULONG Type OPTIONAL,
360 OUT PVOID Data OPTIONAL,
361 IN OUT PULONG DataLength OPTIONAL)
362 {
363 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
364 UNICODE_STRING Name;
365 ULONG BufferLength = 0;
366 NTSTATUS Status;
367
368 RtlInitUnicodeString(&Name, ValueName);
369
370 if (DataLength != NULL)
371 BufferLength = *DataLength;
372
373 /* Check if the caller provided a valid buffer */
374 if ((Data != NULL) && (BufferLength != 0))
375 {
376 BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
377
378 /* Allocate memory for the value */
379 ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferLength, 'MpcA');
380 if (ValueInfo == NULL)
381 return STATUS_NO_MEMORY;
382 }
383 else
384 {
385 /* Caller didn't provide a valid buffer, assume he wants the size only */
386 ValueInfo = NULL;
387 BufferLength = 0;
388 }
389
390 /* Query the value */
391 Status = ZwQueryValueKey(KeyHandle,
392 &Name,
393 KeyValuePartialInformation,
394 ValueInfo,
395 BufferLength,
396 &BufferLength);
397
398 if (DataLength != NULL)
399 *DataLength = BufferLength;
400
401 /* Check if we have the size only */
402 if (ValueInfo == NULL)
403 {
404 /* Check for unexpected status */
405 if ((Status != STATUS_BUFFER_OVERFLOW) &&
406 (Status != STATUS_BUFFER_TOO_SMALL))
407 {
408 return Status;
409 }
410
411 /* All is well */
412 Status = STATUS_SUCCESS;
413 }
414 /* Otherwise the caller wanted data back, check if we got it */
415 else if (NT_SUCCESS(Status))
416 {
417 if (Type != NULL)
418 *Type = ValueInfo->Type;
419
420 /* Copy it */
421 RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
422
423 /* if the type is REG_SZ and data is not 0-terminated
424 * and there is enough space in the buffer NT appends a \0 */
425 if (((ValueInfo->Type == REG_SZ) ||
426 (ValueInfo->Type == REG_EXPAND_SZ) ||
427 (ValueInfo->Type == REG_MULTI_SZ)) &&
428 (ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)))
429 {
430 WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
431 if ((ptr > (WCHAR *)Data) && ptr[-1])
432 *ptr = 0;
433 }
434 }
435
436 /* Free the memory and return status */
437 if (ValueInfo != NULL)
438 {
439 ExFreePoolWithTag(ValueInfo, 'MpcA');
440 }
441
442 return Status;
443 }
444
445 static
446 NTSTATUS
447 GetProcessorInformation(VOID)
448 {
449 LPWSTR ProcessorIdentifier = NULL;
450 LPWSTR ProcessorVendorIdentifier = NULL;
451 LPWSTR HardwareIdsBuffer = NULL;
452 HANDLE ProcessorHandle = NULL;
453 ULONG Length = 0, Level1Length = 0, Level2Length = 0, Level3Length = 0;
454 SIZE_T HardwareIdsLength = 0;
455 SIZE_T VendorIdentifierLength;
456 ULONG i;
457 PWCHAR Ptr;
458 NTSTATUS Status;
459
460 DPRINT("GetProcessorInformation()\n");
461
462 /* Open the key for CPU 0 */
463 Status = AcpiRegOpenKey(NULL,
464 L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
465 KEY_READ,
466 &ProcessorHandle);
467 if (!NT_SUCCESS(Status))
468 {
469 DPRINT1("Failed to open CentralProcessor registry key: 0x%lx\n", Status);
470 goto done;
471 }
472
473 /* Query the processor identifier length */
474 Status = AcpiRegQueryValue(ProcessorHandle,
475 L"Identifier",
476 NULL,
477 NULL,
478 &Length);
479 if (!NT_SUCCESS(Status))
480 {
481 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
482 goto done;
483 }
484
485 /* Remember the length as fallback for level 1-3 length */
486 Level1Length = Level2Length = Level3Length = Length;
487
488 /* Allocate a buffer large enough to be zero terminated */
489 Length += sizeof(UNICODE_NULL);
490 ProcessorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
491 if (ProcessorIdentifier == NULL)
492 {
493 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
494 Status = STATUS_INSUFFICIENT_RESOURCES;
495 goto done;
496 }
497
498 /* Query the processor identifier string */
499 Status = AcpiRegQueryValue(ProcessorHandle,
500 L"Identifier",
501 NULL,
502 ProcessorIdentifier,
503 &Length);
504 if (!NT_SUCCESS(Status))
505 {
506 DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
507 goto done;
508 }
509
510 /* Query the processor name length */
511 Length = 0;
512 Status = AcpiRegQueryValue(ProcessorHandle,
513 L"ProcessorNameString",
514 NULL,
515 NULL,
516 &Length);
517 if (!NT_SUCCESS(Status))
518 {
519 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
520 goto done;
521 }
522
523 /* Allocate a buffer large enough to be zero terminated */
524 Length += sizeof(UNICODE_NULL);
525 ProcessorNameString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
526 if (ProcessorNameString == NULL)
527 {
528 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
529 Status = STATUS_INSUFFICIENT_RESOURCES;
530 goto done;
531 }
532
533 /* Query the processor name string */
534 Status = AcpiRegQueryValue(ProcessorHandle,
535 L"ProcessorNameString",
536 NULL,
537 ProcessorNameString,
538 &Length);
539 if (!NT_SUCCESS(Status))
540 {
541 DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
542 goto done;
543 }
544
545 /* Query the vendor identifier length */
546 Length = 0;
547 Status = AcpiRegQueryValue(ProcessorHandle,
548 L"VendorIdentifier",
549 NULL,
550 NULL,
551 &Length);
552 if (!NT_SUCCESS(Status) || (Length == 0))
553 {
554 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
555 goto done;
556 }
557
558 /* Allocate a buffer large enough to be zero terminated */
559 Length += sizeof(UNICODE_NULL);
560 ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
561 if (ProcessorVendorIdentifier == NULL)
562 {
563 DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
564 Status = STATUS_INSUFFICIENT_RESOURCES;
565 goto done;
566 }
567
568 /* Query the vendor identifier string */
569 Status = AcpiRegQueryValue(ProcessorHandle,
570 L"VendorIdentifier",
571 NULL,
572 ProcessorVendorIdentifier,
573 &Length);
574 if (!NT_SUCCESS(Status))
575 {
576 DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
577 goto done;
578 }
579
580 /* Change spaces to underscores */
581 for (i = 0; i < wcslen(ProcessorIdentifier); i++)
582 {
583 if (ProcessorIdentifier[i] == L' ')
584 ProcessorIdentifier[i] = L'_';
585 }
586
587 Ptr = wcsstr(ProcessorIdentifier, L"Stepping");
588 if (Ptr != NULL)
589 {
590 Ptr--;
591 Level1Length = (ULONG)(Ptr - ProcessorIdentifier);
592 }
593
594 Ptr = wcsstr(ProcessorIdentifier, L"Model");
595 if (Ptr != NULL)
596 {
597 Ptr--;
598 Level2Length = (ULONG)(Ptr - ProcessorIdentifier);
599 }
600
601 Ptr = wcsstr(ProcessorIdentifier, L"Family");
602 if (Ptr != NULL)
603 {
604 Ptr--;
605 Level3Length = (ULONG)(Ptr - ProcessorIdentifier);
606 }
607
608 VendorIdentifierLength = (USHORT)wcslen(ProcessorVendorIdentifier);
609
610 /* Calculate the size of the full REG_MULTI_SZ data (see swprintf below) */
611 HardwareIdsLength = (5 + VendorIdentifierLength + 3 + Level1Length + 1 +
612 1 + VendorIdentifierLength + 3 + Level1Length + 1 +
613 5 + VendorIdentifierLength + 3 + Level2Length + 1 +
614 1 + VendorIdentifierLength + 3 + Level2Length + 1 +
615 5 + VendorIdentifierLength + 3 + Level3Length + 1 +
616 1 + VendorIdentifierLength + 3 + Level3Length + 1 +
617 1) * sizeof(WCHAR);
618
619 /* Allocate a buffer to the data */
620 HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength, 'IpcA');
621 if (HardwareIdsBuffer == NULL)
622 {
623 Status = STATUS_INSUFFICIENT_RESOURCES;
624 goto done;
625 }
626
627 Length = 0;
628 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
629 HardwareIdsBuffer[Length++] = UNICODE_NULL;
630
631 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
632 HardwareIdsBuffer[Length++] = UNICODE_NULL;
633
634 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
635 HardwareIdsBuffer[Length++] = UNICODE_NULL;
636
637 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
638 HardwareIdsBuffer[Length++] = UNICODE_NULL;
639
640 Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
641 HardwareIdsBuffer[Length++] = UNICODE_NULL;
642
643 Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
644 HardwareIdsBuffer[Length++] = UNICODE_NULL;
645 HardwareIdsBuffer[Length++] = UNICODE_NULL;
646
647 /* Make sure we counted correctly */
648 NT_ASSERT(Length * sizeof(WCHAR) == HardwareIdsLength);
649
650 ProcessorHardwareIds.Length = (SHORT)HardwareIdsLength;
651 ProcessorHardwareIds.MaximumLength = ProcessorHardwareIds.Length;
652 ProcessorHardwareIds.Buffer = HardwareIdsBuffer;
653
654 Length = (5 + VendorIdentifierLength + 3 + Level1Length + 1) * sizeof(WCHAR);
655 ProcessorIdString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
656 if (ProcessorIdString != NULL)
657 {
658 Length = swprintf(ProcessorIdString, L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
659 ProcessorIdString[Length++] = UNICODE_NULL;
660 DPRINT("ProcessorIdString: %S\n", ProcessorIdString);
661 }
662
663 done:
664 if (ProcessorHandle != NULL)
665 ZwClose(ProcessorHandle);
666
667 if (ProcessorIdentifier != NULL)
668 ExFreePoolWithTag(ProcessorIdentifier, 'IpcA');
669
670 if (ProcessorVendorIdentifier != NULL)
671 ExFreePoolWithTag(ProcessorVendorIdentifier, 'IpcA');
672
673 if (!NT_SUCCESS(Status))
674 {
675 if (HardwareIdsBuffer != NULL)
676 ExFreePoolWithTag(HardwareIdsBuffer, 'IpcA');
677 }
678
679 return Status;
680 }
681
682 NTSTATUS
683 NTAPI
684 DriverEntry (
685 PDRIVER_OBJECT DriverObject,
686 PUNICODE_STRING RegistryPath
687 )
688 {
689 NTSTATUS Status;
690 DPRINT("Driver Entry \n");
691
692 Status = GetProcessorInformation();
693 if (!NT_SUCCESS(Status))
694 {
695 NT_ASSERT(FALSE);
696 return Status;
697 }
698
699 //
700 // Set entry points into the driver
701 //
702 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
703 DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
704 DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
705 DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
706 DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
707
708 DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
709
710 return STATUS_SUCCESS;
711 }