HRESULT Progress::cancel() { AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); if (!mCancelable) return setError(VBOX_E_INVALID_OBJECT_STATE, tr("Operation cannot be canceled")); if (!mCanceled) { LogThisFunc(("Canceling\n")); mCanceled = TRUE; if (m_pfnCancelCallback) m_pfnCancelCallback(m_pvCancelUserArg); } else LogThisFunc(("Already canceled\n")); return S_OK; }
/** * Called to copy over the progress information from @a pOtherProgress. * * @param pOtherProgress The source of the information. * @param fEarly Early copy. * * @note The caller owns the write lock and as cleared mptrOtherProgress * already (or we might recurse forever)! */ void ProgressProxy::copyProgressInfo(IProgress *pOtherProgress, bool fEarly) { HRESULT hrc; LogFlowThisFunc(("\n")); NOREF(fEarly); /* * No point in doing this if the progress object was canceled already. */ if (!mCanceled) { /* Detect if the other progress object was canceled. */ BOOL fCanceled; hrc = pOtherProgress->COMGETTER(Canceled)(&fCanceled); if (FAILED(hrc)) fCanceled = FALSE; if (fCanceled) { LogFlowThisFunc(("Canceled\n")); mCanceled = TRUE; if (m_pfnCancelCallback) m_pfnCancelCallback(m_pvCancelUserArg); } else { /* Has it completed? */ BOOL fCompleted; hrc = pOtherProgress->COMGETTER(Completed)(&fCompleted); if (FAILED(hrc)) fCompleted = TRUE; Assert(fCompleted || fEarly); if (fCompleted) { /* Check the result. */ LONG hrcResult; hrc = pOtherProgress->COMGETTER(ResultCode)(&hrcResult); if (FAILED(hrc)) hrcResult = hrc; if (SUCCEEDED((HRESULT)hrcResult)) LogFlowThisFunc(("Succeeded\n")); else { /* Get the error information. */ ComPtr<IVirtualBoxErrorInfo> ptrErrorInfo; hrc = pOtherProgress->COMGETTER(ErrorInfo)(ptrErrorInfo.asOutParam()); if (SUCCEEDED(hrc) && !ptrErrorInfo.isNull()) { Bstr bstrIID; hrc = ptrErrorInfo->COMGETTER(InterfaceID)(bstrIID.asOutParam()); AssertComRC(hrc); if (FAILED(hrc)) bstrIID.setNull(); Bstr bstrComponent; hrc = ptrErrorInfo->COMGETTER(Component)(bstrComponent.asOutParam()); AssertComRC(hrc); if (FAILED(hrc)) bstrComponent = "failed"; Bstr bstrText; hrc = ptrErrorInfo->COMGETTER(Text)(bstrText.asOutParam()); AssertComRC(hrc); if (FAILED(hrc)) bstrText = "<failed>"; Utf8Str strText(bstrText); LogFlowThisFunc(("Got ErrorInfo(%s); hrcResult=%Rhrc\n", strText.c_str(), hrcResult)); Progress::notifyComplete((HRESULT)hrcResult, Guid(bstrIID).ref(), Utf8Str(bstrComponent).c_str(), "%s", strText.c_str()); } else { LogFlowThisFunc(("ErrorInfo failed with hrc=%Rhrc; hrcResult=%Rhrc\n", hrc, hrcResult)); Progress::notifyComplete((HRESULT)hrcResult, COM_IIDOF(IProgress), "ProgressProxy", tr("No error info")); } } } else LogFlowThisFunc(("Not completed\n")); } } else LogFlowThisFunc(("Already canceled\n")); /* * Did cancelable state change (point of no return)? */ if (mCancelable && !mCompleted && !mCanceled) { BOOL fCancelable; hrc = pOtherProgress->COMGETTER(Cancelable)(&fCancelable); AssertComRC(hrc); if (SUCCEEDED(hrc) && !fCancelable) { LogFlowThisFunc(("point-of-no-return reached\n")); mCancelable = FALSE; } } }