ReactOS 0.4.15-dev-8058-ga7cbb60
nsnames.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Module Name: nsnames - Name manipulation and search
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 "amlcode.h"
47#include "acnamesp.h"
48
49
50#define _COMPONENT ACPI_NAMESPACE
51 ACPI_MODULE_NAME ("nsnames")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION: AcpiNsGetExternalPathname
57 *
58 * PARAMETERS: Node - Namespace node whose pathname is needed
59 *
60 * RETURN: Pointer to storage containing the fully qualified name of
61 * the node, In external format (name segments separated by path
62 * separators.)
63 *
64 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
65 * for error and debug statements.
66 *
67 ******************************************************************************/
68
69char *
72{
73 char *NameBuffer;
74
75
76 ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);
77
78
80 return_PTR (NameBuffer);
81}
82
83
84/*******************************************************************************
85 *
86 * FUNCTION: AcpiNsGetPathnameLength
87 *
88 * PARAMETERS: Node - Namespace node
89 *
90 * RETURN: Length of path, including prefix
91 *
92 * DESCRIPTION: Get the length of the pathname string for this node
93 *
94 ******************************************************************************/
95
96ACPI_SIZE
99{
100 ACPI_SIZE Size;
101
102
103 /* Validate the Node */
104
106 {
108 "Invalid/cached reference target node: %p, descriptor type %d",
110 return (0);
111 }
112
114 return (Size);
115}
116
117
118/*******************************************************************************
119 *
120 * FUNCTION: AcpiNsHandleToName
121 *
122 * PARAMETERS: TargetHandle - Handle of named object whose name is
123 * to be found
124 * Buffer - Where the name is returned
125 *
126 * RETURN: Status, Buffer is filled with name if status is AE_OK
127 *
128 * DESCRIPTION: Build and return a full namespace name
129 *
130 ******************************************************************************/
131
136{
139 const char *NodeName;
140
141
142 ACPI_FUNCTION_TRACE_PTR (NsHandleToName, TargetHandle);
143
144
146 if (!Node)
147 {
149 }
150
151 /* Validate/Allocate/Clear caller buffer */
152
154 if (ACPI_FAILURE (Status))
155 {
157 }
158
159 /* Just copy the ACPI name from the Node and zero terminate it */
160
161 NodeName = AcpiUtGetNodeName (Node);
162 ACPI_COPY_NAMESEG (Buffer->Pointer, NodeName);
163 ((char *) Buffer->Pointer) [ACPI_NAMESEG_SIZE] = 0;
164
165 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%4.4s\n", (char *) Buffer->Pointer));
167}
168
169
170/*******************************************************************************
171 *
172 * FUNCTION: AcpiNsHandleToPathname
173 *
174 * PARAMETERS: TargetHandle - Handle of named object whose name is
175 * to be found
176 * Buffer - Where the pathname is returned
177 * NoTrailing - Remove trailing '_' for each name
178 * segment
179 *
180 * RETURN: Status, Buffer is filled with pathname if status is AE_OK
181 *
182 * DESCRIPTION: Build and return a full namespace pathname
183 *
184 ******************************************************************************/
185
190 BOOLEAN NoTrailing)
191{
194 ACPI_SIZE RequiredSize;
195
196
197 ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
198
199
201 if (!Node)
202 {
204 }
205
206 /* Determine size required for the caller buffer */
207
209 if (!RequiredSize)
210 {
212 }
213
214 /* Validate/Allocate/Clear caller buffer */
215
217 if (ACPI_FAILURE (Status))
218 {
220 }
221
222 /* Build the path in the caller buffer */
223
225 (UINT32) RequiredSize, NoTrailing);
226
227 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n",
228 (char *) Buffer->Pointer, (UINT32) RequiredSize));
230}
231
232
233/*******************************************************************************
234 *
235 * FUNCTION: AcpiNsBuildNormalizedPath
236 *
237 * PARAMETERS: Node - Namespace node
238 * FullPath - Where the path name is returned
239 * PathSize - Size of returned path name buffer
240 * NoTrailing - Remove trailing '_' from each name segment
241 *
242 * RETURN: Return 1 if the AML path is empty, otherwise returning (length
243 * of pathname + 1) which means the 'FullPath' contains a trailing
244 * null.
245 *
246 * DESCRIPTION: Build and return a full namespace pathname.
247 * Note that if the size of 'FullPath' isn't large enough to
248 * contain the namespace node's path name, the actual required
249 * buffer length is returned, and it should be greater than
250 * 'PathSize'. So callers are able to check the returning value
251 * to determine the buffer size of 'FullPath'.
252 *
253 ******************************************************************************/
254
255UINT32
258 char *FullPath,
259 UINT32 PathSize,
260 BOOLEAN NoTrailing)
261{
262 UINT32 Length = 0, i;
264 BOOLEAN DoNoTrailing;
265 char c, *Left, *Right;
266 ACPI_NAMESPACE_NODE *NextNode;
267
268
269 ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node);
270
271
272#define ACPI_PATH_PUT8(Path, Size, Byte, Length) \
273 do { \
274 if ((Length) < (Size)) \
275 { \
276 (Path)[(Length)] = (Byte); \
277 } \
278 (Length)++; \
279 } while (0)
280
281 /*
282 * Make sure the PathSize is correct, so that we don't need to
283 * validate both FullPath and PathSize.
284 */
285 if (!FullPath)
286 {
287 PathSize = 0;
288 }
289
290 if (!Node)
291 {
292 goto BuildTrailingNull;
293 }
294
295 NextNode = Node;
296 while (NextNode && NextNode != AcpiGbl_RootNode)
297 {
298 if (NextNode != Node)
299 {
300 ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length);
301 }
302
303 ACPI_MOVE_32_TO_32 (Name, &NextNode->Name);
304 DoNoTrailing = NoTrailing;
305 for (i = 0; i < 4; i++)
306 {
307 c = Name[4-i-1];
308 if (DoNoTrailing && c != '_')
309 {
310 DoNoTrailing = FALSE;
311 }
312 if (!DoNoTrailing)
313 {
314 ACPI_PATH_PUT8(FullPath, PathSize, c, Length);
315 }
316 }
317
318 NextNode = NextNode->Parent;
319 }
320
321 ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length);
322
323 /* Reverse the path string */
324
325 if (Length <= PathSize)
326 {
327 Left = FullPath;
328 Right = FullPath+Length - 1;
329
330 while (Left < Right)
331 {
332 c = *Left;
333 *Left++ = *Right;
334 *Right-- = c;
335 }
336 }
337
338 /* Append the trailing null */
339
340BuildTrailingNull:
341 ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length);
342
343#undef ACPI_PATH_PUT8
344
346}
347
348
349/*******************************************************************************
350 *
351 * FUNCTION: AcpiNsGetNormalizedPathname
352 *
353 * PARAMETERS: Node - Namespace node whose pathname is needed
354 * NoTrailing - Remove trailing '_' from each name segment
355 *
356 * RETURN: Pointer to storage containing the fully qualified name of
357 * the node, In external format (name segments separated by path
358 * separators.)
359 *
360 * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
361 * for error and debug statements. All trailing '_' will be
362 * removed from the full pathname if 'NoTrailing' is specified..
363 *
364 ******************************************************************************/
365
366char *
369 BOOLEAN NoTrailing)
370{
371 char *NameBuffer;
372 ACPI_SIZE Size;
373
374
375 ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node);
376
377
378 /* Calculate required buffer size based on depth below root */
379
380 Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
381 if (!Size)
382 {
384 }
385
386 /* Allocate a buffer to be returned to caller */
387
388 NameBuffer = ACPI_ALLOCATE_ZEROED (Size);
389 if (!NameBuffer)
390 {
392 "Could not allocate %u bytes", (UINT32) Size));
394 }
395
396 /* Build the path in the allocated buffer */
397
398 (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, (UINT32) Size, NoTrailing);
399
400 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "%s: Path \"%s\"\n",
401 ACPI_GET_FUNCTION_NAME, NameBuffer));
402
403 return_PTR (NameBuffer);
404}
405
406
407/*******************************************************************************
408 *
409 * FUNCTION: AcpiNsBuildPrefixedPathname
410 *
411 * PARAMETERS: PrefixScope - Scope/Path that prefixes the internal path
412 * InternalPath - Name or path of the namespace node
413 *
414 * RETURN: None
415 *
416 * DESCRIPTION: Construct a fully qualified pathname from a concatenation of:
417 * 1) Path associated with the PrefixScope namespace node
418 * 2) External path representation of the Internal path
419 *
420 ******************************************************************************/
421
422char *
424 ACPI_GENERIC_STATE *PrefixScope,
425 const char *InternalPath)
426{
428 char *FullPath = NULL;
429 char *ExternalPath = NULL;
430 char *PrefixPath = NULL;
431 ACPI_SIZE PrefixPathLength = 0;
432
433
434 /* If there is a prefix, get the pathname to it */
435
436 if (PrefixScope && PrefixScope->Scope.Node)
437 {
438 PrefixPath = AcpiNsGetNormalizedPathname (PrefixScope->Scope.Node, TRUE);
439 if (PrefixPath)
440 {
441 PrefixPathLength = strlen (PrefixPath);
442 }
443 }
444
446 NULL, &ExternalPath);
447 if (ACPI_FAILURE (Status))
448 {
449 goto Cleanup;
450 }
451
452 /* Merge the prefix path and the path. 2 is for one dot and trailing null */
453
454 FullPath = ACPI_ALLOCATE_ZEROED (
455 PrefixPathLength + strlen (ExternalPath) + 2);
456 if (!FullPath)
457 {
458 goto Cleanup;
459 }
460
461 /* Don't merge if the External path is already fully qualified */
462
463 if (PrefixPath &&
464 (*ExternalPath != '\\') &&
465 (*ExternalPath != '^'))
466 {
467 strcat (FullPath, PrefixPath);
468 if (PrefixPath[1])
469 {
470 strcat (FullPath, ".");
471 }
472 }
473
474 AcpiNsNormalizePathname (ExternalPath);
475 strcat (FullPath, ExternalPath);
476
477Cleanup:
478 if (PrefixPath)
479 {
480 ACPI_FREE (PrefixPath);
481 }
482 if (ExternalPath)
483 {
484 ACPI_FREE (ExternalPath);
485 }
486
487 return (FullPath);
488}
489
490
491/*******************************************************************************
492 *
493 * FUNCTION: AcpiNsNormalizePathname
494 *
495 * PARAMETERS: OriginalPath - Path to be normalized, in External format
496 *
497 * RETURN: The original path is processed in-place
498 *
499 * DESCRIPTION: Remove trailing underscores from each element of a path.
500 *
501 * For example: \A___.B___.C___ becomes \A.B.C
502 *
503 ******************************************************************************/
504
505void
507 char *OriginalPath)
508{
509 char *InputPath = OriginalPath;
510 char *NewPathBuffer;
511 char *NewPath;
512 UINT32 i;
513
514
515 /* Allocate a temp buffer in which to construct the new path */
516
517 NewPathBuffer = ACPI_ALLOCATE_ZEROED (strlen (InputPath) + 1);
518 NewPath = NewPathBuffer;
519 if (!NewPathBuffer)
520 {
521 return;
522 }
523
524 /* Special characters may appear at the beginning of the path */
525
526 if (*InputPath == '\\')
527 {
528 *NewPath = *InputPath;
529 NewPath++;
530 InputPath++;
531 }
532
533 while (*InputPath == '^')
534 {
535 *NewPath = *InputPath;
536 NewPath++;
537 InputPath++;
538 }
539
540 /* Remainder of the path */
541
542 while (*InputPath)
543 {
544 /* Do one nameseg at a time */
545
546 for (i = 0; (i < ACPI_NAMESEG_SIZE) && *InputPath; i++)
547 {
548 if ((i == 0) || (*InputPath != '_')) /* First char is allowed to be underscore */
549 {
550 *NewPath = *InputPath;
551 NewPath++;
552 }
553
554 InputPath++;
555 }
556
557 /* Dot means that there are more namesegs to come */
558
559 if (*InputPath == '.')
560 {
561 *NewPath = *InputPath;
562 NewPath++;
563 InputPath++;
564 }
565 }
566
567 *NewPath = 0;
568 strcpy (OriginalPath, NewPathBuffer);
569 ACPI_FREE (NewPathBuffer);
570}
unsigned char BOOLEAN
unsigned int UINT32
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
#define AE_OK
Definition: acexcep.h:97
#define ACPI_GET_FUNCTION_NAME
Definition: acgcc.h:67
#define ACPI_GET_DESCRIPTOR_TYPE(d)
Definition: acmacros.h:414
#define ACPI_MOVE_32_TO_32(d, s)
Definition: acmacros.h:148
ACPI_NAMESPACE_NODE * AcpiNsValidateHandle(ACPI_HANDLE Handle)
Definition: nsutils.c:655
ACPI_STATUS AcpiNsExternalizeName(UINT32 InternalNameLength, const char *InternalName, UINT32 *ConvertedNameLength, char **ConvertedName)
Definition: nsutils.c:470
#define ACPI_DESC_TYPE_NAMED
Definition: acobject.h:577
#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_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_DEBUG_PRINT_RAW(pl)
Definition: acoutput.h:476
#define return_UINT32(s)
Definition: acoutput.h:501
#define ACPI_DB_NAMES
Definition: acoutput.h:166
#define ACPI_COPY_NAMESEG(dest, src)
Definition: actypes.h:565
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_PATH_SEGMENT_LENGTH
Definition: actypes.h:416
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
#define ACPI_NAMESEG_SIZE
Definition: actypes.h:415
ACPI_STATUS AcpiUtInitializeBuffer(ACPI_BUFFER *Buffer, ACPI_SIZE RequiredLength)
Definition: utalloc.c:336
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
#define AML_DUAL_NAME_PREFIX
Definition: amlcode.h:66
#define AML_ROOT_PREFIX
Definition: amlcode.h:69
@ InternalPath
Definition: bl.h:284
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
unsigned char
Definition: typeof.h:29
static const WCHAR Cleanup[]
Definition: register.c:80
Status
Definition: gdiplustypes.h:25
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define c
Definition: ke_i.h:80
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:431
void AcpiNsNormalizePathname(char *OriginalPath)
Definition: nsnames.c:506
ACPI_STATUS AcpiNsHandleToName(ACPI_HANDLE TargetHandle, ACPI_BUFFER *Buffer)
Definition: nsnames.c:133
char * AcpiNsGetNormalizedPathname(ACPI_NAMESPACE_NODE *Node, BOOLEAN NoTrailing)
Definition: nsnames.c:367
ACPI_SIZE AcpiNsGetPathnameLength(ACPI_NAMESPACE_NODE *Node)
Definition: nsnames.c:97
UINT32 AcpiNsBuildNormalizedPath(ACPI_NAMESPACE_NODE *Node, char *FullPath, UINT32 PathSize, BOOLEAN NoTrailing)
Definition: nsnames.c:256
char * AcpiNsBuildPrefixedPathname(ACPI_GENERIC_STATE *PrefixScope, const char *InternalPath)
Definition: nsnames.c:423
ACPI_STATUS AcpiNsHandleToPathname(ACPI_HANDLE TargetHandle, ACPI_BUFFER *Buffer, BOOLEAN NoTrailing)
Definition: nsnames.c:187
char * AcpiNsGetExternalPathname(ACPI_NAMESPACE_NODE *Node)
Definition: nsnames.c:70
#define ACPI_PATH_PUT8(Path, Size, Byte, Length)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
struct acpi_namespace_node * Parent
Definition: aclocal.h:192
ACPI_NAME_UNION Name
Definition: aclocal.h:191
ACPI_STATE_COMMON ACPI_NAMESPACE_NODE * Node
Definition: aclocal.h:740
ACPI_SCOPE_STATE Scope
Definition: aclocal.h:825
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439