|
|
/*++
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; }
|