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.
 
 
 
 
 
 

1057 lines
29 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
genobj.h
Abstract:
Definitions for the generic object implementation.
AZ roles has so many objects that need creation, enumeration, etc
that it seems prudent to have a single body of code for doing those operations.
Author:
Cliff Van Dyke (cliffv) 11-Apr-2001
--*/
#ifdef __cplusplus
extern "C" {
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Structure definitions
//
/////////////////////////////////////////////////////////////////////////////
//
// A generic object list head.
//
// This structure represent the head of a linked list of objects. The linked
// list of objects are considered to be "children" of this structure.
//
typedef struct _GENERIC_OBJECT_HEAD {
//
// Head of the linked list of objects
//
LIST_ENTRY Head;
//
// Count of entries on the list headed by Head
//
ULONG ObjectCount;
//
// Tree of the names of the objects
//
RTL_GENERIC_TABLE AvlTree;
//
// Back pointer to the GenericObject containing this structure
//
struct _GENERIC_OBJECT *ParentGenericObject;
//
// Each of the list heads that are rooted on a single object are linked
// together. That list is headed by GENERIC_OBJECT->ChildGenericObjectHead.
// This field is a pointer to the next entry in the list.
//
struct _GENERIC_OBJECT_HEAD *SiblingGenericObjectHead;
//
// The next sequence number to give out.
//
ULONG NextSequenceNumber;
//
// Object type of objects in this list
//
ULONG ObjectType;
//
// Flag to indicate that the parent needs to be loaded before this object can be
// referenced
//
BOOLEAN LoadParentBeforeReferencing;
//
// The order of the defines below must match the tables at the top of genobj.cxx
//
// Define object types that are not visible to the providers
//
#define OBJECT_TYPE_SID (OBJECT_TYPE_COUNT)
#define OBJECT_TYPE_CLIENT_CONTEXT (OBJECT_TYPE_COUNT+1)
#define OBJECT_TYPE_ROOT (OBJECT_TYPE_COUNT+2)
#define OBJECT_TYPE_MAXIMUM (OBJECT_TYPE_COUNT+3)
} GENERIC_OBJECT_HEAD, *PGENERIC_OBJECT_HEAD;
//
// The name of a generic object
//
// This is a separate structure since the AVL tree manager insists on allocating its own
// structure. Combine that with the facts that objects can be renamed and that a pointer
// to the object is returned directly to the user as the handle to the object. These
// facts imply that the structure containing the object name and the structure implementing
// the "handle" cannot be the same structure. I chose to not implement a separate "handle"
// structure. Such an implementation would have to "re-create and copy" the generic object
// structure upon rename.
//
typedef struct _GENERIC_OBJECT_NAME {
//
// Name of the object
//
AZP_STRING ObjectName;
//
// Pointer to the GenericObject structure named by this name
//
struct _GENERIC_OBJECT *GenericObject;
} GENERIC_OBJECT_NAME, *PGENERIC_OBJECT_NAME;
//
// The new name of a generic object
//
// This structure is only used during an AzPersistUpdateCache. Every attempt is made
// to update the name of the object in the AVL tree. However, if there are name conflicts,
// a GUID-ized name is used. That's certainly OK in a pinch. And we'll leave the name
// that way if we can't fix it or in certain bounday low memory conditions. However, we
// should fix it up if we can. This structure remembers the real name of the object and
// allows AzpPersistReconcile to try to fix the name up.
//
typedef struct _NEW_OBJECT_NAME {
//
// Link to the next new name for the same authorization store object
//
LIST_ENTRY Next;
//
// Pointer to the GenericObject structure named by this name
// The specified generic object has its reference count incremented.
//
struct _GENERIC_OBJECT *GenericObject;
//
// New name of the object
//
AZP_STRING ObjectName;
} NEW_OBJECT_NAME, *PNEW_OBJECT_NAME;
//
// Object List
//
// Some objects have lists of references to other objects. These lists are
// not parent/child relationships. Rather they represent memberships, etc.
//
// This structure represents the head of such a list.
//
// Both the pointed-from and pointed-to object have a generic object list. The
// "forward" link represents the list that is managed via external API. The
// "backward" link is provided to allow fixup of references when an object is deleted.
// The "backward" link is also provided for cases where internal routines need to
// traverse the link relationship in the opposite direction of the external API.
// By convention, GENERIC_OBJECT_LIST instances in the forward direction are named
// simply by the name of the object to point to. For instance, an object list that points
// to AZ_OPERATION objects might be called "Operations". By convention, GENERIC_OBJECT_LIST
// instances in the backward direction are prefixed by the name "back". For instance,
// "backTasks".
//
// Note, there really isn't any reason why we couldn't expose "AddPropertyItem" and
// "RemovePropertyItem" APIs for the "back" lists. See the IsBackLink and LinkPairId
// definition.
//
typedef struct _GENERIC_OBJECT_LIST {
//
// Each of the object lists that are rooted on a single object are linked
// together. That list is headed by GENERIC_OBJECT->GenericObjectLists.
// This field is a pointer to the next entry in the list.
//
struct _GENERIC_OBJECT_LIST *NextGenericObjectList;
//
// Since an object list is a list of other objects, we want to be able to
// generically find the other objects. The array below is an array of pointers
// to the head of the lists that contain the other objects.
//
//
// Unused elements in this array are set to NULL.
//
// These pointers are always pointers to a field in a "parent" structure.
// Therefore, reference counts aren't needed. Instead, the "child" structure
// containing the pointer to the parent will be deleted before the parent structure.
//
#define GEN_OBJECT_HEAD_COUNT 3
PGENERIC_OBJECT_HEAD GenericObjectHeads[GEN_OBJECT_HEAD_COUNT];
//
// List identifier.
//
// The code maintains the link and the backlink. To do that, the code needs to
// find one the "other" generic object list from this one. That algorithm uses
// the IsBackLink and LinkPairId field.
//
// One object list has IsBackLink set TRUE and the other set FALSE. This handles
// the case where an object contain both a forward an backward object list. For
// instance, the AZ_GROUP object contains the AppMembers and backAppMembers fields.
// This field differentiates between the two.
//
// There are cases where an object has multiple links between the same object types.
// For instance, the AZ_GROUP object has both AppMembers and AppNonMembers links.
// In those cases, the LinkPairId is set to a unique value to identify the pair.
// In most cases, the value is simply zero.
//
BOOL IsBackLink;
ULONG LinkPairId;
#define AZP_LINKPAIR_MEMBERS 1
#define AZP_LINKPAIR_NON_MEMBERS 2
#define AZP_LINKPAIR_SID_MEMBERS 3
#define AZP_LINKPAIR_SID_NON_MEMBERS 4
#define AZP_LINKPAIR_POLICY_ADMINS 5
#define AZP_LINKPAIR_POLICY_READERS 6
#define AZP_LINKPAIR_DELEGATED_POLICY_USERS 7
//
// Dirty Bit to be set when this list is changed
//
ULONG DirtyBit;
//
// The array of pointers to the generic objects.
//
// Being in this list does not increment the ReferenceCount on the pointed-to
// generic object.
//
AZP_PTR_ARRAY GenericObjects;
//
// An array of pointers to AZP_DELTA_ENTRY containing the GUIDs of the pointed to objects.
//
// This array contains GUIDs of links that have not yet been persisted.
// It also contains GUIDs of links that have been updated from the persistence
// provider but not yet merged into GenericObjects.
AZP_PTR_ARRAY DeltaArray;
} GENERIC_OBJECT_LIST, *PGENERIC_OBJECT_LIST;
//
// A generic object
//
typedef struct _GENERIC_OBJECT {
//
// Link to the next instance of an object of this type for the same parent object
//
LIST_ENTRY Next;
//
// Back pointer to the head of the list this object is in
//
PGENERIC_OBJECT_HEAD ParentGenericObjectHead;
GENERIC_OBJECT_HEAD AzpSids;
//
// Pointer to the list heads for children of this object
// This is a static list of the various GENERIC_OBJECT_HEAD structures
// that exist in the object type specific portion of this object.
// The list allows the generic object code to have insight into the
// children of this object.
//
PGENERIC_OBJECT_HEAD ChildGenericObjectHead;
//
// Pointer to the list heads of pointers to other objects
// This is a static list of the various GENERIC_OBJECT_LIST structures
// that exist in the object type specific portion of this object.
// The list allows the generic object code to have insight into the
// other types of objects pointed to by this object.
//
struct _GENERIC_OBJECT_LIST *GenericObjectLists;
//
// Pointer to the generic object at the root of all generic objects
// (Pointer to an AzAuthorizationStore object)
//
struct _AZP_AZSTORE *AzStoreObject;
//
// Pointer to provider specific data for this object
//
PVOID ProviderData;
//
// A list of SIDs as policy users
// Used by AzAuthorizationStore, AzApplication and AzScope objects
//
GENERIC_OBJECT_LIST PolicyAdmins;
GENERIC_OBJECT_LIST PolicyReaders;
//
// Boolean specifying whether or not the object ACL-able
//
// Used by AzAuthorizationStore, AzApplication and AzScope objects
LONG IsAclSupported;
//
// Boolean specifying if delegation is supported. It is set during the
// persist open calls at the provider levels. For example, an XML provider
// would set this to FALSE, while an LDAP provider would set it to TRUE
//
// Used by AzAuthorizationStore and AzApplication objects
//
LONG IsDelegationSupported;
//
// A list of SIDs as delegated users
// Used by AzAuthorizationStore and AzApplication
//
GENERIC_OBJECT_LIST DelegatedPolicyUsers;
//
// Name of the object
//
PGENERIC_OBJECT_NAME ObjectName;
//
// Opaque private information added by an application
//
AZP_STRING ApplicationData;
//
// Description of the object
//
AZP_STRING Description;
//
// Boolean indicating if the caller can write the object
//
LONG IsWritable;
//
// Boolen indicating if the caller can create children for this object
//
LONG CanCreateChildren;
//
// GUID of the object
// The Guid of the object is assigned by the persistence provider.
// The GUID is needed to make the object rename safe.
//
GUID PersistenceGuid;
//
// Number of references to this instance of the object
// These are references from within our code.
//
LONG ReferenceCount;
//
// Number of references to this instance of the object
// These are references represented by handles passed back to our caller.
//
LONG HandleReferenceCount;
//
// Sequence number of this object.
// The list specified in Next is maintained in SequenceNumber order.
// New entries are added to the tail end.
// Enumerations are returned in SequenceNumber order.
// SequenceNumber is returned to the caller as the EnumerationContext.
//
// This mechanism allows insertions and deletions to be handled seemlessly.
//
ULONG SequenceNumber;
//
// Specific object type represented by this generic object
//
ULONG ObjectType;
//
// Flags describing attributes of the generic object
//
ULONG Flags;
#define GENOBJ_FLAGS_DELETED 0x01 // Object has been deleted
#define GENOBJ_FLAGS_PERSIST_OK 0x02 // Persist provider has finished with this object
#define GENOBJ_FLAGS_REFRESH_ME 0x04 // Object needs to be refreshed from cache
//
// Flags to indicate which attributes are dirty
// High order bits are generic to all objects
// Low order bits are specific to individual objects
//
// Bits in "DirtyBits" indicates that the object needs to be submitted
// See the AZ_DIRTY_* defines.
//
ULONG DirtyBits;
//
// Flags to indicate that Persistence provider has changed the attribute
// Access to this field is serialized by the PersistCritSect
//
// See the AZ_DIRTY_* defines.
//
ULONG PersistDirtyBits;
//
// Boolean specifying whether or not audits should be generated. Only
// Authorizartion Store and application objects have this property. When this
// is set to TRUE all possible audits for this AzAuthStore/application are generated.
//
LONG IsGeneratingAudits;
//
// Apply SACL property. Only AzAuthorizationStore, application and Scope objects
// have this property.
//
LONG ApplySacl;
//
// whether apply SACL property is supported or not.
// For AD stores, AzAuthorizationStore, application and Scope objects support it.
// For XML stores, only AzAuthorizationStore supports it.
//
LONG IsSACLSupported;
//
// Boolean to indicate if the children are loaded into cache
//
BOOLEAN AreChildrenLoaded;
//
// Boolean to indicate that the object has been closed
//
BOOLEAN ObjectClosed;
} GENERIC_OBJECT, *PGENERIC_OBJECT;
//
// Property ID to dirty bit mapping table
//
// This structure gives a mapping between property ID and the corresponding dirty bit.
// It also provides a default value for the property.
//
typedef struct _AZP_DEFAULT_VALUE {
ULONG PropertyId;
ULONG DirtyBit;
PVOID DefaultValue;
} AZP_DEFAULT_VALUE, *PAZP_DEFAULT_VALUE;
/////////////////////////////////////////////////////////////////////////////
//
// Macro definitions
//
/////////////////////////////////////////////////////////////////////////////
//
// Macro to determine if a GENERIC_OBJECT_LIST is a list of sids
//
#define AzpIsSidList( _gol ) \
((_gol)->GenericObjectHeads[0] != NULL && \
(_gol)->GenericObjectHeads[0]->ObjectType == OBJECT_TYPE_SID )
//
// Macro to determine the address of a parent object from a child object
//
#define ParentOfChild( _go ) \
((_go)->ParentGenericObjectHead->ParentGenericObject)
//
// Macro to determine if an object type is a container type object or not
//
#define IsContainerObject( _objT ) \
( (_objT) == OBJECT_TYPE_AZAUTHSTORE || \
(_objT) == OBJECT_TYPE_APPLICATION || \
(_objT) == OBJECT_TYPE_SCOPE )
//
// Macro to determine is an object type is a delegator type object or not
//
#define IsDelegatorObject( _objT ) \
( (_objT) == OBJECT_TYPE_AZAUTHSTORE || \
(_objT) == OBJECT_TYPE_APPLICATION )
//
// Macros to determine if the provider actually supports ACLs or delegation
//
#define CHECK_ACL_SUPPORT(_o) \
(IsContainerObject( (_o)->ObjectType ) ? \
((_o)->IsAclSupported ? NO_ERROR : ERROR_NOT_SUPPORTED) : \
ERROR_INVALID_PARAMETER )
#define CHECK_DELEGATION_SUPPORT(_o) \
(IsDelegatorObject( (_o)->ObjectType ) ? \
((_o)->IsDelegationSupported ? NO_ERROR : ERROR_NOT_SUPPORTED) : \
ERROR_INVALID_PARAMETER )
//
// Macro to set a property in the cache.
//
// This macro acts as a wrapper around the code to set the property.
// The macro detects the mode of the caller and properly handles the following:
//
// * Ensures object supports this "dirty" bit
// * Sets the appropriate "dirty" bit depending on mode
// * Avoids setting the property on AzUpdateCache if the property is dirty
//
// The correct calling sequence of the macros is:
//
// case AZ_PROP_XXX:
// BEGIN_SETPROP( &WinStatus, Object, AZ_DIRTY_XXX ) {
// WinStatus = f( Object->Property );
// /* Optionally */ if ( WinStatus != NO_ERROR ) goto Cleanup
// } END_SETPROP;
// break;
//
extern DWORD AzGlObjectAllDirtyBits[];
#define BEGIN_SETPROP( __WinStatusPtr, __ObjectPtr, __Flags, __DirtyBit ) \
{ \
DWORD *_WinStatusPtr = (__WinStatusPtr); \
PGENERIC_OBJECT _GenericObject = ((PGENERIC_OBJECT)(__ObjectPtr)); \
ULONG _DirtyBit = (__DirtyBit); \
ULONG _Flags = (__Flags); \
BOOLEAN _DoSetProperty = FALSE; \
\
if ( (AzGlObjectAllDirtyBits[_GenericObject->ObjectType] & _DirtyBit) == 0 ) { \
AzPrint(( AZD_INVPARM, "SetProperty: Object doesn't support dirty bit 0x%lx\n", _DirtyBit )); \
*_WinStatusPtr = ERROR_INVALID_PARAMETER; \
\
} else if ( IsNormalFlags(_Flags) ) { \
\
_DoSetProperty = TRUE; \
AzPrint(( AZD_PERSIST_MORE, "IsNormalFlags(_Flags) = TRUE\n" )); \
if ( (_Flags & AZP_FLAGS_SETTING_TO_DEFAULT) == 0 && !AzpAzStoreVersionAllowWrite(_GenericObject->AzStoreObject) ) \
{ \
*_WinStatusPtr = ERROR_REVISION_MISMATCH; \
} \
else { \
_DoSetProperty = TRUE; \
} \
\
} else { \
\
if ( (_GenericObject->DirtyBits & _DirtyBit) == 0 ) { \
AzPrint(( AZD_PERSIST_MORE, "(_GenericObject->DirtyBits & _DirtyBit) = 0\n" )); \
_DoSetProperty = TRUE; \
} else if (IsRefreshFlags(_Flags)) { \
AzPrint(( AZD_PERSIST_MORE, "IsRefreshFlags(_Flags) = TRUE\n" )); \
_DoSetProperty = TRUE; \
} else { \
*_WinStatusPtr = NO_ERROR; \
} \
\
} \
\
if ( _DoSetProperty ) { \
#define END_SETPROP( __PropHasChanged ) \
if ( *_WinStatusPtr == NO_ERROR && \
(_Flags & AZP_FLAGS_SETTING_TO_DEFAULT) == 0 ) { \
if ( IsNormalFlags( _Flags ) ) { \
if ( (__PropHasChanged) ) { \
_GenericObject->DirtyBits |= _DirtyBit; \
} \
} else { \
ASSERT( AzpIsCritsectLocked( &_GenericObject->AzStoreObject->PersistCritSect ) ); \
ASSERT( (_GenericObject->Flags & GENOBJ_FLAGS_PERSIST_OK) == 0 ); \
_GenericObject->PersistDirtyBits |= _DirtyBit; \
} \
\
} \
} \
}
//
// Macro to do validity checking after setting a property in the cache.
//
// This macro acts as a wrapper around the code to do the validity checking.
// Some validity checking is only appropriate only when the caller is the UI
// or application. This validity checking may not be valid when setting default
// values or when populating the cache from the store.
//
// The correct calling sequence of the macros is:
//
// case AZ_PROP_XXX:
// BEGIN_SETPROP( &WinStatus, Object, AZ_DIRTY_XXX ) {
//
// BEGIN_VALIDITY_CHECKING( Flags ) {
// checks to see if property is valid
// } END_VALIDITY_CHECKING;
//
// WinStatus = f( Object->Property );
//
// /* Optionally */ if ( WinStatus != NO_ERROR ) goto Cleanup
// } END_SETPROP;
// break;
//
#define DO_VALIDITY_CHECKING( _Flags ) \
( IsNormalFlags(_Flags) && (_Flags & (AZP_FLAGS_SETTING_TO_DEFAULT)) == 0 )
#define BEGIN_VALIDITY_CHECKING( _Flags ) \
{ \
\
if ( DO_VALIDITY_CHECKING( _Flags ) ) {
#define END_VALIDITY_CHECKING \
} \
}
//
// Macro to handle validity check on string length.
//
// The correct calling sequence of the macros is:
//
// case AZ_PROP_XXX:
// BEGIN_SETPROP( &WinStatus, Object, AZ_DIRTY_XXX ) {
//
// //
// // Capture the input string
// //
//
// WinStatus = AzpCaptureString( &CapturedString,
// (LPWSTR) PropertyValue,
// CHECK_STRING_LENGTH( Flags, AZ_MAX_XXX),
// TRUE ); // NULL is OK
//
// if ( WinStatus != NO_ERROR ) {
// goto Cleanup;
// }
//
// WinStatus = f( Object->Property );
//
// /* Optionally */ if ( WinStatus != NO_ERROR ) goto Cleanup
// } END_SETPROP;
// break;
//
#define CHECK_STRING_LENGTH( _Flags, _MaxLen ) \
(DO_VALIDITY_CHECKING( _Flags ) ? (_MaxLen) : 0xFFFFFFFF)
/////////////////////////////////////////////////////////////////////////////
//
// Procedure definitions
//
/////////////////////////////////////////////////////////////////////////////
VOID
ObInitGenericHead(
IN PGENERIC_OBJECT_HEAD GenericObjectHead,
IN ULONG ObjectType,
IN PGENERIC_OBJECT ParentGenericObject,
IN PGENERIC_OBJECT_HEAD SiblingGenericObjectHead OPTIONAL
);
VOID
ObFreeGenericObject(
IN PGENERIC_OBJECT GenericObject
);
VOID
ObIncrHandleRefCount(
IN PGENERIC_OBJECT GenericObject
);
DWORD
ObDecrHandleRefCount(
IN PGENERIC_OBJECT GenericObject
);
DWORD
ObGetHandleType(
IN PGENERIC_OBJECT Handle,
IN BOOL AllowDeletedObjects,
OUT PULONG ObjectType
);
DWORD
ObReferenceObjectByName(
IN PGENERIC_OBJECT_HEAD GenericObjectHead,
IN PAZP_STRING ObjectName,
IN ULONG Flags,
OUT PGENERIC_OBJECT *RetGenericObject
);
DWORD
ObReferenceObjectByHandle(
IN PGENERIC_OBJECT Handle,
IN BOOL AllowDeletedObjects,
IN BOOLEAN RefreshCache,
IN ULONG ObjectType
);
VOID
ObDereferenceObject(
IN PGENERIC_OBJECT GenericObject
);
typedef DWORD
(OBJECT_INIT_ROUTINE)(
IN PGENERIC_OBJECT ParentGenericObject,
IN PGENERIC_OBJECT ChildGenericObject
);
typedef DWORD
(OBJECT_NAME_CONFLICT_ROUTINE)(
IN PGENERIC_OBJECT ParentGenericObject,
IN PAZP_STRING ChildObjectNameString
);
typedef VOID
(OBJECT_FREE_ROUTINE)(
IN PGENERIC_OBJECT GenericObject
);
typedef DWORD
(OBJECT_GET_PROPERTY_ROUTINE)(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
OUT PVOID *PropertyValue
);
typedef DWORD
(OBJECT_SET_PROPERTY_ROUTINE)(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
IN PVOID PropertyValue
);
typedef DWORD
(OBJECT_ADD_PROPERTY_ITEM_ROUTINE)(
IN PGENERIC_OBJECT GenericObject,
IN PGENERIC_OBJECT_LIST GenericObjectList,
IN PGENERIC_OBJECT LinkedToObject
);
DWORD
ObCreateObject(
IN PGENERIC_OBJECT ParentGenericObject,
IN PGENERIC_OBJECT_HEAD GenericChildHead,
IN ULONG ChildObjectType,
IN PAZP_STRING ChildObjectNameString,
IN GUID *ChildObjectGuid OPTIONAL,
IN ULONG Flags,
OUT PGENERIC_OBJECT *RetChildGenericObject
);
//
// Flags to various internal functions
// The low order 2 bytes of this DWORD are shared with the AZPE_FLAGS defines in azper.h
//
#define AZP_FLAGS_SETTING_TO_DEFAULT 0x00010000 // Property is being set to default value
#define AZP_FLAGS_BY_GUID 0x00020000 // Name based routine should use GUID instead
#define AZP_FLAGS_ALLOW_DELETED_OBJECTS 0x00040000 // Allow deleted objects to be found
#define AZP_FLAGS_REFRESH_CACHE 0x00080000 // Ensure cache is up to date
#define AZP_FLAGS_RECONCILE 0x00100000 // The caller is AzpPersistReconcile
//
// Macro to return TRUE if this is a normal caller
// (e.g., the app and not an internal caller)
//
#define IsNormalFlags( _Flags ) (((_Flags) & (AZPE_FLAGS_PERSIST_MASK|AZP_FLAGS_RECONCILE)) == 0 )
#define IsRefreshFlags( _Flags ) (((_Flags) & (AZPE_FLAGS_PERSIST_REFRESH)) != 0 )
DWORD
ObGetProperty(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
OUT PVOID *PropertyValue
);
DWORD
ObSetProperty(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
IN PVOID PropertyValue
);
DWORD
ObSetPropertyToDefault(
IN PGENERIC_OBJECT GenericObject,
IN ULONG DirtyBits
);
DWORD
ObCommonCreateObject(
IN PGENERIC_OBJECT ParentGenericObject,
IN ULONG ParentObjectType,
IN PGENERIC_OBJECT_HEAD GenericChildHead,
IN ULONG ChildObjectType,
IN LPCWSTR ChildObjectName,
IN DWORD Reserved,
OUT PGENERIC_OBJECT *RetChildGenericObject
);
DWORD
ObCommonOpenObject(
IN PGENERIC_OBJECT ParentGenericObject,
IN ULONG ParentObjectType,
IN PGENERIC_OBJECT_HEAD GenericChildHead,
IN ULONG ChildObjectType,
IN LPCWSTR ChildObjectName,
IN DWORD Reserved,
OUT PGENERIC_OBJECT *RetChildGenericObject
);
DWORD
ObEnumObjects(
IN PGENERIC_OBJECT_HEAD GenericChildHead,
IN BOOL EnumerateDeletedObjects,
IN BOOL RefreshCache,
IN OUT PULONG EnumerationContext,
OUT PGENERIC_OBJECT *RetChildGenericObject
);
DWORD
ObCommonEnumObjects(
IN PGENERIC_OBJECT ParentGenericObject,
IN ULONG ParentObjectType,
IN PGENERIC_OBJECT_HEAD GenericChildHead,
IN OUT PULONG EnumerationContext,
IN DWORD Reserved,
OUT PGENERIC_OBJECT *RetChildGenericObject
);
DWORD
ObCommonGetProperty(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
IN DWORD Reserved,
OUT PVOID *PropertyValue
);
DWORD
ObCommonSetProperty(
IN PGENERIC_OBJECT GenericObject,
IN ULONG PropertyId,
IN DWORD Reserved,
IN PVOID PropertyValue
);
VOID
ObMarkObjectDeleted(
IN PGENERIC_OBJECT GenericObject
);
DWORD
ObCommonDeleteObject(
IN PGENERIC_OBJECT ParentGenericObject,
IN ULONG ParentObjectType,
IN PGENERIC_OBJECT_HEAD GenericChildHead,
IN ULONG ChildObjectType,
IN LPCWSTR ChildObjectName,
IN DWORD Reserved
);
VOID
ObInitObjectList(
IN OUT PGENERIC_OBJECT_LIST GenericObjectList,
IN PGENERIC_OBJECT_LIST NextGenericObjectList OPTIONAL,
IN BOOL IsBackLink,
IN ULONG LinkPairId,
IN ULONG DirtyBit,
IN PGENERIC_OBJECT_HEAD GenericObjectHead0 OPTIONAL,
IN PGENERIC_OBJECT_HEAD GenericObjectHead1 OPTIONAL,
IN PGENERIC_OBJECT_HEAD GenericObjectHead2 OPTIONAL
);
DWORD
ObAddPropertyItem(
IN PGENERIC_OBJECT GenericObject,
IN PGENERIC_OBJECT_LIST GenericObjectList,
IN ULONG Flags,
IN PAZP_STRING ObjectName
);
DWORD
ObLookupPropertyItem(
IN PGENERIC_OBJECT_LIST GenericObjectList,
IN PAZP_STRING ObjectName,
OUT PULONG InsertionPoint OPTIONAL
);
DWORD
ObRemovePropertyItem(
IN PGENERIC_OBJECT GenericObject,
IN PGENERIC_OBJECT_LIST GenericObjectList,
IN PAZP_STRING ObjectName
);
PAZ_STRING_ARRAY
ObGetPropertyItems(
IN PGENERIC_OBJECT_LIST GenericObjectList
);
PAZ_GUID_ARRAY
ObGetPropertyItemGuids(
IN PGENERIC_OBJECT_LIST GenericObjectList
);
VOID
ObRemoveObjectListLink(
IN PGENERIC_OBJECT GenericObject,
IN PGENERIC_OBJECT_LIST GenericObjectList,
IN ULONG Index
);
VOID
ObRemoveObjectListLinks(
IN PGENERIC_OBJECT GenericObject
);
VOID
ObFreeObjectList(
IN PGENERIC_OBJECT GenericObject,
IN OUT PGENERIC_OBJECT_LIST GenericObjectList
);
DWORD
ObCheckNameConflict(
IN PGENERIC_OBJECT_HEAD GenericObjectHead,
IN PAZP_STRING ObjectNameString,
IN ULONG ConflictListOffset,
IN ULONG GrandchildListOffset,
IN ULONG GrandChildConflictListOffset
);
DWORD
ObMapPropIdToObjectList(
IN PGENERIC_OBJECT GenericObject,
IN ULONG PropertyId,
OUT PGENERIC_OBJECT_LIST *GenericObjectList,
OUT PULONG ObjectType
);
BOOLEAN
ObLookupDelta(
IN ULONG DeltaFlags,
IN GUID *Guid,
IN PAZP_PTR_ARRAY AzpPtrArray,
OUT PULONG InsertionPoint OPTIONAL
);
DWORD
ObAddDeltaToArray(
IN ULONG DeltaFlags,
IN GUID *Guid,
IN PAZP_PTR_ARRAY AzpPtrArray,
IN BOOLEAN DiscardDeletes
);
VOID
ObFreeDeltaArray(
IN PAZP_PTR_ARRAY DeltaArray,
IN BOOLEAN FreeAllEntries
);
BOOLEAN
ObAllocateNewName(
IN PGENERIC_OBJECT GenericObject,
IN PAZP_STRING ObjectName
);
VOID
ObFreeNewName(
IN PNEW_OBJECT_NAME NewObjectName
);
DWORD
ObUnloadChildGenericHeads(
IN PGENERIC_OBJECT pParentObject
);
#ifdef __cplusplus
}
#endif