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.
 
 
 
 
 
 

1210 lines
32 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
app.cxx
Abstract:
Routines implementing the Application object
Author:
Cliff Van Dyke (cliffv) 11-Apr-2001
--*/
#include "pch.hxx"
//
// Define the default values for all scalar attributes
//
AZP_DEFAULT_VALUE AzGlApplicationDefaultValues[] = {
{ AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID, AZ_DIRTY_APPLICATION_AUTHZ_INTERFACE_CLSID, NULL },
{ AZ_PROP_APPLICATION_VERSION, AZ_DIRTY_APPLICATION_VERSION, NULL },
{ 0, 0, NULL }
};
DWORD
AzpApplicationGenerateInitializationAudit(
PAZP_APPLICATION Application,
PAZP_AZSTORE AzAuthorizationStore
)
/*++
Routine Description:
This routine generates an application initialization audit.
Arguments:
Application - Application which just initialized.
AzAuthorizationStore - Authorization Store maitaining the application.
Return Value:
NO_ERROR - The operation was successful
ERROR_NOT_ENOUGH_MEMORY - not enough memory
Other exception status codes
--*/
{
DWORD WinStatus = NO_ERROR;
AUTHZ_AUDIT_EVENT_HANDLE hAuditEvent = NULL;
PAUDIT_PARAMS pAuditParams = NULL;
BOOL b;
//
// If audit handle is NULL, then do no generate any audits
//
if ( (AzAuthorizationStore->hApplicationInitializationAuditEventType == NULL) ) {
return NO_ERROR;
}
//
// The audit format will be as follows:
// %tApplication Name:%t%1%n
// %tApplication Instance ID:%t%2%n
// %tClient Name:%t%3%n
// %tClient Domain:%t%4%n
// %tClient ID:%t%5%n
// %tPolicy Store URL:%t%6%n
//
if (!AuthziAllocateAuditParams(
&pAuditParams,
AZP_APPINIT_AUDITPARAMS_NO
)) {
goto Cleanup;
}
//
// Put the audit parameters in the array.
//
b = AuthziInitializeAuditParamsWithRM( APF_AuditSuccess,
Application->AuthzResourceManager,
AZP_APPINIT_AUDITPARAMS_NO,
pAuditParams,
APT_String,Application->GenericObject.ObjectName->ObjectName.String,
APT_Luid, Application->InstanceId,
APT_LogonId | AP_PrimaryLogonId,
APT_String, AzAuthorizationStore->PolicyUrl.String );
if ( !b ) {
WinStatus = GetLastError();
goto Cleanup;
}
//
// Initialize the audit event handle with the audit parameters.
//
b = AuthziInitializeAuditEvent( 0,
NULL,
AzAuthorizationStore->hApplicationInitializationAuditEventType,
pAuditParams,
NULL,
INFINITE,
L"", L"", L"", L"",
&hAuditEvent );
if ( !b ) {
WinStatus = GetLastError();
goto Cleanup;
}
//
// Send the audit to Lsa.
//
b = AuthziLogAuditEvent( 0,
hAuditEvent,
NULL );
if ( !b ) {
WinStatus = GetLastError();
goto Cleanup;
}
Cleanup:
//
// Free the audit event handle.
//
if ( hAuditEvent != NULL ) {
(VOID) AuthzFreeAuditEvent( hAuditEvent );
}
//
// Free the PAUDIT_PARAMS structure
//
if ( pAuditParams ) {
AuthziFreeAuditParams( pAuditParams );
}
return WinStatus;
}
DWORD
AzpApplicationInit(
IN PGENERIC_OBJECT ParentGenericObject,
IN PGENERIC_OBJECT ChildGenericObject
)
/*++
Routine Description:
This routine is a worker routine for AzApplicationCreate. It does any object specific
initialization that needs to be done.
On entry, AzGlResource must be locked exclusively.
Arguments:
ParentGenericObject - Specifies the parent object to add the child object onto.
The reference count has been incremented on this object.
ChildGenericObject - Specifies the newly allocated child object.
The reference count has been incremented on this object.
Return Value:
NO_ERROR - The operation was successful
ERROR_NOT_ENOUGH_MEMORY - not enough memory
Other exception status codes
--*/
{
PAZP_APPLICATION Application = (PAZP_APPLICATION) ChildGenericObject;
PAZP_AZSTORE AzAuthorizationStore = (PAZP_AZSTORE) ParentGenericObject;
NTSTATUS Status;
DWORD WinStatus = NO_ERROR;
HANDLE hToken = NULL;
TOKEN_PRIVILEGES NewState = {0};
TOKEN_PRIVILEGES OldState = {0};
BOOL PrivilegeAdjusted = FALSE;
DWORD AuthzFlags = 0;
//
// Initialization
//
ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
//
// Sanity check the parent
//
ASSERT( ParentGenericObject->ObjectType == OBJECT_TYPE_AZAUTHSTORE );
UNREFERENCED_PARAMETER( ParentGenericObject );
//
// If policy store has been initialized in store manage mode only,
// then we do not need to initialize the authz resource manager for auditing
//
if ( AzpOpenToManageStore(AzAuthorizationStore) ) {
AuthzFlags = AUTHZ_RM_FLAG_NO_AUDIT;
} else {
//
// Get the current token to adjust the Audit privilege.
//
WinStatus = AzpGetCurrentToken( &hToken );
if ( WinStatus != NO_ERROR ) {
return WinStatus;
}
//
// Enable the audit privilege.
//
WinStatus = AzpChangeSinglePrivilege(
SE_AUDIT_PRIVILEGE,
hToken,
&NewState,
&OldState );
if ( WinStatus == NO_ERROR ) {
PrivilegeAdjusted = TRUE;
} else {
//
// If auditing is not mandatory, then initialize the resource manager
// with no audit flag
//
if ( (AzAuthorizationStore->InitializeFlag & AZ_AZSTORE_FLAG_AUDIT_IS_CRITICAL) == 0) {
WinStatus = NO_ERROR;
AuthzFlags = AUTHZ_RM_FLAG_NO_AUDIT;
} else {
goto Cleanup;
}
}
}
if ( !AuthzInitializeResourceManager(
AuthzFlags,
NULL, // No Callback ace function
NULL, // We compute our own dynamic groups
NULL, // " "
Application->GenericObject.ObjectName->ObjectName.String,
&Application->AuthzResourceManager ) ) {
WinStatus = GetLastError();
if ( WinStatus != NO_ERROR ) {
if ( WinStatus == ERROR_ACCESS_DENIED ) {
WinStatus = NO_ERROR;
//
// the caller may be on an impersonated thread which doesn't have
// access to the process token, let's call again to initialize
// resource manager on the impersonated thread
//
if ( !AuthzInitializeResourceManager(
AuthzFlags |
AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION, // allow impersonation thread
NULL, // No Callback ace function
NULL, // We compute our own dynamic groups
NULL, // " "
Application->GenericObject.ObjectName->ObjectName.String,
&Application->AuthzResourceManager ) ) {
WinStatus = GetLastError();
goto Cleanup;
}
} else {
goto Cleanup;
}
}
}
//
// Initialize the lists of child objects
// Let the generic object manager know all of the types of children we support
//
ChildGenericObject->ChildGenericObjectHead = &Application->Operations;
// List of child operations
ObInitGenericHead( &Application->Operations,
OBJECT_TYPE_OPERATION,
ChildGenericObject,
&Application->Tasks );
// List of child tasks
ObInitGenericHead( &Application->Tasks,
OBJECT_TYPE_TASK,
ChildGenericObject,
&Application->Scopes );
// List of child scopes
ObInitGenericHead( &Application->Scopes,
OBJECT_TYPE_SCOPE,
ChildGenericObject,
&Application->Groups );
// List of child groups
ObInitGenericHead( &Application->Groups,
OBJECT_TYPE_GROUP,
ChildGenericObject,
&Application->Roles );
// List of child roles
ObInitGenericHead( &Application->Roles,
OBJECT_TYPE_ROLE,
ChildGenericObject,
&Application->ClientContexts );
// List of child ClientContexts
ObInitGenericHead( &Application->ClientContexts,
OBJECT_TYPE_CLIENT_CONTEXT,
ChildGenericObject,
&ChildGenericObject->AzpSids );
// List of child AzpSids
ObInitGenericHead( &ChildGenericObject->AzpSids,
OBJECT_TYPE_SID,
ChildGenericObject,
NULL );
//
// Allocate a luid for this instance of the application
//
Status = NtAllocateLocallyUniqueId(&Application->InstanceId);
if ( !NT_SUCCESS(Status) ) {
WinStatus = RtlNtStatusToDosError( Status );
goto Cleanup;
}
//
// By default generate audits
//
Application->GenericObject.IsGeneratingAudits = TRUE;
//
// Generate app initialization audit if the authorization store level boolean
// is true and we are not in manage store mode
//
if ( AzAuthorizationStore->GenericObject.IsGeneratingAudits &&
!AzpOpenToManageStore(AzAuthorizationStore) ) {
WinStatus = AzpApplicationGenerateInitializationAudit( Application,
AzAuthorizationStore );
if ( WinStatus != NO_ERROR ) {
goto Cleanup;
}
}
//
// If the parent AzAuthorizationStore object support delegation, then the application object
// supports the following options:
// . AZPE_OPTIONS_SUPPORTS_DACL
// . AZPE_OPTIONS_SUPPORTS_DELEGATION
// . AZPE_OPTIONS_SUPPORTS_SACL
//
if ( CHECK_DELEGATION_SUPPORT( ParentGenericObject ) == NO_ERROR ) {
ChildGenericObject->IsAclSupported = TRUE;
ChildGenericObject->IsDelegationSupported = TRUE;
ChildGenericObject->IsSACLSupported = TRUE;
}
//
// If the provider does not support Lazy load, set the AreChildrenLoaded to
// TRUE. Else leave it as FALSE. This will be set to true during the call
// to AzPersistUpdateChildrenCache.
//
if ( !(AzAuthorizationStore->ChildLazyLoadSupported) ) {
ChildGenericObject->AreChildrenLoaded = TRUE;
} else {
ChildGenericObject->AreChildrenLoaded = FALSE;
}
//
// Set the boolean to indicate that the application needs to be unloaded to FALSE
// For providers where lazy load is not supported, this will always remain FALSE.
//
((PAZP_APPLICATION)ChildGenericObject)->UnloadApplicationObject = FALSE;
//
// Set the boolean to indicate that the application is closed. This will
// be set to false whenever the application is opened by the user (lazy
// loading the application is similar to open)
//
ChildGenericObject->ObjectClosed = TRUE;
//
// Set the AppSequenceNumber to 1. Whenever the application is closed,
// increment the AppSequenceNumber. This is used to track invalid COM
// handles to the application object after the application object has
// been closed
//
((PAZP_APPLICATION)ChildGenericObject)->AppSequenceNumber = 1;
Cleanup:
//
// If we had adjusted the audit privilege, revert to the original state.
//
if ( PrivilegeAdjusted ) {
DWORD TempWinStatus;
TempWinStatus = AzpChangeSinglePrivilege(
0, // This is ignored since OldState is NULL.
hToken,
&OldState,
NULL ); // This should be set to NULL to specify REVERT.
ASSERT( TempWinStatus == NO_ERROR );
}
if ( hToken != NULL ) {
CloseHandle( hToken );
hToken = NULL;
}
if ( WinStatus != NO_ERROR ) {
//
// Free the authz resource manager handle.
//
if ( Application->AuthzResourceManager != NULL ) {
AuthzFreeResourceManager( Application->AuthzResourceManager );
Application->AuthzResourceManager = NULL;
}
}
return WinStatus;
}
VOID
AzpApplicationFree(
IN PGENERIC_OBJECT GenericObject
)
/*++
Routine Description:
This routine is a worker routine for Application object free. It does any object specific
cleanup that needs to be done.
On entry, AzGlResource must be locked exclusively.
Arguments:
GenericObject - Specifies a pointer to the object to be deleted.
Return Value:
None
--*/
{
PAZP_APPLICATION Application = (PAZP_APPLICATION) GenericObject;
//
// Initialization
//
ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
//
// Free any local strings
//
AzpFreeString( &Application->AppVersion );
AzpFreeString( &Application->AuthzInterfaceClsid );
if ( Application->AuthzResourceManager != NULL ) {
if ( !AuthzFreeResourceManager( Application->AuthzResourceManager ) ) {
ASSERT( FALSE );
}
}
}
DWORD
AzpApplicationGetProperty(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
OUT PVOID *PropertyValue
)
/*++
Routine Description:
This routine is the Application specific worker routine for AzGetProperty.
It does any object specific property gets.
On entry, AzGlResource must be locked shared.
Arguments:
GenericObject - Specifies a pointer to the object to be queried
Flags - Specifies internal flags
AZP_FLAGS_BY_GUID - name lists should be returned as GUID lists
AZP_FLAGS_PERSIST_* - Call is from the persistence provider
PropertyId - Specifies which property to return.
PropertyValue - Specifies a pointer to return the property in.
The returned pointer must be freed using AzFreeMemory.
The returned value and type depends in PropertyId. The valid values are:
AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID LPWSTR - CLSID of the IAppAuthzInterface interface supplied by the application
AZ_PROP_APPLICATION_VERSION LPWSTR - Version string for the application
Return Value:
Status of the operation
--*/
{
DWORD WinStatus = NO_ERROR;
PAZP_APPLICATION Application = (PAZP_APPLICATION) GenericObject;
UNREFERENCED_PARAMETER( Flags );
//
// Initialization
//
ASSERT( AzpIsLockedShared( &AzGlResource ) );
*PropertyValue = NULL;
//
// Return any object specific attribute
//
switch ( PropertyId ) {
//
// Return IAppAuthzInterface CLSID
//
case AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID:
*PropertyValue = AzpGetStringProperty( &Application->AuthzInterfaceClsid );
if ( *PropertyValue == NULL ) {
WinStatus = ERROR_NOT_ENOUGH_MEMORY;
}
break;
//
// Return application version to the caller
//
case AZ_PROP_APPLICATION_VERSION:
*PropertyValue = AzpGetStringProperty( &Application->AppVersion );
if ( *PropertyValue == NULL ) {
WinStatus = ERROR_NOT_ENOUGH_MEMORY;
}
break;
default:
AzPrint(( AZD_INVPARM, "AzApplicationGetProperty: invalid prop id %ld\n", PropertyId ));
WinStatus = ERROR_INVALID_PARAMETER;
break;
}
return WinStatus;
}
DWORD
AzpApplicationSetProperty(
IN PGENERIC_OBJECT GenericObject,
IN ULONG Flags,
IN ULONG PropertyId,
IN PVOID PropertyValue
)
/*++
Routine Description:
This routine is the Application object specific worker routine for AzSetProperty.
It does any object specific property sets.
On entry, AzGlResource must be locked exclusive.
Arguments:
GenericObject - Specifies a pointer to the object to be modified
Flags - Specifies flags controlling to operation of the routine
AZP_FLAGS_SETTING_TO_DEFAULT - Property is being set to default value
AZP_FLAGS_PERSIST_* - Call is from the persistence provider
PropertyId - Specifies which property to set.
PropertyValue - Specifies a pointer to the property.
The specified value and type depends in PropertyId. The valid values are:
AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID LPWSTR - CLSID of the IAppAuthzInterface interface supplied by the application
AZ_PROP_APPLICATION_VERSION LPWSTR - Version string for the application
Return Value:
Status of the operation
--*/
{
DWORD WinStatus = NO_ERROR;
PAZP_APPLICATION Application = (PAZP_APPLICATION) GenericObject;
AZP_STRING CapturedString;
BOOL bHasChanged = TRUE;
//
// Initialization
//
UNREFERENCED_PARAMETER( Flags );
ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
AzpInitString( &CapturedString, NULL );
//
// Set any object specific attribute
//
switch ( PropertyId ) {
//
// Set IAppAuthzInterface CLSID attribute
//
case AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID:
BEGIN_SETPROP( &WinStatus, Application, Flags, AZ_DIRTY_APPLICATION_AUTHZ_INTERFACE_CLSID ) {
//
// Capture the input string
//
WinStatus = AzpCaptureString( &CapturedString,
(LPWSTR) PropertyValue,
CHECK_STRING_LENGTH( Flags, 512), // Guess larger than needed
TRUE ); // NULL is OK
if ( WinStatus != NO_ERROR ) {
goto Cleanup;
}
//
// Do parameter validity checking
//
BEGIN_VALIDITY_CHECKING( Flags ) {
GUID TempGuid;
//
// It must syntactically be a UUID
//
WinStatus = UuidFromString( CapturedString.String,
&TempGuid );
if ( WinStatus != NO_ERROR ) {
AzPrint(( AZD_INVPARM, "AzpApplicationSetProperty: cannot convert CLSID %ws %ld\n", CapturedString.String, WinStatus ));
goto Cleanup;
}
} END_VALIDITY_CHECKING;
//
// Swap the old/new names
//
AzpSwapStrings( &CapturedString, &Application->AuthzInterfaceClsid );
} END_SETPROP(bHasChanged);
break;
//
// Set application version on the object
//
case AZ_PROP_APPLICATION_VERSION:
BEGIN_SETPROP( &WinStatus, Application, Flags, AZ_DIRTY_APPLICATION_VERSION ) {
//
// Capture the input string
//
WinStatus = AzpCaptureString( &CapturedString,
(LPWSTR) PropertyValue,
CHECK_STRING_LENGTH( Flags, AZ_MAX_APPLICATION_VERSION_LENGTH),
TRUE ); // NULL is OK
if ( WinStatus != NO_ERROR ) {
goto Cleanup;
}
//
// Swap the old/new names
//
AzpSwapStrings( &CapturedString, &Application->AppVersion );
} END_SETPROP(bHasChanged);
break;
default:
AzPrint(( AZD_INVPARM, "AzpApplicationSetProperty: invalid prop id %ld\n", PropertyId ));
WinStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
//
// Free any local resources
//
Cleanup:
AzpFreeString( &CapturedString );
return WinStatus;
}
DWORD
WINAPI
AzApplicationCreate(
IN AZ_HANDLE AzAuthorizationStoreHandle,
IN LPCWSTR ApplicationName,
IN DWORD Reserved,
OUT PAZ_HANDLE ApplicationHandle
)
/*++
Routine Description:
This routine adds an application into the scope of the specified AzAuthorizationStore. It also sets
Application object specific optional characteristics using the parent AzAuthorizationStore object.
Arguments:
AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
ApplicationName - Specifies the name of the application to add.
Reserved - Reserved. Must by zero.
ApplicationHandle - Return a handle to the application.
The caller must close this handle by calling AzCloseHandle.
Return Value:
NO_ERROR - The operation was successful
ERROR_ALREADY_EXISTS - An object by that name already exists
--*/
{
//
// Call the common routine to do most of the work
//
return ObCommonCreateObject(
(PGENERIC_OBJECT) AzAuthorizationStoreHandle,
OBJECT_TYPE_AZAUTHSTORE,
&(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
OBJECT_TYPE_APPLICATION,
ApplicationName,
Reserved,
(PGENERIC_OBJECT *) ApplicationHandle );
}
DWORD
WINAPI
AzApplicationOpen(
IN AZ_HANDLE AzAuthorizationStoreHandle,
IN LPCWSTR ApplicationName,
IN DWORD Reserved,
OUT PAZ_HANDLE ApplicationHandle
)
/*++
Routine Description:
This routine opens an application into the scope of the specified AzAuthorizationStore.
Arguments:
AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
ApplicationName - Specifies the name of the application to open
Reserved - Reserved. Must by zero.
ApplicationHandle - Return a handle to the application.
The caller must close this handle by calling AzCloseHandle.
Return Value:
NO_ERROR - The operation was successful
ERROR_NOT_FOUND - There is no application by that name
--*/
{
DWORD WinStatus = 0;
//
// Call the common routine to do most of the work
//
WinStatus = ObCommonOpenObject(
(PGENERIC_OBJECT) AzAuthorizationStoreHandle,
OBJECT_TYPE_AZAUTHSTORE,
&(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
OBJECT_TYPE_APPLICATION,
ApplicationName,
Reserved,
(PGENERIC_OBJECT *) ApplicationHandle );
if ( WinStatus == NO_ERROR ) {
//
// Load the children if the Application object has already been submitted to
// the store
//
if ( !((PGENERIC_OBJECT) *ApplicationHandle)->AreChildrenLoaded ) {
//
// Grab the resource lock exclusive
//
AzpLockResourceExclusive( &AzGlResource );
WinStatus = AzPersistUpdateChildrenCache(
(PGENERIC_OBJECT) *ApplicationHandle
);
AzpUnlockResource( &AzGlResource );
if ( WinStatus != NO_ERROR ) {
//
// Dereference the application handle and return nothing to the caller
//
AzCloseHandle( (PGENERIC_OBJECT)*ApplicationHandle, 0 );
*ApplicationHandle = NULL;
}
}
}
//
// The application object is no longer closed. Mark that in the object.
//
if ( WinStatus == NO_ERROR ) {
((PGENERIC_OBJECT)*ApplicationHandle)->ObjectClosed = FALSE;
}
return WinStatus;
}
DWORD
WINAPI
AzApplicationClose(
IN AZ_HANDLE AzAuthorizationStoreHandle,
IN LPCWSTR pApplicationName,
IN LONG lFlags
)
/*++
Routine Description:
This routine unloads the children of the application object specified
by pApplicationName from the cache. It will leave the application object
in cache however.
If the provider does not support lazy loading of objects, then it is not
possible to call the close API. Return ERROR_NOT_SUPPORTED.
Arguments:
AzAuthorizationStoreHandle - Handle to the authorization store object
pApplicationName - Name of the application to be unloaded from the cache
lFlags - Flag specifying the behavior of the close
AZ_AZSTORE_FORCE_APPLICATION_CLOSE - Forcefully remove all children
of the specified of application from cache
If no flags are specified, then the application will be unloaded only
when the reference handle count reaches zero.
Return Value:
NO_ERROR - The application was successfully unloaded from the cache
ERROR_NOT_SUPPORTED - Provider does not support this API
ERROR_NOT_ENOUGH_MEMORY - Lack of resources
Other status codes
--*/
{
DWORD WinStatus = NO_ERROR;
PGENERIC_OBJECT pApplication = NULL;
AZP_STRING AppName;
BOOLEAN bResourceLocked = FALSE;
//
// Validation
//
ASSERT( AzAuthorizationStoreHandle != INVALID_HANDLE_VALUE );
AzpInitString( &AppName, NULL );
//
// If the store is a provider that does not support lazy load,
// then we do not support unloading an application for that
// provider
//
if ( !((PAZP_AZSTORE)AzAuthorizationStoreHandle)->ChildLazyLoadSupported ) {
WinStatus = ERROR_NOT_SUPPORTED;
goto Cleanup;
}
//
// Reference the application object by name
//
WinStatus = AzpCaptureString(
&AppName,
pApplicationName,
AZ_MAX_APPLICATION_NAME_LENGTH,
FALSE // NULL not OK
);
if ( WinStatus != NO_ERROR ) {
AzPrint(( AZD_INVPARM,
"AzApplicationClose: Failed to capture application name: %ld\n",
WinStatus
));
goto Cleanup;
}
//
// Grab the cache lock exclusively to unload the application
//
AzpLockResourceExclusive( &AzGlResource );
bResourceLocked = TRUE;
WinStatus = ObReferenceObjectByName(
&((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications,
&AppName,
0, // No flags
&pApplication
);
if ( WinStatus != NULL ) {
AzPrint(( AZD_REF,
"AzApplicationClose: Cannot reference application %ws: %ld\n",
pApplicationName,
WinStatus
));
goto Cleanup;
}
//
// Check the flags that were sent by the user. If the user
// does not wish to perform a forcefull unloading of the application,
// then simply set the boolean on the application object indicating
// that the application object needs to be unloaded when the handle
// reference count reaches 0.
//
if ( (lFlags & AZ_AZSTORE_FORCE_APPLICATION_CLOSE) != 0 ) {
//
// Forcefull close required
//
//
// Call the routine to clean up all the child generic heads
//
WinStatus = ObUnloadChildGenericHeads( pApplication );
if ( WinStatus != ERROR_NOT_SUPPORTED && WinStatus != NO_ERROR ) {
//
// Update the children cache of this application object
//
DWORD TempWinStatus = NO_ERROR;
TempWinStatus = AzPersistUpdateChildrenCache( pApplication );
if ( TempWinStatus != NO_ERROR ) {
AzPrint(( AZD_REF,
"AzApplicationClose: Cannot reload children on unload failure: %ld\n",
TempWinStatus
));
}
goto Cleanup;
}
//
// Set the boolean on the object specifying that its children are no
// longer loaded
//
((PGENERIC_OBJECT)pApplication)->AreChildrenLoaded = FALSE;
} else {
((PAZP_APPLICATION)pApplication)->UnloadApplicationObject = TRUE;
}
WinStatus = NO_ERROR;
Cleanup:
if ( pApplication != NULL ) {
ObDereferenceObject( pApplication );
}
AzpFreeString( &AppName );
//
// drop the global lock
//
if ( bResourceLocked ) {
AzpUnlockResource( &AzGlResource );
}
return WinStatus;
}
DWORD
WINAPI
AzApplicationEnum(
IN AZ_HANDLE AzAuthorizationStoreHandle,
IN DWORD Reserved,
IN OUT PULONG EnumerationContext,
OUT PAZ_HANDLE ApplicationHandle
)
/*++
Routine Description:
Enumerates all of the applications for the specified AzAuthorizationStore.
Arguments:
AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
Reserved - Reserved. Must by zero.
EnumerationContext - Specifies a context indicating the next application to return
On input for the first call, should point to zero.
On input for subsequent calls, should point to the value returned on the previous call.
On output, returns a value to be passed on the next call.
ApplicationHandle - Returns a handle to the next application object.
The caller must close this handle by calling AzCloseHandle.
Return Value:
NO_ERROR - The operation was successful (a handle was returned)
ERROR_NO_MORE_ITEMS - No more items were available for enumeration
--*/
{
//
// Call the common routine to do most of the work
//
return ObCommonEnumObjects(
(PGENERIC_OBJECT) AzAuthorizationStoreHandle,
OBJECT_TYPE_AZAUTHSTORE,
&(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
EnumerationContext,
Reserved,
(PGENERIC_OBJECT *) ApplicationHandle );
}
DWORD
WINAPI
AzApplicationDelete(
IN AZ_HANDLE AzAuthorizationStoreHandle,
IN LPCWSTR ApplicationName,
IN DWORD Reserved
)
/*++
Routine Description:
This routine deletes an application from the scope of the specified AzAuthorizationStore.
Also deletes any child objects of ApplicationName.
Arguments:
AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
ApplicationName - Specifies the name of the application to delete.
Reserved - Reserved. Must by zero.
Return Value:
NO_ERROR - The operation was successful
ERROR_NOT_FOUND - An object by that name cannot be found
--*/
{
//
// Call the common routine to do most of the work
//
return ObCommonDeleteObject(
(PGENERIC_OBJECT) AzAuthorizationStoreHandle,
OBJECT_TYPE_AZAUTHSTORE,
&(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
OBJECT_TYPE_APPLICATION,
ApplicationName,
Reserved );
}