SUPSvc-win.cpp revision f313ed48a0cc2d9d12580dc9412291ae15773f02
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * VirtualBox Support Service - Windows Specific Code.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * Copyright (C) 2008 Oracle Corporation
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * available from http://www.virtualbox.org. This file is free software;
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * General Public License (GPL) as published by the Free Software
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * The contents of this file may alternatively be used under the terms
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * of the Common Development and Distribution License Version 1.0
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * VirtualBox OSE distribution, in which case the provisions of the
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * CDDL are applicable instead of those of the GPL.
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * You may elect to license modified versions of this file under the
1a9a76385f412e8c5762baadaa30afe308b1cd12vboxsync * terms and conditions of either the GPL or the CDDL or both.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/*******************************************************************************
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync* Header Files *
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync*******************************************************************************/
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/*******************************************************************************
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync* Defined Constants And Macros *
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync*******************************************************************************/
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/** The service name. */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/** The service display name. */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync#define SUPSVC_SERVICE_DISPLAY_NAME "VirtualBox Support Service"
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/*******************************************************************************
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync* Global Variables *
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync*******************************************************************************/
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/** The service control handler handle. */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic SERVICE_STATUS_HANDLE g_hSupSvcWinCtrlHandler = NULL;
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/** The service status. */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic uint32_t volatile g_u32SupSvcWinStatus = SERVICE_STOPPED;
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/** The semaphore the main service thread is waiting on in supSvcWinServiceMain. */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic RTSEMEVENTMULTI g_hSupSvcWinEvent = NIL_RTSEMEVENTMULTI;
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync/*******************************************************************************
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync* Internal Functions *
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync*******************************************************************************/
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic SC_HANDLE supSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * Opens the service control manager.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * When this fails, an error message will be displayed.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @returns Valid handle on success.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * NULL on failure, will display an error message.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param pszAction The action which is requesting access to SCM.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param dwAccess The desired access.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic SC_HANDLE supSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess)
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync SC_HANDLE hSCM = OpenSCManager(NULL /* lpMachineName*/, NULL /* lpDatabaseName */, dwAccess);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync supSvcDisplayError("%s - OpenSCManager failure: access denied\n", pszAction);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync supSvcDisplayError("%s - OpenSCManager failure: %d\n", pszAction, err);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * Opens the service.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * Last error is preserved on failure and set to 0 on success.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @returns Valid service handle on success.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * NULL on failure, will display an error message unless it's ignored.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param pszAction The action which is requestion access to the service.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param dwSCMAccess The service control manager access.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param dwSVCAccess The desired service access.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param cIgnoredErrors The number of ignored errors.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync * @param ... Errors codes that should not cause a message to be displayed.
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic SC_HANDLE supSvcWinOpenService(const char *pszAction, DWORD dwSCMAccess, DWORD dwSVCAccess,
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync unsigned cIgnoredErrors, ...)
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync SC_HANDLE hSCM = supSvcWinOpenSCManager(pszAction, dwSCMAccess);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync SC_HANDLE hSvc = OpenService(hSCM, SUPSVC_SERVICE_NAME, dwSVCAccess);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync bool fIgnored = false;
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync supSvcDisplayError("%s - OpenService failure: access denied\n", pszAction);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync supSvcDisplayError("%s - OpenService failure: The service does not exist. Reinstall it.\n", pszAction);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync supSvcDisplayError("%s - OpenService failure: %d\n", pszAction, err);
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync HANDLE hEventLog = RegisterEventSource(NULL /* local computer */, "VBoxSupSvc");
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync 0, /* wCategory */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync 0, /* dwDataSize */
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsyncstatic int supSvcWinInterrogate(int argc, char **argv)
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync RTPrintf("VBoxSupSvc: The \"interrogate\" action is not implemented.\n");
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync RTPrintf("VBoxSupSvc: The \"stop\" action is not implemented.\n");
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync RTPrintf("VBoxSupSvc: The \"continue\" action is not implemented.\n");
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync RTPrintf("VBoxSupSvc: The \"pause\" action is not implemented.\n");
38b0f04a36431d57eed1de01653dd0a015eae4c3vboxsync RTPrintf("VBoxSupSvc: The \"start\" action is not implemented.\n");
bool fVerbose = false;
int ch;
RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
switch (ch)
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (hSvc)
rc = 0;
if (fVerbose)
rc = 0;
return rc;
bool fVerbose = false;
int iArg = 0;
int ch;
switch (ch)
SC_HANDLE hSCM = supSvcWinOpenSCManager("create", SC_MANAGER_CREATE_SERVICE); /*SC_MANAGER_ALL_ACCESS*/
if (hSCM)
if (fVerbose)
if (hSvc)
rc = 0;
switch (err)
case ERROR_SERVICE_EXISTS:
return rc;
switch (dwStatus)
case SERVICE_START_PENDING:
switch (dwStatus)
case SERVICE_RUNNING:
case SERVICE_STOPPED:
static DWORD WINAPI supSvcWinServiceCtrlHandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID pvEventData, LPVOID pvContext)
switch (dwControl)
return NO_ERROR;
case SERVICE_CONTROL_STOP:
return NO_ERROR;
case SERVICE_CONTROL_PAUSE:
case SERVICE_CONTROL_CONTINUE:
case SERVICE_CONTROL_SHUTDOWN:
return ERROR_CALL_NOT_IMPLEMENTED;
return NO_ERROR;
g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerEx(SUPSVC_SERVICE_NAME, supSvcWinServiceCtrlHandlerEx, NULL);
int ch;
int rc = 0;
while ( !rc
switch (ch)
if (!rc)
int iArg = 0;
int ch;
switch (ch)
switch (err)
supSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n");
bool fBrief = false;
int iArg = 0;
int ch;
switch (ch)
if (fBrief)
static int supSvcWinShowHelp(void)
#ifdef DEBUG_bird
return supSvcWinShowHelp();
iArg--;
iArg++;
switch (enmAction)
case kSupSvcAction_RunIt:
case kSupSvcAction_Create:
case kSupSvcAction_Delete:
case kSupSvcAction_Enable:
case kSupSvcAction_Disable:
case kSupSvcAction_Start:
case kSupSvcAction_Pause:
case kSupSvcAction_Continue:
case kSupSvcAction_Stop: