mirror of
https://github.com/reactos/reactos.git
synced 2024-09-20 01:31:34 +00:00
c501d8112c
svn path=/branches/aicom-network-fixes/; revision=34994
246 lines
6.2 KiB
C
246 lines
6.2 KiB
C
/*******************************************************************************
|
|
*
|
|
* Module Name: nsnames - Name manipulation and search
|
|
* $Revision: 1.1 $
|
|
*
|
|
******************************************************************************/
|
|
|
|
/*
|
|
* Copyright (C) 2000, 2001 R. Byron Moore
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
|
|
#include <acpi.h>
|
|
|
|
#define _COMPONENT ACPI_NAMESPACE
|
|
MODULE_NAME ("nsnames")
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: Acpi_ns_get_table_pathname
|
|
*
|
|
* PARAMETERS: Node - Scope whose name is needed
|
|
*
|
|
* RETURN: Pointer to storage containing the fully qualified name of
|
|
* the scope, in Label format (all segments strung together
|
|
* with no separators)
|
|
*
|
|
* DESCRIPTION: Used for debug printing in Acpi_ns_search_table().
|
|
*
|
|
******************************************************************************/
|
|
|
|
NATIVE_CHAR *
|
|
acpi_ns_get_table_pathname (
|
|
ACPI_NAMESPACE_NODE *node)
|
|
{
|
|
NATIVE_CHAR *name_buffer;
|
|
u32 size;
|
|
ACPI_NAME name;
|
|
ACPI_NAMESPACE_NODE *child_node;
|
|
ACPI_NAMESPACE_NODE *parent_node;
|
|
|
|
|
|
if (!acpi_gbl_root_node || !node) {
|
|
/*
|
|
* If the name space has not been initialized,
|
|
* this function should not have been called.
|
|
*/
|
|
return (NULL);
|
|
}
|
|
|
|
child_node = node->child;
|
|
|
|
|
|
/* Calculate required buffer size based on depth below root */
|
|
|
|
size = 1;
|
|
parent_node = child_node;
|
|
while (parent_node) {
|
|
parent_node = acpi_ns_get_parent_object (parent_node);
|
|
if (parent_node) {
|
|
size += ACPI_NAME_SIZE;
|
|
}
|
|
}
|
|
|
|
|
|
/* Allocate a buffer to be returned to caller */
|
|
|
|
name_buffer = acpi_cm_callocate (size + 1);
|
|
if (!name_buffer) {
|
|
REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n"));
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
/* Store terminator byte, then build name backwards */
|
|
|
|
name_buffer[size] = '\0';
|
|
while ((size > ACPI_NAME_SIZE) &&
|
|
acpi_ns_get_parent_object (child_node)) {
|
|
size -= ACPI_NAME_SIZE;
|
|
name = acpi_ns_find_parent_name (child_node);
|
|
|
|
/* Put the name into the buffer */
|
|
|
|
MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name);
|
|
child_node = acpi_ns_get_parent_object (child_node);
|
|
}
|
|
|
|
name_buffer[--size] = AML_ROOT_PREFIX;
|
|
|
|
|
|
return (name_buffer);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: Acpi_ns_get_pathname_length
|
|
*
|
|
* PARAMETERS: Node - Namespace node
|
|
*
|
|
* RETURN: Length of path, including prefix
|
|
*
|
|
* DESCRIPTION: Get the length of the pathname string for this node
|
|
*
|
|
******************************************************************************/
|
|
|
|
u32
|
|
acpi_ns_get_pathname_length (
|
|
ACPI_NAMESPACE_NODE *node)
|
|
{
|
|
u32 size;
|
|
ACPI_NAMESPACE_NODE *next_node;
|
|
|
|
/*
|
|
* Compute length of pathname as 5 * number of name segments.
|
|
* Go back up the parent tree to the root
|
|
*/
|
|
for (size = 0, next_node = node;
|
|
acpi_ns_get_parent_object (next_node);
|
|
next_node = acpi_ns_get_parent_object (next_node)) {
|
|
size += PATH_SEGMENT_LENGTH;
|
|
}
|
|
|
|
/* Special case for size still 0 - no parent for "special" nodes */
|
|
|
|
if (!size) {
|
|
size = PATH_SEGMENT_LENGTH;
|
|
}
|
|
|
|
return (size + 1);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* FUNCTION: Acpi_ns_handle_to_pathname
|
|
*
|
|
* PARAMETERS: Target_handle - Handle of named object whose name is
|
|
* to be found
|
|
* Buf_size - Size of the buffer provided
|
|
* User_buffer - Where the pathname is returned
|
|
*
|
|
* RETURN: Status, Buffer is filled with pathname if status is AE_OK
|
|
*
|
|
* DESCRIPTION: Build and return a full namespace pathname
|
|
*
|
|
* MUTEX: Locks Namespace
|
|
*
|
|
******************************************************************************/
|
|
|
|
ACPI_STATUS
|
|
acpi_ns_handle_to_pathname (
|
|
ACPI_HANDLE target_handle,
|
|
u32 *buf_size,
|
|
NATIVE_CHAR *user_buffer)
|
|
{
|
|
ACPI_STATUS status = AE_OK;
|
|
ACPI_NAMESPACE_NODE *node;
|
|
u32 path_length;
|
|
u32 user_buf_size;
|
|
ACPI_NAME name;
|
|
u32 size;
|
|
|
|
|
|
if (!acpi_gbl_root_node || !target_handle) {
|
|
/*
|
|
* If the name space has not been initialized,
|
|
* this function should not have been called.
|
|
*/
|
|
|
|
return (AE_NO_NAMESPACE);
|
|
}
|
|
|
|
node = acpi_ns_convert_handle_to_entry (target_handle);
|
|
if (!node) {
|
|
return (AE_BAD_PARAMETER);
|
|
}
|
|
|
|
|
|
/* Set return length to the required path length */
|
|
|
|
path_length = acpi_ns_get_pathname_length (node);
|
|
size = path_length - 1;
|
|
|
|
user_buf_size = *buf_size;
|
|
*buf_size = path_length;
|
|
|
|
/* Check if the user buffer is sufficiently large */
|
|
|
|
if (path_length > user_buf_size) {
|
|
status = AE_BUFFER_OVERFLOW;
|
|
goto exit;
|
|
}
|
|
|
|
/* Store null terminator */
|
|
|
|
user_buffer[size] = 0;
|
|
size -= ACPI_NAME_SIZE;
|
|
|
|
/* Put the original ACPI name at the end of the path */
|
|
|
|
MOVE_UNALIGNED32_TO_32 ((user_buffer + size),
|
|
&node->name);
|
|
|
|
user_buffer[--size] = PATH_SEPARATOR;
|
|
|
|
/* Build name backwards, putting "." between segments */
|
|
|
|
while ((size > ACPI_NAME_SIZE) && node) {
|
|
size -= ACPI_NAME_SIZE;
|
|
name = acpi_ns_find_parent_name (node);
|
|
MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &name);
|
|
|
|
user_buffer[--size] = PATH_SEPARATOR;
|
|
node = acpi_ns_get_parent_object (node);
|
|
}
|
|
|
|
/*
|
|
* Overlay the "." preceding the first segment with
|
|
* the root name "\"
|
|
*/
|
|
|
|
user_buffer[size] = '\\';
|
|
|
|
exit:
|
|
return (status);
|
|
}
|
|
|
|
|