ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nsutils.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
00004  *                        parents and siblings and Scope manipulation
00005  *
00006  *****************************************************************************/
00007 
00008 /******************************************************************************
00009  *
00010  * 1. Copyright Notice
00011  *
00012  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00013  * All rights reserved.
00014  *
00015  * 2. License
00016  *
00017  * 2.1. This is your license from Intel Corp. under its intellectual property
00018  * rights.  You may have additional license terms from the party that provided
00019  * you this software, covering your right to use that party's intellectual
00020  * property rights.
00021  *
00022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00023  * copy of the source code appearing in this file ("Covered Code") an
00024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00025  * base code distributed originally by Intel ("Original Intel Code") to copy,
00026  * make derivatives, distribute, use and display any portion of the Covered
00027  * Code in any form, with the right to sublicense such rights; and
00028  *
00029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00030  * license (with the right to sublicense), under only those claims of Intel
00031  * patents that are infringed by the Original Intel Code, to make, use, sell,
00032  * offer to sell, and import the Covered Code and derivative works thereof
00033  * solely to the minimum extent necessary to exercise the above copyright
00034  * license, and in no event shall the patent license extend to any additions
00035  * to or modifications of the Original Intel Code.  No other license or right
00036  * is granted directly or by implication, estoppel or otherwise;
00037  *
00038  * The above copyright and patent license is granted only if the following
00039  * conditions are met:
00040  *
00041  * 3. Conditions
00042  *
00043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00044  * Redistribution of source code of any substantial portion of the Covered
00045  * Code or modification with rights to further distribute source must include
00046  * the above Copyright Notice, the above License, this list of Conditions,
00047  * and the following Disclaimer and Export Compliance provision.  In addition,
00048  * Licensee must cause all Covered Code to which Licensee contributes to
00049  * contain a file documenting the changes Licensee made to create that Covered
00050  * Code and the date of any change.  Licensee must include in that file the
00051  * documentation of any changes made by any predecessor Licensee.  Licensee
00052  * must include a prominent statement that the modification is derived,
00053  * directly or indirectly, from Original Intel Code.
00054  *
00055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00056  * Redistribution of source code of any substantial portion of the Covered
00057  * Code or modification without rights to further distribute source must
00058  * include the following Disclaimer and Export Compliance provision in the
00059  * documentation and/or other materials provided with distribution.  In
00060  * addition, Licensee may not authorize further sublicense of source of any
00061  * portion of the Covered Code, and must include terms to the effect that the
00062  * license from Licensee to its licensee is limited to the intellectual
00063  * property embodied in the software Licensee provides to its licensee, and
00064  * not to intellectual property embodied in modifications its licensee may
00065  * make.
00066  *
00067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00068  * substantial portion of the Covered Code or modification must reproduce the
00069  * above Copyright Notice, and the following Disclaimer and Export Compliance
00070  * provision in the documentation and/or other materials provided with the
00071  * distribution.
00072  *
00073  * 3.4. Intel retains all right, title, and interest in and to the Original
00074  * Intel Code.
00075  *
00076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00077  * Intel shall be used in advertising or otherwise to promote the sale, use or
00078  * other dealings in products derived from or relating to the Covered Code
00079  * without prior written authorization from Intel.
00080  *
00081  * 4. Disclaimer and Export Compliance
00082  *
00083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 #define __NSUTILS_C__
00118 
00119 #include "acpi.h"
00120 #include "accommon.h"
00121 #include "acnamesp.h"
00122 #include "amlcode.h"
00123 
00124 #define _COMPONENT          ACPI_NAMESPACE
00125         ACPI_MODULE_NAME    ("nsutils")
00126 
00127 /* Local prototypes */
00128 
00129 static BOOLEAN
00130 AcpiNsValidPathSeparator (
00131     char                    Sep);
00132 
00133 #ifdef ACPI_OBSOLETE_FUNCTIONS
00134 ACPI_NAME
00135 AcpiNsFindParentName (
00136     ACPI_NAMESPACE_NODE     *NodeToSearch);
00137 #endif
00138 
00139 
00140 /*******************************************************************************
00141  *
00142  * FUNCTION:    AcpiNsPrintNodePathname
00143  *
00144  * PARAMETERS:  Node            - Object
00145  *              Message         - Prefix message
00146  *
00147  * DESCRIPTION: Print an object's full namespace pathname
00148  *              Manages allocation/freeing of a pathname buffer
00149  *
00150  ******************************************************************************/
00151 
00152 void
00153 AcpiNsPrintNodePathname (
00154     ACPI_NAMESPACE_NODE     *Node,
00155     const char              *Message)
00156 {
00157     ACPI_BUFFER             Buffer;
00158     ACPI_STATUS             Status;
00159 
00160 
00161     if (!Node)
00162     {
00163         AcpiOsPrintf ("[NULL NAME]");
00164         return;
00165     }
00166 
00167     /* Convert handle to full pathname and print it (with supplied message) */
00168 
00169     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
00170 
00171     Status = AcpiNsHandleToPathname (Node, &Buffer);
00172     if (ACPI_SUCCESS (Status))
00173     {
00174         if (Message)
00175         {
00176             AcpiOsPrintf ("%s ", Message);
00177         }
00178 
00179         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
00180         ACPI_FREE (Buffer.Pointer);
00181     }
00182 }
00183 
00184 
00185 /*******************************************************************************
00186  *
00187  * FUNCTION:    AcpiNsValidRootPrefix
00188  *
00189  * PARAMETERS:  Prefix          - Character to be checked
00190  *
00191  * RETURN:      TRUE if a valid prefix
00192  *
00193  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
00194  *
00195  ******************************************************************************/
00196 
00197 BOOLEAN
00198 AcpiNsValidRootPrefix (
00199     char                    Prefix)
00200 {
00201 
00202     return ((BOOLEAN) (Prefix == '\\'));
00203 }
00204 
00205 
00206 /*******************************************************************************
00207  *
00208  * FUNCTION:    AcpiNsValidPathSeparator
00209  *
00210  * PARAMETERS:  Sep         - Character to be checked
00211  *
00212  * RETURN:      TRUE if a valid path separator
00213  *
00214  * DESCRIPTION: Check if a character is a valid ACPI path separator
00215  *
00216  ******************************************************************************/
00217 
00218 static BOOLEAN
00219 AcpiNsValidPathSeparator (
00220     char                    Sep)
00221 {
00222 
00223     return ((BOOLEAN) (Sep == '.'));
00224 }
00225 
00226 
00227 /*******************************************************************************
00228  *
00229  * FUNCTION:    AcpiNsGetType
00230  *
00231  * PARAMETERS:  Node        - Parent Node to be examined
00232  *
00233  * RETURN:      Type field from Node whose handle is passed
00234  *
00235  * DESCRIPTION: Return the type of a Namespace node
00236  *
00237  ******************************************************************************/
00238 
00239 ACPI_OBJECT_TYPE
00240 AcpiNsGetType (
00241     ACPI_NAMESPACE_NODE     *Node)
00242 {
00243     ACPI_FUNCTION_TRACE (NsGetType);
00244 
00245 
00246     if (!Node)
00247     {
00248         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
00249         return_UINT32 (ACPI_TYPE_ANY);
00250     }
00251 
00252     return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type);
00253 }
00254 
00255 
00256 /*******************************************************************************
00257  *
00258  * FUNCTION:    AcpiNsLocal
00259  *
00260  * PARAMETERS:  Type        - A namespace object type
00261  *
00262  * RETURN:      LOCAL if names must be found locally in objects of the
00263  *              passed type, 0 if enclosing scopes should be searched
00264  *
00265  * DESCRIPTION: Returns scope rule for the given object type.
00266  *
00267  ******************************************************************************/
00268 
00269 UINT32
00270 AcpiNsLocal (
00271     ACPI_OBJECT_TYPE        Type)
00272 {
00273     ACPI_FUNCTION_TRACE (NsLocal);
00274 
00275 
00276     if (!AcpiUtValidObjectType (Type))
00277     {
00278         /* Type code out of range  */
00279 
00280         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
00281         return_UINT32 (ACPI_NS_NORMAL);
00282     }
00283 
00284     return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
00285 }
00286 
00287 
00288 /*******************************************************************************
00289  *
00290  * FUNCTION:    AcpiNsGetInternalNameLength
00291  *
00292  * PARAMETERS:  Info            - Info struct initialized with the
00293  *                                external name pointer.
00294  *
00295  * RETURN:      None
00296  *
00297  * DESCRIPTION: Calculate the length of the internal (AML) namestring
00298  *              corresponding to the external (ASL) namestring.
00299  *
00300  ******************************************************************************/
00301 
00302 void
00303 AcpiNsGetInternalNameLength (
00304     ACPI_NAMESTRING_INFO    *Info)
00305 {
00306     const char              *NextExternalChar;
00307     UINT32                  i;
00308 
00309 
00310     ACPI_FUNCTION_ENTRY ();
00311 
00312 
00313     NextExternalChar = Info->ExternalName;
00314     Info->NumCarats = 0;
00315     Info->NumSegments = 0;
00316     Info->FullyQualified = FALSE;
00317 
00318     /*
00319      * For the internal name, the required length is 4 bytes per segment, plus
00320      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
00321      * (which is not really needed, but no there's harm in putting it there)
00322      *
00323      * strlen() + 1 covers the first NameSeg, which has no path separator
00324      */
00325     if (AcpiNsValidRootPrefix (*NextExternalChar))
00326     {
00327         Info->FullyQualified = TRUE;
00328         NextExternalChar++;
00329 
00330         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
00331 
00332         while (AcpiNsValidRootPrefix (*NextExternalChar))
00333         {
00334             NextExternalChar++;
00335         }
00336     }
00337     else
00338     {
00339         /* Handle Carat prefixes */
00340 
00341         while (*NextExternalChar == '^')
00342         {
00343             Info->NumCarats++;
00344             NextExternalChar++;
00345         }
00346     }
00347 
00348     /*
00349      * Determine the number of ACPI name "segments" by counting the number of
00350      * path separators within the string. Start with one segment since the
00351      * segment count is [(# separators) + 1], and zero separators is ok.
00352      */
00353     if (*NextExternalChar)
00354     {
00355         Info->NumSegments = 1;
00356         for (i = 0; NextExternalChar[i]; i++)
00357         {
00358             if (AcpiNsValidPathSeparator (NextExternalChar[i]))
00359             {
00360                 Info->NumSegments++;
00361             }
00362         }
00363     }
00364 
00365     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
00366                     4 + Info->NumCarats;
00367 
00368     Info->NextExternalChar = NextExternalChar;
00369 }
00370 
00371 
00372 /*******************************************************************************
00373  *
00374  * FUNCTION:    AcpiNsBuildInternalName
00375  *
00376  * PARAMETERS:  Info            - Info struct fully initialized
00377  *
00378  * RETURN:      Status
00379  *
00380  * DESCRIPTION: Construct the internal (AML) namestring
00381  *              corresponding to the external (ASL) namestring.
00382  *
00383  ******************************************************************************/
00384 
00385 ACPI_STATUS
00386 AcpiNsBuildInternalName (
00387     ACPI_NAMESTRING_INFO    *Info)
00388 {
00389     UINT32                  NumSegments = Info->NumSegments;
00390     char                    *InternalName = Info->InternalName;
00391     const char              *ExternalName = Info->NextExternalChar;
00392     char                    *Result = NULL;
00393     UINT32                  i;
00394 
00395 
00396     ACPI_FUNCTION_TRACE (NsBuildInternalName);
00397 
00398 
00399     /* Setup the correct prefixes, counts, and pointers */
00400 
00401     if (Info->FullyQualified)
00402     {
00403         InternalName[0] = '\\';
00404 
00405         if (NumSegments <= 1)
00406         {
00407             Result = &InternalName[1];
00408         }
00409         else if (NumSegments == 2)
00410         {
00411             InternalName[1] = AML_DUAL_NAME_PREFIX;
00412             Result = &InternalName[2];
00413         }
00414         else
00415         {
00416             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
00417             InternalName[2] = (char) NumSegments;
00418             Result = &InternalName[3];
00419         }
00420     }
00421     else
00422     {
00423         /*
00424          * Not fully qualified.
00425          * Handle Carats first, then append the name segments
00426          */
00427         i = 0;
00428         if (Info->NumCarats)
00429         {
00430             for (i = 0; i < Info->NumCarats; i++)
00431             {
00432                 InternalName[i] = '^';
00433             }
00434         }
00435 
00436         if (NumSegments <= 1)
00437         {
00438             Result = &InternalName[i];
00439         }
00440         else if (NumSegments == 2)
00441         {
00442             InternalName[i] = AML_DUAL_NAME_PREFIX;
00443             Result = &InternalName[(ACPI_SIZE) i+1];
00444         }
00445         else
00446         {
00447             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
00448             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
00449             Result = &InternalName[(ACPI_SIZE) i+2];
00450         }
00451     }
00452 
00453     /* Build the name (minus path separators) */
00454 
00455     for (; NumSegments; NumSegments--)
00456     {
00457         for (i = 0; i < ACPI_NAME_SIZE; i++)
00458         {
00459             if (AcpiNsValidPathSeparator (*ExternalName) ||
00460                (*ExternalName == 0))
00461             {
00462                 /* Pad the segment with underscore(s) if segment is short */
00463 
00464                 Result[i] = '_';
00465             }
00466             else
00467             {
00468                 /* Convert the character to uppercase and save it */
00469 
00470                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
00471                 ExternalName++;
00472             }
00473         }
00474 
00475         /* Now we must have a path separator, or the pathname is bad */
00476 
00477         if (!AcpiNsValidPathSeparator (*ExternalName) &&
00478             (*ExternalName != 0))
00479         {
00480             return_ACPI_STATUS (AE_BAD_PARAMETER);
00481         }
00482 
00483         /* Move on the next segment */
00484 
00485         ExternalName++;
00486         Result += ACPI_NAME_SIZE;
00487     }
00488 
00489     /* Terminate the string */
00490 
00491     *Result = 0;
00492 
00493     if (Info->FullyQualified)
00494     {
00495         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
00496             InternalName, InternalName));
00497     }
00498     else
00499     {
00500         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
00501             InternalName, InternalName));
00502     }
00503 
00504     return_ACPI_STATUS (AE_OK);
00505 }
00506 
00507 
00508 /*******************************************************************************
00509  *
00510  * FUNCTION:    AcpiNsInternalizeName
00511  *
00512  * PARAMETERS:  *ExternalName           - External representation of name
00513  *              **Converted Name        - Where to return the resulting
00514  *                                        internal represention of the name
00515  *
00516  * RETURN:      Status
00517  *
00518  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
00519  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
00520  *
00521  *******************************************************************************/
00522 
00523 ACPI_STATUS
00524 AcpiNsInternalizeName (
00525     const char              *ExternalName,
00526     char                    **ConvertedName)
00527 {
00528     char                    *InternalName;
00529     ACPI_NAMESTRING_INFO    Info;
00530     ACPI_STATUS             Status;
00531 
00532 
00533     ACPI_FUNCTION_TRACE (NsInternalizeName);
00534 
00535 
00536     if ((!ExternalName)      ||
00537         (*ExternalName == 0) ||
00538         (!ConvertedName))
00539     {
00540         return_ACPI_STATUS (AE_BAD_PARAMETER);
00541     }
00542 
00543     /* Get the length of the new internal name */
00544 
00545     Info.ExternalName = ExternalName;
00546     AcpiNsGetInternalNameLength (&Info);
00547 
00548     /* We need a segment to store the internal  name */
00549 
00550     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
00551     if (!InternalName)
00552     {
00553         return_ACPI_STATUS (AE_NO_MEMORY);
00554     }
00555 
00556     /* Build the name */
00557 
00558     Info.InternalName = InternalName;
00559     Status = AcpiNsBuildInternalName (&Info);
00560     if (ACPI_FAILURE (Status))
00561     {
00562         ACPI_FREE (InternalName);
00563         return_ACPI_STATUS (Status);
00564     }
00565 
00566     *ConvertedName = InternalName;
00567     return_ACPI_STATUS (AE_OK);
00568 }
00569 
00570 
00571 /*******************************************************************************
00572  *
00573  * FUNCTION:    AcpiNsExternalizeName
00574  *
00575  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
00576  *              InternalName        - Internal representation of name
00577  *              ConvertedNameLength - Where the length is returned
00578  *              ConvertedName       - Where the resulting external name
00579  *                                    is returned
00580  *
00581  * RETURN:      Status
00582  *
00583  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
00584  *              to its external (printable) form (e.g. "\_PR_.CPU0")
00585  *
00586  ******************************************************************************/
00587 
00588 ACPI_STATUS
00589 AcpiNsExternalizeName (
00590     UINT32                  InternalNameLength,
00591     const char              *InternalName,
00592     UINT32                  *ConvertedNameLength,
00593     char                    **ConvertedName)
00594 {
00595     UINT32                  NamesIndex = 0;
00596     UINT32                  NumSegments = 0;
00597     UINT32                  RequiredLength;
00598     UINT32                  PrefixLength = 0;
00599     UINT32                  i = 0;
00600     UINT32                  j = 0;
00601 
00602 
00603     ACPI_FUNCTION_TRACE (NsExternalizeName);
00604 
00605 
00606     if (!InternalNameLength     ||
00607         !InternalName           ||
00608         !ConvertedName)
00609     {
00610         return_ACPI_STATUS (AE_BAD_PARAMETER);
00611     }
00612 
00613     /* Check for a prefix (one '\' | one or more '^') */
00614 
00615     switch (InternalName[0])
00616     {
00617     case '\\':
00618         PrefixLength = 1;
00619         break;
00620 
00621     case '^':
00622         for (i = 0; i < InternalNameLength; i++)
00623         {
00624             if (InternalName[i] == '^')
00625             {
00626                 PrefixLength = i + 1;
00627             }
00628             else
00629             {
00630                 break;
00631             }
00632         }
00633 
00634         if (i == InternalNameLength)
00635         {
00636             PrefixLength = i;
00637         }
00638 
00639         break;
00640 
00641     default:
00642         break;
00643     }
00644 
00645     /*
00646      * Check for object names. Note that there could be 0-255 of these
00647      * 4-byte elements.
00648      */
00649     if (PrefixLength < InternalNameLength)
00650     {
00651         switch (InternalName[PrefixLength])
00652         {
00653         case AML_MULTI_NAME_PREFIX_OP:
00654 
00655             /* <count> 4-byte names */
00656 
00657             NamesIndex = PrefixLength + 2;
00658             NumSegments = (UINT8)
00659                 InternalName[(ACPI_SIZE) PrefixLength + 1];
00660             break;
00661 
00662         case AML_DUAL_NAME_PREFIX:
00663 
00664             /* Two 4-byte names */
00665 
00666             NamesIndex = PrefixLength + 1;
00667             NumSegments = 2;
00668             break;
00669 
00670         case 0:
00671 
00672             /* NullName */
00673 
00674             NamesIndex = 0;
00675             NumSegments = 0;
00676             break;
00677 
00678         default:
00679 
00680             /* one 4-byte name */
00681 
00682             NamesIndex = PrefixLength;
00683             NumSegments = 1;
00684             break;
00685         }
00686     }
00687 
00688     /*
00689      * Calculate the length of ConvertedName, which equals the length
00690      * of the prefix, length of all object names, length of any required
00691      * punctuation ('.') between object names, plus the NULL terminator.
00692      */
00693     RequiredLength = PrefixLength + (4 * NumSegments) +
00694                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
00695 
00696     /*
00697      * Check to see if we're still in bounds.  If not, there's a problem
00698      * with InternalName (invalid format).
00699      */
00700     if (RequiredLength > InternalNameLength)
00701     {
00702         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
00703         return_ACPI_STATUS (AE_BAD_PATHNAME);
00704     }
00705 
00706     /* Build the ConvertedName */
00707 
00708     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
00709     if (!(*ConvertedName))
00710     {
00711         return_ACPI_STATUS (AE_NO_MEMORY);
00712     }
00713 
00714     j = 0;
00715 
00716     for (i = 0; i < PrefixLength; i++)
00717     {
00718         (*ConvertedName)[j++] = InternalName[i];
00719     }
00720 
00721     if (NumSegments > 0)
00722     {
00723         for (i = 0; i < NumSegments; i++)
00724         {
00725             if (i > 0)
00726             {
00727                 (*ConvertedName)[j++] = '.';
00728             }
00729 
00730             (*ConvertedName)[j++] = InternalName[NamesIndex++];
00731             (*ConvertedName)[j++] = InternalName[NamesIndex++];
00732             (*ConvertedName)[j++] = InternalName[NamesIndex++];
00733             (*ConvertedName)[j++] = InternalName[NamesIndex++];
00734         }
00735     }
00736 
00737     if (ConvertedNameLength)
00738     {
00739         *ConvertedNameLength = (UINT32) RequiredLength;
00740     }
00741 
00742     return_ACPI_STATUS (AE_OK);
00743 }
00744 
00745 
00746 /*******************************************************************************
00747  *
00748  * FUNCTION:    AcpiNsValidateHandle
00749  *
00750  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
00751  *                                namespace node.
00752  *
00753  * RETURN:      A pointer to a namespace node
00754  *
00755  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
00756  *              cases for the root node.
00757  *
00758  * NOTE: Real integer handles would allow for more verification
00759  *       and keep all pointers within this subsystem - however this introduces
00760  *       more overhead and has not been necessary to this point. Drivers
00761  *       holding handles are typically notified before a node becomes invalid
00762  *       due to a table unload.
00763  *
00764  ******************************************************************************/
00765 
00766 ACPI_NAMESPACE_NODE *
00767 AcpiNsValidateHandle (
00768     ACPI_HANDLE             Handle)
00769 {
00770 
00771     ACPI_FUNCTION_ENTRY ();
00772 
00773 
00774     /* Parameter validation */
00775 
00776     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
00777     {
00778         return (AcpiGbl_RootNode);
00779     }
00780 
00781     /* We can at least attempt to verify the handle */
00782 
00783     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
00784     {
00785         return (NULL);
00786     }
00787 
00788     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
00789 }
00790 
00791 
00792 /*******************************************************************************
00793  *
00794  * FUNCTION:    AcpiNsTerminate
00795  *
00796  * PARAMETERS:  none
00797  *
00798  * RETURN:      none
00799  *
00800  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
00801  *
00802  ******************************************************************************/
00803 
00804 void
00805 AcpiNsTerminate (
00806     void)
00807 {
00808     ACPI_OPERAND_OBJECT     *ObjDesc;
00809 
00810 
00811     ACPI_FUNCTION_TRACE (NsTerminate);
00812 
00813 
00814     /*
00815      * 1) Free the entire namespace -- all nodes and objects
00816      *
00817      * Delete all object descriptors attached to namepsace nodes
00818      */
00819     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
00820 
00821     /* Detach any objects attached to the root */
00822 
00823     ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
00824     if (ObjDesc)
00825     {
00826         AcpiNsDetachObject (AcpiGbl_RootNode);
00827     }
00828 
00829     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
00830     return_VOID;
00831 }
00832 
00833 
00834 /*******************************************************************************
00835  *
00836  * FUNCTION:    AcpiNsOpensScope
00837  *
00838  * PARAMETERS:  Type        - A valid namespace type
00839  *
00840  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
00841  *              to the ACPI specification, else 0
00842  *
00843  ******************************************************************************/
00844 
00845 UINT32
00846 AcpiNsOpensScope (
00847     ACPI_OBJECT_TYPE        Type)
00848 {
00849     ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type));
00850 
00851 
00852     if (!AcpiUtValidObjectType (Type))
00853     {
00854         /* type code out of range  */
00855 
00856         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
00857         return_UINT32 (ACPI_NS_NORMAL);
00858     }
00859 
00860     return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
00861 }
00862 
00863 
00864 /*******************************************************************************
00865  *
00866  * FUNCTION:    AcpiNsGetNode
00867  *
00868  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
00869  *                            \ (backslash) and ^ (carat) prefixes, and the
00870  *                            . (period) to separate segments are supported.
00871  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
00872  *                            root of the name space.  If Name is fully
00873  *                            qualified (first INT8 is '\'), the passed value
00874  *                            of Scope will not be accessed.
00875  *              Flags       - Used to indicate whether to perform upsearch or
00876  *                            not.
00877  *              ReturnNode  - Where the Node is returned
00878  *
00879  * DESCRIPTION: Look up a name relative to a given scope and return the
00880  *              corresponding Node.  NOTE: Scope can be null.
00881  *
00882  * MUTEX:       Locks namespace
00883  *
00884  ******************************************************************************/
00885 
00886 ACPI_STATUS
00887 AcpiNsGetNode (
00888     ACPI_NAMESPACE_NODE     *PrefixNode,
00889     const char              *Pathname,
00890     UINT32                  Flags,
00891     ACPI_NAMESPACE_NODE     **ReturnNode)
00892 {
00893     ACPI_GENERIC_STATE      ScopeInfo;
00894     ACPI_STATUS             Status;
00895     char                    *InternalPath;
00896 
00897 
00898     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
00899 
00900 
00901     if (!Pathname)
00902     {
00903         *ReturnNode = PrefixNode;
00904         if (!PrefixNode)
00905         {
00906             *ReturnNode = AcpiGbl_RootNode;
00907         }
00908         return_ACPI_STATUS (AE_OK);
00909     }
00910 
00911     /* Convert path to internal representation */
00912 
00913     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
00914     if (ACPI_FAILURE (Status))
00915     {
00916         return_ACPI_STATUS (Status);
00917     }
00918 
00919     /* Must lock namespace during lookup */
00920 
00921     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
00922     if (ACPI_FAILURE (Status))
00923     {
00924         goto Cleanup;
00925     }
00926 
00927     /* Setup lookup scope (search starting point) */
00928 
00929     ScopeInfo.Scope.Node = PrefixNode;
00930 
00931     /* Lookup the name in the namespace */
00932 
00933     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
00934                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
00935                 NULL, ReturnNode);
00936     if (ACPI_FAILURE (Status))
00937     {
00938         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
00939                 Pathname, AcpiFormatException (Status)));
00940     }
00941 
00942     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
00943 
00944 Cleanup:
00945     ACPI_FREE (InternalPath);
00946     return_ACPI_STATUS (Status);
00947 }

Generated on Sun May 27 2012 04:27:21 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.