Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

997 lines
20 KiB

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
exclist.c
Abstract:
Implements a set of APIs to manage exclusion lists of objects
of various well-known types.
Author:
Ovidiu Temereanca (ovidiut) 23-Nov-1999
Revision History:
<alias> <date> <comments>
--*/
#include "pch.h"
//
// Includes
//
// None
#define DBG_EXCLIST "ExcList"
//
// Strings
//
#define S_EXCLUSIONLIST "ExcList"
//
// Constants
//
// None
//
// Macros
//
#define pAllocateMemory(Size) PmGetMemory (g_ElPool,Size)
#define pFreeMemory(Buffer) if (Buffer) PmReleaseMemory (g_ElPool, (PVOID)Buffer)
//
// Types
//
typedef struct {
DWORD TypeId;
PCSTR TypeName;
} EXCLISTPROPS, *PEXCLISTPROPS;
//
// Globals
//
PMHANDLE g_ElPool;
GROWLIST* g_ElTypeLists;
//
// Macro expansion list
//
// Defined in exclist.h
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
#define DEFMAC(TypeId,TypeName) TypeId, TypeName,
EXCLISTPROPS g_ExcListProps [] = {
EXCLUSIONLIST_TYPES /* , */
ELT_LAST, NULL
};
#undef DEFMAC
//
// Code
//
BOOL
ElInitialize (
VOID
)
/*++
Routine Description:
ElInitialize initializes this library.
Arguments:
none
Return Value:
TRUE if the init was successful.
FALSE if not. GetLastError() returns extended error info.
--*/
{
MYASSERT (!g_ElPool);
g_ElPool = PmCreateNamedPool (S_EXCLUSIONLIST);
if (!g_ElPool) {
return FALSE;
}
MYASSERT (!g_ElTypeLists);
g_ElTypeLists = pAllocateMemory (ELT_LAST * DWSIZEOF (GROWLIST));
MYASSERT (g_ElTypeLists);
ZeroMemory (g_ElTypeLists, ELT_LAST * DWSIZEOF (GROWLIST));
return TRUE;
}
/*++
Routine Description:
ElTerminate is called to free resources used by this lib.
Arguments:
none
Return Value:
none
--*/
VOID
ElTerminateA (
VOID
)
{
ElRemoveAllA ();
if (g_ElTypeLists) {
pFreeMemory (g_ElTypeLists);
g_ElTypeLists = NULL;
}
if (g_ElPool) {
PmDestroyPool (g_ElPool);
g_ElPool = NULL;
}
}
VOID
ElTerminateW (
VOID
)
{
ElRemoveAllW ();
if (g_ElTypeLists) {
pFreeMemory (g_ElTypeLists);
g_ElTypeLists = NULL;
}
if (g_ElPool) {
PmDestroyPool (g_ElPool);
g_ElPool = NULL;
}
}
/*++
Routine Description:
ElGetTypeId returns the TypeId of a type given by name
Arguments:
TypeName - Specifies the name
Return Value:
One of DWORD enumeration values
--*/
DWORD
ElGetTypeId (
IN PCSTR TypeName
)
{
UINT u;
if (TypeName) {
for (u = 0; g_ExcListProps[u].TypeName; u++) {
if (StringIMatchA (g_ExcListProps[u].TypeName, TypeName)) {
return g_ExcListProps[u].TypeId;
}
}
}
return ELT_LAST;
}
/*++
Routine Description:
ElGetTypeName returns the type name of a type given by TypeId
Arguments:
TypeId - Specifies the ID
Return Value:
A pointer to one of the known type names or NULL if TypeId is unknown
--*/
PCSTR
ElGetTypeName (
IN DWORD TypeId
)
{
MYASSERT (TypeId < ELT_LAST);
if (TypeId >= ELT_LAST) {
return NULL;
}
return g_ExcListProps[TypeId].TypeName;
}
/*++
Routine Description:
ElAdd adds the given object of the given type to the exclusion list. The object
is first parsed so that the decision if a given string matches this pattern is faster.
Arguments:
ObjectType - Specifies the object type
ObjectName - Specifies the object pattern string
Return Value:
TRUE if the string pattern was successfully parsed and added to the list
--*/
BOOL
ElAddA (
IN DWORD ObjectType,
IN PCSTR ObjectName
)
{
POBSPARSEDPATTERNA pp;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (ObjectName);
//
// add each object in its own type list
//
pp = ObsCreateParsedPatternExA (NULL, ObjectName, ObjectType == ELT_FILE);
if (!pp) {
DEBUGMSGA ((
DBG_EXCLIST,
"ElAddA: Bad ObjectName: %s (type %s)",
ObjectName,
ElGetTypeName (ObjectType)
));
return FALSE;
}
//
// add the pointer to the list
//
GlAppend (&g_ElTypeLists[ObjectType], (PBYTE)&pp, DWSIZEOF (pp));
DEBUGMSGA ((
DBG_EXCLIST,
"ElAddA: Added excluded %s as type %s",
ObjectName,
ElGetTypeName (ObjectType)
));
return TRUE;
}
BOOL
ElAddW (
IN DWORD ObjectType,
IN PCWSTR ObjectName
)
{
POBSPARSEDPATTERNW pp;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (ObjectName);
//
// add each object in its own type list
//
pp = ObsCreateParsedPatternExW (NULL, ObjectName, ObjectType == ELT_FILE);
if (!pp) {
DEBUGMSGW ((
DBG_EXCLIST,
"ElAddW: Bad ObjectName: %s (type %hs)",
ObjectName,
ElGetTypeName (ObjectType)
));
return FALSE;
}
//
// add the pointer to the list
//
GlAppend (&g_ElTypeLists[ObjectType], (PBYTE)&pp, DWSIZEOF (pp));
DEBUGMSGW ((
DBG_EXCLIST,
"ElAddW: Added excluded %s as type %hs",
ObjectName,
ElGetTypeName (ObjectType)
));
return TRUE;
}
/*++
Routine Description:
ElRemoveAll removes all object patterns from the exclusion list.
Arguments:
none
Return Value:
none
--*/
VOID
ElRemoveAllA (
VOID
)
{
PGROWLIST gl;
UINT u;
UINT i;
if (g_ElTypeLists) {
for (u = 0; u < ELT_LAST; u++) {
gl = &g_ElTypeLists[u];
for (i = GlGetSize (gl); i > 0; i--) {
ObsDestroyParsedPatternA (*(POBSPARSEDPATTERNA*) GlGetItem (gl, i - 1));
GlDeleteItem (gl, i - 1);
}
GlFree (gl);
}
ZeroMemory (g_ElTypeLists, ELT_LAST * DWSIZEOF (GROWLIST));
}
}
VOID
ElRemoveAllW (
VOID
)
{
PGROWLIST gl;
UINT u;
UINT i;
if (g_ElTypeLists) {
for (u = 0; u < ELT_LAST; u++) {
gl = &g_ElTypeLists[u];
for (i = GlGetSize (gl); i > 0; i--) {
ObsDestroyParsedPatternW (*(POBSPARSEDPATTERNW*) GlGetItem (gl, i - 1));
GlDeleteItem (gl, i - 1);
}
GlFree (gl);
}
ZeroMemory (g_ElTypeLists, ELT_LAST * DWSIZEOF (GROWLIST));
}
}
/*++
Routine Description:
ElIsExcluded decides if the given object string is excluded (if it matches one of the
patterns added previously).
Arguments:
ObjectType - Specifies the object type
Object - Specifies the object string
Return Value:
TRUE if the string is excluded
--*/
BOOL
ElIsExcludedA (
IN DWORD ObjectType,
IN PCSTR Object
)
{
PGROWLIST gl;
POBSPARSEDPATTERNA pp;
UINT i;
PSTR node;
PSTR leaf;
BOOL b = FALSE;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (Object);
if (!Object) {
return FALSE;
}
//
// lookup each object in its own type list
//
gl = &g_ElTypeLists[ObjectType];
if (!ObsSplitObjectStringExA (Object, &node, &leaf, g_ElPool, FALSE)) {
DEBUGMSGA ((DBG_EXCLIST, "ElIsExcludedA: invalid Object: \"%s\"", Object));
return FALSE;
}
for (i = GlGetSize (gl); i > 0; i--) {
pp = *(POBSPARSEDPATTERNA*) GlGetItem (gl, i - 1);
//
// if stored pattern doesn't contain a node,
// that means "any node matches"
//
if (pp->NodePattern && !node) {
continue;
}
if (!pp->LeafPattern && leaf || pp->LeafPattern && !leaf) {
continue;
}
if (leaf) {
MYASSERT (pp->LeafPattern);
if (!TestParsedPatternA (pp->LeafPattern, leaf)) {
continue;
}
}
if (pp->NodePattern && !TestParsedPatternA (pp->NodePattern, node)) {
continue;
}
//
// the patterns match!
//
b = TRUE;
break;
}
pFreeMemory (node);
pFreeMemory (leaf);
return b;
}
BOOL
ElIsExcludedW (
IN DWORD ObjectType,
IN PCWSTR Object
)
{
PGROWLIST gl;
POBSPARSEDPATTERNW pp;
UINT i;
PWSTR node;
PWSTR leaf;
BOOL b = FALSE;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (Object);
if (!Object) {
return FALSE;
}
//
// lookup each object in its own type list
//
gl = &g_ElTypeLists[ObjectType];
if (!ObsSplitObjectStringExW (Object, &node, &leaf, g_ElPool, FALSE)) {
DEBUGMSGW ((DBG_EXCLIST, "ElIsExcludedW: invalid Object: \"%s\"", Object));
return FALSE;
}
for (i = GlGetSize (gl); i > 0; i--) {
pp = *(POBSPARSEDPATTERNW*) GlGetItem (gl, i - 1);
//
// if stored pattern doesn't contain a node,
// that means "any node matches"
//
if (pp->NodePattern && !node) {
continue;
}
if (!pp->LeafPattern && leaf || pp->LeafPattern && !leaf) {
continue;
}
if (leaf) {
MYASSERT (pp->LeafPattern);
if (!TestParsedPatternW (pp->LeafPattern, leaf)) {
continue;
}
}
if (pp->NodePattern && !TestParsedPatternW (pp->NodePattern, node)) {
continue;
}
//
// the patterns match!
//
b = TRUE;
break;
}
pFreeMemory (node);
pFreeMemory (leaf);
return b;
}
/*++
Routine Description:
ElIsExcluded2 decides if the object given by its 2 components is excluded
(if it matches one of the patterns added previously).
Arguments:
ObjectType - Specifies the object type
Node - Specifies the node part of the object
Leaf - Specifies the leaf part of the object; optional
Return Value:
TRUE if the string is excluded
--*/
BOOL
ElIsExcluded2A (
IN DWORD ObjectType,
IN PCSTR Node, OPTIONAL
IN PCSTR Leaf OPTIONAL
)
{
PGROWLIST gl;
POBSPARSEDPATTERNA pp;
UINT i;
//
// validate params
//
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
gl = &g_ElTypeLists[ObjectType];
for (i = GlGetSize (gl); i > 0; i--) {
pp = *(POBSPARSEDPATTERNA*) GlGetItem (gl, i - 1);
//
// if stored pattern doesn't contain a node,
// that means "any node matches"
//
if (pp->NodePattern && !Node) {
continue;
}
if (!pp->LeafPattern && Leaf || pp->LeafPattern && !Leaf) {
continue;
}
if (Leaf) {
MYASSERT (pp->LeafPattern);
if (!TestParsedPatternA (pp->LeafPattern, Leaf)) {
continue;
}
}
if (pp->NodePattern && !TestParsedPatternA (pp->NodePattern, Node)) {
continue;
}
//
// the patterns match!
//
return TRUE;
}
return FALSE;
}
BOOL
ElIsExcluded2W (
IN DWORD ObjectType,
IN PCWSTR Node, OPTIONAL
IN PCWSTR Leaf OPTIONAL
)
{
PGROWLIST gl;
POBSPARSEDPATTERNW pp;
UINT i;
//
// validate params
//
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
gl = &g_ElTypeLists[ObjectType];
for (i = GlGetSize (gl); i > 0; i--) {
pp = *(POBSPARSEDPATTERNW*) GlGetItem (gl, i - 1);
//
// if stored pattern doesn't contain a node,
// that means "any node matches"
//
if (pp->NodePattern && !Node) {
continue;
}
if (!pp->LeafPattern && Leaf || pp->LeafPattern && !Leaf) {
continue;
}
if (Leaf) {
MYASSERT (pp->LeafPattern);
if (!TestParsedPatternW (pp->LeafPattern, Leaf)) {
continue;
}
}
if (pp->NodePattern && !TestParsedPatternW (pp->NodePattern, Node)) {
continue;
}
//
// the patterns match!
//
return TRUE;
}
return FALSE;
}
/*++
Routine Description:
ElIsTreeExcluded2 decides if the object given by its 2 components and representing the
whole tree beneath it (as a root) is excluded; i.e. if any child of the given object
is excluded
Arguments:
ObjectType - Specifies the object type
Root - Specifies the root of the tree
LeafPattern - Specifies the leaf pattern to be used for this decision; optional;
if NULL, no leaf pattern matching will be attempted
Return Value:
TRUE if the tree is excluded, given the leaf pattern
--*/
BOOL
ElIsTreeExcluded2A (
IN DWORD ObjectType,
IN PCSTR Root,
IN PCSTR LeafPattern OPTIONAL
)
{
PGROWLIST gl;
UINT i;
POBSPARSEDPATTERNA pp;
PCSTR subTreePattern;
PPARSEDPATTERNA stpp;
PPARSEDPATTERNA lpp;
BOOL b;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (Root);
if (!Root) {
return FALSE;
}
gl = &g_ElTypeLists[ObjectType];
if (GlGetSize (gl) == 0) {
return FALSE;
}
if (LeafPattern) {
lpp = CreateParsedPatternA (LeafPattern);
if (!lpp) {
DEBUGMSGA ((DBG_EXCLIST, "ElIsTreeExcluded2A: invalid LeafPattern: %s", LeafPattern));
return FALSE;
}
} else {
lpp = NULL;
}
//
// look if Root ends with "\*"
//
subTreePattern = FindLastWackA (Root);
if (!subTreePattern || subTreePattern[1] != '*' || subTreePattern[2] != 0) {
subTreePattern = JoinPathsInPoolExA ((g_ElPool, Root, "*", NULL));
} else {
subTreePattern = Root;
}
b = FALSE;
stpp = CreateParsedPatternA (subTreePattern);
if (stpp) {
for (i = GlGetSize (gl); i > 0; i--) {
pp = *(POBSPARSEDPATTERNA*) GlGetItem (gl, i - 1);
if (!pp->LeafPattern && LeafPattern || pp->LeafPattern && !LeafPattern) {
continue;
}
if (LeafPattern) {
MYASSERT (pp->LeafPattern);
if (!PatternIncludesPatternA (pp->LeafPattern, lpp)) {
continue;
}
}
if (!PatternIncludesPatternA (pp->NodePattern, stpp)) {
continue;
}
//
// the patterns match!
//
b = TRUE;
break;
}
DestroyParsedPatternA (stpp);
}
ELSE_DEBUGMSGA ((DBG_EXCLIST, "ElIsTreeExcluded2A: invalid Root: %s", Root));
if (subTreePattern != Root) {
pFreeMemory (subTreePattern);
}
if (lpp) {
DestroyParsedPatternA (lpp);
}
return b;
}
BOOL
ElIsTreeExcluded2W (
IN DWORD ObjectType,
IN PCWSTR Root,
IN PCWSTR LeafPattern OPTIONAL
)
{
PGROWLIST gl;
UINT i;
POBSPARSEDPATTERNW pp;
PCWSTR subTreePattern;
PPARSEDPATTERNW stpp;
PPARSEDPATTERNW lpp;
BOOL b;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (Root);
if (!Root) {
return FALSE;
}
gl = &g_ElTypeLists[ObjectType];
if (GlGetSize (gl) == 0) {
return FALSE;
}
if (LeafPattern) {
lpp = CreateParsedPatternW (LeafPattern);
if (!lpp) {
DEBUGMSGW ((DBG_EXCLIST, "ElIsTreeExcluded2W: invalid LeafPattern: %s", LeafPattern));
return FALSE;
}
} else {
lpp = NULL;
}
//
// look if Root ends with "\*"
//
subTreePattern = FindLastWackW (Root);
if (!subTreePattern || subTreePattern[1] != L'*' || subTreePattern[2] != 0) {
subTreePattern = JoinPathsInPoolExW ((g_ElPool, Root, L"*", NULL));
} else {
subTreePattern = Root;
}
b = FALSE;
stpp = CreateParsedPatternW (subTreePattern);
if (stpp) {
for (i = GlGetSize (gl); i > 0; i--) {
pp = *(POBSPARSEDPATTERNW*) GlGetItem (gl, i - 1);
if (!pp->LeafPattern && LeafPattern || pp->LeafPattern && !LeafPattern) {
continue;
}
if (LeafPattern) {
MYASSERT (pp->LeafPattern);
if (!PatternIncludesPatternW (pp->LeafPattern, lpp)) {
continue;
}
}
if (!PatternIncludesPatternW (pp->NodePattern, stpp)) {
continue;
}
//
// the patterns match!
//
b = TRUE;
break;
}
DestroyParsedPatternW (stpp);
}
ELSE_DEBUGMSGW ((DBG_EXCLIST, "ElIsTreeExcluded2W: invalid Root: %s", Root));
if (subTreePattern != Root) {
pFreeMemory (subTreePattern);
}
if (lpp) {
DestroyParsedPatternW (lpp);
}
return b;
}
/*++
Routine Description:
ElIsObsPatternExcluded decides if the object given by its parsed pattern is excluded;
i.e. if any object matching this pattern is excluded
Arguments:
ObjectType - Specifies the object type
Pattern - Specifies the parsed pattern to be used for this decision
Return Value:
TRUE if the object is excluded
--*/
BOOL
ElIsObsPatternExcludedA (
IN DWORD ObjectType,
IN POBSPARSEDPATTERNA Pattern
)
{
PGROWLIST gl;
UINT i;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (Pattern);
if (!Pattern) {
return FALSE;
}
gl = &g_ElTypeLists[ObjectType];
for (i = GlGetSize (gl); i > 0; i--) {
if (ObsPatternIncludesPatternA (*(POBSPARSEDPATTERNA*) GlGetItem (gl, i - 1), Pattern)) {
return TRUE;
}
}
return FALSE;
}
BOOL
ElIsObsPatternExcludedW (
IN DWORD ObjectType,
IN POBSPARSEDPATTERNW Pattern
)
{
PGROWLIST gl;
UINT i;
MYASSERT (ObjectType < ELT_LAST);
if (ObjectType >= ELT_LAST) {
return FALSE;
}
MYASSERT (Pattern);
if (!Pattern) {
return FALSE;
}
gl = &g_ElTypeLists[ObjectType];
for (i = GlGetSize (gl); i > 0; i--) {
if (ObsPatternIncludesPatternW (*(POBSPARSEDPATTERNW*) GlGetItem (gl, i - 1), Pattern)) {
return TRUE;
}
}
return FALSE;
}