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