windows-nt/Source/XPSP1/NT/windows/winstate/cobra/engine/ism/attrib.c
2020-09-26 16:20:57 +08:00

1659 lines
35 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
attrib.c
Abstract:
Implements the attribute interface for the ISM. Attributes are caller-defined
flags that are associated with objects, for purposes of understanding and
organizing state.
Author:
Jim Schmidt (jimschm) 01-Feb-2000
Revision History:
<alias> <date> <comments>
--*/
//
// Includes
//
#include "pch.h"
#include "ism.h"
#include "ismp.h"
#define DBG_ATTRIB "Attrib"
//
// Strings
//
#define S_PERSISTENT_ATTRIBUTE TEXT("$PERSISTENT")
#define S_APPLY_ATTRIBUTE TEXT("$APPLY")
#define S_ABANDONED_ATTRIBUTE TEXT("$ABANDONED")
#define S_NONCRITICAL_ATTRIBUTE TEXT("$NONCRITICAL")
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
typedef struct {
PUINT LinkageList;
UINT Count;
UINT Index;
} OBJECTATTRIBUTE_HANDLE, *POBJECTATTRIBUTE_HANDLE;
typedef struct {
PUINT LinkageList;
UINT Count;
UINT Index;
PCTSTR ObjectFromMemdb;
} OBJECTWITHATTRIBUTE_HANDLE, *POBJECTWITHATTRIBUTE_HANDLE;
//
// Globals
//
MIG_ATTRIBUTEID g_PersistentAttributeId = 0;
MIG_ATTRIBUTEID g_ApplyAttributeId = 0;
MIG_ATTRIBUTEID g_AbandonedAttributeId = 0;
MIG_ATTRIBUTEID g_NonCriticalAttributeId = 0;
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
PCTSTR
pGetAttributeNameForDebugMsg (
IN MIG_ATTRIBUTEID AttributeId
)
{
static TCHAR name[256];
if (!IsmGetAttributeName (AttributeId, name, ARRAYSIZE(name), NULL, NULL, NULL)) {
StringCopy (name, TEXT("<invalid attribute>"));
}
return name;
}
PCTSTR
pAttributePathFromId (
IN MIG_ATTRIBUTEID AttributeId
)
{
return MemDbGetKeyFromHandle ((UINT) AttributeId, 0);
}
VOID
pAttributePathFromName (
IN PCTSTR AttributeName,
OUT PTSTR Path
)
{
wsprintf (Path, TEXT("Attrib\\%s"), AttributeName);
}
MIG_ATTRIBUTEID
IsmRegisterAttribute (
IN PCTSTR AttributeName,
IN BOOL Private
)
/*++
Routine Description:
IsmRegisterAttribute creates a public or private attribute and returns the
ID to the caller. If the attribute already exists, then the existing ID is
returned to the caller.
Arguments:
AttribName - Specifies the attribute name to register.
Private - Specifies TRUE if the attribute is owned by the calling module
only, or FALSE if it is shared by all modules. If TRUE is
specified, the caller must be in an ISM callback function.
Return Value:
The ID of the attribute, or 0 if the registration failed.
--*/
{
TCHAR attribPath[MEMDB_MAX];
TCHAR decoratedName[MEMDB_MAX];
UINT offset;
if (!g_CurrentGroup && Private) {
DEBUGMSG ((DBG_ERROR, "IsmRegisterAttribute called for private attribute outside of ISM-managed context"));
return 0;
}
if (!IsValidCNameWithDots (AttributeName)) {
DEBUGMSG ((DBG_ERROR, "attribute name \"%s\" is illegal", AttributeName));
return 0;
}
#ifdef DEBUG
if (Private && !IsValidCName (g_CurrentGroup)) {
DEBUGMSG ((DBG_ERROR, "group name \"%s\" is illegal", g_CurrentGroup));
return 0;
}
#endif
if (Private) {
wsprintf (decoratedName, TEXT("%s:%s"), g_CurrentGroup, AttributeName);
} else {
wsprintf (decoratedName, S_COMMON TEXT(":%s"), AttributeName);
}
pAttributePathFromName (decoratedName, attribPath);
if (!MarkGroupIds (attribPath)) {
DEBUGMSG ((
DBG_ERROR,
"%s conflicts with previously registered attribute",
attribPath
));
return 0;
}
offset = MemDbSetKey (attribPath);
if (!offset) {
EngineError ();
return 0;
}
return (MIG_ATTRIBUTEID) offset;
}
BOOL
RegisterInternalAttributes (
VOID
)
{
TCHAR attribPath[MEMDB_MAX];
TCHAR decoratedName[MEMDB_MAX];
UINT offset;
wsprintf (decoratedName, S_COMMON TEXT(":%s"), S_PERSISTENT_ATTRIBUTE);
pAttributePathFromName (decoratedName, attribPath);
if (!MarkGroupIds (attribPath)) {
DEBUGMSG ((
DBG_ERROR,
"%s conflicts with previously registered attribute",
attribPath
));
return 0;
}
offset = MemDbSetKey (attribPath);
if (!offset) {
EngineError ();
return FALSE;
}
g_PersistentAttributeId = (MIG_ATTRIBUTEID) offset;
wsprintf (decoratedName, S_COMMON TEXT(":%s"), S_APPLY_ATTRIBUTE);
pAttributePathFromName (decoratedName, attribPath);
if (!MarkGroupIds (attribPath)) {
DEBUGMSG ((
DBG_ERROR,
"%s conflicts with previously registered attribute",
attribPath
));
return 0;
}
offset = MemDbSetKey (attribPath);
if (!offset) {
EngineError ();
return FALSE;
}
g_ApplyAttributeId = (MIG_ATTRIBUTEID) offset;
wsprintf (decoratedName, S_COMMON TEXT(":%s"), S_ABANDONED_ATTRIBUTE);
pAttributePathFromName (decoratedName, attribPath);
if (!MarkGroupIds (attribPath)) {
DEBUGMSG ((
DBG_ERROR,
"%s conflicts with previously registered attribute",
attribPath
));
return 0;
}
offset = MemDbSetKey (attribPath);
if (!offset) {
EngineError ();
return FALSE;
}
g_AbandonedAttributeId = (MIG_ATTRIBUTEID) offset;
wsprintf (decoratedName, S_COMMON TEXT(":%s"), S_NONCRITICAL_ATTRIBUTE);
pAttributePathFromName (decoratedName, attribPath);
if (!MarkGroupIds (attribPath)) {
DEBUGMSG ((
DBG_ERROR,
"%s conflicts with previously registered attribute",
attribPath
));
return 0;
}
offset = MemDbSetKey (attribPath);
if (!offset) {
EngineError ();
return FALSE;
}
g_NonCriticalAttributeId = (MIG_ATTRIBUTEID) offset;
return TRUE;
}
BOOL
IsmGetAttributeName (
IN MIG_ATTRIBUTEID AttributeId,
OUT PTSTR AttributeName, OPTIONAL
IN UINT AttributeNameBufChars,
OUT PBOOL Private, OPTIONAL
OUT PBOOL BelongsToMe, OPTIONAL
OUT PUINT ObjectReferences OPTIONAL
)
/*++
Routine Description:
IsmGetAttributeName obtains the attribute text name from a numeric ID. It
also identifies private and owned attributes.
Arguments:
AttributeId - Specifies the attribute ID to look up.
AttributeName - Receives the attribute name. The name is filled for
all valid AttributeId values, even when the return
value is FALSE.
AttributeNameBufChars - Specifies the number of TCHARs that AttributeName
can hold, including the nul terminator.
Private - Receives TRUE if the attribute is private, or FALSE
if it is public.
BelongsToMe - Receives TRUE if the attribute is private and
belongs to the caller, FALSE otherwise.
ObjectReferences - Receives the number of objects that reference the
attribute
Return Value:
TRUE if the attribute is public, or if the attribute is private and belongs to
the caller.
FALSE if the attribute is private and belongs to someone else. AttributeName,
Private and BelongsToMe are valid in this case.
FALSE if AttributeId is not valid. Attributename, Private and BelongsToMe are
not modified in this case. Do not use this function to test if AttributeId
is valid or not.
--*/
{
PCTSTR attribPath = NULL;
PCTSTR start;
PTSTR p, q;
BOOL privateAttribute = FALSE;
BOOL groupMatch = FALSE;
BOOL result = FALSE;
UINT references;
PUINT linkageList;
__try {
//
// Get the attribute path from memdb, then parse it for group and name
//
attribPath = pAttributePathFromId (AttributeId);
if (!attribPath) {
__leave;
}
p = _tcschr (attribPath, TEXT('\\'));
if (!p) {
__leave;
}
start = _tcsinc (p);
p = _tcschr (start, TEXT(':'));
if (!p) {
__leave;
}
q = _tcsinc (p);
*p = 0;
if (StringIMatch (start, S_COMMON)) {
//
// This attribute is a global attribute.
//
privateAttribute = FALSE;
groupMatch = TRUE;
} else if (g_CurrentGroup) {
//
// This attribute is private. Check if it is ours.
//
privateAttribute = TRUE;
if (StringIMatch (start, g_CurrentGroup)) {
groupMatch = TRUE;
} else {
groupMatch = FALSE;
}
} else {
//
// This is a private attribute, but the caller is not
// a module that can own attributes.
//
DEBUGMSG ((DBG_WARNING, "IsmGetAttributeName: Caller cannot own private attributes"));
}
//
// Copy the name to the buffer, update outbound BOOLs, set result
//
if (AttributeName && AttributeNameBufChars >= sizeof (TCHAR)) {
StringCopyByteCount (AttributeName, q, AttributeNameBufChars * sizeof (TCHAR));
}
if (Private) {
*Private = privateAttribute;
}
if (BelongsToMe) {
*BelongsToMe = privateAttribute && groupMatch;
}
if (ObjectReferences) {
linkageList = MemDbGetDoubleLinkageArrayByKeyHandle (
AttributeId,
ATTRIBUTE_INDEX,
&references
);
references /= SIZEOF(KEYHANDLE);
if (linkageList) {
MemDbReleaseMemory (linkageList);
INVALID_POINTER (linkageList);
} else {
references = 0;
}
*ObjectReferences = references;
}
if (groupMatch) {
result = TRUE;
}
}
__finally {
if (attribPath) { //lint !e774
MemDbReleaseMemory (attribPath);
attribPath = NULL;
}
}
return result;
}
MIG_ATTRIBUTEID
IsmGetAttributeGroup (
IN MIG_ATTRIBUTEID AttributeId
)
{
return (MIG_ATTRIBUTEID) GetGroupOfId ((KEYHANDLE) AttributeId);
}
BOOL
pSetAttributeOnObjectId (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId,
IN BOOL QueryOnly
)
{
BOOL result = FALSE;
__try {
//
// Test if object is locked, then if not locked, add linkage
//
if (TestLock (ObjectId, (KEYHANDLE) AttributeId)) {
SetLastError (ERROR_LOCKED);
DEBUGMSG ((
DBG_WARNING,
"Can't set attribute %s on %s because of lock",
pGetAttributeNameForDebugMsg (AttributeId),
GetObjectNameForDebugMsg (ObjectId)
));
__leave;
}
if (QueryOnly) {
result = TRUE;
__leave;
}
result = MemDbAddDoubleLinkageByKeyHandle (
ObjectId,
AttributeId,
ATTRIBUTE_INDEX
);
if (!result) {
EngineError ();
}
}
__finally {
}
return result;
}
BOOL
pSetAttributeGroup (
IN KEYHANDLE AttributeId,
IN BOOL FirstPass,
IN ULONG_PTR Arg
)
{
MYASSERT (IsItemId (AttributeId));
return pSetAttributeOnObjectId (
(MIG_OBJECTID) Arg,
(MIG_ATTRIBUTEID) AttributeId,
FirstPass
);
}
BOOL
IsmSetAttributeOnObjectId (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId
)
{
RECURSERETURN rc;
//
// If AttributeId is a group, set all attribs in the group
//
rc = RecurseForGroupItems (
AttributeId,
pSetAttributeGroup,
(ULONG_PTR) ObjectId,
FALSE,
FALSE
);
if (rc == RECURSE_FAIL) {
return FALSE;
} else if (rc == RECURSE_SUCCESS) {
return TRUE;
}
MYASSERT (rc == RECURSE_NOT_NEEDED);
return pSetAttributeOnObjectId (ObjectId, AttributeId, FALSE);
}
BOOL
IsmSetAttributeOnObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName,
IN MIG_ATTRIBUTEID AttributeId
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = GetObjectIdForModification (ObjectTypeId, EncodedObjectName);
if (objectId) {
result = IsmSetAttributeOnObjectId (objectId, AttributeId);
}
return result;
}
BOOL
IsmMakePersistentObjectId (
IN MIG_OBJECTID ObjectId
)
{
MIG_OBJECTTYPEID objectTypeId;
BOOL result;
if (IsmIsPersistentObjectId (ObjectId)) {
return TRUE;
}
result = pSetAttributeOnObjectId (ObjectId, g_PersistentAttributeId, FALSE);
if (result) {
g_TotalObjects.PersistentObjects ++;
result = MemDbGetValueByHandle (ObjectId, &objectTypeId);
if (result) {
if ((objectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE) {
g_SourceObjects.PersistentObjects ++;
} else {
g_DestinationObjects.PersistentObjects ++;
}
IncrementPersistentObjectCount (objectTypeId);
}
result = TRUE;
}
return result;
}
BOOL
IsmMakePersistentObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, FALSE);
if (objectId) {
result = IsmMakePersistentObjectId (objectId);
}
return result;
}
BOOL
IsmMakeApplyObjectId (
IN MIG_OBJECTID ObjectId
)
{
MIG_OBJECTTYPEID objectTypeId;
BOOL result;
if (IsmIsApplyObjectId (ObjectId)) {
return TRUE;
}
if (!IsmMakePersistentObjectId (ObjectId)) {
return FALSE;
}
result = pSetAttributeOnObjectId (ObjectId, g_ApplyAttributeId, FALSE);
if (result) {
g_TotalObjects.ApplyObjects ++;
result = MemDbGetValueByHandle (ObjectId, &objectTypeId);
if (result) {
if ((objectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE) {
g_SourceObjects.ApplyObjects ++;
} else {
g_DestinationObjects.ApplyObjects ++;
}
IncrementApplyObjectCount (objectTypeId);
}
result = TRUE;
}
return result;
}
BOOL
IsmMakeApplyObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, FALSE);
if (objectId) {
result = IsmMakeApplyObjectId (objectId);
}
return result;
}
BOOL
IsmAbandonObjectIdOnCollision (
IN MIG_OBJECTID ObjectId
)
{
BOOL result;
if (IsmIsObjectIdAbandonedOnCollision (ObjectId)) {
return TRUE;
}
result = pSetAttributeOnObjectId (ObjectId, g_AbandonedAttributeId, FALSE);
return result;
}
BOOL
IsmAbandonObjectOnCollision (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, FALSE);
if (objectId) {
result = IsmAbandonObjectIdOnCollision (objectId);
}
return result;
}
BOOL
IsmMakeNonCriticalObjectId (
IN MIG_OBJECTID ObjectId
)
{
if (IsmIsNonCriticalObjectId (ObjectId)) {
return TRUE;
}
return pSetAttributeOnObjectId (ObjectId, g_NonCriticalAttributeId, FALSE);
}
BOOL
IsmMakeNonCriticalObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, FALSE);
if (objectId) {
result = IsmMakeNonCriticalObjectId (objectId);
}
return result;
}
VOID
IsmLockAttribute (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId
)
{
LockHandle (ObjectId, (KEYHANDLE) AttributeId);
}
BOOL
pClearAttributeOnObjectId (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId,
IN BOOL QueryOnly
)
{
PCTSTR groupKey = NULL;
PCTSTR enumKey = NULL;
BOOL result = FALSE;
__try {
if (TestLock (ObjectId, (KEYHANDLE) AttributeId)) {
SetLastError (ERROR_LOCKED);
DEBUGMSG ((
DBG_ERROR,
"Can't clear attribute %s on %s because of lock",
pGetAttributeNameForDebugMsg (AttributeId),
GetObjectNameForDebugMsg (ObjectId)
));
__leave;
}
if (QueryOnly) {
result = TRUE;
__leave;
}
result = MemDbDeleteDoubleLinkageByKeyHandle (
ObjectId,
AttributeId,
ATTRIBUTE_INDEX
);
}
__finally {
if (groupKey) {
MemDbReleaseMemory (groupKey);
INVALID_POINTER (groupKey);
}
if (enumKey) {
FreeText (enumKey);
INVALID_POINTER (enumKey);
}
}
return result;
}
BOOL
pClearAttributeGroup (
IN KEYHANDLE AttributeId,
IN BOOL FirstPass,
IN ULONG_PTR Arg
)
{
return pClearAttributeOnObjectId (
(MIG_OBJECTID) Arg,
(MIG_ATTRIBUTEID) AttributeId,
FirstPass
);
}
BOOL
IsmClearAttributeOnObjectId (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId
)
{
RECURSERETURN rc;
//
// If AttributeId is a group, set all attribs in the group
//
rc = RecurseForGroupItems (
AttributeId,
pClearAttributeGroup,
(ULONG_PTR) ObjectId,
FALSE,
FALSE
);
if (rc == RECURSE_FAIL) {
return FALSE;
} else if (rc == RECURSE_SUCCESS) {
return TRUE;
}
MYASSERT (rc == RECURSE_NOT_NEEDED);
return pClearAttributeOnObjectId (ObjectId, AttributeId, FALSE);
}
BOOL
IsmClearAttributeOnObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName,
IN MIG_ATTRIBUTEID AttributeId
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
result = IsmClearAttributeOnObjectId (objectId, AttributeId);
}
return result;
}
BOOL
IsmClearPersistenceOnObjectId (
IN MIG_OBJECTID ObjectId
)
{
MIG_OBJECTTYPEID objectTypeId;
BOOL result;
if (!IsmIsPersistentObjectId (ObjectId)) {
return TRUE;
}
if (!IsmClearApplyOnObjectId (ObjectId)) {
return FALSE;
}
result = pClearAttributeOnObjectId (ObjectId, g_PersistentAttributeId, FALSE);
if (result) {
g_TotalObjects.PersistentObjects --;
result = MemDbGetValueByHandle (ObjectId, &objectTypeId);
if (result) {
if ((objectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE) {
g_SourceObjects.PersistentObjects --;
} else {
g_DestinationObjects.PersistentObjects --;
}
DecrementPersistentObjectCount (objectTypeId);
}
result = TRUE;
}
return result;
}
BOOL
IsmClearPersistenceOnObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
result = IsmClearPersistenceOnObjectId (objectId);
}
return result;
}
BOOL
IsmClearApplyOnObjectId (
IN MIG_OBJECTID ObjectId
)
{
MIG_OBJECTTYPEID objectTypeId;
BOOL result;
if (!IsmIsApplyObjectId (ObjectId)) {
return TRUE;
}
result = pClearAttributeOnObjectId (ObjectId, g_ApplyAttributeId, FALSE);
if (result) {
g_TotalObjects.ApplyObjects --;
result = MemDbGetValueByHandle (ObjectId, &objectTypeId);
if (result) {
if ((objectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE) {
g_SourceObjects.ApplyObjects --;
} else {
g_DestinationObjects.ApplyObjects --;
}
DecrementApplyObjectCount (objectTypeId);
}
result = TRUE;
}
return result;
}
BOOL
IsmClearApplyOnObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
result = IsmClearApplyOnObjectId (objectId);
}
return result;
}
BOOL
IsmClearAbandonObjectIdOnCollision (
IN MIG_OBJECTID ObjectId
)
{
BOOL result;
if (!IsmIsObjectIdAbandonedOnCollision (ObjectId)) {
return TRUE;
}
result = pClearAttributeOnObjectId (ObjectId, g_AbandonedAttributeId, FALSE);
return result;
}
BOOL
IsmClearAbandonObjectOnCollision (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
result = IsmClearAbandonObjectIdOnCollision (objectId);
}
return result;
}
BOOL
IsmClearNonCriticalFlagOnObjectId (
IN MIG_OBJECTID ObjectId
)
{
if (!IsmIsNonCriticalObjectId (ObjectId)) {
return TRUE;
}
return pClearAttributeOnObjectId (ObjectId, g_NonCriticalAttributeId, FALSE);
}
BOOL
IsmClearNonCriticalFlagOnObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
BOOL result = FALSE;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
result = IsmClearNonCriticalFlagOnObjectId (objectId);
}
return result;
}
BOOL
pIsAttributeSetOnObjectId (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId
)
{
return MemDbTestDoubleLinkageByKeyHandle (
ObjectId,
AttributeId,
ATTRIBUTE_INDEX
);
}
BOOL
pQueryAttributeGroup (
IN KEYHANDLE AttributeId,
IN BOOL FirstPass,
IN ULONG_PTR Arg
)
{
return pIsAttributeSetOnObjectId (
(MIG_OBJECTID) Arg,
(MIG_ATTRIBUTEID) AttributeId
);
}
BOOL
IsmIsAttributeSetOnObjectId (
IN MIG_OBJECTID ObjectId,
IN MIG_ATTRIBUTEID AttributeId
)
{
RECURSERETURN rc;
//
// If AttributeId is a group, query all properties in the group
//
rc = RecurseForGroupItems (
AttributeId,
pQueryAttributeGroup,
(ULONG_PTR) ObjectId,
TRUE,
TRUE
);
if (rc == RECURSE_FAIL) {
return FALSE;
} else if (rc == RECURSE_SUCCESS) {
return TRUE;
}
MYASSERT (rc == RECURSE_NOT_NEEDED);
return pIsAttributeSetOnObjectId (ObjectId, AttributeId);
}
BOOL
IsmIsAttributeSetOnObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName,
IN MIG_ATTRIBUTEID AttributeId
)
{
MIG_OBJECTID objectId;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
return IsmIsAttributeSetOnObjectId (objectId, AttributeId);
}
return FALSE;
}
BOOL
IsmIsPersistentObjectId (
IN MIG_OBJECTID ObjectId
)
{
return pIsAttributeSetOnObjectId (ObjectId, g_PersistentAttributeId);
}
BOOL
IsmIsPersistentObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
return IsmIsPersistentObjectId (objectId);
}
return FALSE;
}
BOOL
IsmIsApplyObjectId (
IN MIG_OBJECTID ObjectId
)
{
return pIsAttributeSetOnObjectId (ObjectId, g_ApplyAttributeId);
}
BOOL
IsmIsApplyObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
return IsmIsApplyObjectId (objectId);
}
return FALSE;
}
BOOL
IsmIsObjectIdAbandonedOnCollision (
IN MIG_OBJECTID ObjectId
)
{
return pIsAttributeSetOnObjectId (ObjectId, g_AbandonedAttributeId);
}
BOOL
IsmIsObjectAbandonedOnCollision (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
return IsmIsObjectIdAbandonedOnCollision (objectId);
}
return FALSE;
}
BOOL
IsmIsNonCriticalObjectId (
IN MIG_OBJECTID ObjectId
)
{
return pIsAttributeSetOnObjectId (ObjectId, g_NonCriticalAttributeId);
}
BOOL
IsmIsNonCriticalObject (
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
return IsmIsNonCriticalObjectId (objectId);
}
return FALSE;
}
BOOL
IsmEnumFirstObjectAttributeById (
OUT PMIG_OBJECTATTRIBUTE_ENUM EnumPtr,
IN MIG_OBJECTID ObjectId
)
{
POBJECTATTRIBUTE_HANDLE handle;
BOOL result = TRUE;
ZeroMemory (EnumPtr, sizeof (MIG_OBJECTATTRIBUTE_ENUM));
EnumPtr->Handle = MemAllocZeroed (sizeof (OBJECTATTRIBUTE_HANDLE));
handle = (POBJECTATTRIBUTE_HANDLE) EnumPtr->Handle;
handle->LinkageList = MemDbGetDoubleLinkageArrayByKeyHandle (
ObjectId,
ATTRIBUTE_INDEX,
&handle->Count
);
handle->Count = handle->Count / SIZEOF(KEYHANDLE);
if (!handle->LinkageList || !handle->Count) {
IsmAbortObjectAttributeEnum (EnumPtr);
result = FALSE;
} else {
result = IsmEnumNextObjectAttribute (EnumPtr);
}
return result;
}
BOOL
IsmEnumFirstObjectAttribute (
OUT PMIG_OBJECTATTRIBUTE_ENUM EnumPtr,
IN MIG_OBJECTTYPEID ObjectTypeId,
IN ENCODEDSTRHANDLE EncodedObjectName
)
{
MIG_OBJECTID objectId;
ObjectTypeId = FixEnumerationObjectTypeId (ObjectTypeId);
objectId = IsmGetObjectIdFromName (ObjectTypeId, EncodedObjectName, TRUE);
if (objectId) {
return IsmEnumFirstObjectAttributeById (EnumPtr, objectId);
}
return FALSE;
}
BOOL
IsmEnumNextObjectAttribute (
IN OUT PMIG_OBJECTATTRIBUTE_ENUM EnumPtr
)
{
POBJECTATTRIBUTE_HANDLE handle;
BOOL result = FALSE;
BOOL mine;
handle = (POBJECTATTRIBUTE_HANDLE) EnumPtr->Handle;
if (!handle) {
return FALSE;
}
do {
MYASSERT (!result);
//
// Check if we hit the end
//
if (handle->Index >= handle->Count) {
break;
}
//
// Return the next attribute
//
EnumPtr->AttributeId = (MIG_ATTRIBUTEID) handle->LinkageList[handle->Index];
handle->Index++;
result = IsmGetAttributeName (
EnumPtr->AttributeId,
NULL,
0,
&EnumPtr->Private,
&mine,
NULL
);
//
// Continue when the attribute is not owned by the caller
//
if (result && EnumPtr->Private && !mine) {
result = FALSE;
}
//
// Continue when we are talking about reserved persistent/apply attribute
//
if (result) {
if (EnumPtr->AttributeId == g_PersistentAttributeId ||
EnumPtr->AttributeId == g_ApplyAttributeId ||
EnumPtr->AttributeId == g_AbandonedAttributeId ||
EnumPtr->AttributeId == g_NonCriticalAttributeId
) {
result = FALSE;
}
}
} while (!result);
if (!result) {
IsmAbortObjectAttributeEnum (EnumPtr);
}
return result;
}
VOID
IsmAbortObjectAttributeEnum (
IN OUT PMIG_OBJECTATTRIBUTE_ENUM EnumPtr
)
{
POBJECTATTRIBUTE_HANDLE handle;
if (EnumPtr->Handle) {
handle = (POBJECTATTRIBUTE_HANDLE) EnumPtr->Handle;
if (handle->LinkageList) {
MemDbReleaseMemory (handle->LinkageList);
INVALID_POINTER (handle->LinkageList);
}
MemFree (g_hHeap, 0, EnumPtr->Handle);
INVALID_POINTER (EnumPtr->Handle);
}
ZeroMemory (EnumPtr, sizeof (MIG_OBJECTATTRIBUTE_ENUM));
}
BOOL
IsmEnumFirstObjectWithAttribute (
OUT PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr,
IN MIG_ATTRIBUTEID AttributeId
)
{
POBJECTWITHATTRIBUTE_HANDLE handle;
BOOL result = FALSE;
__try {
if (!IsItemId ((KEYHANDLE) AttributeId)) {
DEBUGMSG ((DBG_ERROR, "IsmEnumFirstObjectWithAttribute: invalid attribute id"));
__leave;
}
ZeroMemory (EnumPtr, sizeof (MIG_OBJECTWITHATTRIBUTE_ENUM));
EnumPtr->Handle = MemAllocZeroed (sizeof (OBJECTWITHATTRIBUTE_HANDLE));
handle = (POBJECTWITHATTRIBUTE_HANDLE) EnumPtr->Handle;
handle->LinkageList = MemDbGetDoubleLinkageArrayByKeyHandle (
AttributeId,
ATTRIBUTE_INDEX,
&handle->Count
);
handle->Count = handle->Count / SIZEOF(KEYHANDLE);
if (!handle->LinkageList || !handle->Count) {
IsmAbortObjectWithAttributeEnum (EnumPtr);
__leave;
} else {
result = IsmEnumNextObjectWithAttribute (EnumPtr);
}
}
__finally {
}
return result;
}
BOOL
IsmEnumNextObjectWithAttribute (
IN OUT PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
POBJECTWITHATTRIBUTE_HANDLE handle;
PCTSTR objectPath = NULL;
BOOL result = FALSE;
PTSTR p;
__try {
handle = (POBJECTWITHATTRIBUTE_HANDLE) EnumPtr->Handle;
if (!handle) {
__leave;
}
do {
//
// Check if enum is done
//
if (handle->Index >= handle->Count) {
break;
}
//
// Get the next object id from the linkage list
//
EnumPtr->ObjectId = handle->LinkageList[handle->Index];
handle->Index++;
if (handle->ObjectFromMemdb) {
MemDbReleaseMemory (handle->ObjectFromMemdb);
INVALID_POINTER (handle->ObjectFromMemdb);
}
handle->ObjectFromMemdb = MemDbGetKeyFromHandle ((KEYHANDLE) EnumPtr->ObjectId, 0);
if (!handle->ObjectFromMemdb) {
MYASSERT (FALSE); // this error shouldn't happen -- but don't give up
continue;
}
//
// Turn the object id into a name
//
p = _tcschr (handle->ObjectFromMemdb, TEXT('\\'));
if (p) {
result = TRUE;
EnumPtr->ObjectName = _tcsinc (p);
*p = 0;
EnumPtr->ObjectTypeId = GetObjectTypeId (handle->ObjectFromMemdb);
}
} while (!result);
}
__finally {
}
if (!result) {
IsmAbortObjectWithAttributeEnum (EnumPtr);
}
return result;
}
VOID
IsmAbortObjectWithAttributeEnum (
IN PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
POBJECTWITHATTRIBUTE_HANDLE handle;
if (EnumPtr->Handle) {
handle = (POBJECTWITHATTRIBUTE_HANDLE) EnumPtr->Handle;
if (handle->ObjectFromMemdb) {
MemDbReleaseMemory (handle->ObjectFromMemdb);
INVALID_POINTER (handle->ObjectFromMemdb);
}
if (handle->LinkageList) {
MemDbReleaseMemory (handle->LinkageList);
INVALID_POINTER (handle->LinkageList);
}
FreeAlloc (EnumPtr->Handle);
INVALID_POINTER (EnumPtr->Handle);
}
ZeroMemory (EnumPtr, sizeof (MIG_OBJECTWITHATTRIBUTE_ENUM));
}
BOOL
IsmEnumFirstPersistentObject (
OUT PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
return IsmEnumFirstObjectWithAttribute (EnumPtr, g_PersistentAttributeId);
}
BOOL
IsmEnumNextPersistentObject (
IN OUT PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
return IsmEnumNextObjectWithAttribute (EnumPtr);
}
VOID
IsmAbortPersistentObjectEnum (
IN PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
IsmAbortObjectWithAttributeEnum (EnumPtr);
}
BOOL
IsmEnumFirstApplyObject (
OUT PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
return IsmEnumFirstObjectWithAttribute (EnumPtr, g_ApplyAttributeId);
}
BOOL
IsmEnumNextApplyObject (
IN OUT PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
return IsmEnumNextObjectWithAttribute (EnumPtr);
}
VOID
IsmAbortApplyObjectEnum (
IN PMIG_OBJECTWITHATTRIBUTE_ENUM EnumPtr
)
{
IsmAbortObjectWithAttributeEnum (EnumPtr);
}