VirtualBox

Changeset 33924 in vbox


Ignore:
Timestamp:
Nov 10, 2010 8:53:54 AM (14 years ago)
Author:
vboxsync
Message:

VBoxManage/GuestControl: Some refactoring.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r33901 r33924  
    6363
    6464/** Set by the signal handler. */
    65 static volatile bool    g_fExecCanceled = false;
    66 static volatile bool    g_fCopyCanceled = false;
     65static volatile bool    g_fGuestCtrlCanceled = false;
    6766
    6867/*
     
    109108
    110109/**
    111  * Signal handler that sets g_fCanceled.
     110 * Signal handler that sets g_fGuestCtrlCanceled.
    112111 *
    113112 * This can be executed on any thread in the process, on Windows it may even be
     
    115114 * unnecessary here.
    116115 */
    117 static void ctrlExecProcessSignalHandler(int iSignal)
     116static void guestCtrlSignalHandler(int iSignal)
    118117{
    119118    NOREF(iSignal);
    120     ASMAtomicWriteBool(&g_fExecCanceled, true);
    121 }
    122 
     119    ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true);
     120}
     121
     122/**
     123 * Installs a custom signal handler to get notified
     124 * whenever the user wants to intercept the program.
     125 */
     126static void ctrlSignalHandlerInstall()
     127{
     128    signal(SIGINT,   guestCtrlSignalHandler);
     129#ifdef SIGBREAK
     130    signal(SIGBREAK, guestCtrlSignalHandler);
     131#endif
     132}
     133
     134/**
     135 * Uninstalls a previously installed signal handler.
     136 */
     137static void ctrlSignalHandlerUninstall()
     138{
     139    signal(SIGINT,   SIG_DFL);
     140#ifdef SIGBREAK
     141    signal(SIGBREAK, SIG_DFL);
     142#endif
     143}
     144
     145/**
     146 * Translates a process status to a human readable
     147 * string.
     148 */
    123149static const char *ctrlExecGetStatus(ULONG uStatus)
    124150{
     
    146172}
    147173
     174static int ctrlPrintError(ComPtr<IUnknown> object, const GUID &aIID)
     175{
     176    com::ErrorInfo info(object, aIID);
     177    if (   info.isFullAvailable()
     178        || info.isBasicAvailable())
     179    {
     180        /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
     181         * because it contains more accurate info about what went wrong. */
     182        if (info.getResultCode() == VBOX_E_IPRT_ERROR)
     183            RTMsgError("%ls.", info.getText().raw());
     184        else
     185        {
     186            RTMsgError("Error details:");
     187            GluePrintErrorInfo(info);
     188        }
     189        return VERR_GENERAL_FAILURE; /** @todo */
     190    }
     191    AssertMsgFailedReturn(("Object has indicated no error!?\n"),
     192                          VERR_INVALID_PARAMETER);
     193}
     194
     195/**
     196 * Un-initializes the VM after guest control usage.
     197 */
     198static void ctrlUninitVM(HandlerArg *pArg)
     199{
     200    AssertPtrReturnVoid(pArg);
     201    if (pArg->session)
     202        pArg->session->UnlockMachine();
     203}
     204
     205/**
     206 * Initializes the VM, that is checks whether it's up and
     207 * running, if it can be locked (shared only) and returns a
     208 * valid IGuest pointer on success.
     209 *
     210 * @return  IPRT status code.
     211 * @param   pArg            Our command line argument structure.
     212 * @param   pszNameOrId     The VM's name or UUID to use.
     213 * @param   pGuest          Pointer where to store the IGuest interface.
     214 */
     215static int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest> *pGuest)
     216{
     217    AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
     218    AssertPtrReturn(pszNameOrId, VERR_INVALID_PARAMETER);
     219
     220    /* Lookup VM. */
     221    ComPtr<IMachine> machine;
     222    /* Assume it's an UUID. */
     223    HRESULT rc;
     224    CHECK_ERROR(pArg->virtualBox, FindMachine(Bstr(pszNameOrId).raw(),
     225                                              machine.asOutParam()));
     226    if (FAILED(rc))
     227        return VERR_NOT_FOUND;
     228
     229    /* Machine is running? */
     230    MachineState_T machineState;
     231    CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1);
     232    if (machineState != MachineState_Running)
     233    {
     234        RTMsgError("Machine \"%s\" is not running!\n", pszNameOrId);
     235        return VERR_VM_INVALID_VM_STATE;
     236    }
     237
     238    do
     239    {
     240        /* Open a session for the VM. */
     241        CHECK_ERROR_BREAK(machine, LockMachine(pArg->session, LockType_Shared));
     242        /* Get the associated console. */
     243        ComPtr<IConsole> console;
     244        CHECK_ERROR_BREAK(pArg->session, COMGETTER(Console)(console.asOutParam()));
     245        /* ... and session machine. */
     246        ComPtr<IMachine> sessionMachine;
     247        CHECK_ERROR_BREAK(pArg->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
     248        /* Get IGuest interface. */
     249        CHECK_ERROR_BREAK(console, COMGETTER(Guest)(pGuest->asOutParam()));
     250    } while (0);
     251
     252    if (FAILED(rc))
     253        ctrlUninitVM(pArg);
     254    return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
     255}
     256
    148257static int handleCtrlExecProgram(HandlerArg *a)
    149258{
     
    307416                           "No user name specified!");
    308417
    309     /* Lookup VM. */
    310     ComPtr<IMachine> machine;
    311     /* Assume it's an UUID. */
    312     HRESULT rc;
    313     CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
    314                                            machine.asOutParam()));
    315     if (FAILED(rc))
    316         return 1;
    317 
    318     /* Machine is running? */
    319     MachineState_T machineState;
    320     CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1);
    321     if (machineState != MachineState_Running)
    322     {
    323         RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]);
    324         return 1;
    325     }
    326 
    327     /* Open a session for the VM. */
    328     CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    329 
    330     do
    331     {
    332         /* Get the associated console. */
    333         ComPtr<IConsole> console;
    334         CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
    335         /* ... and session machine */
    336         ComPtr<IMachine> sessionMachine;
    337         CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
    338 
    339         ComPtr<IGuest> guest;
    340         CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
    341 
     418    HRESULT rc = S_OK;
     419    ComPtr<IGuest> guest;
     420    int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
     421    if (RT_SUCCESS(vrc))
     422    {
    342423        ComPtr<IProgress> progress;
    343424        ULONG uPID = 0;
     
    363444        if (FAILED(rc))
    364445        {
    365             /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    366              * because it contains more accurate info about what went wrong. */
    367             ErrorInfo info(guest, COM_IIDOF(IGuest));
    368             if (info.isFullAvailable())
    369             {
    370                 if (rc == VBOX_E_IPRT_ERROR)
    371                     RTMsgError("%ls.", info.getText().raw());
    372                 else
    373                     RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode());
    374             }
    375             break;
    376         }
    377         if (fVerbose)
    378             RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID);
    379         if (fWaitForExit)
    380         {
    381             if (fTimeout)
    382             {
    383                 /* Calculate timeout value left after process has been started.  */
    384                 uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS;
    385                 /* Is timeout still bigger than current difference? */
    386                 if (u32TimeoutMS > u64Elapsed)
    387                 {
    388                     u32TimeoutMS -= (uint32_t)u64Elapsed;
    389                     if (fVerbose)
    390                         RTPrintf("Waiting for process to exit (%ums left) ...\n", u32TimeoutMS);
    391                 }
    392                 else
    393                 {
    394                     if (fVerbose)
    395                         RTPrintf("No time left to wait for process!\n");
    396                 }
    397             }
    398             else if (fVerbose)
    399                 RTPrintf("Waiting for process to exit ...\n");
    400 
    401             /* Setup signal handling if cancelable. */
    402             ASSERT(progress);
    403             bool fCanceledAlready = false;
    404             BOOL fCancelable;
    405             HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
    406             if (FAILED(hrc))
    407                 fCancelable = FALSE;
    408             if (fCancelable)
    409             {
    410                 signal(SIGINT,   ctrlExecProcessSignalHandler);
    411         #ifdef SIGBREAK
    412                 signal(SIGBREAK, ctrlExecProcessSignalHandler);
    413         #endif
    414             }
    415 
    416             /* Wait for process to exit ... */
    417             BOOL fCompleted = FALSE;
    418             BOOL fCanceled = FALSE;
    419             while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
    420             {
    421                 SafeArray<BYTE> aOutputData;
    422                 ULONG cbOutputData = 0;
    423 
    424                 /*
    425                  * Some data left to output?
    426                  */
    427                 if (   fWaitForStdOut
    428                     || fWaitForStdErr)
    429                 {
    430                     rc = guest->GetProcessOutput(uPID, 0 /* aFlags */,
    431                                                  u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData));
    432                     if (FAILED(rc))
     446            vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
     447        }
     448        else
     449        {
     450            if (fVerbose)
     451                RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID);
     452            if (fWaitForExit)
     453            {
     454                if (fTimeout)
     455                {
     456                    /* Calculate timeout value left after process has been started.  */
     457                    uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS;
     458                    /* Is timeout still bigger than current difference? */
     459                    if (u32TimeoutMS > u64Elapsed)
    433460                    {
    434                         /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    435                          * because it contains more accurate info about what went wrong. */
    436                         ErrorInfo info(guest, COM_IIDOF(IGuest));
    437                         if (info.isFullAvailable())
    438                         {
    439                             if (rc == VBOX_E_IPRT_ERROR)
    440                                 RTMsgError("%ls.", info.getText().raw());
    441                             else
    442                                 RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode());
    443                         }
    444                         cbOutputData = 0;
    445                         fCompleted = true; /* rc contains a failure, so we'll go into aborted state down below. */
     461                        u32TimeoutMS -= (uint32_t)u64Elapsed;
     462                        if (fVerbose)
     463                            RTPrintf("Waiting for process to exit (%ums left) ...\n", u32TimeoutMS);
    446464                    }
    447465                    else
    448466                    {
    449                         cbOutputData = aOutputData.size();
    450                         if (cbOutputData > 0)
     467                        if (fVerbose)
     468                            RTPrintf("No time left to wait for process!\n");
     469                    }
     470                }
     471                else if (fVerbose)
     472                    RTPrintf("Waiting for process to exit ...\n");
     473
     474                /* Setup signal handling if cancelable. */
     475                ASSERT(progress);
     476                bool fCanceledAlready = false;
     477                BOOL fCancelable;
     478                HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
     479                if (FAILED(hrc))
     480                    fCancelable = FALSE;
     481                if (fCancelable)
     482                    ctrlSignalHandlerInstall();
     483
     484                /* Wait for process to exit ... */
     485                BOOL fCompleted = FALSE;
     486                BOOL fCanceled = FALSE;
     487                while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
     488                {
     489                    SafeArray<BYTE> aOutputData;
     490                    ULONG cbOutputData = 0;
     491
     492                    /*
     493                     * Some data left to output?
     494                     */
     495                    if (   fWaitForStdOut
     496                        || fWaitForStdErr)
     497                    {
     498                        rc = guest->GetProcessOutput(uPID, 0 /* aFlags */,
     499                                                     u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData));
     500                        if (FAILED(rc))
    451501                        {
    452                             /* aOutputData has a platform dependent line ending, standardize on
    453                              * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
    454                              * Windows. Otherwise we end up with CR/CR/LF on Windows. */
    455                             ULONG cbOutputDataPrint = cbOutputData;
    456                             for (BYTE *s = aOutputData.raw(), *d = s;
    457                                  s - aOutputData.raw() < (ssize_t)cbOutputData;
    458                                  s++, d++)
     502                            vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
     503
     504                            cbOutputData = 0;
     505                            fCompleted = true; /* rc contains a failure, so we'll go into aborted state down below. */
     506                        }
     507                        else
     508                        {
     509                            cbOutputData = aOutputData.size();
     510                            if (cbOutputData > 0)
    459511                            {
    460                                 if (*s == '\r')
     512                                /* aOutputData has a platform dependent line ending, standardize on
     513                                 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
     514                                 * Windows. Otherwise we end up with CR/CR/LF on Windows. */
     515                                ULONG cbOutputDataPrint = cbOutputData;
     516                                for (BYTE *s = aOutputData.raw(), *d = s;
     517                                     s - aOutputData.raw() < (ssize_t)cbOutputData;
     518                                     s++, d++)
    461519                                {
    462                                     /* skip over CR, adjust destination */
    463                                     d--;
    464                                     cbOutputDataPrint--;
     520                                    if (*s == '\r')
     521                                    {
     522                                        /* skip over CR, adjust destination */
     523                                        d--;
     524                                        cbOutputDataPrint--;
     525                                    }
     526                                    else if (s != d)
     527                                        *d = *s;
    465528                                }
    466                                 else if (s != d)
    467                                     *d = *s;
     529                                RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint);
    468530                            }
    469                             RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint);
    470531                        }
    471532                    }
    472                 }
    473                 if (cbOutputData <= 0) /* No more output data left? */
    474                 {
    475                     if (fCompleted)
    476                         break;
    477 
    478                     if (   fTimeout
    479                         && RTTimeMilliTS() - u64StartMS > u32TimeoutMS + 5000)
     533                    if (cbOutputData <= 0) /* No more output data left? */
    480534                    {
    481                         progress->Cancel();
     535                        if (fCompleted)
     536                            break;
     537
     538                        if (   fTimeout
     539                            && RTTimeMilliTS() - u64StartMS > u32TimeoutMS + 5000)
     540                        {
     541                            progress->Cancel();
     542                            break;
     543                        }
     544                    }
     545
     546                    /* Process async cancelation */
     547                    if (g_fGuestCtrlCanceled && !fCanceledAlready)
     548                    {
     549                        hrc = progress->Cancel();
     550                        if (SUCCEEDED(hrc))
     551                            fCanceledAlready = TRUE;
     552                        else
     553                            g_fGuestCtrlCanceled = false;
     554                    }
     555
     556                    /* Progress canceled by Main API? */
     557                    if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
     558                        && fCanceled)
     559                    {
    482560                        break;
    483561                    }
    484562                }
    485563
    486                 /* Process async cancelation */
    487                 if (g_fExecCanceled && !fCanceledAlready)
    488                 {
    489                     hrc = progress->Cancel();
    490                     if (SUCCEEDED(hrc))
    491                         fCanceledAlready = TRUE;
    492                     else
    493                         g_fExecCanceled = false;
    494                 }
    495 
    496                 /* Progress canceled by Main API? */
    497                 if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
    498                     && fCanceled)
    499                 {
    500                     break;
    501                 }
    502             }
    503 
    504             /* Undo signal handling */
    505             if (fCancelable)
    506             {
    507                 signal(SIGINT,   SIG_DFL);
    508         #ifdef SIGBREAK
    509                 signal(SIGBREAK, SIG_DFL);
    510         #endif
    511             }
    512 
    513             if (fCanceled)
    514             {
    515                 if (fVerbose)
    516                     RTPrintf("Process execution canceled!\n");
    517             }
    518             else if (   fCompleted
    519                      && SUCCEEDED(rc))
    520             {
    521                 LONG iRc = false;
    522                 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    523                 if (FAILED(iRc))
    524                 {
    525                     com::ProgressErrorInfo info(progress);
    526                     if (   info.isFullAvailable()
    527                         || info.isBasicAvailable())
     564                /* Undo signal handling */
     565                if (fCancelable)
     566                    ctrlSignalHandlerUninstall();
     567
     568                if (fCanceled)
     569                {
     570                    if (fVerbose)
     571                        RTPrintf("Process execution canceled!\n");
     572                }
     573                else if (   fCompleted
     574                         && SUCCEEDED(rc))
     575                {
     576                    LONG iRc = false;
     577                    CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
     578                    if (FAILED(iRc))
    528579                    {
    529                         /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    530                          * because it contains more accurate info about what went wrong. */
    531                         if (info.getResultCode() == VBOX_E_IPRT_ERROR)
    532                             RTMsgError("%ls.", info.getText().raw());
    533                         else
    534                         {
    535                             RTMsgError("Process error details:");
    536                             GluePrintErrorInfo(info);
    537                         }
     580                        vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
    538581                    }
    539                     else
    540                         com::GluePrintRCMessage(iRc);
    541                 }
    542                 else if (fVerbose)
    543                 {
    544                     ULONG uRetStatus, uRetExitCode, uRetFlags;
    545                     rc = guest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus);
    546                     if (SUCCEEDED(rc))
    547                         RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, uRetStatus, ctrlExecGetStatus(uRetStatus), uRetFlags);
    548                 }
    549             }
    550             else
    551             {
    552                 if (fVerbose)
    553                     RTPrintf("Process execution aborted!\n");
    554             }
    555         }
    556         a->session->UnlockMachine();
    557     } while (0);
     582                    else if (fVerbose)
     583                    {
     584                        ULONG uRetStatus, uRetExitCode, uRetFlags;
     585                        rc = guest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus);
     586                        if (SUCCEEDED(rc))
     587                            RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, uRetStatus, ctrlExecGetStatus(uRetStatus), uRetFlags);
     588                    }
     589                }
     590                else
     591                {
     592                    if (fVerbose)
     593                        RTPrintf("Process execution aborted!\n");
     594                }
     595            }
     596        }
     597        ctrlUninitVM(a);
     598    }
     599
     600    if (RT_FAILURE(vrc))
     601        rc = VBOX_E_IPRT_ERROR;
    558602    return SUCCEEDED(rc) ? 0 : 1;
    559 }
    560 
    561 /**
    562  * Signal handler that sets g_fCopyCanceled.
    563  *
    564  * This can be executed on any thread in the process, on Windows it may even be
    565  * a thread dedicated to delivering this signal.  Do not doing anything
    566  * unnecessary here.
    567  */
    568 static void ctrlCopySignalHandler(int iSignal)
    569 {
    570     NOREF(iSignal);
    571     ASMAtomicWriteBool(&g_fCopyCanceled, true);
    572603}
    573604
     
    940971    if (FAILED(rc))
    941972    {
    942         /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    943          * because it contains more accurate info about what went wrong. */
    944         ErrorInfo info(pGuest, COM_IIDOF(IGuest));
    945         if (info.isFullAvailable())
    946         {
    947             if (rc == VBOX_E_IPRT_ERROR)
    948                 RTMsgError("%ls.", info.getText().raw());
    949             else
    950                 RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode());
    951         }
    952         vrc = VERR_GENERAL_FAILURE;
     973        vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
    953974    }
    954975    else
     
    957978        ASSERT(progress);
    958979        bool fCanceledAlready = false;
    959         BOOL fCancelable;
     980        BOOL fCancelable = FALSE;
    960981        HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
    961         if (FAILED(hrc))
    962             fCancelable = FALSE;
    963982        if (fCancelable)
    964         {
    965             signal(SIGINT,   ctrlCopySignalHandler);
    966     #ifdef SIGBREAK
    967             signal(SIGBREAK, ctrlCopySignalHandler);
    968     #endif
    969         }
     983            ctrlSignalHandlerInstall();
    970984
    971985        /* Wait for process to exit ... */
     
    976990        {
    977991            /* Process async cancelation */
    978             if (g_fCopyCanceled && !fCanceledAlready)
     992            if (g_fGuestCtrlCanceled && !fCanceledAlready)
    979993            {
    980994                hrc = progress->Cancel();
     
    982996                    fCanceledAlready = TRUE;
    983997                else
    984                     g_fCopyCanceled = false;
     998                    g_fGuestCtrlCanceled = false;
    985999            }
    9861000
     
    9931007        }
    9941008
    995         /* Undo signal handling */
     1009        /* Undo signal handling. */
    9961010        if (fCancelable)
    997         {
    998             signal(SIGINT,   SIG_DFL);
    999     #ifdef SIGBREAK
    1000             signal(SIGBREAK, SIG_DFL);
    1001     #endif
    1002         }
     1011            ctrlSignalHandlerUninstall();
    10031012
    10041013        if (fCanceled)
    10051014        {
    1006             //RTPrintf("Copy operation canceled!\n");
     1015            /* Nothing to do here right now. */
    10071016        }
    10081017        else if (   fCompleted
     
    10121021            CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    10131022            if (FAILED(iRc))
    1014             {
    1015                 com::ProgressErrorInfo info(progress);
    1016                 if (   info.isFullAvailable()
    1017                     || info.isBasicAvailable())
    1018                 {
    1019                     /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    1020                      * because it contains more accurate info about what went wrong. */
    1021                     if (info.getResultCode() == VBOX_E_IPRT_ERROR)
    1022                         RTMsgError("%ls.", info.getText().raw());
    1023                     else
    1024                     {
    1025                         RTMsgError("Copy operation error details:");
    1026                         GluePrintErrorInfo(info);
    1027                     }
    1028                 }
    1029                 else
    1030                 {
    1031                     if (RT_FAILURE(vrc))
    1032                         RTMsgError("Error while looking up error code, rc=%Rrc\n", vrc);
    1033                     else
    1034                         com::GluePrintRCMessage(iRc);
    1035                 }
    1036                 vrc = VERR_GENERAL_FAILURE;
    1037             }
     1023                vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
    10381024        }
    10391025    }
     
    11371123                           "No user name specified!");
    11381124
    1139     /* Lookup VM. */
    1140     ComPtr<IMachine> machine;
    1141     /* Assume it's an UUID. */
    1142     HRESULT rc;
    1143     CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
    1144                                            machine.asOutParam()));
    1145     if (FAILED(rc))
    1146         return 1;
    1147 
    1148     /* Machine is running? */
    1149     MachineState_T machineState;
    1150     CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1);
    1151     if (machineState != MachineState_Running)
    1152     {
    1153         RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]);
    1154         return 1;
    1155     }
    1156 
    1157     /* Open a session for the VM. */
    1158     CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    1159 
    1160     do
    1161     {
    1162         /* Get the associated console. */
    1163         ComPtr<IConsole> console;
    1164         CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
    1165         /* ... and session machine */
    1166         ComPtr<IMachine> sessionMachine;
    1167         CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
    1168 
    1169         ComPtr<IGuest> guest;
    1170         CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
    1171 
     1125    HRESULT rc = S_OK;
     1126    ComPtr<IGuest> guest;
     1127    int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
     1128    if (RT_SUCCESS(vrc))
     1129    {
    11721130        if (fVerbose)
    11731131        {
     
    11791137        RTLISTNODE listToCopy;
    11801138        uint32_t cObjects = 0;
    1181         int vrc = ctrlCopyInit(Utf8Source.c_str(), Utf8Dest.c_str(), uFlags,
    1182                                &cObjects, &listToCopy);
     1139        vrc = ctrlCopyInit(Utf8Source.c_str(), Utf8Dest.c_str(), uFlags,
     1140                           &cObjects, &listToCopy);
    11831141        if (RT_FAILURE(vrc))
    11841142        {
     
    12371195            ctrlCopyDestroy(&listToCopy);
    12381196        }
    1239         a->session->UnlockMachine();
    1240     } while (0);
     1197        ctrlUninitVM(a);
     1198    }
     1199
     1200    if (RT_FAILURE(vrc))
     1201        rc = VBOX_E_IPRT_ERROR;
    12411202    return SUCCEEDED(rc) ? 0 : 1;
    12421203}
     
    13101271            }
    13111272        }
    1312         /** @todo Add force flag for overwriting existing stuff. */
    13131273        else if (!strcmp(a->argv[i], "--verbose"))
    13141274            fVerbose = true;
     
    13291289                           "No user name specified!");
    13301290
    1331     /* Lookup VM. */
    1332     ComPtr<IMachine> machine;
    1333     /* Assume it's an UUID. */
    1334     HRESULT rc;
    1335     CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
    1336                                            machine.asOutParam()));
    1337     if (FAILED(rc))
    1338         return 1;
    1339 
    1340     /* Machine is running? */
    1341     MachineState_T machineState;
    1342     CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1);
    1343     if (machineState != MachineState_Running)
    1344     {
    1345         RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]);
    1346         return 1;
    1347     }
    1348 
    1349     /* Open a session for the VM. */
    1350     CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    1351 
    1352     do
    1353     {
    1354         /* Get the associated console. */
    1355         ComPtr<IConsole> console;
    1356         CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
    1357         /* ... and session machine */
    1358         ComPtr<IMachine> sessionMachine;
    1359         CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
    1360 
    1361         ComPtr<IGuest> guest;
    1362         CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
    1363 
     1291    HRESULT rc = S_OK;
     1292    ComPtr<IGuest> guest;
     1293    int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
     1294    if (RT_SUCCESS(vrc))
     1295    {
    13641296        ComPtr<IProgress> progress;
    13651297        rc = guest->CreateDirectory(Bstr(Utf8Directory).raw(),
     
    13851317            bool fCanceledAlready = false;
    13861318            BOOL fCancelable;
    1387             HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
    1388             if (FAILED(hrc))
     1319            rc = progress->COMGETTER(Cancelable)(&fCancelable);
     1320            if (FAILED(rc))
    13891321                fCancelable = FALSE;
    13901322            if (fCancelable)
    1391             {
    1392                 signal(SIGINT,   ctrlCopySignalHandler);
    1393         #ifdef SIGBREAK
    1394                 signal(SIGBREAK, ctrlCopySignalHandler);
    1395         #endif
    1396             }
     1323                ctrlSignalHandlerInstall();
    13971324
    13981325            /* Wait for process to exit ... */
     
    14031330            {
    14041331                /* Process async cancelation */
    1405                 if (g_fCopyCanceled && !fCanceledAlready)
    1406                 {
    1407                     hrc = progress->Cancel();
    1408                     if (SUCCEEDED(hrc))
     1332                if (g_fGuestCtrlCanceled && !fCanceledAlready)
     1333                {
     1334                    rc = progress->Cancel();
     1335                    if (SUCCEEDED(rc))
    14091336                        fCanceledAlready = TRUE;
    14101337                    else
    1411                         g_fCopyCanceled = false;
     1338                        g_fGuestCtrlCanceled = false;
    14121339                }
    14131340
     
    14201347            }
    14211348
    1422             /* Undo signal handling */
     1349            /* Undo signal handling. */
    14231350            if (fCancelable)
    1424             {
    1425                 signal(SIGINT,   SIG_DFL);
    1426         #ifdef SIGBREAK
    1427                 signal(SIGBREAK, SIG_DFL);
    1428         #endif
    1429             }
     1351                ctrlSignalHandlerUninstall();
    14301352
    14311353            if (fCanceled)
     
    14391361                CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    14401362                if (FAILED(iRc))
    1441                 {
    1442                     com::ProgressErrorInfo info(progress);
    1443                     if (   info.isFullAvailable()
    1444                         || info.isBasicAvailable())
    1445                     {
    1446                         /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    1447                          * because it contains more accurate info about what went wrong. */
    1448                         if (info.getResultCode() == VBOX_E_IPRT_ERROR)
    1449                             RTMsgError("%ls.", info.getText().raw());
    1450                         else
    1451                         {
    1452                             RTMsgError("Copy operation error details:");
    1453                             GluePrintErrorInfo(info);
    1454                         }
    1455                     }
    1456                 }
    1457             }
    1458         }
    1459 
    1460         a->session->UnlockMachine();
    1461     } while (0);
     1363                    vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
     1364            }
     1365        }
     1366        ctrlUninitVM(a);
     1367    }
     1368
     1369    if (RT_FAILURE(vrc))
     1370        rc = VBOX_E_IPRT_ERROR;
    14621371    return SUCCEEDED(rc) ? 0 : 1;
    14631372}
     
    14991408        return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
    15001409
    1501     /* Lookup VM. */
    1502     ComPtr<IMachine> machine;
    1503     /* Assume it's an UUID. */
    1504     HRESULT rc;
    1505     CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
    1506                                            machine.asOutParam()));
    1507     if (FAILED(rc))
    1508         return 1;
    1509 
    1510     /* Machine is running? */
    1511     MachineState_T machineState;
    1512     CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1);
    1513     if (machineState != MachineState_Running)
    1514     {
    1515         RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]);
    1516         return 1;
    1517     }
    1518 
    1519     /* Open a session for the VM. */
    1520     CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
    1521 
    1522     do
    1523     {
    1524         /* Get the associated console. */
    1525         ComPtr<IConsole> console;
    1526         CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam()));
    1527         /* ... and session machine */
    1528         ComPtr<IMachine> sessionMachine;
    1529         CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
    1530 
    1531         ComPtr<IGuest> guest;
    1532         CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam()));
    1533 
     1410    HRESULT rc = S_OK;
     1411    ComPtr<IGuest> guest;
     1412    int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest);
     1413    if (RT_SUCCESS(vrc))
     1414    {
    15341415        if (fVerbose)
    15351416            RTPrintf("Updating Guest Additions of machine \"%s\" ...\n", a->argv[0]);
     
    15431424        {
    15441425            char strTemp[RTPATH_MAX];
    1545             int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
    1546             AssertRC(vrc);
     1426            rc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));
     1427            AssertRC(rc);
    15471428            Utf8Str Utf8Src1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso");
    15481429
    1549             vrc = RTPathExecDir(strTemp, sizeof(strTemp));
    1550             AssertRC(vrc);
     1430            rc = RTPathExecDir(strTemp, sizeof(strTemp));
     1431            AssertRC(rc);
    15511432            Utf8Str Utf8Src2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso");
    15521433
     
    15591440            {
    15601441                RTMsgError("Source could not be determined! Please use --source to specify a valid source.\n");
    1561                 break;
     1442                rc = VERR_FILE_NOT_FOUND;
    15621443            }
    15631444        }
     
    15651446        {
    15661447            RTMsgError("Source \"%s\" does not exist!\n", Utf8Source.c_str());
    1567             break;
    1568         }
    1569         if (fVerbose)
    1570             RTPrintf("Using source: %s\n", Utf8Source.c_str());
    1571 
    1572         ComPtr<IProgress> progress;
    1573         CHECK_ERROR_BREAK(guest, UpdateGuestAdditions(Bstr(Utf8Source).raw(),
    1574                                                       0 /* Flags, not used. */,
    1575                                                       progress.asOutParam()));
    1576         rc = showProgress(progress);
    1577         if (FAILED(rc))
    1578         {
    1579             com::ProgressErrorInfo info(progress);
    1580             if (info.isBasicAvailable())
    1581                 RTMsgError("Failed to start Guest Additions update. Error message: %lS\n", info.getText().raw());
    1582             else
    1583                 RTMsgError("Failed to start Guest Additions update. No error message available!\n");
    1584         }
    1585         else
     1448            rc = VERR_FILE_NOT_FOUND;
     1449        }
     1450
     1451        if (RT_SUCCESS(rc))
    15861452        {
    15871453            if (fVerbose)
     1454                RTPrintf("Using source: %s\n", Utf8Source.c_str());
     1455
     1456            ComPtr<IProgress> progress;
     1457            CHECK_ERROR(guest, UpdateGuestAdditions(Bstr(Utf8Source).raw(),
     1458                                                    0 /* Flags, not used. */,
     1459                                                    progress.asOutParam()));
     1460            rc = showProgress(progress);
     1461            if (FAILED(rc))
     1462                vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
     1463            else if (fVerbose)
    15881464                RTPrintf("Guest Additions installer successfully copied and started.\n");
    15891465        }
    1590         a->session->UnlockMachine();
    1591     } while (0);
     1466        ctrlUninitVM(a);
     1467    }
     1468
     1469    if (RT_FAILURE(vrc))
     1470        rc = VBOX_E_IPRT_ERROR;
    15921471    return SUCCEEDED(rc) ? 0 : 1;
    15931472}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette