ReactOS  0.4.15-dev-1377-ga59cecd
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 - 2020, 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 #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 
69 char *
72 {
73  char *NameBuffer;
74 
75 
76  ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);
77 
78 
79  NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE);
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 
96 ACPI_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 
208  RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
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 
255 UINT32
258  char *FullPath,
259  UINT32 PathSize,
260  BOOLEAN NoTrailing)
261 {
262  UINT32 Length = 0, i;
263  char Name[ACPI_NAMESEG_SIZE];
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 
340 BuildTrailingNull:
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 
366 char *
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  {
383  return_PTR (NULL);
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));
393  return_PTR (NULL);
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 
422 char *
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 
477 Cleanup:
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 
505 void
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 }
#define ACPI_DEBUG_PRINT_RAW(pl)
Definition: acoutput.h:476
#define ACPI_FREE(a)
Definition: actypes.h:386
#define ACPI_ALLOCATE_ZEROED(a)
Definition: actypes.h:385
ACPI_STATUS AcpiUtInitializeBuffer(ACPI_BUFFER *Buffer, ACPI_SIZE RequiredLength)
Definition: utalloc.c:336
#define return_PTR(s)
Definition: acoutput.h:497
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define AE_BAD_PARAMETER
Definition: acexcep.h:151
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
#define return_UINT32(s)
Definition: acoutput.h:501
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
UINT32 ACPI_STATUS
Definition: actypes.h:460
ACPI_STATUS AcpiNsHandleToPathname(ACPI_HANDLE TargetHandle, ACPI_BUFFER *Buffer, BOOLEAN NoTrailing)
Definition: nsnames.c:187
struct acpi_namespace_node * Parent
Definition: aclocal.h:192
#define ACPI_PATH_PUT8(Path, Size, Byte, Length)
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define FALSE
Definition: types.h:117
unsigned int UINT32
union node Node
Definition: types.h:1255
UINT32 AcpiNsBuildNormalizedPath(ACPI_NAMESPACE_NODE *Node, char *FullPath, UINT32 PathSize, BOOLEAN NoTrailing)
Definition: nsnames.c:256
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define AML_DUAL_NAME_PREFIX
Definition: amlcode.h:66
unsigned char BOOLEAN
#define AE_INFO
Definition: acoutput.h:230
unsigned char
Definition: typeof.h:29
ACPI_NAME_UNION Name
Definition: aclocal.h:191
ACPI_STATUS AcpiNsExternalizeName(UINT32 InternalNameLength, const char *InternalName, UINT32 *ConvertedNameLength, char **ConvertedName)
Definition: nsutils.c:470
ACPI_STATUS AcpiNsHandleToName(ACPI_HANDLE TargetHandle, ACPI_BUFFER *Buffer)
Definition: nsnames.c:133
Definition: bufpool.h:45
#define ACPI_FUNCTION_TRACE_PTR(a, b)
Definition: acoutput.h:481
Status
Definition: gdiplustypes.h:24
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
const GLubyte * c
Definition: glext.h:8905
#define AML_ROOT_PREFIX
Definition: amlcode.h:69
ACPI_SIZE AcpiNsGetPathnameLength(ACPI_NAMESPACE_NODE *Node)
Definition: nsnames.c:97
#define ACPI_MOVE_32_TO_32(d, s)
Definition: acmacros.h:148
#define ACPI_COPY_NAMESEG(dest, src)
Definition: actypes.h:562
static const WCHAR Cleanup[]
Definition: register.c:80
#define ACPI_PATH_SEGMENT_LENGTH
Definition: actypes.h:416
#define ACPI_GET_FUNCTION_NAME
Definition: acgcc.h:67
char * AcpiNsGetNormalizedPathname(ACPI_NAMESPACE_NODE *Node, BOOLEAN NoTrailing)
Definition: nsnames.c:367
#define ACPI_DB_EXEC
Definition: acoutput.h:165
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 return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_DB_NAMES
Definition: acoutput.h:166
char * AcpiNsBuildPrefixedPathname(ACPI_GENERIC_STATE *PrefixScope, const char *InternalPath)
Definition: nsnames.c:423
ACPI_STATE_COMMON ACPI_NAMESPACE_NODE * Node
Definition: aclocal.h:740
#define NULL
Definition: types.h:112
char * AcpiNsGetExternalPathname(ACPI_NAMESPACE_NODE *Node)
Definition: nsnames.c:70
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
const char * AcpiUtGetNodeName(void *Object)
Definition: utdecode.c:306
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define c
Definition: ke_i.h:80
ACPI_NAMESPACE_NODE * AcpiNsValidateHandle(ACPI_HANDLE Handle)
Definition: nsutils.c:655
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4431
#define ACPI_DESC_TYPE_NAMED
Definition: acobject.h:575
void AcpiNsNormalizePathname(char *OriginalPath)
Definition: nsnames.c:506
#define ACPI_NAMESEG_SIZE
Definition: actypes.h:415
#define AE_OK
Definition: acexcep.h:97
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:429
ACPI_SCOPE_STATE Scope
Definition: aclocal.h:825
Definition: dlist.c:348
#define ACPI_GET_DESCRIPTOR_TYPE(d)
Definition: acmacros.h:414