VirtualBox

Changeset 43967 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Nov 26, 2012 7:35:33 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
82312
Message:

Autostart: More updates for the Windows service

Location:
trunk/src/VBox/Frontends/VBoxAutostart
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxAutostart/Makefile.kmk

    r43909 r43967  
    2020
    2121ifeq ($(KBUILD_TARGET),win)
    22 # PROGRAMS += VBoxAutostartSvc
    23 # VBoxAutostart_TEMPLATE   = VBOXMAINCLIENTEXE
    24 # VBoxAutostart_SOURCES    = \
    25 #       VBoxAutostartStart.cpp \
    26 #       VBoxAutostartStop.cpp \
    27 #       VBoxAutostartUtils.cpp \
    28 #       VBoxAutostart-win.cpp
     22 PROGRAMS += VBoxAutostartSvc
     23 VBoxAutostartSvc_TEMPLATE   = VBOXMAINCLIENTEXE
     24 VBoxAutostartSvc_SOURCES    = \
     25        VBoxAutostartCfg.cpp \
     26        VBoxAutostartStart.cpp \
     27        VBoxAutostartStop.cpp \
     28        VBoxAutostartUtils.cpp \
     29        VBoxAutostart-win.cpp
    2930else
    3031 PROGRAMS += VBoxAutostart
  • trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart-posix.cpp

    r43909 r43967  
    243243}
    244244
    245 DECLHIDDEN(void) serviceLog(const char *pszFormat, ...)
     245DECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType)
    246246{
    247247    va_list args;
    248     va_start(args, pszFormat);
    249     char *psz = NULL;
    250     RTStrAPrintfV(&psz, pszFormat, args);
    251     va_end(args);
    252 
    253     LogRel(("%s", psz));
    254 
    255     RTStrFree(psz);
     248
     249    if (   enmLogType == AUTOSTARTLOGTYPE_VERBOSE
     250        && !g_fVerbose)
     251        return;
     252
     253    LogRel(("%s", pszMsg));
    256254}
    257255
     
    335333
    336334    RTStrmPrintf(g_pStdErr, "\nUse environment variable VBOXAUTOSTART_RELEASE_LOG for logging options.\n");
    337 }
    338 
    339 /**
    340  * Creates all global COM objects.
    341  *
    342  * @return  HRESULT
    343  */
    344 static int autostartSetup()
    345 {
    346     serviceLogVerbose(("Setting up ...\n"));
    347 
    348     /*
    349      * Setup VirtualBox + session interfaces.
    350      */
    351     HRESULT rc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());
    352     if (SUCCEEDED(rc))
    353     {
    354         rc = g_pSession.createInprocObject(CLSID_Session);
    355         if (FAILED(rc))
    356             RTMsgError("Failed to create a session object (rc=%Rhrc)!", rc);
    357     }
    358     else
    359         RTMsgError("Failed to get VirtualBox object (rc=%Rhrc)!", rc);
    360 
    361     if (FAILED(rc))
    362         return VERR_COM_OBJECT_NOT_FOUND;
    363 
    364     return VINF_SUCCESS;
    365 }
    366 
    367 static void autostartShutdown()
    368 {
    369     serviceLogVerbose(("Shutting down ...\n"));
    370 
    371     g_pSession.setNull();
    372     g_pVirtualBox.setNull();
    373335}
    374336
     
    583545#endif
    584546
    585     /*
    586      * Initialize COM.
    587      */
    588     using namespace com;
    589     HRESULT hrc = com::Initialize();
    590 # ifdef VBOX_WITH_XPCOM
    591     if (hrc == NS_ERROR_FILE_ACCESS_DENIED)
    592     {
    593         char szHome[RTPATH_MAX] = "";
    594         com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome));
    595         return RTMsgErrorExit(RTEXITCODE_FAILURE,
    596                "Failed to initialize COM because the global settings directory '%s' is not accessible!", szHome);
    597     }
    598 # endif
    599     if (FAILED(hrc))
    600         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM (%Rhrc)!", hrc);
    601 
    602     hrc = g_pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
    603     if (FAILED(hrc))
    604     {
    605         RTMsgError("Failed to create the VirtualBoxClient object (%Rhrc)!", hrc);
    606         com::ErrorInfo info;
    607         if (!info.isFullAvailable() && !info.isBasicAvailable())
    608         {
    609             com::GluePrintRCMessage(hrc);
    610             RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start.");
    611         }
    612         else
    613             com::GluePrintErrorInfo(info);
    614         return RTEXITCODE_FAILURE;
    615     }
    616 
     547    /* Set up COM */
    617548    rc = autostartSetup();
    618549    if (RT_FAILURE(rc))
     
    632563
    633564    autostartShutdown();
    634 
    635     g_pVirtualBoxClient.setNull();
    636 
    637     com::Shutdown();
    638 
    639565    return rcExit;
    640566}
  • trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart-win.cpp

    r43911 r43967  
    2929*******************************************************************************/
    3030#include <Windows.h>
     31
     32#include <VBox/com/com.h>
     33#include <VBox/com/string.h>
     34#include <VBox/com/Guid.h>
     35#include <VBox/com/array.h>
     36#include <VBox/com/ErrorInfo.h>
     37#include <VBox/com/errorprint.h>
     38
     39#include <VBox/com/EventQueue.h>
     40#include <VBox/com/listeners.h>
     41#include <VBox/com/VirtualBox.h>
    3142
    3243#include <VBox/log.h>
     
    3849#include <iprt/getopt.h>
    3950#include <iprt/semaphore.h>
     51#include <iprt/thread.h>
    4052
    4153#include "VBoxAutostart.h"
     
    4961#define AUTOSTART_SERVICE_DISPLAY_NAME     "VirtualBox Autostart Service"
    5062
     63ComPtr<IVirtualBoxClient> g_pVirtualBoxClient = NULL;
     64bool                      g_fVerbose    = false;
     65ComPtr<IVirtualBox>       g_pVirtualBox = NULL;
     66ComPtr<ISession>          g_pSession    = NULL;
    5167
    5268/*******************************************************************************
     
    6682static SC_HANDLE autostartSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess);
    6783
     84/**
     85 * Print out progress on the console.
     86 *
     87 * This runs the main event queue every now and then to prevent piling up
     88 * unhandled things (which doesn't cause real problems, just makes things
     89 * react a little slower than in the ideal case).
     90 */
     91DECLHIDDEN(HRESULT) showProgress(ComPtr<IProgress> progress)
     92{
     93    using namespace com;
     94
     95    BOOL fCompleted = FALSE;
     96    ULONG ulCurrentPercent = 0;
     97    ULONG ulLastPercent = 0;
     98
     99    ULONG ulLastOperationPercent = (ULONG)-1;
     100
     101    ULONG ulLastOperation = (ULONG)-1;
     102    Bstr bstrOperationDescription;
     103
     104    EventQueue::getMainEventQueue()->processEventQueue(0);
     105
     106    ULONG cOperations = 1;
     107    HRESULT hrc = progress->COMGETTER(OperationCount)(&cOperations);
     108    if (FAILED(hrc))
     109        return hrc;
     110
     111    /* setup signal handling if cancelable */
     112    bool fCanceledAlready = false;
     113    BOOL fCancelable;
     114    hrc = progress->COMGETTER(Cancelable)(&fCancelable);
     115    if (FAILED(hrc))
     116        fCancelable = FALSE;
     117
     118    hrc = progress->COMGETTER(Completed(&fCompleted));
     119    while (SUCCEEDED(hrc))
     120    {
     121        progress->COMGETTER(Percent(&ulCurrentPercent));
     122
     123        if (fCompleted)
     124            break;
     125
     126        /* process async cancelation */
     127        if (!fCanceledAlready)
     128        {
     129            hrc = progress->Cancel();
     130            if (SUCCEEDED(hrc))
     131                fCanceledAlready = true;
     132        }
     133
     134        /* make sure the loop is not too tight */
     135        progress->WaitForCompletion(100);
     136
     137        EventQueue::getMainEventQueue()->processEventQueue(0);
     138        hrc = progress->COMGETTER(Completed(&fCompleted));
     139    }
     140
     141    /* complete the line. */
     142    LONG iRc = E_FAIL;
     143    hrc = progress->COMGETTER(ResultCode)(&iRc);
     144    if (SUCCEEDED(hrc))
     145    {
     146        hrc = iRc;
     147    }
     148
     149    return hrc;
     150}
     151
     152DECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType)
     153{
     154    HANDLE hEventLog = RegisterEventSourceA(NULL /* local computer */, "VBoxAutostartSvc");
     155    AssertReturnVoid(hEventLog != NULL);
     156    WORD wType = 0;
     157    const char *apsz[2];
     158    apsz[0] = "VBoxAutostartSvc";
     159    apsz[1] = pszMsg;
     160
     161    switch (enmLogType)
     162    {
     163        case AUTOSTARTLOGTYPE_INFO:
     164            wType = 0;
     165            break;
     166        case AUTOSTARTLOGTYPE_ERROR:
     167            wType = EVENTLOG_ERROR_TYPE;
     168            break;
     169        case AUTOSTARTLOGTYPE_WARNING:
     170            wType = EVENTLOG_WARNING_TYPE;
     171            break;
     172        case AUTOSTARTLOGTYPE_VERBOSE:
     173            if (!g_fVerbose)
     174                return;
     175            wType = EVENTLOG_INFORMATION_TYPE;
     176            break;
     177        default:
     178            AssertMsgFailed(("Invalid log type %d\n", enmLogType));
     179    }
     180
     181    BOOL fRc = ReportEventA(hEventLog,               /* hEventLog */
     182                            wType,                   /* wType */
     183                            0,                       /* wCategory */
     184                            0 /** @todo mc */,       /* dwEventID */
     185                            NULL,                    /* lpUserSid */
     186                            RT_ELEMENTS(apsz),       /* wNumStrings */
     187                            0,                       /* dwDataSize */
     188                            apsz,                    /* lpStrings */
     189                            NULL);                   /* lpRawData */
     190    AssertMsg(fRc, ("%d\n", GetLastError()));
     191    DeregisterEventSource(hEventLog);
     192}
    68193
    69194/**
     
    119244        return NULL;
    120245
    121     SC_HANDLE hSvc = OpenService(hSCM, SUPSVC_SERVICE_NAME, dwSVCAccess);
     246    SC_HANDLE hSvc = OpenServiceA(hSCM, AUTOSTART_SERVICE_NAME, dwSVCAccess);
    122247    if (hSvc)
    123248    {
     
    156281}
    157282
    158 
    159 
    160 void autostartSvcOsLogErrorStr(const char *pszMsg)
    161 {
    162     HANDLE hEventLog = RegisterEventSource(NULL /* local computer */, "VBoxAutostartSvc");
    163     AssertReturnVoid(hEventLog != NULL);
    164     const char *apsz[2];
    165     apsz[0] = "VBoxAutostartSvc";
    166     apsz[1] = pszMsg;
    167     BOOL fRc = ReportEvent(hEventLog,               /* hEventLog */
    168                            EVENTLOG_ERROR_TYPE,     /* wType */
    169                            0,                       /* wCategory */
    170                            0 /** @todo mc */,       /* dwEventID */
    171                            NULL,                    /* lpUserSid */
    172                            RT_ELEMENTS(apsz),       /* wNumStrings */
    173                            0,                       /* dwDataSize */
    174                            apsz,                    /* lpStrings */
    175                            NULL);                   /* lpRawData */
    176     AssertMsg(fRc, ("%d\n", GetLastError()));
    177     DeregisterEventSource(hEventLog);
    178 }
    179 
    180 
    181283static RTEXITCODE autostartSvcWinInterrogate(int argc, char **argv)
    182284{
     
    210312{
    211313    RTPrintf("VBoxAutostartSvc: The \"start\" action is not implemented.\n");
    212     return RTEXITCODE_FAILURE;
     314    return RTEXITCODE_SUCCESS;
    213315}
    214316
     
    259361    };
    260362    int ch;
     363    unsigned iArg = 0;
    261364    RTGETOPTUNION Value;
    262365    RTGETOPTSTATE GetState;
    263366    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
    264367    while ((ch = RTGetOpt(&GetState, &Value)))
     368    {
    265369        switch (ch)
    266370        {
     
    274378        }
    275379
     380        iArg++;
     381    }
     382
    276383    /*
    277384     * Create the service.
     
    279386    int rc = RTEXITCODE_FAILURE;
    280387    SC_HANDLE hSvc = autostartSvcWinOpenService("delete", SERVICE_CHANGE_CONFIG, DELETE,
    281                                           1, ERROR_SERVICE_DOES_NOT_EXIST);
     388                                                1, ERROR_SERVICE_DOES_NOT_EXIST);
    282389    if (hSvc)
    283390    {
    284391        if (DeleteService(hSvc))
    285392        {
    286             RTPrintf("Successfully deleted the %s service.\n", SUPSVC_SERVICE_NAME);
     393            RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME);
    287394            rc = RTEXITCODE_SUCCESS;
    288395        }
     
    295402
    296403        if (fVerbose)
    297             RTPrintf("The service %s was not installed, nothing to be done.", SUPSVC_SERVICE_NAME);
     404            RTPrintf("The service %s was not installed, nothing to be done.", AUTOSTART_SERVICE_NAME);
    298405        else
    299             RTPrintf("Successfully deleted the %s service.\n", SUPSVC_SERVICE_NAME);
     406            RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME);
    300407        rc = RTEXITCODE_SUCCESS;
    301408    }
     
    319426    const char *pszUser = NULL;
    320427    const char *pszPwd = NULL;
    321     static const RTOPTIONDEF s_aOptions[] =
     428    static const RTGETOPTDEF s_aOptions[] =
    322429    {
    323430        { "--verbose",  'v', RTGETOPT_REQ_NOTHING },
    324         { "--user",     'u', RTGETOPT_REQ_STRIN },
    325         { "--password", 'p', RTGETOPT_REQ_STRIN }
     431        { "--user",     'u', RTGETOPT_REQ_STRING },
     432        { "--password", 'p', RTGETOPT_REQ_STRING }
    326433    };
    327434    int iArg = 0;
    328435    int ch;
    329436    RTGETOPTUNION Value;
    330     while ((ch = RTGetOpt(argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value)))
     437    RTGETOPTSTATE GetState;
     438    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
     439    while ((ch = RTGetOpt(&GetState, &Value)))
     440    {
    331441        switch (ch)
    332442        {
     
    337447                pszUser = Value.psz;
    338448                break;
    339             case 'p'
     449            case 'p':
    340450                pszPwd = Value.psz;
    341451                break;
     
    343453                return autostartSvcDisplayGetOptError("create", ch, argc, argv, iArg, &Value);
    344454        }
     455        iArg++;
     456    }
    345457    if (iArg != argc)
    346458        return autostartSvcDisplayTooManyArgsError("create", argc, argv, iArg);
     
    349461     * Create the service.
    350462     */
    351     int rc = RTEXITCODE_FAILURE;
     463    RTEXITCODE rc = RTEXITCODE_FAILURE;
    352464    SC_HANDLE hSCM = autostartSvcWinOpenSCManager("create", SC_MANAGER_CREATE_SERVICE); /*SC_MANAGER_ALL_ACCESS*/
    353465    if (hSCM)
    354466    {
    355467        char szExecPath[MAX_PATH];
    356         if (GetModuleFileName(NULL /* the executable */, szExecPath, sizeof(szExecPath)))
     468        if (GetModuleFileNameA(NULL /* the executable */, szExecPath, sizeof(szExecPath)))
    357469        {
    358470            if (fVerbose)
    359471                RTPrintf("Creating the %s service, binary \"%s\"...\n",
    360                          SUPSVC_SERVICE_NAME, szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */
    361 
    362             SC_HANDLE hSvc = CreateService(hSCM,                            /* hSCManager */
    363                                            SUPSVC_SERVICE_NAME,             /* lpServiceName */
    364                                            SUPSVC_SERVICE_DISPLAY_NAME,     /* lpDisplayName */
    365                                            SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, /* dwDesiredAccess */
    366                                            SERVICE_WIN32_OWN_PROCESS,       /* dwServiceType ( | SERVICE_INTERACTIVE_PROCESS? ) */
    367                                            SERVICE_DEMAND_START/*_AUTO*/,   /* dwStartType */
    368                                            SERVICE_ERROR_NORMAL,            /* dwErrorControl */
    369                                            szExecPath,                      /* lpBinaryPathName */
    370                                            NULL,                            /* lpLoadOrderGroup */
    371                                            NULL,                            /* lpdwTagId */
    372                                            NULL,                            /* lpDependencies */
    373                                            pszUser,                         /* lpServiceStartName (NULL => LocalSystem) */
    374                                            pszPwd);                         /* lpPassword */
     472                         AUTOSTART_SERVICE_NAME, szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */
     473
     474            SC_HANDLE hSvc = CreateServiceA(hSCM,                            /* hSCManager */
     475                                            AUTOSTART_SERVICE_NAME,          /* lpServiceName */
     476                                            AUTOSTART_SERVICE_DISPLAY_NAME,  /* lpDisplayName */
     477                                            SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, /* dwDesiredAccess */
     478                                            SERVICE_WIN32_OWN_PROCESS,       /* dwServiceType ( | SERVICE_INTERACTIVE_PROCESS? ) */
     479                                            SERVICE_AUTO_START,              /* dwStartType */
     480                                            SERVICE_ERROR_NORMAL,            /* dwErrorControl */
     481                                            szExecPath,                      /* lpBinaryPathName */
     482                                            NULL,                            /* lpLoadOrderGroup */
     483                                            NULL,                            /* lpdwTagId */
     484                                            NULL,                            /* lpDependencies */
     485                                            pszUser,                         /* lpServiceStartName (NULL => LocalSystem) */
     486                                            pszPwd);                         /* lpPassword */
    375487            if (hSvc)
    376488            {
    377                 RTPrintf("Successfully created the %s service.\n", SUPSVC_SERVICE_NAME);
     489                RTPrintf("Successfully created the %s service.\n", AUTOSTART_SERVICE_NAME);
    378490                /** @todo Set the service description or it'll look weird in the vista service manager.
    379491                 *  Anything else that should be configured? Start access or something? */
     
    482594             */
    483595            autostartSvcWinSetServiceStatus(SERVICE_STOP_PENDING, 3000, NO_ERROR);
    484             int rc = autostartSvcTryStopServices();
    485             if (RT_SUCCESS(rc))
    486             {
    487                 /*
    488                  * Notify the main thread that we're done, it will wait for the
    489                  * real services to stop, destroy them, and finally set the windows
    490                  * service status to SERVICE_STOPPED and return.
    491                  */
    492                 rc = RTSemEventMultiSignal(g_hSupSvcWinEvent);
    493                 if (RT_FAILURE(rc))
    494                     autostartSvcLogError("SERVICE_CONTROL_STOP: RTSemEventMultiSignal failed, %Rrc\n", rc);
    495             }
     596            /*
     597             * Notify the main thread that we're done, it will wait for the
     598             * VMs to stop, and set the windows service status to SERVICE_STOPPED
     599             * and return.
     600             */
     601            int rc = RTSemEventMultiSignal(g_hSupSvcWinEvent);
     602            if (RT_FAILURE(rc))
     603                autostartSvcLogError("SERVICE_CONTROL_STOP: RTSemEventMultiSignal failed, %Rrc\n", rc);
     604
    496605            return NO_ERROR;
    497606        }
     
    522631}
    523632
     633static int autostartWorker(RTTHREAD ThreadSelf, void *pvUser)
     634{
     635                        int rc = autostartSetup();
     636
     637                        /** @todo: Implement config options. */
     638                        rc = autostartStartMain(NULL);
     639                        if (RT_FAILURE(rc))
     640                            autostartSvcLogError("Starting VMs failed, rc=%Rrc", rc);
     641
     642    return rc;
     643}
    524644
    525645/**
     
    532652 * @param   papszArgs       Argument vector.
    533653 */
    534 static VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LPSTR *papszArgs)
     654static VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LPTSTR *papszArgs)
    535655{
    536656    LogFlowFuncEnter();
     
    540660     */
    541661    Assert(g_u32SupSvcWinStatus == SERVICE_STOPPED);
    542     g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerEx(SUPSVC_SERVICE_NAME, autostartSvcWinServiceCtrlHandlerEx, NULL);
     662    g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerExA(AUTOSTART_SERVICE_NAME, autostartSvcWinServiceCtrlHandlerEx, NULL);
    543663    if (g_hSupSvcWinCtrlHandler)
    544664    {
     
    546666        if (autostartSvcWinSetServiceStatus(SERVICE_START_PENDING, 3000, NO_ERROR))
    547667        {
    548             /*
    549              * Parse arguments.
    550              */
    551             static const RTOPTIONDEF s_aOptions[] =
    552             {
    553                 { "--dummy", 'd', RTGETOPT_REQ_NOTHING }
    554             };
    555             int iArg = 1; /* the first arg is the service name */
    556             int ch;
    557             int rc = 0;
    558             RTGETOPTUNION Value;
    559             while (   !rc
    560                    && (ch = RTGetOpt(cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value)))
    561                 switch (ch)
    562                 {
    563                     default:    rc = autostartSvcLogGetOptError("main", ch, cArgs, papszArgs, iArg, &Value); break;
    564                 }
    565             if (iArg != cArgs)
    566                 rc = autostartSvcLogTooManyArgsError("main", cArgs, papszArgs, iArg);
    567             if (!rc)
     668            if (cArgs == 1)
    568669            {
    569670                /*
     
    574675                if (RT_SUCCESS(rc))
    575676                {
    576                     rc = autostartSvcCreateAndStartServices();
    577                     if (RT_SUCCESS(rc))
     677                    /*
     678                     * Update the status and enter the work loop.
     679                     */
     680                    if (autostartSvcWinSetServiceStatus(SERVICE_RUNNING, 0, 0))
    578681                    {
    579                         /*
    580                          * Update the status and enter the work loop.
    581                          *
    582                          * The work loop is just a dummy wait here as the services run
    583                          * in independent threads.
    584                          */
    585                         if (autostartSvcWinSetServiceStatus(SERVICE_RUNNING, 0, 0))
     682                        LogFlow(("autostartSvcWinServiceMain: calling RTSemEventMultiWait\n"));
     683                        RTTHREAD hWorker;
     684                        RTThreadCreate(&hWorker, autostartWorker, NULL, 0, RTTHREADTYPE_DEFAULT, 0, "WorkerThread");
     685
     686                        LogFlow(("autostartSvcWinServiceMain: woke up\n"));
     687                        err = NO_ERROR;
     688                        rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT);
     689                        if (RT_SUCCESS(rc))
    586690                        {
    587                             LogFlow(("autostartSvcWinServiceMain: calling RTSemEventMultiWait\n"));
    588                             /** @todo: Implement autostart */
    589                             rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT);
    590                             if (RT_SUCCESS(rc))
    591                             {
    592                                 LogFlow(("autostartSvcWinServiceMain: woke up\n"));
    593                                 err = NO_ERROR;
    594                             }
    595                             else
    596                                 autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc);
     691                            LogFlow(("autostartSvcWinServiceMain: woke up\n"));
     692                            /** @todo: Autostop part. */
     693                            err = NO_ERROR;
    597694                        }
    598695                        else
    599                         {
    600                             err = GetLastError();
    601                             autostartSvcLogError("SetServiceStatus failed, err=%d", err);
    602                         }
    603 
    604                         /*
    605                          * Destroy the service instances, stopping them if
    606                          * they're still running (weird failure cause).
    607                          */
    608                         autostartSvcStopAndDestroyServices();
     696                            autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc);
     697
     698                        autostartShutdown();
     699                    }
     700                    else
     701                    {
     702                        err = GetLastError();
     703                        autostartSvcLogError("SetServiceStatus failed, err=%d", err);
    609704                    }
    610705
     
    615710                    autostartSvcLogError("RTSemEventMultiCreate failed, rc=%Rrc", rc);
    616711            }
    617             /* else: bad args */
     712            else
     713                autostartSvcLogTooManyArgsError("main", cArgs, NULL, 0);
    618714        }
    619715        else
     
    626722    else
    627723        autostartSvcLogError("RegisterServiceCtrlHandlerEx failed, err=%d", GetLastError());
     724
    628725    LogFlowFuncLeave();
    629726}
     
    649746     * Parse the arguments.
    650747     */
    651     static const RTOPTIONDEF s_aOptions[] =
     748    static const RTGETOPTDEF s_aOptions[] =
    652749    {
    653750        { "--dummy", 'd', RTGETOPT_REQ_NOTHING }
     
    656753    int ch;
    657754    RTGETOPTUNION Value;
    658     while ((ch = RTGetOpt(argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value)))
     755    RTGETOPTSTATE GetState;
     756    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
     757    while ((ch = RTGetOpt(&GetState, &Value)))
    659758        switch (ch)
    660759        {
     
    670769    static SERVICE_TABLE_ENTRY const s_aServiceStartTable[] =
    671770    {
    672         { SUPSVC_SERVICE_NAME, autostartSvcWinServiceMain },
     771        { _T(AUTOSTART_SERVICE_NAME), autostartSvcWinServiceMain },
    673772        { NULL, NULL}
    674773    };
     
    683782    {
    684783        case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
    685             autostartSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n");
     784            autostartSvcWinServiceMain(0, NULL);//autostartSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n");
    686785            break;
    687786        default:
     
    704803     */
    705804    bool fBrief = false;
    706     static const RTOPTIONDEF s_aOptions[] =
     805    static const RTGETOPTDEF s_aOptions[] =
    707806    {
    708807        { "--brief", 'b', RTGETOPT_REQ_NOTHING }
     
    711810    int ch;
    712811    RTGETOPTUNION Value;
    713     while ((ch = RTGetOpt(argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value)))
     812    RTGETOPTSTATE GetState;
     813    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
     814    while ((ch = RTGetOpt(&GetState, &Value)))
    714815        switch (ch)
    715816        {
     
    731832                 "All rights reserved.\n",
    732833                 VBOX_VERSION_STRING);
    733     return 0;
     834    return RTEXITCODE_SUCCESS;
    734835}
    735836
     
    758859             "VBoxAutostartSvc <install|/RegServer|/i>\n"
    759860             "      Installs the service.\n"
    760              "VBoxAutostartSvc <install|delete|/UnregServer|/u>\n"
     861             "VBoxAutostartSvc <uninstall|delete|/UnregServer|/u>\n"
    761862             "      Uninstalls the service.\n"
    762863             );
     
    774875 * @param   argv    Argument vector.
    775876 */
    776 RTEXITCODE main(int argc, char **argv)
     877int main(int argc, char **argv)
    777878{
    778879    /*
     
    783884    {
    784885        autostartSvcLogError("RTR3InitExe failed with rc=%Rrc", rc);
    785         return 1;
    786     }
     886        return RTEXITCODE_FAILURE;
     887    }
     888
     889    RTThreadSleep(10 * 1000);
    787890
    788891    /*
  • trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart.h

    r43378 r43967  
    2222*   Header Files                                                               *
    2323*******************************************************************************/
     24#include <iprt/getopt.h>
     25#include <iprt/types.h>
     26
    2427#include <VBox/cdefs.h>
    2528#include <VBox/types.h>
     
    9396
    9497/** Flag whether we are in verbose logging mode. */
    95 extern bool                g_fVerbose;
     98extern bool                      g_fVerbose;
    9699/** Handle to the VirtualBox interface. */
    97 extern ComPtr<IVirtualBox> g_pVirtualBox;
     100extern ComPtr<IVirtualBox>       g_pVirtualBox;
    98101/** Handle to the session interface. */
    99 extern ComPtr<ISession>    g_pSession;
    100 
    101 /**
    102  * Log information in verbose mode.
    103  */
    104 #define serviceLogVerbose(a) if (g_fVerbose) { serviceLog a; }
    105 
    106 /**
    107  * Log messages to the release log.
     102extern ComPtr<ISession>          g_pSession;
     103/** handle to the VirtualBox interface. */
     104extern ComPtr<IVirtualBoxClient> g_pVirtualBoxClient;
     105/**
     106 * System log type.
     107 */
     108typedef enum AUTOSTARTLOGTYPE
     109{
     110    /** Invalid log type. */
     111    AUTOSTARTLOGTYPE_INVALID = 0,
     112    /** Log info message. */
     113    AUTOSTARTLOGTYPE_INFO,
     114    /** Log error message. */
     115    AUTOSTARTLOGTYPE_ERROR,
     116    /** Log warning message. */
     117    AUTOSTARTLOGTYPE_WARNING,
     118    /** Log verbose message, only if verbose mode is activated. */
     119    AUTOSTARTLOGTYPE_VERBOSE,
     120    /** Famous 32bit hack. */
     121    AUTOSTARTLOGTYPE_32BIT_HACK = 0x7fffffff
     122} AUTOSTARTLOGTYPE;
     123
     124/**
     125 * Log messages to the system and release log.
    108126 *
    109127 * @returns nothing.
    110  * @param   pszFormat    Format string.
    111  */
    112 DECLHIDDEN(void) serviceLog(const char *pszFormat, ...);
     128 * @param   pszMsg            Message to log.
     129 * @param   enmLogType        Log type to use.
     130 */
     131DECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType);
    113132
    114133/**
     
    173192DECLHIDDEN(RTEXITCODE) autostartStopMain(PCFGAST pCfgAst);
    174193
     194/**
     195 * Logs a verbose message to the appropriate system log.
     196 *
     197 * @param   pszFormat   The log string. No trailing newline.
     198 * @param   ...         Format arguments.
     199 */
     200DECLHIDDEN(void) autostartSvcLogVerboseV(const char *pszFormat, va_list va);
     201
     202/**
     203 * Logs a verbose message to the appropriate system log.
     204 *
     205 * @param   pszFormat   The log string. No trailing newline.
     206 * @param   ...         Format arguments.
     207 */
     208DECLHIDDEN(void) autostartSvcLogVerbose(const char *pszFormat, ...);
     209
     210/**
     211 * Logs a warning message to the appropriate system log.
     212 *
     213 * @param   pszFormat   The log string. No trailing newline.
     214 * @param   ...         Format arguments.
     215 */
     216DECLHIDDEN(void) autostartSvcLogWarningV(const char *pszFormat, va_list va);
     217
     218/**
     219 * Logs a warning message to the appropriate system log.
     220 *
     221 * @param   pszFormat   The log string. No trailing newline.
     222 * @param   ...         Format arguments.
     223 */
     224DECLHIDDEN(void) autostartSvcLogWarning(const char *pszFormat, ...);
     225
     226/**
     227 * Logs a info message to the appropriate system log.
     228 *
     229 * @param   pszFormat   The log string. No trailing newline.
     230 * @param   ...         Format arguments.
     231 */
     232DECLHIDDEN(void) autostartSvcLogInfoV(const char *pszFormat, va_list va);
     233
     234/**
     235 * Logs a info message to the appropriate system log.
     236 *
     237 * @param   pszFormat   The log string. No trailing newline.
     238 * @param   ...         Format arguments.
     239 */
     240DECLHIDDEN(void) autostartSvcLogInfo(const char *pszFormat, ...);
     241
     242/**
     243 * Logs the message to the appropriate system log.
     244 *
     245 * In debug builds this will also put it in the debug log.
     246 *
     247 * @param   pszFormat   The log string. No trailing newline.
     248 * @param   ...         Format arguments.
     249 *
     250 * @todo    This should later be replaced by the release logger and callback destination(s).
     251 */
     252DECLHIDDEN(void) autostartSvcLogErrorV(const char *pszFormat, va_list va);
     253
     254/**
     255 * Logs the error message to the appropriate system log.
     256 *
     257 * In debug builds this will also put it in the debug log.
     258 *
     259 * @param   pszFormat   The log string. No trailing newline.
     260 * @param   ...         Format arguments.
     261 *
     262 * @todo    This should later be replaced by the release logger and callback destination(s).
     263 */
     264DECLHIDDEN(void) autostartSvcLogError(const char *pszFormat, ...);
     265
     266/**
     267 * Deals with RTGetOpt failure, bitching in the system log.
     268 *
     269 * @returns 1
     270 * @param   pszAction       The action name.
     271 * @param   rc              The RTGetOpt return value.
     272 * @param   argc            The argument count.
     273 * @param   argv            The argument vector.
     274 * @param   iArg            The argument index.
     275 * @param   pValue          The value returned by RTGetOpt.
     276 */
     277DECLHIDDEN(RTEXITCODE) autostartSvcLogGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue);
     278
     279/**
     280 * Bitch about too many arguments (after RTGetOpt stops) in the system log.
     281 *
     282 * @returns 1
     283 * @param   pszAction       The action name.
     284 * @param   argc            The argument count.
     285 * @param   argv            The argument vector.
     286 * @param   iArg            The argument index.
     287 */
     288DECLHIDDEN(RTEXITCODE) autostartSvcLogTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg);
     289
     290/**
     291 * Prints an error message to the screen.
     292 *
     293 * @param   pszFormat   The message format string.
     294 * @param   va          Format arguments.
     295 */
     296DECLHIDDEN(void) autostartSvcDisplayErrorV(const char *pszFormat, va_list va);
     297
     298/**
     299 * Prints an error message to the screen.
     300 *
     301 * @param   pszFormat   The message format string.
     302 * @param   ...         Format arguments.
     303 */
     304DECLHIDDEN(void) autostartSvcDisplayError(const char *pszFormat, ...);
     305
     306/**
     307 * Deals with RTGetOpt failure.
     308 *
     309 * @returns 1
     310 * @param   pszAction       The action name.
     311 * @param   rc              The RTGetOpt return value.
     312 * @param   argc            The argument count.
     313 * @param   argv            The argument vector.
     314 * @param   iArg            The argument index.
     315 * @param   pValue          The value returned by RTGetOpt.
     316 */
     317DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue);
     318
     319/**
     320 * Bitch about too many arguments (after RTGetOpt stops).
     321 *
     322 * @returns RTEXITCODE_FAILURE
     323 * @param   pszAction       The action name.
     324 * @param   argc            The argument count.
     325 * @param   argv            The argument vector.
     326 * @param   iArg            The argument index.
     327 */
     328DECLHIDDEN(RTEXITCODE) autostartSvcDisplayTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg);
     329
     330DECLHIDDEN(int) autostartSetup();
     331
     332DECLHIDDEN(void) autostartShutdown();
     333
    175334#endif /* __VBoxAutostart_h__ */
    176335
  • trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStart.cpp

    r42732 r43967  
    7272    if (uStartupDelay)
    7373    {
    74         serviceLogVerbose(("Delay starting for %d seconds ...\n", uStartupDelay));
     74        autostartSvcLogVerbose("Delay starting for %d seconds ...\n", uStartupDelay);
    7575        vrc = RTThreadSleep(uStartupDelay * 1000);
    7676    }
     
    129129                if ((*it).uStartupDelay > uDelayCurr)
    130130                {
    131                     serviceLogVerbose(("Delay starting of the next VMs for %d seconds ...\n",
    132                                        (*it).uStartupDelay - uDelayCurr));
     131                    autostartSvcLogVerbose("Delay starting of the next VMs for %d seconds ...\n",
     132                                           (*it).uStartupDelay - uDelayCurr);
    133133                    RTThreadSleep(((*it).uStartupDelay - uDelayCurr) * 1000);
    134134                    uDelayCurr = (*it).uStartupDelay;
     
    142142                if (SUCCEEDED(rc) && !progress.isNull())
    143143                {
    144                     serviceLogVerbose(("Waiting for VM \"%ls\" to power on...\n", (*it).strId.raw()));
     144                    autostartSvcLogVerbose("Waiting for VM \"%ls\" to power on...\n", (*it).strId.raw());
    145145                    CHECK_ERROR(progress, WaitForCompletion(-1));
    146146                    if (SUCCEEDED(rc))
     
    162162                                }
    163163                                else
    164                                     serviceLogVerbose(("VM \"%ls\" has been successfully started.\n", (*it).strId.raw()));
     164                                    autostartSvcLogVerbose("VM \"%ls\" has been successfully started.\n", (*it).strId.raw());
    165165                            }
    166166                        }
  • trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStop.cpp

    r43909 r43967  
    202202                                CHECK_ERROR_BREAK(console, PowerButton());
    203203
    204                                 serviceLog("Waiting for VM \"%ls\" to power off...\n", (*it).strId.raw());
     204                                autostartSvcLogInfo("Waiting for VM \"%ls\" to power off...\n", (*it).strId.raw());
    205205
    206206                                do
     
    213213                            {
    214214                                /* Use save state instead and log this to the console. */
    215                                 serviceLog("The guest of VM \"%ls\" does not support ACPI shutdown or is currently paused, saving state...\n",
    216                                            (*it).strId.raw());
     215                                autostartSvcLogWarning("The guest of VM \"%ls\" does not support ACPI shutdown or is currently paused, saving state...\n",
     216                                                       (*it).strId.raw());
    217217                                rc = autostartSaveVMState(console);
    218218                            }
     
    220220                        }
    221221                        default:
    222                             serviceLog("Unknown autostop type for VM \"%ls\"\n", (*it).strId.raw());
     222                            autostartSvcLogWarning("Unknown autostop type for VM \"%ls\"\n", (*it).strId.raw());
    223223                    }
    224224                    g_pSession->UnlockMachine();
  • trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp

    r43912 r43967  
    2424#include <VBox/com/errorprint.h>
    2525
     26#include <VBox/err.h>
     27
    2628#include <iprt/message.h>
    2729#include <iprt/thread.h>
    2830#include <iprt/stream.h>
    2931#include <iprt/log.h>
     32#include <iprt/path.h>
    3033
    3134#include <algorithm>
     
    8790}
    8891
     92DECLHIDDEN(void) autostartSvcLogErrorV(const char *pszFormat, va_list va)
     93{
     94    if (*pszFormat)
     95    {
     96        char *pszMsg = NULL;
     97        if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1)
     98        {
     99            autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_ERROR);
     100            RTStrFree(pszMsg);
     101        }
     102        else
     103            autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_ERROR);
     104    }
     105}
     106
     107DECLHIDDEN(void) autostartSvcLogError(const char *pszFormat, ...)
     108{
     109    va_list va;
     110    va_start(va, pszFormat);
     111    autostartSvcLogErrorV(pszFormat, va);
     112    va_end(va);
     113}
     114
     115DECLHIDDEN(void) autostartSvcLogVerboseV(const char *pszFormat, va_list va)
     116{
     117    if (*pszFormat)
     118    {
     119        char *pszMsg = NULL;
     120        if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1)
     121        {
     122            autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_VERBOSE);
     123            RTStrFree(pszMsg);
     124        }
     125        else
     126            autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_VERBOSE);
     127    }
     128}
     129
     130DECLHIDDEN(void) autostartSvcLogVerbose(const char *pszFormat, ...)
     131{
     132    va_list va;
     133    va_start(va, pszFormat);
     134    autostartSvcLogVerboseV(pszFormat, va);
     135    va_end(va);
     136}
     137
     138DECLHIDDEN(void) autostartSvcLogWarningV(const char *pszFormat, va_list va)
     139{
     140    if (*pszFormat)
     141    {
     142        char *pszMsg = NULL;
     143        if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1)
     144        {
     145            autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_WARNING);
     146            RTStrFree(pszMsg);
     147        }
     148        else
     149            autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_WARNING);
     150    }
     151}
     152
     153DECLHIDDEN(void) autostartSvcLogInfo(const char *pszFormat, ...)
     154{
     155    va_list va;
     156    va_start(va, pszFormat);
     157    autostartSvcLogInfoV(pszFormat, va);
     158    va_end(va);
     159}
     160
     161DECLHIDDEN(void) autostartSvcLogInfoV(const char *pszFormat, va_list va)
     162{
     163    if (*pszFormat)
     164    {
     165        char *pszMsg = NULL;
     166        if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1)
     167        {
     168            autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_INFO);
     169            RTStrFree(pszMsg);
     170        }
     171        else
     172            autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_INFO);
     173    }
     174}
     175
     176DECLHIDDEN(void) autostartSvcLogWarning(const char *pszFormat, ...)
     177{
     178    va_list va;
     179    va_start(va, pszFormat);
     180    autostartSvcLogWarningV(pszFormat, va);
     181    va_end(va);
     182}
     183
     184DECLHIDDEN(RTEXITCODE) autostartSvcLogGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue)
     185{
     186    NOREF(pValue);
     187    autostartSvcLogError("%s - RTGetOpt failure, %Rrc (%d): %s",
     188                   pszAction, rc, rc, iArg < argc ? argv[iArg] : "<null>");
     189    return RTEXITCODE_FAILURE;
     190}
     191
     192DECLHIDDEN(RTEXITCODE) autostartSvcLogTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg)
     193{
     194    Assert(iArg < argc);
     195    autostartSvcLogError("%s - Too many arguments: %s", pszAction, argv[iArg]);
     196    for ( ; iArg < argc; iArg++)
     197        LogRel(("arg#%i: %s\n", iArg, argv[iArg]));
     198    return RTEXITCODE_FAILURE;
     199}
     200
     201DECLHIDDEN(void) autostartSvcDisplayErrorV(const char *pszFormat, va_list va)
     202{
     203    RTStrmPrintf(g_pStdErr, "VBoxSupSvc error: ");
     204    RTStrmPrintfV(g_pStdErr, pszFormat, va);
     205    Log(("autostartSvcDisplayErrorV: %s", pszFormat)); /** @todo format it! */
     206}
     207
     208DECLHIDDEN(void) autostartSvcDisplayError(const char *pszFormat, ...)
     209{
     210    va_list va;
     211    va_start(va, pszFormat);
     212    autostartSvcDisplayErrorV(pszFormat, va);
     213    va_end(va);
     214}
     215
     216DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue)
     217{
     218    autostartSvcDisplayError("%s - RTGetOpt failure, %Rrc (%d): %s\n",
     219                       pszAction, rc, rc, iArg < argc ? argv[iArg] : "<null>");
     220    return RTEXITCODE_FAILURE;
     221}
     222
     223DECLHIDDEN(RTEXITCODE) autostartSvcDisplayTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg)
     224{
     225    Assert(iArg < argc);
     226    autostartSvcDisplayError("%s - Too many arguments: %s\n", pszAction, argv[iArg]);
     227    return RTEXITCODE_FAILURE;
     228}
     229
     230DECLHIDDEN(int) autostartSetup()
     231{
     232    autostartSvcOsLogStr("Setting up ...\n", AUTOSTARTLOGTYPE_VERBOSE);
     233
     234    /*
     235     * Initialize COM.
     236     */
     237    using namespace com;
     238    HRESULT hrc = com::Initialize();
     239# ifdef VBOX_WITH_XPCOM
     240    if (hrc == NS_ERROR_FILE_ACCESS_DENIED)
     241    {
     242        char szHome[RTPATH_MAX] = "";
     243        com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome));
     244        return RTMsgErrorExit(RTEXITCODE_FAILURE,
     245               "Failed to initialize COM because the global settings directory '%s' is not accessible!", szHome);
     246    }
     247# endif
     248    if (FAILED(hrc))
     249        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM (%Rhrc)!", hrc);
     250
     251    hrc = g_pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient);
     252    if (FAILED(hrc))
     253    {
     254        RTMsgError("Failed to create the VirtualBoxClient object (%Rhrc)!", hrc);
     255        com::ErrorInfo info;
     256        if (!info.isFullAvailable() && !info.isBasicAvailable())
     257        {
     258            com::GluePrintRCMessage(hrc);
     259            RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start.");
     260        }
     261        else
     262            com::GluePrintErrorInfo(info);
     263        return RTEXITCODE_FAILURE;
     264    }
     265
     266    /*
     267     * Setup VirtualBox + session interfaces.
     268     */
     269    HRESULT rc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());
     270    if (SUCCEEDED(rc))
     271    {
     272        rc = g_pSession.createInprocObject(CLSID_Session);
     273        if (FAILED(rc))
     274            RTMsgError("Failed to create a session object (rc=%Rhrc)!", rc);
     275    }
     276    else
     277        RTMsgError("Failed to get VirtualBox object (rc=%Rhrc)!", rc);
     278
     279    if (FAILED(rc))
     280        return VERR_COM_OBJECT_NOT_FOUND;
     281
     282    return VINF_SUCCESS;
     283}
     284
     285DECLHIDDEN(void) autostartShutdown()
     286{
     287    autostartSvcOsLogStr("Shutting down ...\n", AUTOSTARTLOGTYPE_VERBOSE);
     288
     289    g_pSession.setNull();
     290    g_pVirtualBox.setNull();
     291    g_pVirtualBoxClient.setNull();
     292    com::Shutdown();
     293}
     294
Note: See TracChangeset for help on using the changeset viewer.

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