[ACPI]
[reactos.git] / reactos / drivers / bus / acpi / main.c
index cafba70..b58c097 100644 (file)
@@ -1,12 +1,5 @@
-#include <ntddk.h>
+#include "precomp.h"
 
-#include <acpi.h>
-#include <acpisys.h>
-
-#include <acpi_bus.h>
-#include <acpi_drivers.h>
-
-#include <acpiioct.h>
 #include <poclass.h>
 
 #define NDEBUG
@@ -29,6 +22,7 @@ extern struct acpi_device *sleep_button;
 extern struct acpi_device *power_button;
 
 UNICODE_STRING ProcessorHardwareIds = {0, 0, NULL};
+LPWSTR ProcessorIdString = NULL;
 LPWSTR ProcessorNameString = NULL;
 
 
@@ -43,8 +37,8 @@ Bus_AddDevice(
     NTSTATUS            status;
     PDEVICE_OBJECT      deviceObject = NULL;
     PFDO_DEVICE_DATA    deviceData = NULL;
-    PWCHAR              deviceName = NULL;
 #ifndef NDEBUG
+    PWCHAR              deviceName = NULL;
     ULONG               nameLength;
 #endif
 
@@ -130,8 +124,7 @@ Bus_AddDevice(
         goto End;
     }
 
-    deviceName = ExAllocatePoolWithTag (NonPagedPool,
-                            nameLength, 'IPCA');
+    deviceName = ExAllocatePoolWithTag(NonPagedPool, nameLength, 'MpcA');
 
     if (NULL == deviceName) {
         DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
@@ -166,9 +159,11 @@ Bus_AddDevice(
     deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 
 End:
+#ifndef NDEBUG
     if (deviceName){
-        ExFreePoolWithTag(deviceName, 'IPCA');
+        ExFreePoolWithTag(deviceName, 'MpcA');
     }
+#endif
     if (!NT_SUCCESS(status) && deviceObject){
         if (deviceData && deviceData->NextLowerDriver){
             IoDetachDevice (deviceData->NextLowerDriver);
@@ -225,7 +220,7 @@ ButtonWaitThread(PVOID Context)
 
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 }
-    
+
 
 NTSTATUS
 NTAPI
@@ -277,23 +272,23 @@ ACPIDispatchDeviceControl(
                    */
                   if (power_button)
                   {
-                      DPRINT1("Fixed power button reported to power manager\n");
+                      DPRINT("Fixed power button reported to power manager\n");
                       Caps |= SYS_BUTTON_POWER;
                   }
                   if (sleep_button)
                   {
-                      DPRINT1("Fixed sleep button reported to power manager\n");
+                      DPRINT("Fixed sleep button reported to power manager\n");
                       Caps |= SYS_BUTTON_SLEEP;
                   }
               }
               else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
               {
-                  DPRINT1("Control method power button reported to power manager\n");
+                  DPRINT("Control method power button reported to power manager\n");
                   Caps |= SYS_BUTTON_POWER;
               }
               else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
               {
-                  DPRINT1("Control method sleep reported to power manager\n");
+                  DPRINT("Control method sleep reported to power manager\n");
                   Caps |= SYS_BUTTON_SLEEP;
               }
               else
@@ -372,18 +367,27 @@ AcpiRegQueryValue(IN HANDLE KeyHandle,
     ULONG BufferLength = 0;
     NTSTATUS Status;
 
-    RtlInitUnicodeString(&Name,
-                         ValueName);
+    RtlInitUnicodeString(&Name, ValueName);
 
     if (DataLength != NULL)
         BufferLength = *DataLength;
 
-    BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+    /* Check if the caller provided a valid buffer */
+    if ((Data != NULL) && (BufferLength != 0))
+    {
+        BufferLength += FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
 
-    /* Allocate memory for the value */
-    ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferLength, 'IPCA');
-    if (ValueInfo == NULL)
-        return STATUS_NO_MEMORY;
+        /* Allocate memory for the value */
+        ValueInfo = ExAllocatePoolWithTag(PagedPool, BufferLength, 'MpcA');
+        if (ValueInfo == NULL)
+            return STATUS_NO_MEMORY;
+    }
+    else
+    {
+        /* Caller didn't provide a valid buffer, assume he wants the size only */
+        ValueInfo = NULL;
+        BufferLength = 0;
+    }
 
     /* Query the value */
     Status = ZwQueryValueKey(KeyHandle,
@@ -392,26 +396,37 @@ AcpiRegQueryValue(IN HANDLE KeyHandle,
                              ValueInfo,
                              BufferLength,
                              &BufferLength);
-    if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
+
+    if (DataLength != NULL)
+        *DataLength = BufferLength;
+
+    /* Check if we have the size only */
+    if (ValueInfo == NULL)
     {
-        if (Type != NULL)
-            *Type = ValueInfo->Type;
+        /* Check for unexpected status */
+        if ((Status != STATUS_BUFFER_OVERFLOW) &&
+            (Status != STATUS_BUFFER_TOO_SMALL))
+        {
+            return Status;
+        }
 
-        if (DataLength != NULL)
-            *DataLength = ValueInfo->DataLength;
+        /* All is well */
+        Status = STATUS_SUCCESS;
     }
-
-    /* Check if the caller wanted data back, and we got it */
-    if ((NT_SUCCESS(Status)) && (Data != NULL))
+    /* Otherwise the caller wanted data back, check if we got it */
+    else if (NT_SUCCESS(Status))
     {
+        if (Type != NULL)
+            *Type = ValueInfo->Type;
+
         /* Copy it */
-        RtlMoveMemory(Data,
-                      ValueInfo->Data,
-                      ValueInfo->DataLength);
+        RtlMoveMemory(Data, ValueInfo->Data, ValueInfo->DataLength);
 
         /* if the type is REG_SZ and data is not 0-terminated
          * and there is enough space in the buffer NT appends a \0 */
-        if (((ValueInfo->Type == REG_SZ) || (ValueInfo->Type == REG_EXPAND_SZ) || (ValueInfo->Type == REG_MULTI_SZ)) &&
+        if (((ValueInfo->Type == REG_SZ) ||
+             (ValueInfo->Type == REG_EXPAND_SZ) ||
+             (ValueInfo->Type == REG_MULTI_SZ)) &&
             (ValueInfo->DataLength <= *DataLength - sizeof(WCHAR)))
         {
             WCHAR *ptr = (WCHAR *)((ULONG_PTR)Data + ValueInfo->DataLength);
@@ -421,10 +436,10 @@ AcpiRegQueryValue(IN HANDLE KeyHandle,
     }
 
     /* Free the memory and return status */
-    ExFreePoolWithTag(ValueInfo, 'IPCA');
-
-    if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
-        Status = STATUS_SUCCESS;
+    if (ValueInfo != NULL)
+    {
+        ExFreePoolWithTag(ValueInfo, 'MpcA');
+    }
 
     return Status;
 }
@@ -437,99 +452,134 @@ GetProcessorInformation(VOID)
     LPWSTR ProcessorVendorIdentifier = NULL;
     LPWSTR HardwareIdsBuffer = NULL;
     HANDLE ProcessorHandle = NULL;
-    ULONG Length, Level1Length = 0, Level2Length = 0, Level3Length = 0;
-    ULONG HardwareIdsLength = 0;
+    ULONG Length = 0, Level1Length = 0, Level2Length = 0, Level3Length = 0;
+    SIZE_T HardwareIdsLength = 0;
+    SIZE_T VendorIdentifierLength;
     ULONG i;
     PWCHAR Ptr;
     NTSTATUS Status;
 
-    DPRINT1("GetProcessorInformation()\n");
+    DPRINT("GetProcessorInformation()\n");
 
+    /* Open the key for CPU 0 */
     Status = AcpiRegOpenKey(NULL,
                             L"\\Registry\\Machine\\Hardware\\Description\\System\\CentralProcessor\\0",
                             KEY_READ,
                             &ProcessorHandle);
     if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open CentralProcessor registry key: 0x%lx\n", Status);
         goto done;
+    }
 
-    AcpiRegQueryValue(ProcessorHandle,
-                      L"Identifier",
-                      NULL,
-                      NULL,
-                      &Length);
-
-    if (Length != 0)
+    /* Query the processor identifier length */
+    Status = AcpiRegQueryValue(ProcessorHandle,
+                               L"Identifier",
+                               NULL,
+                               NULL,
+                               &Length);
+    if (!NT_SUCCESS(Status))
     {
-        ProcessorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IPCA');
-        if (ProcessorIdentifier == NULL)
-        {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto done;
-        }
+        DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
+        goto done;
+    }
 
-        Status = AcpiRegQueryValue(ProcessorHandle,
-                                   L"Identifier",
-                                   NULL,
-                                   ProcessorIdentifier,
-                                   &Length);
-        if (!NT_SUCCESS(Status))
-            goto done;
+    /* Remember the length as fallback for level 1-3 length */
+    Level1Length = Level2Length = Level3Length = Length;
 
-        Length = 0;
+    /* Allocate a buffer large enough to be zero terminated */
+    Length += sizeof(UNICODE_NULL);
+    ProcessorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
+    if (ProcessorIdentifier == NULL)
+    {
+        DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
     }
 
-    AcpiRegQueryValue(ProcessorHandle,
-                      L"ProcessorNameString",
-                      NULL,
-                      NULL,
-                      &Length);
-
-    if (Length != 0)
+    /* Query the processor identifier string */
+    Status = AcpiRegQueryValue(ProcessorHandle,
+                               L"Identifier",
+                               NULL,
+                               ProcessorIdentifier,
+                               &Length);
+    if (!NT_SUCCESS(Status))
     {
-        ProcessorNameString = ExAllocatePoolWithTag(PagedPool, Length, 'IPCA');
-        if (ProcessorNameString == NULL)
-        {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto done;
-        }
+        DPRINT1("Failed to query Identifier value: 0x%lx\n", Status);
+        goto done;
+    }
 
-        Status = AcpiRegQueryValue(ProcessorHandle,
-                                   L"ProcessorNameString",
-                                   NULL,
-                                   ProcessorNameString,
-                                   &Length);
-        if (!NT_SUCCESS(Status))
-            goto done;
+    /* Query the processor name length */
+    Length = 0;
+    Status = AcpiRegQueryValue(ProcessorHandle,
+                               L"ProcessorNameString",
+                               NULL,
+                               NULL,
+                               &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
+        goto done;
+    }
 
-        Length = 0;
+    /* Allocate a buffer large enough to be zero terminated */
+    Length += sizeof(UNICODE_NULL);
+    ProcessorNameString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
+    if (ProcessorNameString == NULL)
+    {
+        DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
     }
 
-    AcpiRegQueryValue(ProcessorHandle,
-                      L"VendorIdentifier",
-                      NULL,
-                      NULL,
-                      &Length);
+    /* Query the processor name string */
+    Status = AcpiRegQueryValue(ProcessorHandle,
+                               L"ProcessorNameString",
+                               NULL,
+                               ProcessorNameString,
+                               &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to query ProcessorNameString value: 0x%lx\n", Status);
+        goto done;
+    }
 
-    if (Length != 0)
+    /* Query the vendor identifier length */
+    Length = 0;
+    Status = AcpiRegQueryValue(ProcessorHandle,
+                               L"VendorIdentifier",
+                               NULL,
+                               NULL,
+                               &Length);
+    if (!NT_SUCCESS(Status) || (Length == 0))
     {
-        ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IPCA');
-        if (ProcessorVendorIdentifier == NULL)
-        {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto done;
-        }
+        DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
+        goto done;
+    }
 
-        Status = AcpiRegQueryValue(ProcessorHandle,
-                                   L"VendorIdentifier",
-                                   NULL,
-                                   ProcessorVendorIdentifier,
-                                   &Length);
-        if (!NT_SUCCESS(Status))
-            goto done;
+    /* Allocate a buffer large enough to be zero terminated */
+    Length += sizeof(UNICODE_NULL);
+    ProcessorVendorIdentifier = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
+    if (ProcessorVendorIdentifier == NULL)
+    {
+        DPRINT1("Failed to allocate 0x%lx bytes\n", Length);
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
 
-        Length = 0;
+    /* Query the vendor identifier string */
+    Status = AcpiRegQueryValue(ProcessorHandle,
+                               L"VendorIdentifier",
+                               NULL,
+                               ProcessorVendorIdentifier,
+                               &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to query VendorIdentifier value: 0x%lx\n", Status);
+        goto done;
     }
 
+    /* Change spaces to underscores */
     for (i = 0; i < wcslen(ProcessorIdentifier); i++)
     {
         if (ProcessorIdentifier[i] == L' ')
@@ -557,15 +607,19 @@ GetProcessorInformation(VOID)
         Level3Length = (ULONG)(Ptr - ProcessorIdentifier);
     }
 
-    HardwareIdsLength = 5 + wcslen(ProcessorVendorIdentifier) + 3 + Level1Length + 1 +
-                        1 + wcslen(ProcessorVendorIdentifier) + 3 + Level1Length + 1 +
-                        5 + wcslen(ProcessorVendorIdentifier) + 3 + Level2Length + 1 +
-                        1 + wcslen(ProcessorVendorIdentifier) + 3 + Level2Length + 1 +
-                        5 + wcslen(ProcessorVendorIdentifier) + 3 + Level3Length + 1 +
-                        1 + wcslen(ProcessorVendorIdentifier) + 3 + Level3Length + 1 +
-                        2;
+    VendorIdentifierLength = (USHORT)wcslen(ProcessorVendorIdentifier);
+
+    /* Calculate the size of the full REG_MULTI_SZ data (see swprintf below) */
+    HardwareIdsLength = (5 + VendorIdentifierLength + 3 + Level1Length + 1 +
+                         1 + VendorIdentifierLength + 3 + Level1Length + 1 +
+                         5 + VendorIdentifierLength + 3 + Level2Length + 1 +
+                         1 + VendorIdentifierLength + 3 + Level2Length + 1 +
+                         5 + VendorIdentifierLength + 3 + Level3Length + 1 +
+                         1 + VendorIdentifierLength + 3 + Level3Length + 1 +
+                         1) * sizeof(WCHAR);
 
-    HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength * sizeof(WCHAR), 'IPCA');
+    /* Allocate a buffer to the data */
+    HardwareIdsBuffer = ExAllocatePoolWithTag(PagedPool, HardwareIdsLength, 'IpcA');
     if (HardwareIdsBuffer == NULL)
     {
         Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -574,42 +628,54 @@ GetProcessorInformation(VOID)
 
     Length = 0;
     Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
-    Length++;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
 
     Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
-    Length++;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
 
     Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
-    Length++;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
 
     Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level2Length, ProcessorIdentifier);
-    Length++;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
 
     Length += swprintf(&HardwareIdsBuffer[Length], L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
-    Length++;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
 
     Length += swprintf(&HardwareIdsBuffer[Length], L"*%s_-_%.*s", ProcessorVendorIdentifier, Level3Length, ProcessorIdentifier);
-    Length++;
-    HardwareIdsBuffer[Length] = UNICODE_NULL;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
+    HardwareIdsBuffer[Length++] = UNICODE_NULL;
+
+    /* Make sure we counted correctly */
+    NT_ASSERT(Length * sizeof(WCHAR) == HardwareIdsLength);
 
-    ProcessorHardwareIds.Length = HardwareIdsLength * sizeof(WCHAR);
+    ProcessorHardwareIds.Length = (SHORT)HardwareIdsLength;
     ProcessorHardwareIds.MaximumLength = ProcessorHardwareIds.Length;
     ProcessorHardwareIds.Buffer = HardwareIdsBuffer;
 
+    Length = (5 + VendorIdentifierLength + 3 + Level1Length + 1) * sizeof(WCHAR);
+    ProcessorIdString = ExAllocatePoolWithTag(PagedPool, Length, 'IpcA');
+    if (ProcessorIdString != NULL)
+    {
+        Length = swprintf(ProcessorIdString, L"ACPI\\%s_-_%.*s", ProcessorVendorIdentifier, Level1Length, ProcessorIdentifier);
+        ProcessorIdString[Length++] = UNICODE_NULL;
+        DPRINT("ProcessorIdString: %S\n", ProcessorIdString);
+    }
+
 done:
     if (ProcessorHandle != NULL)
         ZwClose(ProcessorHandle);
 
     if (ProcessorIdentifier != NULL)
-        ExFreePoolWithTag(ProcessorIdentifier, 'IPCA');
+        ExFreePoolWithTag(ProcessorIdentifier, 'IpcA');
 
     if (ProcessorVendorIdentifier != NULL)
-        ExFreePoolWithTag(ProcessorVendorIdentifier, 'IPCA');
+        ExFreePoolWithTag(ProcessorVendorIdentifier, 'IpcA');
 
     if (!NT_SUCCESS(Status))
     {
         if (HardwareIdsBuffer != NULL)
-            ExFreePoolWithTag(HardwareIdsBuffer, 'IPCA');
+            ExFreePoolWithTag(HardwareIdsBuffer, 'IpcA');
     }
 
     return Status;
@@ -622,9 +688,15 @@ DriverEntry (
     PUNICODE_STRING RegistryPath
     )
 {
+    NTSTATUS Status;
     DPRINT("Driver Entry \n");
 
-    GetProcessorInformation();
+    Status = GetProcessorInformation();
+    if (!NT_SUCCESS(Status))
+    {
+        NT_ASSERT(FALSE);
+        return Status;
+    }
 
     //
     // Set entry points into the driver