windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/kdext/unamespac.c

753 lines
16 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
namespac.c
Abstract:
This file contains all of the namespace handling functions
Author:
Based on code by Mike Tsang (MikeTs)
Stephane Plante (Splante)
Environment:
User mode only
Revision History:
--*/
#include "pch.h"
PNSOBJ RootNameSpaceObject;
PNSOBJ CurrentScopeNameSpaceObject;
PNSOBJ CurrentOwnerNameSpaceObject;
NTSTATUS
CreateNameSpaceObject(
PUCHAR ObjectName,
PNSOBJ ObjectScope,
PNSOBJ ObjectOwner,
PNSOBJ *Object,
ULONG Flags
)
/*++
Routine Description:
This routine creates a name space object under the current scope
Arguments:
ObjectName - Name Path String
ObjectScope - Scope to start the search from (NULL == Root)
ObjectOwner - The object which owns this one
Object - Where to store the point to the object that we just created
Flags - Options
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PNSOBJ localObject;
ENTER( (
3,
"CreateNameSpaceObject(%s,Scope=%s,Owner=%p,Object=%p,"
"Flag=%08lx)\n",
ObjectName,
(ObjectScope ? LocalGetObjectPath( ObjectScope ) : "ROOT"),
ObjectOwner,
Object,
Flags
) );
if (ObjectScope == NULL) {
ObjectScope = RootNameSpaceObject;
}
status = GetNameSpaceObject(
ObjectName,
ObjectScope,
&localObject,
NSF_LOCAL_SCOPE
);
if (NT_SUCCESS(status)) {
if (!(Flags & NSF_EXIST_OK)) {
status = STATUS_OBJECT_NAME_COLLISION;
}
} else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
status = STATUS_SUCCESS;
//
// Are we creating root?
//
if (strcmp(ObjectName,"\\") == 0) {
ASSERT( RootNameSpaceObject == NULL );
ASSERT( ObjectOwner == NULL );
localObject = MEMALLOC( sizeof(NSOBJ) );
if (localObject == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
} else {
memset( localObject, 0, sizeof(NSOBJ) );
localObject->dwSig = SIG_NSOBJ;
localObject->dwNameSeg = NAMESEG_ROOT;
RootNameSpaceObject = localObject;
}
} else {
PUCHAR nameEnd;
PNSOBJ objectParent;
nameEnd = strrchr(ObjectName, '.');
if (nameEnd != NULL) {
*nameEnd = '\0';
nameEnd++;
status = GetNameSpaceObject(
ObjectName,
ObjectScope,
&objectParent,
NSF_LOCAL_SCOPE
);
} else if (*ObjectName == '\\') {
nameEnd = &ObjectName[1];
ASSERT( RootNameSpaceObject != NULL );
objectParent = RootNameSpaceObject;
} else if (*ObjectName == '^') {
nameEnd = ObjectName;
objectParent = ObjectScope;
while ( (*nameEnd == '^') && (objectParent != NULL)) {
objectParent = objectParent->pnsParent;
nameEnd++;
}
} else {
ASSERT( ObjectScope );
nameEnd = ObjectName;
objectParent = ObjectScope;
}
if (status == STATUS_SUCCESS) {
ULONG length = strlen(nameEnd);
localObject = MEMALLOC( sizeof(NSOBJ) );
if (localObject == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
} else if ( (*nameEnd != '\0') && (length > sizeof(NAMESEG))) {
status = STATUS_OBJECT_NAME_INVALID;
MEMFREE( localObject );
} else {
memset( localObject, 0, sizeof(NSOBJ) );
localObject->dwSig = SIG_NSOBJ;
localObject->dwNameSeg = NAMESEG_BLANK;
memcpy( &(localObject->dwNameSeg), nameEnd, length );
localObject->hOwner = ObjectOwner;
localObject->pnsParent = objectParent;
ListInsertTail(
&(localObject->list),
(PPLIST) &(objectParent->pnsFirstChild)
);
}
}
}
}
if (NT_SUCCESS(status) && Object != NULL) {
*Object = localObject;
}
EXIT( (
3,
"CreateNameSpaceObject=%08lx (*Object=%p)\n",
status,
localObject
) );
return status;
}
NTSTATUS
CreateObject(
PUCHAR ObjectName,
UCHAR ObjectType,
PNSOBJ *Object
)
/*++
Routine Description:
Creates a NameSpace Object for the term
Arguments:
ObjectName - The name object object
ObjectType - The type of object to create
Object - Where to store a pointer to the created object
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PNSOBJ localObject;
ENTER( (
2,
"CreateObject(%s,Type=%02x,Object=%p)\n",
ObjectName,
ObjectType,
Object
) );
status = CreateNameSpaceObject(
ObjectName,
CurrentScopeNameSpaceObject,
CurrentOwnerNameSpaceObject,
&localObject,
NSF_EXIST_OK
);
if (NT_SUCCESS(status)) {
switch (ObjectType) {
case NSTYPE_UNKNOWN:
break;
case NSTYPE_FIELDUNIT:
localObject->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
break;
case NSTYPE_DEVICE:
localObject->ObjData.dwDataType = OBJTYPE_DEVICE;
break;
case NSTYPE_EVENT:
localObject->ObjData.dwDataType = OBJTYPE_EVENT;
break;
case NSTYPE_METHOD:
localObject->ObjData.dwDataType = OBJTYPE_METHOD;
break;
case NSTYPE_MUTEX:
localObject->ObjData.dwDataType = OBJTYPE_MUTEX;
break;
case NSTYPE_OPREGION:
localObject->ObjData.dwDataType = OBJTYPE_OPREGION;
break;
case NSTYPE_POWERRES:
localObject->ObjData.dwDataType = OBJTYPE_POWERRES;
break;
case NSTYPE_PROCESSOR:
localObject->ObjData.dwDataType = OBJTYPE_PROCESSOR;
break;
case NSTYPE_THERMALZONE:
localObject->ObjData.dwDataType = OBJTYPE_THERMALZONE;
break;
case NSTYPE_OBJALIAS:
localObject->ObjData.dwDataType = OBJTYPE_OBJALIAS;
break;
case NSTYPE_BUFFFIELD:
localObject->ObjData.dwDataType = OBJTYPE_BUFFFIELD;
break;
default:
status = STATUS_OBJECT_TYPE_MISMATCH;
}
if (Object != NULL) {
*Object = localObject;
}
}
EXIT( (
2,
"CreateObject=%08lx (*Object=%p)\n",
status,
localObject
) );
return status;
} //CreateObject
NTSTATUS
GetNameSpaceObject(
PUCHAR ObjectPath,
PNSOBJ ScopeObject,
PNSOBJ *NameObject,
ULONG Flags
)
/*++
Routine Description:
This routine searches the namespace until it finds a matching object
Arguments:
ObjectPath - String with the Name to search for
ScopeObject - Scope to start search at (NULL == ROOT)
NameObject - Where to store the object, if found
Flags - Options
Return Value:
NTSTATUS
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PUCHAR subPath;
ENTER( (
3,
"GetNameSpaceObject(%s,Scope=%s,Object=%p,Flags=%08lx\n",
ObjectPath,
(ScopeObject ? LocalGetObjectPath( ScopeObject ) : "ROOT"),
NameObject,
Flags
) );
if (ScopeObject == NULL) {
ScopeObject = RootNameSpaceObject;
}
if (*ObjectPath == '\\') {
subPath = &ObjectPath[1];
ScopeObject = RootNameSpaceObject;
} else {
subPath = ObjectPath;
while ( (*subPath == '^') && (ScopeObject != NULL)) {
subPath++;
ScopeObject = ScopeObject->pnsParent;
}
}
*NameObject = ScopeObject;
if (ScopeObject == NULL) {
status = STATUS_OBJECT_NAME_NOT_FOUND;
} else if (*subPath != '\0') {
BOOL searchUp;
PNSOBJ tempObject;
searchUp = (BOOL) ( !(Flags & NSF_LOCAL_SCOPE) &&
(ObjectPath[0] != '\\') &&
(ObjectPath[0] != '^') &&
(strlen(ObjectPath) <= sizeof(NAMESEG)) );
while (1) {
do {
tempObject = ScopeObject->pnsFirstChild;
if (tempObject == NULL) {
status = STATUS_OBJECT_NAME_NOT_FOUND;
INFO( (5, "GetNameSpaceObject - %s has no children\n",
LocalGetObjectPath( tempObject ) ) );
} else {
BOOL found;
PUCHAR bufferEnd;
ULONG length;
NAMESEG dwNameSeg;
bufferEnd = strchr( subPath, '.' );
if (bufferEnd != NULL) {
length = (ULONG)(bufferEnd - subPath);
} else {
length = strlen(subPath);
}
if (length > sizeof(NAMESEG)) {
status = STATUS_OBJECT_NAME_INVALID;
found = FALSE;
} else {
dwNameSeg = NAMESEG_BLANK;
memcpy( &dwNameSeg, subPath, length );
INFO( (5, "GetNameSpaceObject - Looking for %*s\n",
length, subPath) );
//
// search all sibling fors a matching nameSeg
//
found = FALSE;
do {
INFO( (5, "GetNameSpaceObject - look at %s\n",
LocalGetObjectPath( tempObject ) ) );
if (tempObject->dwNameSeg == dwNameSeg) {
ScopeObject = tempObject;
found = TRUE;
break;
}
tempObject = (PNSOBJ) tempObject->list.plistNext;
} while (tempObject != tempObject->pnsParent->pnsFirstChild );
}
if (status == STATUS_SUCCESS) {
if (!found) {
status = STATUS_OBJECT_NAME_NOT_FOUND;
} else {
subPath += length;
if (*subPath == '.') {
subPath++;
} else if (*subPath == '\0') {
*NameObject = ScopeObject;
break;
}
}
}
}
} while ( status == STATUS_SUCCESS );
if (status == STATUS_OBJECT_NAME_NOT_FOUND && searchUp &&
ScopeObject != NULL && ScopeObject->pnsParent != NULL) {
INFO( (5, "GetNameSpaceObject - Changing Scope to %s\n",
LocalGetObjectPath( ScopeObject->pnsParent ) ) );
ScopeObject = ScopeObject->pnsParent;
status = STATUS_SUCCESS;
} else {
break;
}
}
}
if (status != STATUS_SUCCESS) {
*NameObject = NULL;
}
EXIT( (
3,
"GetNameSpaceObject=%08lx (*Object=%p)\n",
status,
*NameObject
) );
return status;
}
PUCHAR
GetObjectTypeName(
ULONG ObjectType
)
/*++
Routine Description:
Returns a string which corresponds to the type object the object
Arugment:
ObjectType - The type that we wish to know about
Return Value:
Globally Available String
--*/
{
PUCHAR type = NULL;
ULONG i;
static struct {
ULONG ObjectType;
PUCHAR ObjectTypeName;
} ObjectTypeTable[] =
{
OBJTYPE_UNKNOWN, "Unknown",
OBJTYPE_INTDATA, "Integer",
OBJTYPE_STRDATA, "String",
OBJTYPE_BUFFDATA, "Buffer",
OBJTYPE_PKGDATA, "Package",
OBJTYPE_FIELDUNIT, "FieldUnit",
OBJTYPE_DEVICE, "Device",
OBJTYPE_EVENT, "Event",
OBJTYPE_METHOD, "Method",
OBJTYPE_MUTEX, "Mutex",
OBJTYPE_OPREGION, "OpRegion",
OBJTYPE_POWERRES, "PowerResource",
OBJTYPE_PROCESSOR, "Processor",
OBJTYPE_THERMALZONE,"ThermalZone",
OBJTYPE_BUFFFIELD, "BuffField",
OBJTYPE_DDBHANDLE, "DDBHandle",
OBJTYPE_DEBUG, "Debug",
OBJTYPE_OBJALIAS, "ObjAlias",
OBJTYPE_DATAALIAS, "DataAlias",
OBJTYPE_BANKFIELD, "BankField",
OBJTYPE_FIELD, "Field",
OBJTYPE_INDEXFIELD, "IndexField",
OBJTYPE_DATA, "Data",
OBJTYPE_DATAFIELD, "DataField",
OBJTYPE_DATAOBJ, "DataObject",
OBJTYPE_PNP_RES, "PNPResource",
OBJTYPE_RES_FIELD, "ResField",
0, NULL
};
ENTER( (4, "GetObjectTypeName(Type=%02x)\n", ObjectType ) );
for (i = 0; ObjectTypeTable[i].ObjectTypeName != NULL; i++) {
if (ObjectType == ObjectTypeTable[i].ObjectType) {
type = ObjectTypeTable[i].ObjectTypeName;
break;
}
}
EXIT( (4, "GetObjectTypeName=%s\n", type ? type : "NULL" ) );
return type;
}
PUCHAR
LocalGetObjectPath(
PNSOBJ NameObject
)
/*++
Routine Description:
This routine takes a NameSpace Object and returns a string to represent
its path
Arguments:
NameObject - The object whose path we want
Return Value:
Pointer to the string which represents the path
--*/
{
static UCHAR namePath[MAX_NAME_LEN + 1] = {0};
ULONG i;
ENTER( (6, "LocalGetObjectPath(Object=%p)\n", NameObject ) );
if (NameObject != NULL) {
if (NameObject->pnsParent == NULL) {
strcpy(namePath, "\\");
} else {
LocalGetObjectPath(NameObject->pnsParent);
if (NameObject->pnsParent->pnsParent != NULL) {
strcat(namePath, ".");
}
strncat(namePath, (PUCHAR)&NameObject->dwNameSeg, sizeof(NAMESEG));
}
for (i = strlen(namePath) - 1; i >= 0; --i) {
if (namePath[i] == '_') {
namePath[i] = '\0';
} else {
break;
}
}
} else {
namePath[0] = '\0';
}
EXIT( (6, "LocalGetObjectPath=%s\n", namePath ) );
return namePath;
}
PUCHAR
RemoteGetObjectPath(
ULONG_PTR ObjectAddress
)
/*++
Routine Description:
This routine takes a NameSpace Object and returns a string to represent
its path
Arguments:
NameObject - The object whose path we want
Return Value:
Pointer to the string which represents the path
--*/
{
static UCHAR namePath[MAX_NAME_LEN + 1] = {0};
NSOBJ nameObject;
ULONG i;
ENTER( (6, "RemoteGetObjectPath(Object=%p)\n", ObjectAddress ) );
if (ObjectAddress != 0 && ReadMemory( ObjectAddress, &nameObject, sizeof(nameObject), NULL) ) {
if (nameObject.pnsParent == NULL) {
strcpy(namePath, "\\");
} else {
RemoteGetObjectPath( (ULONG_PTR) nameObject.pnsParent);
if (strlen(namePath) > 1) {
strcat(namePath, ".");
}
strncat(namePath, (PUCHAR)&nameObject.dwNameSeg, sizeof(NAMESEG));
}
for (i = strlen(namePath) - 1; i >= 0; --i) {
if (namePath[i] == '_') {
namePath[i] = '\0';
} else {
break;
}
}
} else {
namePath[0] = '\0';
}
EXIT( (6, "RemoteGetObjectPath=%s\n", namePath ) );
return namePath;
}