1 /****************************************************************************** 2 * 3 * Module Name: oswintbl - Windows OSL for obtaining ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45 #include "acpi.h" 46 47 #ifdef WIN32 48 #pragma warning(disable:4115) /* warning C4115: (caused by rpcasync.h) */ 49 #include <windows.h> 50 51 #elif WIN64 52 #include <windowsx.h> 53 #endif 54 55 #define _COMPONENT ACPI_OS_SERVICES 56 ACPI_MODULE_NAME ("oswintbl") 57 58 59 static char KeyBuffer[64]; 60 static char ErrorBuffer[64]; 61 62 63 /* Little front-end to win FormatMessage */ 64 65 char * 66 OsFormatException ( 67 LONG Status) 68 { 69 70 ErrorBuffer[0] = 0; 71 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, Status, 0, 72 ErrorBuffer, 64, NULL); 73 74 return (ErrorBuffer); 75 } 76 77 78 /****************************************************************************** 79 * 80 * FUNCTION: OsGetTable 81 * 82 * PARAMETERS: Signature - ACPI Signature for desired table. must be 83 * a null terminated string. 84 * 85 * RETURN: Pointer to the table. NULL if failure. 86 * 87 * DESCRIPTION: Get an ACPI table from the Windows registry. 88 * 89 *****************************************************************************/ 90 91 ACPI_TABLE_HEADER * 92 OsGetTable ( 93 char *Signature) 94 { 95 HKEY Handle = NULL; 96 ULONG i; 97 LONG Status; 98 ULONG Type; 99 ULONG NameSize; 100 ULONG DataSize; 101 HKEY SubKey; 102 ACPI_TABLE_HEADER *ReturnTable; 103 104 105 /* Get a handle to the table key */ 106 107 while (1) 108 { 109 ACPI_STRCPY (KeyBuffer, "HARDWARE\\ACPI\\"); 110 ACPI_STRCAT (KeyBuffer, Signature); 111 112 Status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 113 0L, KEY_READ, &Handle); 114 115 if (Status != ERROR_SUCCESS) 116 { 117 /* 118 * Somewhere along the way, MS changed the registry entry for 119 * the FADT from 120 * HARDWARE/ACPI/FACP to 121 * HARDWARE/ACPI/FADT. 122 * 123 * This code allows for both. 124 */ 125 if (ACPI_COMPARE_NAME (Signature, "FACP")) 126 { 127 Signature = "FADT"; 128 } 129 else 130 { 131 AcpiOsPrintf ( 132 "Could not find %s in registry at %s: %s (Status=0x%X)\n", 133 Signature, KeyBuffer, OsFormatException (Status), Status); 134 return (NULL); 135 } 136 } 137 else 138 { 139 break; 140 } 141 } 142 143 /* Actual data for table is down a couple levels */ 144 145 for (i = 0; ;) 146 { 147 Status = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); 148 i += 1; 149 if (Status == ERROR_NO_MORE_ITEMS) 150 { 151 break; 152 } 153 154 Status = RegOpenKey (Handle, KeyBuffer, &SubKey); 155 if (Status != ERROR_SUCCESS) 156 { 157 AcpiOsPrintf ("Could not open %s entry: %s\n", 158 Signature, OsFormatException (Status)); 159 return (NULL); 160 } 161 162 RegCloseKey (Handle); 163 Handle = SubKey; 164 i = 0; 165 } 166 167 /* Find the (binary) table entry */ 168 169 for (i = 0; ;) 170 { 171 NameSize = sizeof (KeyBuffer); 172 Status = RegEnumValue (Handle, i, KeyBuffer, &NameSize, 173 NULL, &Type, NULL, 0); 174 if (Status != ERROR_SUCCESS) 175 { 176 AcpiOsPrintf ("Could not get %s registry entry: %s\n", 177 Signature, OsFormatException (Status)); 178 return (NULL); 179 } 180 181 if (Type == REG_BINARY) 182 { 183 break; 184 } 185 i += 1; 186 } 187 188 /* Get the size of the table */ 189 190 Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, NULL, &DataSize); 191 if (Status != ERROR_SUCCESS) 192 { 193 AcpiOsPrintf ("Could not read the %s table size: %s\n", 194 Signature, OsFormatException (Status)); 195 return (NULL); 196 } 197 198 /* Allocate a new buffer for the table */ 199 200 ReturnTable = AcpiOsAllocate (DataSize); 201 if (!ReturnTable) 202 { 203 goto Cleanup; 204 } 205 206 /* Get the actual table from the registry */ 207 208 Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 209 (UCHAR *) ReturnTable, &DataSize); 210 if (Status != ERROR_SUCCESS) 211 { 212 AcpiOsPrintf ("Could not read %s data: %s\n", 213 Signature, OsFormatException (Status)); 214 AcpiOsFree (ReturnTable); 215 return (NULL); 216 } 217 218 Cleanup: 219 RegCloseKey (Handle); 220 return (ReturnTable); 221 } 222 223