ReactOS 0.4.15-dev-7846-g8ba6c66
exnames.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: exnames - interpreter/scanner name load/execute
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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#include "acpi.h"
45#include "accommon.h"
46#include "acinterp.h"
47#include "amlcode.h"
48
49#define _COMPONENT ACPI_EXECUTER
50 ACPI_MODULE_NAME ("exnames")
51
52/* Local prototypes */
53
54static char *
56 UINT32 PrefixCount,
57 UINT32 NumNameSegs);
58
59static ACPI_STATUS
61 UINT8 **InAmlAddress,
62 char *NameString);
63
64
65/*******************************************************************************
66 *
67 * FUNCTION: AcpiExAllocateNameString
68 *
69 * PARAMETERS: PrefixCount - Count of parent levels. Special cases:
70 * (-1)==root, 0==none
71 * NumNameSegs - count of 4-character name segments
72 *
73 * RETURN: A pointer to the allocated string segment. This segment must
74 * be deleted by the caller.
75 *
76 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
77 * string is long enough, and set up prefix if any.
78 *
79 ******************************************************************************/
80
81static char *
83 UINT32 PrefixCount,
84 UINT32 NumNameSegs)
85{
86 char *TempPtr;
87 char *NameString;
88 UINT32 SizeNeeded;
89
90 ACPI_FUNCTION_TRACE (ExAllocateNameString);
91
92
93 /*
94 * Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix.
95 * Also, one byte for the null terminator.
96 * This may actually be somewhat longer than needed.
97 */
98 if (PrefixCount == ACPI_UINT32_MAX)
99 {
100 /* Special case for root */
101
102 SizeNeeded = 1 + (ACPI_NAMESEG_SIZE * NumNameSegs) + 2 + 1;
103 }
104 else
105 {
106 SizeNeeded = PrefixCount + (ACPI_NAMESEG_SIZE * NumNameSegs) + 2 + 1;
107 }
108
109 /*
110 * Allocate a buffer for the name.
111 * This buffer must be deleted by the caller!
112 */
113 NameString = ACPI_ALLOCATE (SizeNeeded);
114 if (!NameString)
115 {
117 "Could not allocate size %u", SizeNeeded));
119 }
120
121 TempPtr = NameString;
122
123 /* Set up Root or Parent prefixes if needed */
124
125 if (PrefixCount == ACPI_UINT32_MAX)
126 {
127 *TempPtr++ = AML_ROOT_PREFIX;
128 }
129 else
130 {
131 while (PrefixCount--)
132 {
133 *TempPtr++ = AML_PARENT_PREFIX;
134 }
135 }
136
137
138 /* Set up Dual or Multi prefixes if needed */
139
140 if (NumNameSegs > 2)
141 {
142 /* Set up multi prefixes */
143
144 *TempPtr++ = AML_MULTI_NAME_PREFIX;
145 *TempPtr++ = (char) NumNameSegs;
146 }
147 else if (2 == NumNameSegs)
148 {
149 /* Set up dual prefixes */
150
151 *TempPtr++ = AML_DUAL_NAME_PREFIX;
152 }
153
154 /*
155 * Terminate string following prefixes. AcpiExNameSegment() will
156 * append the segment(s)
157 */
158 *TempPtr = 0;
159
160 return_PTR (NameString);
161}
162
163
164/*******************************************************************************
165 *
166 * FUNCTION: AcpiExNameSegment
167 *
168 * PARAMETERS: InAmlAddress - Pointer to the name in the AML code
169 * NameString - Where to return the name. The name is appended
170 * to any existing string to form a namepath
171 *
172 * RETURN: Status
173 *
174 * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
175 *
176 ******************************************************************************/
177
178static ACPI_STATUS
180 UINT8 **InAmlAddress,
181 char *NameString)
182{
183 char *AmlAddress = (void *) *InAmlAddress;
186 char CharBuf[5];
187
188
189 ACPI_FUNCTION_TRACE (ExNameSegment);
190
191
192 /*
193 * If first character is a digit, then we know that we aren't looking
194 * at a valid name segment
195 */
196 CharBuf[0] = *AmlAddress;
197
198 if ('0' <= CharBuf[0] && CharBuf[0] <= '9')
199 {
200 ACPI_ERROR ((AE_INFO, "Invalid leading digit: %c", CharBuf[0]));
202 }
203
204 for (Index = 0;
205 (Index < ACPI_NAMESEG_SIZE) && (AcpiUtValidNameChar (*AmlAddress, 0));
206 Index++)
207 {
208 CharBuf[Index] = *AmlAddress++;
209 }
210
211
212 /* Valid name segment */
213
214 if (Index == 4)
215 {
216 /* Found 4 valid characters */
217
218 CharBuf[4] = '\0';
219
220 if (NameString)
221 {
223 "Appending NameSeg %s\n", CharBuf));
224 strcat (NameString, CharBuf);
225 }
226 else
227 {
229 "No Name string - %s\n", CharBuf));
230 }
231 }
232 else if (Index == 0)
233 {
234 /*
235 * First character was not a valid name character,
236 * so we are looking at something other than a name.
237 */
239 "Leading character is not alpha: %02Xh (not a name)\n",
240 CharBuf[0]));
242 }
243 else
244 {
245 /*
246 * Segment started with one or more valid characters, but fewer than
247 * the required 4
248 */
251 "Bad character 0x%02x in name, at %p",
252 *AmlAddress, AmlAddress));
253 }
254
255 *InAmlAddress = ACPI_CAST_PTR (UINT8, AmlAddress);
257}
258
259
260/*******************************************************************************
261 *
262 * FUNCTION: AcpiExGetNameString
263 *
264 * PARAMETERS: DataType - Object type to be associated with this
265 * name
266 * InAmlAddress - Pointer to the namestring in the AML code
267 * OutNameString - Where the namestring is returned
268 * OutNameLength - Length of the returned string
269 *
270 * RETURN: Status, namestring and length
271 *
272 * DESCRIPTION: Extract a full namepath from the AML byte stream,
273 * including any prefixes.
274 *
275 ******************************************************************************/
276
280 UINT8 *InAmlAddress,
281 char **OutNameString,
282 UINT32 *OutNameLength)
283{
285 UINT8 *AmlAddress = InAmlAddress;
286 char *NameString = NULL;
287 UINT32 NumSegments;
288 UINT32 PrefixCount = 0;
290
291
292 ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress);
293
294
298 {
299 /* Disallow prefixes for types associated with FieldUnit names */
300
301 NameString = AcpiExAllocateNameString (0, 1);
302 if (!NameString)
303 {
305 }
306 else
307 {
308 Status = AcpiExNameSegment (&AmlAddress, NameString);
309 }
310 }
311 else
312 {
313 /*
314 * DataType is not a field name.
315 * Examine first character of name for root or parent prefix operators
316 */
317 switch (*AmlAddress)
318 {
319 case AML_ROOT_PREFIX:
320
321 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n",
322 AmlAddress));
323
324 /*
325 * Remember that we have a RootPrefix --
326 * see comment in AcpiExAllocateNameString()
327 */
328 AmlAddress++;
329 PrefixCount = ACPI_UINT32_MAX;
330 HasPrefix = TRUE;
331 break;
332
334
335 /* Increment past possibly multiple parent prefixes */
336
337 do
338 {
339 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n",
340 AmlAddress));
341
342 AmlAddress++;
343 PrefixCount++;
344
345 } while (*AmlAddress == AML_PARENT_PREFIX);
346
347 HasPrefix = TRUE;
348 break;
349
350 default:
351
352 /* Not a prefix character */
353
354 break;
355 }
356
357 /* Examine first character of name for name segment prefix operator */
358
359 switch (*AmlAddress)
360 {
362
363 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n",
364 AmlAddress));
365
366 AmlAddress++;
367 NameString = AcpiExAllocateNameString (PrefixCount, 2);
368 if (!NameString)
369 {
371 break;
372 }
373
374 /* Indicate that we processed a prefix */
375
376 HasPrefix = TRUE;
377
378 Status = AcpiExNameSegment (&AmlAddress, NameString);
379 if (ACPI_SUCCESS (Status))
380 {
381 Status = AcpiExNameSegment (&AmlAddress, NameString);
382 }
383 break;
384
386
387 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n",
388 AmlAddress));
389
390 /* Fetch count of segments remaining in name path */
391
392 AmlAddress++;
393 NumSegments = *AmlAddress;
394
395 NameString = AcpiExAllocateNameString (
396 PrefixCount, NumSegments);
397 if (!NameString)
398 {
400 break;
401 }
402
403 /* Indicate that we processed a prefix */
404
405 AmlAddress++;
406 HasPrefix = TRUE;
407
408 while (NumSegments &&
409 (Status = AcpiExNameSegment (&AmlAddress, NameString)) ==
410 AE_OK)
411 {
412 NumSegments--;
413 }
414
415 break;
416
417 case 0:
418
419 /* NullName valid as of 8-12-98 ASL/AML Grammar Update */
420
421 if (PrefixCount == ACPI_UINT32_MAX)
422 {
424 "NameSeg is \"\\\" followed by NULL\n"));
425 }
426
427 /* Consume the NULL byte */
428
429 AmlAddress++;
430 NameString = AcpiExAllocateNameString (PrefixCount, 0);
431 if (!NameString)
432 {
434 break;
435 }
436
437 break;
438
439 default:
440
441 /* Name segment string */
442
443 NameString = AcpiExAllocateNameString (PrefixCount, 1);
444 if (!NameString)
445 {
447 break;
448 }
449
450 Status = AcpiExNameSegment (&AmlAddress, NameString);
451 break;
452 }
453 }
454
456 {
457 /* Ran out of segments after processing a prefix */
458
460 "Malformed Name at %p", NameString));
462 }
463
464 if (ACPI_FAILURE (Status))
465 {
466 if (NameString)
467 {
468 ACPI_FREE (NameString);
469 }
471 }
472
473 *OutNameString = NameString;
474 *OutNameLength = (UINT32) (AmlAddress - InAmlAddress);
475
477}
unsigned char BOOLEAN
unsigned char UINT8
unsigned int UINT32
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define AE_AML_BAD_NAME
Definition: acexcep.h:192
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_CTRL_PENDING
Definition: acexcep.h:225
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define return_PTR(s)
Definition: acoutput.h:497
#define ACPI_DB_EXEC
Definition: acoutput.h:165
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define ACPI_DB_LOAD
Definition: acoutput.h:164
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_DB_INFO
Definition: acoutput.h:153
#define ACPI_DB_NAMES
Definition: acoutput.h:166
#define ACPI_TYPE_LOCAL_BANK_FIELD
Definition: actypes.h:717
UINT32 ACPI_OBJECT_TYPE
Definition: actypes.h:685
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_TYPE_LOCAL_REGION_FIELD
Definition: actypes.h:716
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_TYPE_LOCAL_INDEX_FIELD
Definition: actypes.h:718
#define ACPI_ALLOCATE(a)
Definition: actypes.h:384
#define ACPI_NAMESEG_SIZE
Definition: actypes.h:415
BOOLEAN AcpiUtValidNameChar(char Character, UINT32 Position)
Definition: utascii.c:102
#define AML_PARENT_PREFIX
Definition: amlcode.h:70
#define AML_DUAL_NAME_PREFIX
Definition: amlcode.h:66
#define AML_MULTI_NAME_PREFIX
Definition: amlcode.h:67
#define AML_ROOT_PREFIX
Definition: amlcode.h:69
BOOL HasPrefix(_In_ PWSTR pszString, _In_ PWSTR pszPrefix, _Out_opt_ PWSTR *pszSuffix)
Definition: misc.c:58
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned char
Definition: typeof.h:29
static ACPI_STATUS AcpiExNameSegment(UINT8 **InAmlAddress, char *NameString)
Definition: exnames.c:179
ACPI_STATUS AcpiExGetNameString(ACPI_OBJECT_TYPE DataType, UINT8 *InAmlAddress, char **OutNameString, UINT32 *OutNameLength)
Definition: exnames.c:278
static char * AcpiExAllocateNameString(UINT32 PrefixCount, UINT32 NumNameSegs)
Definition: exnames.c:82
Status
Definition: gdiplustypes.h:25
DataType
Definition: simd.h:252
_In_ WDFCOLLECTION _In_ ULONG Index