windows-nt/Source/XPSP1/NT/ds/security/dsrole/server/cancel.c

172 lines
3.7 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
setutl.c
Abstract:
Miscellaneous helper functions
Author:
Mac McLain (MacM) Feb 10, 1997
Environment:
User Mode
Revision History:
--*/
#include <setpch.h>
#include <dssetp.h>
#include <lsarpc.h>
#include <samrpc.h>
#include <samisrv.h>
#include <db.h>
#include <confname.h>
#include <loadfn.h>
#include <ntdsa.h>
#include <dsconfig.h>
#include <attids.h>
#include <dsp.h>
#include <lsaisrv.h>
#include <malloc.h>
#include <dsgetdc.h>
#include <lmcons.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#include <lmerr.h>
#include <netsetp.h>
#include <winsock2.h>
#include <nspapi.h>
#include <dsgetdcp.h>
#include <lmremutl.h>
#include <spmgr.h> // For SetupPhase definition
#include "cancel.h"
DWORD
DsRolepCancel(
BOOL BlockUntilDone
)
/*++
Routine Description:
This routine will cancel a currently running operation
Arguments:
BlockUntilDone - if TRUE, then this call waits for the current operation to
complete before returning. Otherwise return without waiting
Return Values:
ERROR_SUCCESS - Success
--*/
{
DWORD Win32Err = ERROR_SUCCESS;
NTSTATUS Status;
BOOL fWaitForCancelToFinish = TRUE;
DsRolepLogPrint(( DEB_TRACE, "Canceling current operation...\n" ));
//
// Grab the global lock
//
LockOpHandle();
//
// Determine if we are in a cancelable state
//
if ( (DsRolepCurrentOperationHandle.OperationState == DSROLEP_FINISHED)
|| (DsRolepCurrentOperationHandle.OperationState == DSROLEP_CANCELING) ) {
//
// Cancel is happening or just finished, just leave
//
Win32Err = ERROR_SUCCESS;
fWaitForCancelToFinish = FALSE;
DsRolepLogPrint(( DEB_TRACE, "Cancel already happened or the operation is finished.\n" ));
} else if ( !( (DsRolepCurrentOperationHandle.OperationState == DSROLEP_RUNNING)
||(DsRolepCurrentOperationHandle.OperationState == DSROLEP_RUNNING_NON_CRITICAL)) ) {
//
// Invalid state transition requested
//
Win32Err = ERROR_NO_PROMOTION_ACTIVE;
} else {
// Tell the ds to cancel
//
// N.B. This callout to the ds is made under lock.
//
DSROLE_GET_SETUP_FUNC( Win32Err, DsrNtdsInstallCancel );
if ( ERROR_SUCCESS == Win32Err ) {
Win32Err = ( *DsrNtdsInstallCancel )();
}
if ( ERROR_SUCCESS == Win32Err )
{
Status = NtSetEvent( DsRolepCurrentOperationHandle.CancelEvent, NULL );
if ( !NT_SUCCESS( Status ) ) {
Win32Err = RtlNtStatusToDosError( Status );
} else {
DsRolepCurrentOperationHandle.OperationState = DSROLEP_CANCELING;
}
} else {
DsRolepLogOnFailure( Win32Err,
DsRolepLogPrint(( DEB_ERROR,
"Unable to cancel the ds%lu\n",
Win32Err )) );
}
}
//
// Release the lock
//
UnlockOpHandle();
//
// Now, wait for the operation to complete
//
if ( Win32Err == ERROR_SUCCESS
&& fWaitForCancelToFinish
&& BlockUntilDone ) {
DsRolepLogPrint(( DEB_TRACE, "Waiting for the role change operation to complete\n" ));
Status = NtWaitForSingleObject( DsRolepCurrentOperationHandle.CompletionEvent, TRUE, 0 );
if ( !NT_SUCCESS( Status ) ) {
Win32Err = RtlNtStatusToDosError( Status );
}
}
DsRolepLogPrint(( DEB_TRACE, "Request for cancel returning %lu\n", Win32Err ));
return( Win32Err );
}