oswintbl.c revision 1.1.1.2.8.2 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