Ejemplo n.º 1
0
static int FindPartner( void )
{
    BYTE        property_value[130];
    LONG        transport_time;

    if( ReadPropertyValue( (char *)SAPStruct.ASServerIDpacket.serverName,
                           DBG_SERVER_TYPE, "NET_ADDRESS",
                           1, (BYTE *)&property_value ) != 0 ) return( 0 );
    AssignArray( ServHead.destination, property_value );
    if( CIPXGetLocalTarget( ServHead.destination.network,
                            ServECB.immediateAddress, &transport_time ) != 0 ) {
        _DBG_IPX(( "FindPartner -- nobody home\r\n" ));
        return( FALSE );
    }
    RespECB.fragmentDescriptor[1].address = &PartnerSPXSocket;
    CIPXListen( &RespECB );
    CIPXSendPacket( &ServECB );
    while( InUse( ServECB ) ) NothingToDo();
    if( !Completed( ServECB ) ) return( FALSE );
    NothingToDo();
    Tick = 0;
    for( ;; ) {
        if( !InUse( RespECB ) ) {
            _DBG_IPX(( "FindPartner -- %s answered\r\n", Completed( RespECB ) ? "someone" : "noone" ));
            return( Completed( RespECB ) );
        }
        NothingToDo();
        if( Tick > MAX_PARTNER_WAIT ) break;
    }
    CIPXCancelECB( &RespECB );
    return( FALSE );
}
Ejemplo n.º 2
0
ssize_t HttpMessage::ParseFromIOBuf(const butil::IOBuf &buf) {
    if (Completed()) {
        if (buf.empty()) {
            return 0;
        }
        LOG(ERROR) << "Append data(len=" << buf.size()
                   << ") to already-completed message";
        return -1;
    }
    size_t nprocessed = 0;
    for (size_t i = 0; i < buf.backing_block_num(); ++i) {
        butil::StringPiece blk = buf.backing_block(i);
        if (blk.empty()) {
            // length=0 will be treated as EOF by http_parser, must skip.
            continue;
        }
        nprocessed += http_parser_execute(
            &_parser, &g_parser_settings, blk.data(), blk.size());
        if (_parser.http_errno != 0) {
            // May try HTTP on other formats, failure is norm.
            RPC_VLOG << "Fail to parse http message, parser=" << _parser
                     << ", buf=" << butil::ToPrintable(buf);
            return -1;
        }
        if (Completed()) {
            break;
        }
    }
    _parsed_length += nprocessed;
    return (ssize_t)nprocessed;
}
Ejemplo n.º 3
0
    NS_IMETHOD Run()
    {
        NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");

        const char* buffer = mBuffer.get();

        while (mLength) {
            uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX);
            mOmxDecoder->NotifyDataArrived(mBuffer.get(), mLength, mOffset);

            buffer  += length;
            mLength -= length;
            mOffset += length;
        }

        if (mOffset < mFullLength) {
            // We cannot read data in the main thread because it
            // might block for too long. Instead we post an IO task
            // to the IO thread if there is more data available.
            XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new OmxDecoderProcessCachedDataTask(mOmxDecoder.get(), mOffset));
        }

        Completed();

        return NS_OK;
    }
Ejemplo n.º 4
0
void DestroyChipsOrder::Draw(IPoint pos, bool vertical)
{
	if(_timeAppearText > 0)
	{
		//Текст
		Render::BeginAlphaMul(math::clamp(0.f, 1.f, _timeAppearText));
		if(_drawShowCount > 0.0f && !Completed())
		{
			IPoint textOffset = vertical ? IPoint(40, 14) : IPoint(54, 24);
			Render::FreeType::BindFont("OrderOnLock");
			Render::PrintString(pos + textOffset, utils::lexical_cast(math::ceil(_drawShowCount)), 1.f, CenterAlign, CenterAlign);
		}
		Render::EndAlphaMul();
	}
	if(_timeAppearIcon > 0)
	{
		FPoint iconOffset = vertical ? FPoint(40.0f, 53.0f) : FPoint(24.0f, 24.0f);
		//Иконка
		Render::BeginAlphaMul(math::clamp(0.f, 1.f, _timeAppearIcon));
		FRect rect, frect;
		GetOrderIconRect(_rect_num, rect, frect);
		rect.MoveBy(FPoint(0, 30.f)*(1.f - _timeAppearIcon) + pos + iconOffset);
		Game::ordersTexture->Bind();
		Render::DrawRect(rect, frect);
		Render::EndAlphaMul();
	}
}
Ejemplo n.º 5
0
void FillEnergyOrder::Draw(IPoint pos, bool vertical)
{
	if(!Completed())
	{
		Render::FreeType::BindFont("debug");
		Render::PrintString(pos + IPoint(GameSettings::SQUARE_SIDE*3/4, GameSettings::SQUARE_SIDE*3/4), utils::lexical_cast(_area.size()), 1.f, CenterAlign, CenterAlign);
	}
}
Ejemplo n.º 6
0
              void Do()
              {
                  Proc();
                  bool ok = Completed();
                  if (!ok ) return;

                  SwitchState( m_pNextState );
              }
Ejemplo n.º 7
0
bool Room_Resv_Edit_Ui::UpdateReservation()
{
    if ( not currentResv )
    {
        //VERY BAD MOJO
        qDebug("YIKES Invalid current reservation!!");
        return false;
    }

    if ( not currentCustomer )
    {
        qDebug("YIKES Invalid customer!!");
        QMessageBox::warning( this, "Missing Customer",
                              "You must enter a customer before continuing.");
        return false;
    }

    if ( not currentGuest )
    {
        qDebug("YIKES Invalid guest!!");
        QMessageBox::warning( this, "Missing Guest",
                              "You must enter a guest before continuing." );
        return false;
    }




    //prep fields
    int roomNo = ui.roomNumber->text().toInt();
    QDate fromDate = ui.fromDate->date();
    QDate toDate = ui.toDate->date();

    // can I really reserve this room?
    bool okreserve = currentResv->ReserveFor( roomNo, fromDate, toDate );

    if ( not okreserve )
    {
        QString err ("Room #%1 can not be reserved from %2 to %3.\n"
                     "Please correct the reservation.");
        err = err.arg( roomNo );
        err = err.arg( fromDate.toString() );
        err = err.arg( toDate.toString() );

        QMessageBox::warning( this, "Cannot Reserve Room", err );

        return false;

    }

    //primary data change ok, update any other fields.


    emit Completed( currentResv->Store() );

    return true;

}
Ejemplo n.º 8
0
void
Filter::FilterThreadInitFailed()
{
	ASSERT(fNumberOfThreads == fN);
	fNumberOfThreads = 0;
	Completed();
	fIsRunning = false;
	release_sem_etc(fWaitForThreads, fN, 0);
}
Ejemplo n.º 9
0
void ServRespESR( void )
{
    if( Completed( ServECB ) && !InUse( RespECB )
            && (ServHead.length == _SWAPINT( sizeof( IPXHeader ) )
                || ServHead.length == _SWAPINT( sizeof( IPXHeader ) + 1 ) ) ) {
        _DBG_IPX(( "ServRespESR responding\r\n" ));
        RespHead.destination = ServHead.source;
        AssignArray( RespECB.immediateAddress , ServECB.immediateAddress );
        RespECB.fragmentDescriptor[1].address = &SPXSocket;
        CIPXSendPacket( &RespECB );
    }
    CIPXListen( &ServECB );
}
Ejemplo n.º 10
0
bool RemoteConnect( void )
{
    PostListens();
    if( !Listening ) {
        _DBG_IPX(("Listening for connection\r\n"));
        _INITSPXECB( Conn, 1, 0, 0 );
        CSPXListenForConnection( 0, 0, &Connection, &ConnECB );
        Listening = 1;
    } else if( !InUse( ConnECB ) && Completed( ConnECB ) ) {
        _DBG_IPX(("Found a connection\r\n"));
        return( TRUE );
    }
    NothingToDo();
    return( FALSE );
}
Ejemplo n.º 11
0
void
Filter::FilterThreadDone()
{
	if (atomic_add(&fNumberOfThreads, -1) == 1) {
		#if TIME_FILTER
			delete fStopWatch; fStopWatch = NULL;
		#endif
		Completed();
		if (fIsRunning) {
			fListener.SendMessage(fWhat);
		}
		fIsRunning = false;
	}
	release_sem(fWaitForThreads);
}
Ejemplo n.º 12
0
            void Proc()
            {
                if (Completed()) return;

                bool leftRes = m_left.Process();
                bool rightRes = m_right.Process();

                if (leftRes && rightRes)
                {
                    InnerState next = NextState(m_state);
                    if (next == TEST_COMPLETED) 
                    {
                        ResetDrv();
                        m_completed = true;
                        return;
                    }   
                    EnterState(next);
                }
            }
Ejemplo n.º 13
0
int GuestSessionTask::setProgressSuccess(void)
{
    if (mProgress.isNull()) /* Progress is optional. */
        return VINF_SUCCESS;

    BOOL fCanceled;
    BOOL fCompleted;
    if (   SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled)))
        && !fCanceled
        && SUCCEEDED(mProgress->COMGETTER(Completed(&fCompleted)))
        && !fCompleted)
    {
        HRESULT hr = mProgress->notifyComplete(S_OK);
        if (FAILED(hr))
            return VERR_COM_UNEXPECTED; /** @todo Find a better rc. */
    }

    return VINF_SUCCESS;
}
Ejemplo n.º 14
0
int GuestSessionTask::setProgress(ULONG uPercent)
{
    if (mProgress.isNull()) /* Progress is optional. */
        return VINF_SUCCESS;

    BOOL fCanceled;
    if (   SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled)))
        && fCanceled)
        return VERR_CANCELLED;
    BOOL fCompleted;
    if (   SUCCEEDED(mProgress->COMGETTER(Completed(&fCompleted)))
        && !fCompleted)
        return VINF_SUCCESS;
    HRESULT hr = mProgress->SetCurrentOperationProgress(uPercent);
    if (FAILED(hr))
        return VERR_COM_UNEXPECTED;

    return VINF_SUCCESS;
}
  //
  // OutOfAssets
  //
  // The asset manager is informing us there's no more assets
  //
  Bool Asset::Request::TypeBase::OutOfAssets(Manager &manager)
  {
    // Check to see if we have enough assets to continue
    Bool enough = TRUE;

    for (BinTree<U32>::Iterator i(&config->GetAmounts()); *i; i++)
    {
      U32 *amount = amounts.Find(i.GetKey());

      if (!amount || *amount < (**i))
      {
        enough = FALSE;
        break;
      }
    }

    if (enough || acceptInsufficient)
    {
      // Remove all of the units from the base
      if (base.Alive())
      {
        for (NList<Asset>::Iterator a(&assigned); *a; a++)
        {
          UnitObj *unit = (*a)->GetUnit();

          if (unit)
          {
            base->RemoveUnit(unit);
          }
        }
      }

      Completed(manager);
      return (TRUE);
    }
    else
    {
      Reset();
      Abandoned(manager);
      return (FALSE);
    }
  }
Ejemplo n.º 16
0
ssize_t HttpMessage::ParseFromArray(const char *data, const size_t length) {
    if (Completed()) {
        if (length == 0) {
            return 0;
        }
        LOG(ERROR) << "Append data(len=" << length
                   << ") to already-completed message";
        return -1;
    }
    const size_t nprocessed =
        http_parser_execute(&_parser, &g_parser_settings, data, length);
    if (_parser.http_errno != 0) {
        // May try HTTP on other formats, failure is norm.
        RPC_VLOG << "Fail to parse http message, parser=" << _parser
                 << ", buf=`" << butil::StringPiece(data, length) << '\'';
        return -1;
    } 
    _parsed_length += nprocessed;
    return nprocessed;
}
Ejemplo n.º 17
0
HRESULT GuestSessionTask::setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg)
{
    if (mProgress.isNull()) /* Progress is optional. */
        return hr; /* Return original rc. */

    BOOL fCanceled;
    BOOL fCompleted;
    if (   SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled)))
        && !fCanceled
        && SUCCEEDED(mProgress->COMGETTER(Completed(&fCompleted)))
        && !fCompleted)
    {
        HRESULT hr2 = mProgress->notifyComplete(hr,
                                               COM_IIDOF(IGuestSession),
                                               GuestSession::getStaticComponentName(),
                                               strMsg.c_str());
        if (FAILED(hr2))
            return hr2;
    }
    return hr; /* Return original rc. */
}
Ejemplo n.º 18
0
// This gets called in two circumstances.  It may be called for the roots
// in which case the stack will be empty and we want to process it completely
// or it is called for a constant address in which case it will have been
// called from RecursiveScan::ScanAddressesInObject and that can process
// any addresses.
PolyObject *RecursiveScan::ScanObjectAddress(PolyObject *obj)
{
    PolyWord pWord = obj;
    // Test to see if this needs to be scanned.
    // It may update the word.
    bool test = TestForScan(&pWord);
    obj = pWord.AsObjPtr();

    if (test)
    {
        MarkAsScanning(obj);
        if (obj->IsByteObject())
            Completed(obj); // Don't need to put it on the stack
        // If we already have something on the stack we must being called
        // recursively to process a constant in a code segment.  Just push
        // it on the stack and let the caller deal with it.
        else if (StackIsEmpty())
            RecursiveScan::ScanAddressesInObject(obj, obj->LengthWord());
        else
            PushToStack(obj);
    }

    return obj;
}
Ejemplo n.º 19
0
/* static */
HRESULT GuestTask::setProgressErrorInfo(HRESULT hr, ComObjPtr<Progress> pProgress,
                                               const char *pszText, ...)
{
    BOOL fCanceled;
    BOOL fCompleted;
    if (   SUCCEEDED(pProgress->COMGETTER(Canceled(&fCanceled)))
        && !fCanceled
        && SUCCEEDED(pProgress->COMGETTER(Completed(&fCompleted)))
        && !fCompleted)
    {
        va_list va;
        va_start(va, pszText);
        HRESULT hr2 = pProgress->notifyCompleteV(hr,
                                                 COM_IIDOF(IGuest),
                                                 Guest::getStaticComponentName(),
                                                 pszText,
                                                 va);
        va_end(va);
        if (hr2 == S_OK) /* If unable to retrieve error, return input error. */
            hr2 = hr;
        return hr2;
    }
    return S_OK;
}
Ejemplo n.º 20
0
 inline void FileClient::DownloadCompleted(FileDownload * download,
                                           bool success) {
   auto request = download->request();
   // Check if the received hash matches the file's hash
   auto file = request->file();
   manager_->SetFileHash(file);
   if(!compare_md5_hash(download->hash(), file->hash())) {
     LOG_ERR("Incorrect MD5 hash!");
     exit(EXIT_FAILURE);
   }
   // Check if the file size matches
   manager_->SetFileSize(file);
   if(file->size() != download->fsize()) {
     LOG_ERR("Incorrect file size!");
     exit(EXIT_FAILURE);
   }
   std::lock_guard<std::mutex> lock(dl_mutex_);
   if(success) {
     request->Completed();
   } else {
     request->Failed();
   }
   // Delete the download after finishing with the request.
   // Otherwise, the shared_ptr to the request will go out
   // of scope and be freed.
   delete download;
   // Remove the request from the map.
   // Since all listeners are using shared pointers,
   // this should not cause errors.
   request_map_.erase(request->file());
   --num_downloads_;
   if(!request_q_.empty()) {
     DownloadFile(request_q_.front());
     request_q_.pop();
   }
 }
Ejemplo n.º 21
0
// This is called via ScanAddressesInRegion to process the permanent mutables.  It is
// also called from ScanObjectAddress to process root addresses.
// It processes all the addresses reachable from the object.
void RecursiveScan::ScanAddressesInObject(PolyObject *obj, POLYUNSIGNED lengthWord)
{
    if (OBJ_IS_BYTE_OBJECT(lengthWord))
    {
        Completed(obj);
        return;
    }

    while (true)
    {
        ASSERT (OBJ_IS_LENGTH(lengthWord));

        // Get the length and base address.  N.B.  If this is a code segment
        // these will be side-effected by GetConstSegmentForCode.
        POLYUNSIGNED length = OBJ_OBJECT_LENGTH(lengthWord);
        PolyWord *baseAddr = (PolyWord*)obj;

        if (OBJ_IS_CODE_OBJECT(lengthWord))
        {
            // It's better to process the whole code object in one go.
            ScanAddress::ScanAddressesInObject(obj, lengthWord);
            length = 0; // Finished
        }
        ASSERT(! OBJ_IS_BYTE_OBJECT(lengthWord)); // Check - remove this later

        // else it's a normal object,

        // If there are only two addresses in this cell that need to be
        // followed we follow them immediately and treat this cell as done.
        // If there are more than two we push the address of this cell on
        // the stack, follow the first address and then rescan it.  That way
        // list cells are processed once only but we don't overflow the
        // stack by pushing all the addresses in a very large vector.
        PolyWord *endWord = baseAddr + length;
        PolyObject *firstWord = 0;
        PolyObject *secondWord = 0;

        while (baseAddr != endWord)
        {
            PolyWord wordAt = *baseAddr;

            if (wordAt.IsDataPtr() && wordAt != PolyWord::FromUnsigned(0))
            {
                // Normal address.  We can have words of all zeros at least in the
                // situation where we have a partially constructed code segment where
                // the constants at the end of the code have not yet been filled in.
                if (TestForScan(baseAddr)) // Test value at baseAddr (may side-effect it)
                {
                    PolyObject *wObj = (*baseAddr).AsObjPtr();
                    if (wObj->IsByteObject())
                    {
                        // Can do this now - don't need to push it
                        MarkAsScanning(wObj);
                        Completed(wObj);
                    }
                    else if (firstWord == 0)
                    {
                        firstWord = wObj;
                        // We mark the word immediately.  We can have
                        // two words in an object that are the same
                        // and we don't want to process it again.
                        MarkAsScanning(firstWord);
                    }
                    else if (secondWord == 0)
                        secondWord = wObj;
                    else break;  // More than two words.
                }
            }
            else if (wordAt.IsCodePtr())
            {
                // If we're processing the constant area of a code segment this could
                // be a code address.
                PolyObject *oldObject = ObjCodePtrToPtr(wordAt.AsCodePtr());
                // Calculate the byte offset of this value within the code object.
                POLYUNSIGNED offset = wordAt.AsCodePtr() - (byte*)oldObject;
                wordAt = oldObject;
                bool test = TestForScan(&wordAt);
                // TestForScan may side-effect the word.
                PolyObject *newObject = wordAt.AsObjPtr();
                wordAt = PolyWord::FromCodePtr((byte*)newObject + offset);
                if (wordAt != *baseAddr)
                    *baseAddr = wordAt;
                if (test)
                {
                    if (firstWord == 0)
                    {
                        firstWord = newObject;
                        MarkAsScanning(firstWord);
                    }
                    else if (secondWord == 0)
                        secondWord = newObject;
                    else break;
                }
            }
            baseAddr++;
        }

        if (baseAddr == endWord)
        {
            // We have done everything except possibly firstWord and secondWord.
            Completed(obj);
            if (secondWord != 0)
            {
                MarkAsScanning(secondWord);
                // Put this on the stack.  If this is a list node we will be
                // pushing the tail.
                PushToStack(secondWord);
            }
        }
        else // Put this back on the stack while we process the first word
            PushToStack(obj);

        if (firstWord != 0)
            // Process it immediately.
            obj = firstWord;
        else if (StackIsEmpty())
            return;
        else
            obj = PopFromStack();

        lengthWord = obj->LengthWord();
    }
}
 //
 // OutOfAssets
 //
 // The asset manager is informing us there's no more assets
 //
 Bool Asset::Request::Squad::OutOfAssets(Manager &manager)
 {
   Completed(manager);
   return (TRUE);
 }
Ejemplo n.º 23
0
HRESULT Progress::waitForAsyncProgressCompletion(const ComPtr<IProgress> &aPProgressAsync)
{
    LogFlowThisFuncEnter();

    /* Note: we don't lock here, cause we just using public methods. */

    HRESULT rc           = S_OK;
    BOOL fCancelable     = FALSE;
    BOOL fCompleted      = FALSE;
    BOOL fCanceled       = FALSE;
    ULONG prevPercent    = UINT32_MAX;
    ULONG currentPercent = 0;
    ULONG cOp            = 0;
    /* Is the async process cancelable? */
    rc = aPProgressAsync->COMGETTER(Cancelable)(&fCancelable);
    if (FAILED(rc)) return rc;
    /* Loop as long as the sync process isn't completed. */
    while (SUCCEEDED(aPProgressAsync->COMGETTER(Completed(&fCompleted))))
    {
        /* We can forward any cancel request to the async process only when
         * it is cancelable. */
        if (fCancelable)
        {
            rc = COMGETTER(Canceled)(&fCanceled);
            if (FAILED(rc)) return rc;
            if (fCanceled)
            {
                rc = aPProgressAsync->Cancel();
                if (FAILED(rc)) return rc;
            }
        }
        /* Even if the user canceled the process, we have to wait until the
           async task has finished his work (cleanup and such). Otherwise there
           will be sync trouble (still wrong state, dead locks, ...) on the
           used objects. So just do nothing, but wait for the complete
           notification. */
        if (!fCanceled)
        {
            /* Check if the current operation has changed. It is also possible that
             * in the meantime more than one async operation was finished. So we
             * have to loop as long as we reached the same operation count. */
            ULONG curOp;
            for (;;)
            {
                rc = aPProgressAsync->COMGETTER(Operation(&curOp));
                if (FAILED(rc)) return rc;
                if (cOp != curOp)
                {
                    Bstr bstr;
                    ULONG currentWeight;
                    rc = aPProgressAsync->COMGETTER(OperationDescription(bstr.asOutParam()));
                    if (FAILED(rc)) return rc;
                    rc = aPProgressAsync->COMGETTER(OperationWeight(&currentWeight));
                    if (FAILED(rc)) return rc;
                    rc = SetNextOperation(bstr.raw(), currentWeight);
                    if (FAILED(rc)) return rc;
                    ++cOp;
                }
                else
                    break;
            }

            rc = aPProgressAsync->COMGETTER(OperationPercent(&currentPercent));
            if (FAILED(rc)) return rc;
            if (currentPercent != prevPercent)
            {
                prevPercent = currentPercent;
                rc = SetCurrentOperationProgress(currentPercent);
                if (FAILED(rc)) return rc;
            }
        }
        if (fCompleted)
            break;

        /* Make sure the loop is not too tight */
        rc = aPProgressAsync->WaitForCompletion(100);
        if (FAILED(rc)) return rc;
    }

    LogFlowThisFuncLeave();

    return rc;
}
Ejemplo n.º 24
0
HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
{
    LogFlowFuncEnter();

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /*
     * Do *not* take a write lock here since we don't (and won't)
     * touch any class-specific data (of IGuest) here - only the member functions
     * which get called here can do that.
     */

    HRESULT rc = S_OK;

    try
    {
        ComObjPtr<Guest> pGuest = aTask->pGuest;

        /* Does our source file exist? */
        if (!RTFileExists(aTask->strSource.c_str()))
        {
            rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                 Guest::tr("Source file \"%s\" does not exist, or is not a file"),
                                                 aTask->strSource.c_str());
        }
        else
        {
            RTFILE fileSource;
            int vrc = RTFileOpen(&fileSource, aTask->strSource.c_str(),
                                 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
            if (RT_FAILURE(vrc))
            {
                rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                     Guest::tr("Could not open source file \"%s\" for reading (%Rrc)"),
                                                     aTask->strSource.c_str(),  vrc);
            }
            else
            {
                uint64_t cbSize;
                vrc = RTFileGetSize(fileSource, &cbSize);
                if (RT_FAILURE(vrc))
                {
                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                         Guest::tr("Could not query file size of \"%s\" (%Rrc)"),
                                                         aTask->strSource.c_str(), vrc);
                }
                else
                {
                    com::SafeArray<IN_BSTR> args;
                    com::SafeArray<IN_BSTR> env;

                    /*
                     * Prepare tool command line.
                     */
                    char szOutput[RTPATH_MAX];
                    if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", aTask->strDest.c_str()) <= sizeof(szOutput) - 1)
                    {
                        /*
                         * Normalize path slashes, based on the detected guest.
                         */
                        Utf8Str osType = mData.mOSTypeId;
                        if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
                            || osType.contains("Windows", Utf8Str::CaseInsensitive))
                        {
                            /* We have a Windows guest. */
                            RTPathChangeToDosSlashes(szOutput, true /* Force conversion. */);
                        }
                        else /* ... or something which isn't from Redmond ... */
                        {
                            RTPathChangeToUnixSlashes(szOutput, true /* Force conversion. */);
                        }

                        args.push_back(Bstr(szOutput).raw());             /* We want to write a file ... */
                    }
                    else
                    {
                        rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                             Guest::tr("Error preparing command line"));
                    }

                    ComPtr<IProgress> execProgress;
                    ULONG uPID;
                    if (SUCCEEDED(rc))
                    {
                        LogRel(("Copying file \"%s\" to guest \"%s\" (%u bytes) ...\n",
                                aTask->strSource.c_str(), aTask->strDest.c_str(), cbSize));
                        /*
                         * Okay, since we gathered all stuff we need until now to start the
                         * actual copying, start the guest part now.
                         */
                        rc = pGuest->executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
                                                           Bstr("Copying file to guest").raw(),
                                                           ComSafeArrayAsInParam(args),
                                                           ComSafeArrayAsInParam(env),
                                                           Bstr(aTask->strUserName).raw(),
                                                           Bstr(aTask->strPassword).raw(),
                                                           ExecuteProcessFlag_WaitForProcessStartOnly,
                                                           NULL, NULL,
                                                           execProgress.asOutParam(), &uPID);
                        if (FAILED(rc))
                            rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
                    }

                    if (SUCCEEDED(rc))
                    {
                        BOOL fCompleted = FALSE;
                        BOOL fCanceled = FALSE;
                        uint64_t cbTransferedTotal = 0;

                        SafeArray<BYTE> aInputData(_64K);
                        while (   SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted)))
                               && !fCompleted)
                        {
                            size_t cbToRead = cbSize;
                            size_t cbRead = 0;
                            if (cbSize) /* If we have nothing to read, take a shortcut. */
                            {
                                /** @todo Not very efficient, but works for now. */
                                vrc = RTFileSeek(fileSource, cbTransferedTotal,
                                                 RTFILE_SEEK_BEGIN, NULL /* poffActual */);
                                if (RT_SUCCESS(vrc))
                                {
                                    vrc = RTFileRead(fileSource, (uint8_t*)aInputData.raw(),
                                                     RT_MIN(cbToRead, _64K), &cbRead);
                                    /*
                                     * Some other error occured? There might be a chance that RTFileRead
                                     * could not resolve/map the native error code to an IPRT code, so just
                                     * print a generic error.
                                     */
                                    if (RT_FAILURE(vrc))
                                    {
                                        rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                             Guest::tr("Could not read from file \"%s\" (%Rrc)"),
                                                                             aTask->strSource.c_str(), vrc);
                                        break;
                                    }
                                }
                                else
                                {
                                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                         Guest::tr("Seeking file \"%s\" failed; offset = %RU64 (%Rrc)"),
                                                                         aTask->strSource.c_str(), cbTransferedTotal, vrc);
                                    break;
                                }
                            }
                            /* Resize buffer to reflect amount we just have read.
                             * Size 0 is allowed! */
                            aInputData.resize(cbRead);

                            ULONG uFlags = ProcessInputFlag_None;
                            /* Did we reach the end of the content we want to transfer (last chunk)? */
                            if (   (cbRead < _64K)
                                /* Did we reach the last block which is exactly _64K? */
                                || (cbToRead - cbRead == 0)
                                /* ... or does the user want to cancel? */
                                || (   SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
                                    && fCanceled)
                               )
                            {
                                uFlags |= ProcessInputFlag_EndOfFile;
                            }

                            ULONG uBytesWritten = 0;
                            rc = pGuest->SetProcessInput(uPID, uFlags,
                                                         0 /* Infinite timeout */,
                                                         ComSafeArrayAsInParam(aInputData), &uBytesWritten);
                            if (FAILED(rc))
                            {
                                rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
                                break;
                            }

                            Assert(cbRead <= cbToRead);
                            Assert(cbToRead >= cbRead);
                            cbToRead -= cbRead;

                            cbTransferedTotal += uBytesWritten;
                            Assert(cbTransferedTotal <= cbSize);
                            aTask->pProgress->SetCurrentOperationProgress(cbTransferedTotal / (cbSize / 100.0));

                            /* End of file reached? */
                            if (cbToRead == 0)
                                break;

                            /* Did the user cancel the operation above? */
                            if (fCanceled)
                                break;

                            /* Progress canceled by Main API? */
                            if (   SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled)))
                                && fCanceled)
                            {
                                rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                     Guest::tr("Copy operation of file \"%s\" was canceled on guest side"),
                                                                     aTask->strSource.c_str());
                                break;
                            }
                        }

                        if (SUCCEEDED(rc))
                        {
                            /*
                             * If we got here this means the started process either was completed,
                             * canceled or we simply got all stuff transferred.
                             */
                            ExecuteProcessStatus_T retStatus;
                            ULONG uRetExitCode;

                            rc = executeWaitForExit(uPID, execProgress, 0 /* No timeout */,
                                                    &retStatus, &uRetExitCode);
                            if (FAILED(rc))
                            {
                                rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
                            }
                            else
                            {
                                if (   uRetExitCode != 0
                                    || retStatus    != ExecuteProcessStatus_TerminatedNormally)
                                {
                                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                         Guest::tr("Guest process reported error %u (status: %u) while copying file \"%s\" to \"%s\""),
                                                                         uRetExitCode, retStatus, aTask->strSource.c_str(), aTask->strDest.c_str());
                                }
                            }
                        }

                        if (SUCCEEDED(rc))
                        {
                            if (fCanceled)
                            {
                                /*
                                 * In order to make the progress object to behave nicely, we also have to
                                 * notify the object with a complete event when it's canceled.
                                 */
                                aTask->pProgress->notifyComplete(VBOX_E_IPRT_ERROR,
                                                                COM_IIDOF(IGuest),
                                                                Guest::getStaticComponentName(),
                                                                Guest::tr("Copying file \"%s\" canceled"), aTask->strSource.c_str());
                            }
                            else
                            {
                                /*
                                 * Even if we succeeded until here make sure to check whether we really transfered
                                 * everything.
                                 */
                                if (   cbSize > 0
                                    && cbTransferedTotal == 0)
                                {
                                    /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write
                                     * to the destination -> access denied. */
                                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                         Guest::tr("Access denied when copying file \"%s\" to \"%s\""),
                                                                         aTask->strSource.c_str(), aTask->strDest.c_str());
                                }
                                else if (cbTransferedTotal < cbSize)
                                {
                                    /* If we did not copy all let the user know. */
                                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                         Guest::tr("Copying file \"%s\" failed (%u/%u bytes transfered)"),
                                                                         aTask->strSource.c_str(), cbTransferedTotal, cbSize);
                                }
                                else /* Yay, all went fine! */
                                    aTask->pProgress->notifyComplete(S_OK);
                            }
                        }
                    }
                }
                RTFileClose(fileSource);
            }
        }
    }
    catch (HRESULT aRC)
    {
        rc = aRC;
    }

    /* Clean up */
    aTask->rc = rc;

    LogFlowFunc(("rc=%Rhrc\n", rc));
    LogFlowFuncLeave();

    return VINF_SUCCESS;
}
Ejemplo n.º 25
0
HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
{
    LogFlowFuncEnter();

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /*
     * Do *not* take a write lock here since we don't (and won't)
     * touch any class-specific data (of IGuest) here - only the member functions
     * which get called here can do that.
     */

    HRESULT rc = S_OK;

    try
    {
        ComObjPtr<Guest> pGuest = aTask->pGuest;

        /* Does our source file exist? */
        BOOL fFileExists;
        rc = pGuest->FileExists(Bstr(aTask->strSource).raw(),
                                Bstr(aTask->strUserName).raw(), Bstr(aTask->strPassword).raw(),
                                &fFileExists);
        if (SUCCEEDED(rc))
        {
            if (!fFileExists)
                rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                     Guest::tr("Source file \"%s\" does not exist, or is not a file"),
                                                     aTask->strSource.c_str());
        }
        else
            rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);

        /* Query file size to make an estimate for our progress object. */
        if (SUCCEEDED(rc))
        {
            LONG64 lFileSize;
            rc = pGuest->FileQuerySize(Bstr(aTask->strSource).raw(),
                                       Bstr(aTask->strUserName).raw(), Bstr(aTask->strPassword).raw(),
                                       &lFileSize);
            if (FAILED(rc))
                rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);

            com::SafeArray<IN_BSTR> args;
            com::SafeArray<IN_BSTR> env;

            if (SUCCEEDED(rc))
            {
                /*
                 * Prepare tool command line.
                 */
                char szSource[RTPATH_MAX];
                if (RTStrPrintf(szSource, sizeof(szSource), "%s", aTask->strSource.c_str()) <= sizeof(szSource) - 1)
                {
                    /*
                     * Normalize path slashes, based on the detected guest.
                     */
                    Utf8Str osType = mData.mOSTypeId;
                    if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
                        || osType.contains("Windows", Utf8Str::CaseInsensitive))
                    {
                        /* We have a Windows guest. */
                        RTPathChangeToDosSlashes(szSource, true /* Force conversion. */);
                    }
                    else /* ... or something which isn't from Redmond ... */
                    {
                        RTPathChangeToUnixSlashes(szSource, true /* Force conversion. */);
                    }

                    args.push_back(Bstr(szSource).raw()); /* Tell our cat tool which file to output. */
                }
                else
                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                         Guest::tr("Error preparing command line"));
            }

            ComPtr<IProgress> execProgress;
            ULONG uPID;
            if (SUCCEEDED(rc))
            {
                LogRel(("Copying file \"%s\" to host \"%s\" (%u bytes) ...\n",
                        aTask->strSource.c_str(), aTask->strDest.c_str(), lFileSize));

                /*
                 * Okay, since we gathered all stuff we need until now to start the
                 * actual copying, start the guest part now.
                 */
                rc = pGuest->executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
                                                   Bstr("Copying file to host").raw(),
                                                   ComSafeArrayAsInParam(args),
                                                   ComSafeArrayAsInParam(env),
                                                   Bstr(aTask->strUserName).raw(),
                                                   Bstr(aTask->strPassword).raw(),
                                                     ExecuteProcessFlag_WaitForProcessStartOnly
                                                   | ExecuteProcessFlag_WaitForStdOut,
                                                   NULL, NULL,
                                                   execProgress.asOutParam(), &uPID);
                if (FAILED(rc))
                    rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
            }

            if (SUCCEEDED(rc))
            {
                BOOL fCompleted = FALSE;
                BOOL fCanceled = FALSE;

                RTFILE hFileDest;
                int vrc = RTFileOpen(&hFileDest, aTask->strDest.c_str(),
                                     RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE);
                if (RT_FAILURE(vrc))
                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                         Guest::tr("Unable to create/open destination file \"%s\", rc=%Rrc"),
                                                         aTask->strDest.c_str(), vrc);
                else
                {
                    size_t cbToRead = lFileSize;
                    size_t cbTransfered = 0;
                    while (   SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted)))
                           && !fCompleted)
                    {
                        SafeArray<BYTE> aOutputData;
                        rc = pGuest->GetProcessOutput(uPID, ProcessOutputFlag_None /* StdOut */,
                                                      0 /* No timeout. */,
                                                      _64K, ComSafeArrayAsOutParam(aOutputData));
                        if (SUCCEEDED(rc))
                        {
                            if (aOutputData.size())
                            {
                                vrc = RTFileWrite(hFileDest, aOutputData.raw(), aOutputData.size(), NULL /* No partial writes */);
                                if (RT_FAILURE(vrc))
                                {
                                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                         Guest::tr("Error writing to file \"%s\" (%u bytes left), rc=%Rrc"),
                                                                         aTask->strSource.c_str(), cbToRead, vrc);
                                    break;
                                }

                                Assert(cbToRead >= aOutputData.size());
                                cbToRead -= aOutputData.size();
                                cbTransfered += aOutputData.size();

                                aTask->pProgress->SetCurrentOperationProgress(cbTransfered / (lFileSize / 100.0));
                            }

                            /* Nothing read this time; try next round. */
                        }
                        else
                        {
                            rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
                            break;
                        }
                    }

                    RTFileClose(hFileDest);

                    if (SUCCEEDED(rc))
                    {
                        if (   cbTransfered
                            && (cbTransfered != lFileSize))
                        {
                            /*
                             * Only bitch about an unexpected end of a file when there already
                             * was data read from that file. If this was the very first read we can
                             * be (almost) sure that this file is not meant to be read by the specified user.
                             */
                            rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                 Guest::tr("Unexpected end of file \"%s\" (%u bytes total, %u bytes transferred)"),
                                                                 aTask->strSource.c_str(), lFileSize, cbTransfered);
                        }

                        if (SUCCEEDED(rc))
                            aTask->pProgress->notifyComplete(S_OK);
                    }
                }
            }
        }
    }
    catch (HRESULT aRC)
    {
        rc = aRC;
    }

    /* Clean up */
    aTask->rc = rc;

    LogFlowFunc(("rc=%Rhrc\n", rc));
    LogFlowFuncLeave();

    return VINF_SUCCESS;
}
Ejemplo n.º 26
0
bool
Clock::UpdateFromParentTime (TimeSpan parentTime)
{
#define CLAMP_NORMALIZED_TIME do {			\
	if (normalizedTime < 0.0) normalizedTime = 0.0; \
	if (normalizedTime > 1.0) normalizedTime = 1.0; \
} while (0)

	//
	// The idea behind this method is that it is possible (and
	// easier, and clearer) to apply a simple function to our
	// parent clock's time to calculate our own time.
	//
	// We also calculate our progress (MS uses the term
	// "normalized time"), a value in the range [0-1] at the same
	// time.
	//
	// This clock's localTime runs from the range
	// [0-natural_duration] for natural_durations with timespans,
	// and [0-$forever] for Forever durations.  Automatic
	// durations are translated into timespans.

	if (timeline == NULL) {
		// printf ("timeline is null!?  f**k yeah! (clock = %s)\n", name);
		Stop ();
		return false;
	}
		
	if (!GetHasStarted() && !GetWasStopped() && (GetBeginOnTick() || timeline->GetBeginTime () <= parentTime)) {
		if (GetBeginOnTick())
			BeginOnTick (false);
		Begin (parentTime);
	}

	// root_parent_time is the time we were added to our parent clock.
	// timeline->GetBeginTime() is expressed in the time-space of the parent clock.
	//
	// subtracting those two translates our start time to 0
	//
	// we then have to account for our accumulated pause time, and
	// scale the whole thing by our speed ratio.
	//
	// the result is a timespan unaffected by repeatbehavior or
	// autoreverse.  it is simple the timespan our clock has been
	// running.
	TimeSpan localTime = (parentTime - root_parent_time - timeline->GetBeginTime() - accumulated_pause_time) * timeline->GetSpeedRatio();

	bool seek_completed = false;

	if (is_seeking) {
		// if we're seeking, we need to arrange for the above
		// localTime formula to keep time correctly.  we clear
		// accumulated_pause_time, and adjust root_parent_time
		// such that we can re-evaluate localTime and have
		// localTime = seek_time.

		begin_pause_time = 0;
		accumulated_pause_time = 0;

		/* seek_time = localTime

		   seek_time = (parentTime - root_parent_time - timeline->BeginTime() - 0) * timeline->GetSpeedRatio ()

		          seek_time
  		   ------------------------- = parentTime - root_parent_time - timeline->BeginTime();
		   timeline->GetSpeedRatio()
                                                                                  seek_time         
		   root_parent_time = parentTime - timeline->BeginTime() - -------------------------
									   timeline->GetSpeedRatio()
		*/
		root_parent_time = parentTime - (timeline->GetBeginTime () - seek_time) / timeline->GetSpeedRatio ();
		localTime = (seek_time - timeline->GetBeginTime()) * timeline->GetSpeedRatio();
		is_seeking = false;
		seek_completed = true;

		if (!GetHasStarted())
			CalculateFillTime ();
	}
	else if (is_paused) {
		// if we're paused and not seeking, we don't update
		// anything.
		return false;
	}

	// the clock doesn't update and we don't progress if the
	// translated local time is before our begin time.  Keep in
	// mind that this can happen *after* a clock has started,
	// since parentTime isn't strictly increasing.  It can
	// decrease and represent a time before our start time.
	if (localTime < 0)
		return true;

	if (GetClockState () == Clock::Stopped) {
		if (!seek_completed)
			return false;

		// even for stopped clocks we update their position if they're seeked.
	}

	double normalizedTime = 0.0;


	// we only do the bulk of the work if the duration has a
	// timespan.  if we're automatic/forever, our normalizedTime
	// stays pegged at 0.0, and our localTime progresses
	// undisturbed.  i.e. a RepeatBehavior="2x" means nothing if
	// the Duration of the animation is forever.
	if (GetNaturalDuration().HasTimeSpan()) {
		TimeSpan natural_duration_timespan = GetNaturalDuration().GetTimeSpan();
		
		if (natural_duration_timespan <= 0) {
			// for clocks with instantaneous begin times/durations, expressable like so:
			//     <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" BeginTime="00:00:00" Duration="00:00:00" />
			// we keep our localtime pegged at 0 (FIXME:
			// without filling?) and our normalizedTime at
			// 1.  The latter makes sure that value is applied in full.
 			localTime = 0;
 			normalizedTime = 1.0;
			if (GetClockState () == Clock::Active) {
				FillOnNextTick ();
				Completed ();

				SetCurrentTime (localTime);
				progress = normalizedTime;

				return false;
			}
		}
		else if (natural_duration_timespan > 0) {
			RepeatBehavior *repeat = timeline->GetRepeatBehavior ();

			if (!repeat->IsForever() && localTime >= fillTime) {
				// fillTime represents the local time
				// at which the number of repeats
				// (expressed either as a timespan or
				// e.g. "2x") and autoreverses have
				// completed.  i.e. it's the
				// $natural_duration * $repeat_count
				// for repeat behaviors with counts,
				// and $repeat_duration for repeat
				// behaviors with timespans.

				// if the timeline is auto-reversible,
				// we always end at localTime = 0.
				// Otherwise we know it's fillTime.
				localTime = timeline->GetAutoReverse () ? 0 : fillTime;
				normalizedTime = (double)localTime / natural_duration_timespan;
				CLAMP_NORMALIZED_TIME;
				if (GetClockState () == Clock::Active) {
					FillOnNextTick ();
					Completed ();
				}
				else if ((moonlight_flags & RUNTIME_INIT_USE_IDLE_HINT) && GetClockState () == Clock::Filling) {
					return false;
				}
			}
			else {
				if (GetClockState () != Clock::Active)
					SetClockState (Clock::Active);

				if (localTime > 0) {
					double t = (double)localTime / natural_duration_timespan;
					int ti = (int)t;
					double fract = t - ti;

					// This block of code is the first time where localTime is translated
					// into per-repeat/per-autoreverse segments.  We do it here because it
					// allows us to use a cute hack for determining if we're ascending or
					// descending.
					//
					// for instance:

					// <storyboard duration="00:00:12">
					//   <doubleanimation begintime="00:00:00" repeatbehavior="2x" autoreverse="<below>" duration="00:00:03" />
					// </storyboard>
					//
					//  autoreverse = true                       autoreverse = false
					// 0  / 3 = 0        = 0                  0 / 3 = 0           = 0
					// 1  / 3 = .333     > 0.333              1 / 3 = .333        > 0.333
					// 2  / 3 = .666     > 0.666              2 / 3 = .666        > 0.666
					// 3  / 3 = 1        = 1                  3 / 3 = 1           = 1
					// 4  / 3 = 1.33     < 0.666              4 / 3 = 1.33        > 0.333
					// 5  / 3 = 1.66     < 0.333              5 / 3 = 1.66        > 0.666
					// 6  / 3 = 2        = 0                  6 / 3 = 2           = 1
					// 7  / 3 = 2.33     > 0.333
					// 8  / 3 = 2.66     > 0.666
					// 9  / 3 = 3        = 1
					// 10 / 3 = 3.33     < 0.666
					// 11 / 3 = 3.66     < 0.333
					// 12 / 3 = 4        = 0


					// a little explanation:  the $localtime / $natural_duration = $foo is done
					// to factor out the repeat count.  we know that the time within a given repeated
					// run is just the fractional part of that (if the result has a fraction), or 0 or 1.

					// the >,<,= column above represents whether we're increasing, decreasing, or at an
					// end-point, respectively.

					if (timeline->GetAutoReverse()) {
						// left column above
						if (ti & 1) {
							// e.g:
							// 3  / 3 = 1        = 1    
							// 4  / 3 = 1.33     < 0.666
							// 5  / 3 = 1.66     < 0.333

							// we know we're either at normalized time 1 (at our duration), or we're descending,
							// based on if there's a fractional component.
							if (ti == t) {
								normalizedTime = 1.0;
								localTime = natural_duration_timespan;
							}
							else {
								/* we're descending */
								normalizedTime = 1.0 - fract;
								CLAMP_NORMALIZED_TIME;
								localTime = normalizedTime * natural_duration_timespan;
							}
						}
						else {
							// e.g:
							// 6  / 3 = 2        = 0    
							// 7  / 3 = 2.33     > 0.333
							// 8  / 3 = 2.66     > 0.666

							// we know we're either at normalizd time 0 (at our start time), or we're ascending,
							// based on if there's a fractional component.
							if (ti == t) {
								normalizedTime = 0.0;
								localTime = 0;
							}
							else {
								/* we're ascending */
								normalizedTime = fract;
								CLAMP_NORMALIZED_TIME;
								localTime = normalizedTime * natural_duration_timespan;
							}
						}
					}
					else {
						// e.g.:
						// 0 / 3 = 0           = 0
						// 1 / 3 = .333        > 0.333
						// 2 / 3 = .666        > 0.666
						// 3 / 3 = 1           = 1
						// 4 / 3 = 1.33        > 0.333
						// 5 / 3 = 1.66        > 0.666
						// 6 / 3 = 2           = 1

						// we're always ascending here (since autoreverse is off), and we know we're > 0,
						// so we don't need to concern ourselves with that case.  At the integer points we're
						// at our duration, and otherwise we're at the fractional value.
						if (ti == t) {
							normalizedTime = 1.0;
							localTime = natural_duration_timespan;
						}
						else {
							/* we're ascending */
							normalizedTime = fract;
							CLAMP_NORMALIZED_TIME;
							localTime = normalizedTime * natural_duration_timespan;
						}
					}
				}
			}
		}
	}

	SetCurrentTime (localTime);
	progress = normalizedTime;

	// we check to see if there's a clockgroup in our hierarchy
	// that's Filling.  if there is, we return false here, since
	// we won't be updated beyond our current time anyway.
	if (moonlight_flags & RUNTIME_INIT_USE_IDLE_HINT) {
		Clock *cg = this;
		while ((cg = cg->GetParentClock())) {
			if (cg->GetClockState () == Clock::Active && !((ClockGroup*)cg)->IsTimeManagerClockGroup())
				return true;
		}

		return false;
	}

	return true;
}
RocketStorageSelectionDialog::RocketStorageSelectionDialog(RocketPlugin *plugin, MeshmoonStorage *storage, const QStringList &suffixFilters, 
                                                           bool allowChangingFolder, MeshmoonStorageItem &startDirectory, QWidget *parent) :
    QDialog(parent),
    plugin_(plugin),
    storage_(storage),
    suffixFilters_(suffixFilters),
    allowChangingFolder_(allowChangingFolder),
    startDirectory_(startDirectory),
    currentFolder_(0)
{
    // Setup UI
    ui_.setupUi(this);
    ui_.scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui_.lineEditFilter->installEventFilter(this);

    ui_.buttonSelect->setAutoDefault(false);
    ui_.buttonCancel->setAutoDefault(false);

    view_ = new RocketStorageListWidget(this, plugin_);
    view_->SetPreviewFileOnMouse(true);
    view_->setSelectionMode(QAbstractItemView::SingleSelection);

    QVBoxLayout *l = new QVBoxLayout(ui_.scrollAreaWidgetContents);
    l->setSpacing(0);
    l->setContentsMargins(0,0,0,0);
    l->addWidget(view_);
    ui_.scrollAreaWidgetContents->setLayout(l);

    // Connections
    connect(view_, SIGNAL(itemClicked(QListWidgetItem*)), SLOT(OnItemClicked(QListWidgetItem*)));
    connect(view_, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(OnItemDoubleClicked(QListWidgetItem*)));
    connect(ui_.buttonSelect, SIGNAL(clicked()), SLOT(OnSelect()), Qt::QueuedConnection);
    connect(ui_.buttonCancel, SIGNAL(clicked()), SLOT(reject()), Qt::QueuedConnection);
    connect(this, SIGNAL(rejected()), SLOT(OnCancel()));
    connect(ui_.lineEditFilter, SIGNAL(textChanged(const QString&)), SLOT(OnFilterChanged(const QString&)));

    // Dialog setup
    setAttribute(Qt::WA_DeleteOnClose, true);
    setWindowModality(parent != 0 ? Qt::WindowModal : Qt::ApplicationModal);
    setWindowFlags(parent != 0 ? Qt::Tool : Qt::SplashScreen);
    setWindowTitle(parent != 0 ? "Meshmoon Storage Picker" : "");
    setModal(true);

    // Center to main window or to parent window.
    if (!parent)
    {
        plugin_->Notifications()->DimForeground();
        plugin_->Notifications()->CenterToMainWindow(this);
    }
    else
        plugin_->Notifications()->CenterToWindow(parent, this);
    
    // Show and activate
    show();
    setFocus(Qt::ActiveWindowFocusReason);
    activateWindow();
    
    // If this is a splash dialog animate opacity
    if (!parent)
    {
        setWindowOpacity(0.0);

        QPropertyAnimation *showAnim = new QPropertyAnimation(this, "windowOpacity", this);
        showAnim->setStartValue(0.0);
        showAnim->setEndValue(1.0);
        showAnim->setDuration(300);
        showAnim->setEasingCurve(QEasingCurve(QEasingCurve::InOutQuad)); 
        showAnim->start();
    }

    if (!plugin_ || !storage_)
    {
        view_->addItem(new QListWidgetItem("Failed to list storage content"));
        return;
    }
    if (storage_->RootDirectory().IsNull())
        view_->addItem(new QListWidgetItem("Loading..."));

    MeshmoonStorageAuthenticationMonitor *auth = storage_->Authenticate();
    connect(auth, SIGNAL(Completed()), SLOT(OnStorageAuthCompleted()), Qt::QueuedConnection);
    connect(auth, SIGNAL(Canceled()), SLOT(reject()), Qt::QueuedConnection);
    connect(auth, SIGNAL(Failed(const QString&)), SLOT(reject()), Qt::QueuedConnection);
}
Ejemplo n.º 28
0
HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
{
    LogFlowFuncEnter();

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /*
     * Do *not* take a write lock here since we don't (and won't)
     * touch any class-specific data (of IGuest) here - only the member functions
     * which get called here can do that.
     */

    HRESULT rc = S_OK;
    BOOL fCompleted;
    BOOL fCanceled;

    try
    {
        ComObjPtr<Guest> pGuest = aTask->pGuest;

        aTask->pProgress->SetCurrentOperationProgress(10);

        /*
         * Determine guest OS type and the required installer image.
         * At the moment only Windows guests are supported.
         */
        Utf8Str installerImage;
        Bstr osTypeId;
        if (   SUCCEEDED(pGuest->COMGETTER(OSTypeId(osTypeId.asOutParam())))
            && !osTypeId.isEmpty())
        {
            Utf8Str osTypeIdUtf8(osTypeId); /* Needed for .contains(). */
            if (   osTypeIdUtf8.contains("Microsoft", Utf8Str::CaseInsensitive)
                || osTypeIdUtf8.contains("Windows", Utf8Str::CaseInsensitive))
            {
                if (osTypeIdUtf8.contains("64", Utf8Str::CaseInsensitive))
                    installerImage = "VBOXWINDOWSADDITIONS_AMD64.EXE";
                else
                    installerImage = "VBOXWINDOWSADDITIONS_X86.EXE";
                /* Since the installers are located in the root directory,
                 * no further path processing needs to be done (yet). */
            }
            else /* Everything else is not supported (yet). */
                throw GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
                                                      Guest::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
                                                      osTypeIdUtf8.c_str());
        }
        else
            throw GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
                                                  Guest::tr("Could not detected guest OS type/version, please update manually"));
        Assert(!installerImage.isEmpty());

        /*
         * Try to open the .ISO file and locate the specified installer.
         */
        RTISOFSFILE iso;
        int vrc = RTIsoFsOpen(&iso, aTask->strSource.c_str());
        if (RT_FAILURE(vrc))
        {
            rc = GuestTask::setProgressErrorInfo(VBOX_E_FILE_ERROR, aTask->pProgress,
                                                 Guest::tr("Invalid installation medium detected: \"%s\""),
                                                 aTask->strSource.c_str());
        }
        else
        {
            uint32_t cbOffset;
            size_t cbLength;
            vrc = RTIsoFsGetFileInfo(&iso, installerImage.c_str(), &cbOffset, &cbLength);
            if (   RT_SUCCESS(vrc)
                && cbOffset
                && cbLength)
            {
                vrc = RTFileSeek(iso.file, cbOffset, RTFILE_SEEK_BEGIN, NULL);
                if (RT_FAILURE(vrc))
                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                         Guest::tr("Could not seek to setup file on installation medium \"%s\" (%Rrc)"),
                                                         aTask->strSource.c_str(), vrc);
            }
            else
            {
                switch (vrc)
                {
                    case VERR_FILE_NOT_FOUND:
                        rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                             Guest::tr("Setup file was not found on installation medium \"%s\""),
                                                             aTask->strSource.c_str());
                        break;

                    default:
                        rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                             Guest::tr("An unknown error (%Rrc) occured while retrieving information of setup file on installation medium \"%s\""),
                                                             vrc, aTask->strSource.c_str());
                        break;
                }
            }

            /* Specify the ouput path on the guest side. */
            Utf8Str strInstallerPath = "%TEMP%\\VBoxWindowsAdditions.exe";

            if (RT_SUCCESS(vrc))
            {
                /* Okay, we're ready to start our copy routine on the guest! */
                aTask->pProgress->SetCurrentOperationProgress(15);

                /* Prepare command line args. */
                com::SafeArray<IN_BSTR> args;
                com::SafeArray<IN_BSTR> env;

                args.push_back(Bstr("--output").raw());               /* We want to write a file ... */
                args.push_back(Bstr(strInstallerPath.c_str()).raw()); /* ... with this path. */

                if (SUCCEEDED(rc))
                {
                    ComPtr<IProgress> progressCat;
                    ULONG uPID;

                    /*
                     * Start built-in "vbox_cat" tool (inside VBoxService) to
                     * copy over/pipe the data into a file on the guest (with
                     * system rights, no username/password specified).
                     */
                    rc = pGuest->executeProcessInternal(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
                                                          ExecuteProcessFlag_Hidden
                                                        | ExecuteProcessFlag_WaitForProcessStartOnly,
                                                        ComSafeArrayAsInParam(args),
                                                        ComSafeArrayAsInParam(env),
                                                        Bstr("").raw() /* Username. */,
                                                        Bstr("").raw() /* Password */,
                                                        5 * 1000 /* Wait 5s for getting the process started. */,
                                                        &uPID, progressCat.asOutParam(), &vrc);
                    if (FAILED(rc))
                    {
                        /* Errors which return VBOX_E_NOT_SUPPORTED can be safely skipped by the caller
                         * to silently fall back to "normal" (old) .ISO mounting. */

                        /* Due to a very limited COM error range we use vrc for a more detailed error
                         * lookup to figure out what went wrong. */
                        switch (vrc)
                        {
                            /* Guest execution service is not (yet) ready. This basically means that either VBoxService
                             * is not running (yet) or that the Guest Additions are too old (because VBoxService does not
                             * support the guest execution feature in this version). */
                            case VERR_NOT_FOUND:
                                LogRel(("Guest Additions seem not to be installed yet\n"));
                                rc = GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
                                                                     Guest::tr("Guest Additions seem not to be installed or are not ready to update yet"));
                                break;

                            /* Getting back a VERR_INVALID_PARAMETER indicates that the installed Guest Additions are supporting the guest
                             * execution but not the built-in "vbox_cat" tool of VBoxService (< 4.0). */
                            case VERR_INVALID_PARAMETER:
                                LogRel(("Guest Additions are installed but don't supported automatic updating\n"));
                                rc = GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
                                                                     Guest::tr("Installed Guest Additions do not support automatic updating"));
                                break;

                            case VERR_TIMEOUT:
                                LogRel(("Guest was unable to start copying the Guest Additions setup within time\n"));
                                rc = GuestTask::setProgressErrorInfo(E_FAIL, aTask->pProgress,
                                                                     Guest::tr("Guest was unable to start copying the Guest Additions setup within time"));
                                break;

                            default:
                                rc = GuestTask::setProgressErrorInfo(E_FAIL, aTask->pProgress,
                                                                     Guest::tr("Error copying Guest Additions setup file to guest path \"%s\" (%Rrc)"),
                                                                     strInstallerPath.c_str(), vrc);
                                break;
                        }
                    }
                    else
                    {
                        LogRel(("Automatic update of Guest Additions started, using \"%s\"\n", aTask->strSource.c_str()));
                        LogRel(("Copying Guest Additions installer \"%s\" to \"%s\" on guest ...\n",
                                installerImage.c_str(), strInstallerPath.c_str()));
                        aTask->pProgress->SetCurrentOperationProgress(20);

                        /* Wait for process to exit ... */
                        SafeArray<BYTE> aInputData(_64K);
                        while (   SUCCEEDED(progressCat->COMGETTER(Completed(&fCompleted)))
                               && !fCompleted)
                        {
                            size_t cbRead;
                            /* cbLength contains remaining bytes of our installer file
                             * opened above to read. */
                            size_t cbToRead = RT_MIN(cbLength, _64K);
                            if (cbToRead)
                            {
                                vrc = RTFileRead(iso.file, (uint8_t*)aInputData.raw(), cbToRead, &cbRead);
                                if (   cbRead
                                    && RT_SUCCESS(vrc))
                                {
                                    /* Resize buffer to reflect amount we just have read. */
                                    if (cbRead > 0)
                                        aInputData.resize(cbRead);

                                    /* Did we reach the end of the content we want to transfer (last chunk)? */
                                    ULONG uFlags = ProcessInputFlag_None;
                                    if (   (cbRead < _64K)
                                        /* Did we reach the last block which is exactly _64K? */
                                        || (cbToRead - cbRead == 0)
                                        /* ... or does the user want to cancel? */
                                        || (   SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
                                            && fCanceled)
                                       )
                                    {
                                        uFlags |= ProcessInputFlag_EndOfFile;
                                    }

                                    /* Transfer the current chunk ... */
                                #ifdef DEBUG_andy
                                    LogRel(("Copying Guest Additions (%u bytes left) ...\n", cbLength));
                                #endif
                                    ULONG uBytesWritten;
                                    rc = pGuest->SetProcessInput(uPID, uFlags,
                                                                 10 * 1000 /* Wait 10s for getting the input data transfered. */,
                                                                 ComSafeArrayAsInParam(aInputData), &uBytesWritten);
                                    if (FAILED(rc))
                                    {
                                        rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
                                        break;
                                    }

                                    /* If task was canceled above also cancel the process execution. */
                                    if (fCanceled)
                                        progressCat->Cancel();

                                #ifdef DEBUG_andy
                                    LogRel(("Copying Guest Additions (%u bytes written) ...\n", uBytesWritten));
                                #endif
                                    Assert(cbLength >= uBytesWritten);
                                    cbLength -= uBytesWritten;
                                }
                                else if (RT_FAILURE(vrc))
                                {
                                    rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                         Guest::tr("Error while reading setup file \"%s\" (To read: %u, Size: %u) from installation medium (%Rrc)"),
                                                                         installerImage.c_str(), cbToRead, cbLength, vrc);
                                }
                            }

                            /* Internal progress canceled? */
                            if (   SUCCEEDED(progressCat->COMGETTER(Canceled(&fCanceled)))
                                && fCanceled)
                            {
                                aTask->pProgress->Cancel();
                                break;
                            }
                        }
                    }
                }
            }
            RTIsoFsClose(&iso);

            if (   SUCCEEDED(rc)
                && (   SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
                    && !fCanceled
                   )
               )
            {
                /*
                 * Installer was transferred successfully, so let's start it
                 * (with system rights).
                 */
                LogRel(("Preparing to execute Guest Additions update ...\n"));
                aTask->pProgress->SetCurrentOperationProgress(66);

                /* Prepare command line args for installer. */
                com::SafeArray<IN_BSTR> installerArgs;
                com::SafeArray<IN_BSTR> installerEnv;

                /** @todo Only Windows! */
                installerArgs.push_back(Bstr(strInstallerPath).raw()); /* The actual (internal) installer image (as argv[0]). */
                /* Note that starting at Windows Vista the lovely session 0 separation applies:
                 * This means that if we run an application with the profile/security context
                 * of VBoxService (system rights!) we're not able to show any UI. */
                installerArgs.push_back(Bstr("/S").raw());      /* We want to install in silent mode. */
                installerArgs.push_back(Bstr("/l").raw());      /* ... and logging enabled. */
                /* Don't quit VBoxService during upgrade because it still is used for this
                 * piece of code we're in right now (that is, here!) ... */
                installerArgs.push_back(Bstr("/no_vboxservice_exit").raw());
                /* Tell the installer to report its current installation status
                 * using a running VBoxTray instance via balloon messages in the
                 * Windows taskbar. */
                installerArgs.push_back(Bstr("/post_installstatus").raw());

                /*
                 * Start the just copied over installer with system rights
                 * in silent mode on the guest. Don't use the hidden flag since there
                 * may be pop ups the user has to process.
                 */
                ComPtr<IProgress> progressInstaller;
                ULONG uPID;
                rc = pGuest->executeProcessInternal(Bstr(strInstallerPath).raw(),
                                                    ExecuteProcessFlag_WaitForProcessStartOnly,
                                                    ComSafeArrayAsInParam(installerArgs),
                                                    ComSafeArrayAsInParam(installerEnv),
                                                    Bstr("").raw() /* Username */,
                                                    Bstr("").raw() /* Password */,
                                                    10 * 1000 /* Wait 10s for getting the process started */,
                                                    &uPID, progressInstaller.asOutParam(), &vrc);
                if (SUCCEEDED(rc))
                {
                    LogRel(("Guest Additions update is running ...\n"));

                    /* If the caller does not want to wait for out guest update process to end,
                     * complete the progress object now so that the caller can do other work. */
                    if (aTask->uFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)
                        aTask->pProgress->notifyComplete(S_OK);
                    else
                        aTask->pProgress->SetCurrentOperationProgress(70);

                    /* Wait until the Guest Additions installer finishes ... */
                    while (   SUCCEEDED(progressInstaller->COMGETTER(Completed(&fCompleted)))
                           && !fCompleted)
                    {
                        if (   SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
                            && fCanceled)
                        {
                            progressInstaller->Cancel();
                            break;
                        }
                        /* Progress canceled by Main API? */
                        if (   SUCCEEDED(progressInstaller->COMGETTER(Canceled(&fCanceled)))
                            && fCanceled)
                        {
                            break;
                        }
                        RTThreadSleep(100);
                    }

                    ExecuteProcessStatus_T retStatus;
                    ULONG uRetExitCode, uRetFlags;
                    rc = pGuest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
                    if (SUCCEEDED(rc))
                    {
                        if (fCompleted)
                        {
                            if (uRetExitCode == 0)
                            {
                                LogRel(("Guest Additions update successful!\n"));
                                if (   SUCCEEDED(aTask->pProgress->COMGETTER(Completed(&fCompleted)))
                                    && !fCompleted)
                                    aTask->pProgress->notifyComplete(S_OK);
                            }
                            else
                            {
                                LogRel(("Guest Additions update failed (Exit code=%u, Status=%u, Flags=%u)\n",
                                        uRetExitCode, retStatus, uRetFlags));
                                rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                     Guest::tr("Guest Additions update failed with exit code=%u (status=%u, flags=%u)"),
                                                                     uRetExitCode, retStatus, uRetFlags);
                            }
                        }
                        else if (   SUCCEEDED(progressInstaller->COMGETTER(Canceled(&fCanceled)))
                                 && fCanceled)
                        {
                            LogRel(("Guest Additions update was canceled\n"));
                            rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
                                                                 Guest::tr("Guest Additions update was canceled by the guest with exit code=%u (status=%u, flags=%u)"),
                                                                 uRetExitCode, retStatus, uRetFlags);
                        }
                        else
                        {
                            LogRel(("Guest Additions update was canceled by the user\n"));
                        }
                    }
                    else
                        rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
                }
                else
                    rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
            }
        }
    }
    catch (HRESULT aRC)
    {
        rc = aRC;
    }

    /* Clean up */
    aTask->rc = rc;

    LogFlowFunc(("rc=%Rhrc\n", rc));
    LogFlowFuncLeave();

    return VINF_SUCCESS;
}