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