VirtualBox

Ignore:
Timestamp:
Jan 30, 2025 10:12:53 AM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167249
Message:

Windows driver installation/VBoxDrvInst: Implemented 'service' command to control (driver SCM) services. bugref:10762

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/installation/VBoxDrvInst.cpp

    r107973 r107986  
    6565static DECLCALLBACK(RTEXITCODE) vboxDrvInstCmdInstallMain(PRTGETOPTSTATE pGetState);
    6666static DECLCALLBACK(RTEXITCODE) vboxDrvInstCmdUninstallMain(PRTGETOPTSTATE pGetState);
     67static DECLCALLBACK(RTEXITCODE) vboxDrvInstCmdServiceMain(PRTGETOPTSTATE pGetState);
    6768
    6869static DECLCALLBACK(const char *) vboxDrvInstCmdListHelp(PCRTGETOPTDEF pOpt);
    6970static DECLCALLBACK(const char *) vboxDrvInstCmdInstallHelp(PCRTGETOPTDEF pOpt);
    7071static DECLCALLBACK(const char *) vboxDrvInstCmdUninstallHelp(PCRTGETOPTDEF pOpt);
     72static DECLCALLBACK(const char *) vboxDrvInstCmdServiceHelp(PCRTGETOPTDEF pOpt);
    7173
    7274struct VBOXDRVINSTCMD;
     
    217219
    218220/**
     221 * Long option values for the 'service' command.
     222 */
     223enum
     224{
     225    VBOXDRVINST_SERVICE_OPT_START = 900,
     226    VBOXDRVINST_SERVICE_OPT_STOP,
     227    VBOXDRVINST_SERVICE_OPT_RESTART,
     228    VBOXDRVINST_SERVICE_OPT_WAIT,
     229    VBOXDRVINST_SERVICE_OPT_NO_WAIT
     230};
     231
     232/**
     233 * Command line parameters for the 'service' command.
     234 */
     235static const RTGETOPTDEF g_aCmdServiceOptions[] =
     236{
     237    { "start",     VBOXDRVINST_SERVICE_OPT_START,   RTGETOPT_REQ_NOTHING },
     238    { "stop",      VBOXDRVINST_SERVICE_OPT_STOP,    RTGETOPT_REQ_NOTHING },
     239    { "restart",   VBOXDRVINST_SERVICE_OPT_RESTART, RTGETOPT_REQ_NOTHING },
     240    { "--wait",    VBOXDRVINST_SERVICE_OPT_WAIT,    RTGETOPT_REQ_INT32 },
     241    { "--no-wait", VBOXDRVINST_SERVICE_OPT_NO_WAIT, RTGETOPT_REQ_NOTHING }
     242};
     243
     244/**
     245 * Command definition for the 'service' command.
     246 */
     247const VBOXDRVINSTCMD g_CmdService =
     248{
     249    "service",
     250    vboxDrvInstCmdServiceMain,
     251    "Controls services.",
     252    g_aCmdServiceOptions,
     253    RT_ELEMENTS(g_aCmdServiceOptions),
     254    vboxDrvInstCmdServiceHelp
     255};
     256
     257/**
    219258 * Commands.
    220259 */
     
    223262    &g_CmdList,
    224263    &g_CmdInstall,
    225     &g_CmdUninstall
     264    &g_CmdUninstall,
     265    &g_CmdService
    226266};
    227267
     
    666706}
    667707
     708/** Option help for the 'service' command. */
     709static DECLCALLBACK(const char *) vboxDrvInstCmdServiceHelp(PCRTGETOPTDEF pOpt)
     710{
     711    switch (pOpt->iShort)
     712    {
     713        case VBOXDRVINST_SERVICE_OPT_START:   return "Starts the service";
     714        case VBOXDRVINST_SERVICE_OPT_STOP:    return "Stops the service";
     715        case VBOXDRVINST_SERVICE_OPT_RESTART: return "Restarts the service";
     716        case VBOXDRVINST_SERVICE_OPT_WAIT:    return "Waits for the service to reach the desired state";
     717        case VBOXDRVINST_SERVICE_OPT_NO_WAIT: return "Skips waiting for the service to reach the desired state";
     718
     719        default:
     720            break;
     721    }
     722    return NULL;
     723}
     724
     725static DECLCALLBACK(RTEXITCODE) vboxDrvInstCmdServiceMain(PRTGETOPTSTATE pGetState)
     726{
     727    const char     *pszService = NULL;
     728    VBOXWINDRVSVCFN enmFn      = VBOXWINDRVSVCFN_INVALID;
     729    /* We wait 30s by default, unless specified otherwise below. */
     730    uint32_t        fFlags     = VBOXWINDRVSVCFN_F_WAIT;
     731    RTMSINTERVAL    msTimeout  = RT_MS_30SEC;
     732
     733    int           ch;
     734    RTGETOPTUNION ValueUnion;
     735    while ((ch = RTGetOpt(pGetState, &ValueUnion)))
     736    {
     737        switch (ch)
     738        {
     739            case 'h':
     740                return vboxDrvInstShowUsage(g_pStdOut, &g_CmdService);
     741
     742            case VBOXDRVINST_SERVICE_OPT_START:
     743            {
     744                if (enmFn != VBOXWINDRVSVCFN_INVALID)
     745                    return RTMsgErrorExitFailure("Service control function already specified\n");
     746                enmFn = VBOXWINDRVSVCFN_START;
     747                break;
     748            }
     749
     750            case VBOXDRVINST_SERVICE_OPT_STOP:
     751            {
     752                if (enmFn != VBOXWINDRVSVCFN_INVALID)
     753                    return RTMsgErrorExitFailure("Service control function already specified\n");
     754                enmFn = VBOXWINDRVSVCFN_STOP;
     755                break;
     756            }
     757
     758            case VBOXDRVINST_SERVICE_OPT_RESTART:
     759            {
     760                if (enmFn != VBOXWINDRVSVCFN_INVALID)
     761                    return RTMsgErrorExitFailure("Service control function already specified\n");
     762                enmFn = VBOXWINDRVSVCFN_RESTART;
     763                break;
     764            }
     765
     766            case VBOXDRVINST_SERVICE_OPT_WAIT:
     767                /* Note: fFlags already set above. */
     768                msTimeout = ValueUnion.u32 * RT_MS_1SEC; /* Seconds -> Milliseconds. */
     769                if (!msTimeout)
     770                    return RTMsgErrorExitFailure("Timeout value is invalid\n");
     771                break;
     772
     773            case VBOXDRVINST_SERVICE_OPT_NO_WAIT:
     774                fFlags &= ~VBOXWINDRVSVCFN_F_WAIT;
     775                break;
     776
     777            case VINF_GETOPT_NOT_OPTION:
     778            {
     779                if (pszService)
     780                    return RTMsgErrorExitFailure("Service name already specified\n");
     781
     782                pszService = ValueUnion.psz;
     783                break;
     784            }
     785
     786            default:
     787                return RTGetOptPrintError(ch, &ValueUnion);
     788        }
     789    }
     790
     791    if (!pszService)
     792        return RTMsgErrorExitFailure("No service to control specified\n");
     793    if (enmFn == VBOXWINDRVSVCFN_INVALID)
     794        return RTMsgErrorExitFailure("No or invalid service control function specified\n");
     795
     796    VBOXWINDRVINST hWinDrvInst;
     797    int rc = VBoxWinDrvInstCreateEx(&hWinDrvInst, g_uVerbosity, &vboxDrvInstLogCallback, NULL /* pvUser */);
     798    if (RT_SUCCESS(rc))
     799    {
     800        rc = VBooxWinDrvInstControlServiceEx(hWinDrvInst, pszService, enmFn, fFlags, msTimeout);
     801        VBoxWinDrvInstDestroy(hWinDrvInst);
     802    }
     803
     804    return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     805}
     806
    668807/**
    669808 * Shows the commands and their descriptions.
     
    742881    RTStrmPrintf(pStrm, "\t%s uninstall --model \"VBoxUSB.AMD64\"\n", pszProcName);
    743882    RTStrmPrintf(pStrm, "\t%s uninstall --model \"VBoxUSB*\"\n", pszProcName);
     883    RTStrmPrintf(pStrm, "\t%s service   VBoxSDS stop\n", pszProcName);
     884    RTStrmPrintf(pStrm, "\t%s service   VBoxSDS start --no-wait\n", pszProcName);
     885    RTStrmPrintf(pStrm, "\t%s service   VBoxSDS restart --wait 180\n", pszProcName);
    744886    RTStrmPrintf(pStrm, "\t%s list      \"VBox*\"\n\n", pszProcName);
    745887    RTStrmPrintf(pStrm, "Exit codes:\n");
    746     RTStrmPrintf(pStrm, "\t1 - The (un)installation failed.\n");
     888    RTStrmPrintf(pStrm, "\t1 - The requested command failed.\n");
    747889    RTStrmPrintf(pStrm, "\t2 - Syntax error.\n");
    748890    RTStrmPrintf(pStrm, "\t5 - A reboot is needed in order to complete the (un)installation.\n\n");
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