2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/* $Id$ */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/** @file
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * VirtualBox Autostart Service - Windows Specific Code.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/*
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync * Copyright (C) 2012-2013 Oracle Corporation
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * available from http://www.virtualbox.org. This file is free software;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * General Public License (GPL) as published by the Free Software
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/*******************************************************************************
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync* Header Files *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync*******************************************************************************/
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <Windows.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/com.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/string.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/Guid.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/array.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/ErrorInfo.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/errorprint.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync#include <VBox/com/NativeEventQueue.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/listeners.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <VBox/com/VirtualBox.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <VBox/log.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <VBox/version.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <iprt/string.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <iprt/mem.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <iprt/initterm.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <iprt/stream.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <iprt/getopt.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include <iprt/semaphore.h>
b6013430932520fe58eba109db1dfce66a7cad88vboxsync#include <iprt/thread.h>
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#include "VBoxAutostart.h"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/*******************************************************************************
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync* Defined Constants And Macros *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync*******************************************************************************/
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/** The service name. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#define AUTOSTART_SERVICE_NAME "VBoxAutostartSvc"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/** The service display name. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#define AUTOSTART_SERVICE_DISPLAY_NAME "VirtualBox Autostart Service"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncComPtr<IVirtualBoxClient> g_pVirtualBoxClient = NULL;
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncbool g_fVerbose = false;
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncComPtr<IVirtualBox> g_pVirtualBox = NULL;
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncComPtr<ISession> g_pSession = NULL;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/*******************************************************************************
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync* Global Variables *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync*******************************************************************************/
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/** The service control handler handle. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic SERVICE_STATUS_HANDLE g_hSupSvcWinCtrlHandler = NULL;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/** The service status. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic uint32_t volatile g_u32SupSvcWinStatus = SERVICE_STOPPED;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/** The semaphore the main service thread is waiting on in autostartSvcWinServiceMain. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTSEMEVENTMULTI g_hSupSvcWinEvent = NIL_RTSEMEVENTMULTI;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/*******************************************************************************
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync* Internal Functions *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync*******************************************************************************/
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic SC_HANDLE autostartSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync/**
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * Print out progress on the console.
b6013430932520fe58eba109db1dfce66a7cad88vboxsync *
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * This runs the main event queue every now and then to prevent piling up
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * unhandled things (which doesn't cause real problems, just makes things
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * react a little slower than in the ideal case).
b6013430932520fe58eba109db1dfce66a7cad88vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncDECLHIDDEN(HRESULT) showProgress(ComPtr<IProgress> progress)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync{
b6013430932520fe58eba109db1dfce66a7cad88vboxsync using namespace com;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync BOOL fCompleted = FALSE;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync ULONG ulCurrentPercent = 0;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync ULONG ulLastPercent = 0;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync ULONG ulLastOperationPercent = (ULONG)-1;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync ULONG ulLastOperation = (ULONG)-1;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync Bstr bstrOperationDescription;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync NativeEventQueue::getMainEventQueue()->processEventQueue(0);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync ULONG cOperations = 1;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync HRESULT hrc = progress->COMGETTER(OperationCount)(&cOperations);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (FAILED(hrc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return hrc;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /* setup signal handling if cancelable */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync bool fCanceledAlready = false;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync BOOL fCancelable;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync hrc = progress->COMGETTER(Cancelable)(&fCancelable);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (FAILED(hrc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync fCancelable = FALSE;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync hrc = progress->COMGETTER(Completed(&fCompleted));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync while (SUCCEEDED(hrc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync progress->COMGETTER(Percent(&ulCurrentPercent));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (fCompleted)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync break;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /* process async cancelation */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (!fCanceledAlready)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync hrc = progress->Cancel();
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (SUCCEEDED(hrc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync fCanceledAlready = true;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /* make sure the loop is not too tight */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync progress->WaitForCompletion(100);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
1bb6533bfb0d3d111161e0fb45b04b5e8f2c7c85vboxsync NativeEventQueue::getMainEventQueue()->processEventQueue(0);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync hrc = progress->COMGETTER(Completed(&fCompleted));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /* complete the line. */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync LONG iRc = E_FAIL;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync hrc = progress->COMGETTER(ResultCode)(&iRc);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (SUCCEEDED(hrc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync hrc = iRc;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return hrc;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync}
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncDECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync{
b6013430932520fe58eba109db1dfce66a7cad88vboxsync HANDLE hEventLog = RegisterEventSourceA(NULL /* local computer */, "VBoxAutostartSvc");
b6013430932520fe58eba109db1dfce66a7cad88vboxsync AssertReturnVoid(hEventLog != NULL);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync WORD wType = 0;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync const char *apsz[2];
b6013430932520fe58eba109db1dfce66a7cad88vboxsync apsz[0] = "VBoxAutostartSvc";
b6013430932520fe58eba109db1dfce66a7cad88vboxsync apsz[1] = pszMsg;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync switch (enmLogType)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync case AUTOSTARTLOGTYPE_INFO:
b6013430932520fe58eba109db1dfce66a7cad88vboxsync wType = 0;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync break;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync case AUTOSTARTLOGTYPE_ERROR:
b6013430932520fe58eba109db1dfce66a7cad88vboxsync wType = EVENTLOG_ERROR_TYPE;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync break;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync case AUTOSTARTLOGTYPE_WARNING:
b6013430932520fe58eba109db1dfce66a7cad88vboxsync wType = EVENTLOG_WARNING_TYPE;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync break;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync case AUTOSTARTLOGTYPE_VERBOSE:
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (!g_fVerbose)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync wType = EVENTLOG_INFORMATION_TYPE;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync break;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync default:
b6013430932520fe58eba109db1dfce66a7cad88vboxsync AssertMsgFailed(("Invalid log type %d\n", enmLogType));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync BOOL fRc = ReportEventA(hEventLog, /* hEventLog */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync wType, /* wType */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync 0, /* wCategory */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync 0 /** @todo mc */, /* dwEventID */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync NULL, /* lpUserSid */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RT_ELEMENTS(apsz), /* wNumStrings */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync 0, /* dwDataSize */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync apsz, /* lpStrings */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync NULL); /* lpRawData */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync AssertMsg(fRc, ("%d\n", GetLastError()));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync DeregisterEventSource(hEventLog);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Opens the service control manager.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * When this fails, an error message will be displayed.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns Valid handle on success.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * NULL on failure, will display an error message.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param pszAction The action which is requesting access to SCM.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwAccess The desired access.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic SC_HANDLE autostartSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SC_HANDLE hSCM = OpenSCManager(NULL /* lpMachineName*/, NULL /* lpDatabaseName */, dwAccess);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (hSCM == NULL)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync DWORD err = GetLastError();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (err)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case ERROR_ACCESS_DENIED:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("%s - OpenSCManager failure: access denied\n", pszAction);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("%s - OpenSCManager failure: %d\n", pszAction, err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return hSCM;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Opens the service.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Last error is preserved on failure and set to 0 on success.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns Valid service handle on success.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * NULL on failure, will display an error message unless it's ignored.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param pszAction The action which is requesting access to the service.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwSCMAccess The service control manager access.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwSVCAccess The desired service access.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param cIgnoredErrors The number of ignored errors.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param ... Errors codes that should not cause a message to be displayed.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic SC_HANDLE autostartSvcWinOpenService(const char *pszAction, DWORD dwSCMAccess, DWORD dwSVCAccess,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync unsigned cIgnoredErrors, ...)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SC_HANDLE hSCM = autostartSvcWinOpenSCManager(pszAction, dwSCMAccess);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (!hSCM)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return NULL;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync SC_HANDLE hSvc = OpenServiceA(hSCM, AUTOSTART_SERVICE_NAME, dwSVCAccess);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (hSvc)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync CloseServiceHandle(hSCM);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SetLastError(0);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync DWORD err = GetLastError();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync bool fIgnored = false;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync va_list va;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync va_start(va, cIgnoredErrors);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync while (!fIgnored && cIgnoredErrors-- > 0)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync fIgnored = va_arg(va, long) == err;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync va_end(va);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (!fIgnored)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (err)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case ERROR_ACCESS_DENIED:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("%s - OpenService failure: access denied\n", pszAction);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case ERROR_SERVICE_DOES_NOT_EXIST:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("%s - OpenService failure: The service does not exist. Reinstall it.\n", pszAction);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("%s - OpenService failure: %d\n", pszAction, err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync CloseServiceHandle(hSCM);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SetLastError(err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return hSvc;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinInterrogate(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"interrogate\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinStop(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"stop\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinContinue(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"continue\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinPause(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"pause\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinStart(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"start\" action is not implemented.\n");
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return RTEXITCODE_SUCCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinQueryDescription(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"qdescription\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinQueryConfig(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"qconfig\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinDisable(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"disable\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinEnable(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VBoxAutostartSvc: The \"enable\" action is not implemented.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Handle the 'delete' action.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argc The action argument count.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argv The action argument vector.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic int autostartSvcWinDelete(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Parse the arguments.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync bool fVerbose = false;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync static const RTGETOPTDEF s_aOptions[] =
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync { "--verbose", 'v', RTGETOPT_REQ_NOTHING }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync };
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int ch;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync unsigned iArg = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTGETOPTUNION Value;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTGETOPTSTATE GetState;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync while ((ch = RTGetOpt(&GetState, &Value)))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (ch)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case 'v':
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync fVerbose = true;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case VINF_GETOPT_NOT_OPTION:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcDisplayTooManyArgsError("delete", argc, argv, iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcDisplayGetOptError("delete", ch, argc, argv, iArg, &Value);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync iArg++;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Create the service.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int rc = RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SC_HANDLE hSvc = autostartSvcWinOpenService("delete", SERVICE_CHANGE_CONFIG, DELETE,
b6013430932520fe58eba109db1dfce66a7cad88vboxsync 1, ERROR_SERVICE_DOES_NOT_EXIST);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (hSvc)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (DeleteService(hSvc))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync rc = RTEXITCODE_SUCCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("delete - DeleteService failed, err=%d.\n", GetLastError());
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync CloseServiceHandle(hSvc);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (fVerbose)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTPrintf("The service %s was not installed, nothing to be done.", AUTOSTART_SERVICE_NAME);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync rc = RTEXITCODE_SUCCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return rc;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Handle the 'create' action.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns 0 or 1.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argc The action argument count.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argv The action argument vector.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinCreate(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Parse the arguments.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync bool fVerbose = false;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync const char *pszUser = NULL;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync const char *pszPwd = NULL;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync static const RTGETOPTDEF s_aOptions[] =
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
b6013430932520fe58eba109db1dfce66a7cad88vboxsync { "--user", 'u', RTGETOPT_REQ_STRING },
b6013430932520fe58eba109db1dfce66a7cad88vboxsync { "--password", 'p', RTGETOPT_REQ_STRING }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync };
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int iArg = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int ch;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTGETOPTUNION Value;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTGETOPTSTATE GetState;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync while ((ch = RTGetOpt(&GetState, &Value)))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (ch)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case 'v':
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync fVerbose = true;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case 'u':
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync pszUser = Value.psz;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync case 'p':
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync pszPwd = Value.psz;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcDisplayGetOptError("create", ch, argc, argv, iArg, &Value);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync iArg++;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (iArg != argc)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcDisplayTooManyArgsError("create", argc, argv, iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Create the service.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTEXITCODE rc = RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SC_HANDLE hSCM = autostartSvcWinOpenSCManager("create", SC_MANAGER_CREATE_SERVICE); /*SC_MANAGER_ALL_ACCESS*/
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (hSCM)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync char szExecPath[MAX_PATH];
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (GetModuleFileNameA(NULL /* the executable */, szExecPath, sizeof(szExecPath)))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (fVerbose)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("Creating the %s service, binary \"%s\"...\n",
b6013430932520fe58eba109db1dfce66a7cad88vboxsync AUTOSTART_SERVICE_NAME, szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync SC_HANDLE hSvc = CreateServiceA(hSCM, /* hSCManager */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync AUTOSTART_SERVICE_NAME, /* lpServiceName */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync AUTOSTART_SERVICE_DISPLAY_NAME, /* lpDisplayName */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, /* dwDesiredAccess */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync SERVICE_WIN32_OWN_PROCESS, /* dwServiceType ( | SERVICE_INTERACTIVE_PROCESS? ) */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync SERVICE_AUTO_START, /* dwStartType */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync SERVICE_ERROR_NORMAL, /* dwErrorControl */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync szExecPath, /* lpBinaryPathName */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync NULL, /* lpLoadOrderGroup */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync NULL, /* lpdwTagId */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync NULL, /* lpDependencies */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync pszUser, /* lpServiceStartName (NULL => LocalSystem) */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync pszPwd); /* lpPassword */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (hSvc)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTPrintf("Successfully created the %s service.\n", AUTOSTART_SERVICE_NAME);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /** @todo Set the service description or it'll look weird in the vista service manager.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Anything else that should be configured? Start access or something? */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync rc = RTEXITCODE_SUCCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync CloseServiceHandle(hSvc);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync DWORD err = GetLastError();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (err)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case ERROR_SERVICE_EXISTS:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("create - The service already exists.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("create - CreateService failed, err=%d.\n", GetLastError());
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync CloseServiceHandle(hSvc);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcDisplayError("create - Failed to obtain the executable path: %d\n", GetLastError());
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return rc;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Sets the service status, just a SetServiceStatus Wrapper.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns See SetServiceStatus.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwStatus The current status.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param iWaitHint The wait hint, if < 0 then supply a default.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwExitCode The service exit code.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic bool autostartSvcWinSetServiceStatus(DWORD dwStatus, int iWaitHint, DWORD dwExitCode)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SERVICE_STATUS SvcStatus;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwWin32ExitCode = dwExitCode;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwServiceSpecificExitCode = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwWaitHint = iWaitHint >= 0 ? iWaitHint : 3000;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwCurrentState = dwStatus;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync LogFlow(("autostartSvcWinSetServiceStatus: %d -> %d\n", g_u32SupSvcWinStatus, dwStatus));
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync g_u32SupSvcWinStatus = dwStatus;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (dwStatus)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_START_PENDING:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwControlsAccepted = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync static DWORD dwCheckPoint = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (dwStatus)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_RUNNING:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_STOPPED:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwCheckPoint = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync SvcStatus.dwCheckPoint = ++dwCheckPoint;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return SetServiceStatus(g_hSupSvcWinCtrlHandler, &SvcStatus) != FALSE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Service control handler (extended).
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns Windows status (see HandlerEx).
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @retval NO_ERROR if handled.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @retval ERROR_CALL_NOT_IMPLEMENTED if not handled.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwControl The control code.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param dwEventType Event type. (specific to the control?)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param pvEventData Event data, specific to the event.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param pvContext The context pointer registered with the handler.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Currently not used.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic DWORD WINAPI autostartSvcWinServiceCtrlHandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID pvEventData, LPVOID pvContext)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync LogFlow(("autostartSvcWinServiceCtrlHandlerEx: dwControl=%#x dwEventType=%#x pvEventData=%p\n",
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync dwControl, dwEventType, pvEventData));
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (dwControl)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Interrogate the service about it's current status.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * MSDN says that this should just return NO_ERROR and does
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * not need to set the status again.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_INTERROGATE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return NO_ERROR;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Request to stop the service.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_STOP:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Check if the real services can be stopped and then tell them to stop.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcWinSetServiceStatus(SERVICE_STOP_PENDING, 3000, NO_ERROR);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /*
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * Notify the main thread that we're done, it will wait for the
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * VMs to stop, and set the windows service status to SERVICE_STOPPED
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * and return.
b6013430932520fe58eba109db1dfce66a7cad88vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync int rc = RTSemEventMultiSignal(g_hSupSvcWinEvent);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (RT_FAILURE(rc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartSvcLogError("SERVICE_CONTROL_STOP: RTSemEventMultiSignal failed, %Rrc\n", rc);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return NO_ERROR;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_PAUSE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_CONTINUE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_SHUTDOWN:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_PARAMCHANGE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_NETBINDADD:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_NETBINDREMOVE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_NETBINDENABLE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_NETBINDDISABLE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_DEVICEEVENT:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_HARDWAREPROFILECHANGE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_POWEREVENT:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_SESSIONCHANGE:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#ifdef SERVICE_CONTROL_PRESHUTDOWN /* vista */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case SERVICE_CONTROL_PRESHUTDOWN:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync#endif
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return ERROR_CALL_NOT_IMPLEMENTED;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync NOREF(dwEventType);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync NOREF(pvEventData);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync NOREF(pvContext);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return NO_ERROR;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncstatic int autostartWorker(RTTHREAD ThreadSelf, void *pvUser)
b6013430932520fe58eba109db1dfce66a7cad88vboxsync{
b6013430932520fe58eba109db1dfce66a7cad88vboxsync int rc = autostartSetup();
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /** @todo: Implement config options. */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync rc = autostartStartMain(NULL);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (RT_FAILURE(rc))
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartSvcLogError("Starting VMs failed, rc=%Rrc", rc);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return rc;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Windows Service Main.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * This is invoked when the service is started and should not return until
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * the service has been stopped.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param cArgs Argument count.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param papszArgs Argument vector.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncstatic VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LPTSTR *papszArgs)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync LogFlowFuncEnter();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Register the control handler function for the service and report to SCM.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync Assert(g_u32SupSvcWinStatus == SERVICE_STOPPED);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerExA(AUTOSTART_SERVICE_NAME, autostartSvcWinServiceCtrlHandlerEx, NULL);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (g_hSupSvcWinCtrlHandler)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync DWORD err = ERROR_GEN_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (autostartSvcWinSetServiceStatus(SERVICE_START_PENDING, 3000, NO_ERROR))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (cArgs == 1)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Create the event semaphore we'll be waiting on and
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * then instantiate the actual services.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int rc = RTSemEventMultiCreate(&g_hSupSvcWinEvent);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (RT_SUCCESS(rc))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /*
b6013430932520fe58eba109db1dfce66a7cad88vboxsync * Update the status and enter the work loop.
b6013430932520fe58eba109db1dfce66a7cad88vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (autostartSvcWinSetServiceStatus(SERVICE_RUNNING, 0, 0))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync LogFlow(("autostartSvcWinServiceMain: calling RTSemEventMultiWait\n"));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTTHREAD hWorker;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTThreadCreate(&hWorker, autostartWorker, NULL, 0, RTTHREADTYPE_DEFAULT, 0, "WorkerThread");
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync LogFlow(("autostartSvcWinServiceMain: woke up\n"));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync err = NO_ERROR;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync if (RT_SUCCESS(rc))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync LogFlow(("autostartSvcWinServiceMain: woke up\n"));
b6013430932520fe58eba109db1dfce66a7cad88vboxsync /** @todo: Autostop part. */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync err = NO_ERROR;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartShutdown();
b6013430932520fe58eba109db1dfce66a7cad88vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync else
b6013430932520fe58eba109db1dfce66a7cad88vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync err = GetLastError();
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartSvcLogError("SetServiceStatus failed, err=%d", err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTSemEventMultiDestroy(g_hSupSvcWinEvent);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync g_hSupSvcWinEvent = NIL_RTSEMEVENTMULTI;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcLogError("RTSemEventMultiCreate failed, rc=%Rrc", rc);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
b6013430932520fe58eba109db1dfce66a7cad88vboxsync else
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartSvcLogTooManyArgsError("main", cArgs, NULL, 0);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync err = GetLastError();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcLogError("SetServiceStatus failed, err=%d", err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcWinSetServiceStatus(SERVICE_STOPPED, 0, err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcLogError("RegisterServiceCtrlHandlerEx failed, err=%d", GetLastError());
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync LogFlowFuncLeave();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Handle the 'create' action.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argc The action argument count.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argv The action argument vector.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic int autostartSvcWinRunIt(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync LogFlowFuncEnter();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Initialize release logging.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /** @todo release logging of the system-wide service. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Parse the arguments.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsync static const RTGETOPTDEF s_aOptions[] =
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync { "--dummy", 'd', RTGETOPT_REQ_NOTHING }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync };
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int iArg = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int ch;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTGETOPTUNION Value;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTGETOPTSTATE GetState;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync while ((ch = RTGetOpt(&GetState, &Value)))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (ch)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default: return autostartSvcDisplayGetOptError("runit", ch, argc, argv, iArg, &Value);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (iArg != argc)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcDisplayTooManyArgsError("runit", argc, argv, iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Register the service with the service control manager
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * and start dispatching requests from it (all done by the API).
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync static SERVICE_TABLE_ENTRY const s_aServiceStartTable[] =
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
b6013430932520fe58eba109db1dfce66a7cad88vboxsync { _T(AUTOSTART_SERVICE_NAME), autostartSvcWinServiceMain },
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync { NULL, NULL}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync };
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (StartServiceCtrlDispatcher(&s_aServiceStartTable[0]))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync LogFlowFuncLeave();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_SUCCESS; /* told to quit, so quit. */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync DWORD err = GetLastError();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (err)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
b6013430932520fe58eba109db1dfce66a7cad88vboxsync autostartSvcWinServiceMain(0, NULL);//autostartSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n");
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcLogError("StartServiceCtrlDispatcher failed, err=%d", err);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Show the version info.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns RTEXITCODE_SUCCESS.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinShowVersion(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Parse the arguments.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync bool fBrief = false;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync static const RTGETOPTDEF s_aOptions[] =
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync { "--brief", 'b', RTGETOPT_REQ_NOTHING }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync };
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int iArg = 0;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int ch;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTGETOPTUNION Value;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTGETOPTSTATE GetState;
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync while ((ch = RTGetOpt(&GetState, &Value)))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (ch)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case 'b': fBrief = true; break;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default: return autostartSvcDisplayGetOptError("version", ch, argc, argv, iArg, &Value);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (iArg != argc)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcDisplayTooManyArgsError("version", argc, argv, iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Do the printing.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (fBrief)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("%s\n", VBOX_VERSION_STRING);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VirtualBox Autostart Service Version %s\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "(C) 2012 Oracle Corporation\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "All rights reserved.\n",
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync VBOX_VERSION_STRING);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return RTEXITCODE_SUCCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Show the usage help screen.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns RTEXITCODE_SUCCESS.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsyncstatic RTEXITCODE autostartSvcWinShowHelp(void)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("VirtualBox Autostart Service Version %s\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "(C) 2012 Oracle Corporation\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "All rights reserved.\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "\n",
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync VBOX_VERSION_STRING);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync RTPrintf("Usage:\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "VBoxAutostartSvc\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync " Runs the service.\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "VBoxAutostartSvc <version|-v|--version> [-brief]\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync " Displays the version.\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "VBoxAutostartSvc <help|-?|-h|--help> [...]\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync " Displays this help screen.\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync "VBoxAutostartSvc <install|/RegServer|/i>\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync " Installs the service.\n"
b6013430932520fe58eba109db1dfce66a7cad88vboxsync "VBoxAutostartSvc <uninstall|delete|/UnregServer|/u>\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync " Uninstalls the service.\n"
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync );
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_SUCCESS;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync/**
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * VBoxAutostart main(), Windows edition.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @returns 0 on success.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync *
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argc Number of arguments in argv.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * @param argv Argument vector.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
b6013430932520fe58eba109db1dfce66a7cad88vboxsyncint main(int argc, char **argv)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync{
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Initialize the IPRT first of all.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int rc = RTR3InitExe(argc, &argv, 0);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (RT_FAILURE(rc))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync autostartSvcLogError("RTR3InitExe failed with rc=%Rrc", rc);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
b6013430932520fe58eba109db1dfce66a7cad88vboxsync RTThreadSleep(10 * 1000);
b6013430932520fe58eba109db1dfce66a7cad88vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Parse the initial arguments to determine the desired action.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enum
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_RunIt,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Create,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Delete,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Enable,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Disable,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_QueryConfig,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_QueryDescription,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Start,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Pause,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Continue,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Stop,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_Interrogate,
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync kAutoSvcAction_End
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync } enmAction = kAutoSvcAction_RunIt;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync int iArg = 1;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if (argc > 1)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync if ( !stricmp(argv[iArg], "/RegServer")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "install")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/i"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Create;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if ( !stricmp(argv[iArg], "/UnregServer")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/u")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "uninstall")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "delete"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Delete;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "enable"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Enable;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "disable"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Disable;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "qconfig"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_QueryConfig;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "qdescription"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_QueryDescription;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if ( !stricmp(argv[iArg], "start")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/t"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Start;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "pause"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Start;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "continue"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Continue;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "stop"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Stop;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if (!stricmp(argv[iArg], "interrogate"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync enmAction = kAutoSvcAction_Interrogate;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if ( !stricmp(argv[iArg], "help")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "?")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/?")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "-?")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/h")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "-h")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/help")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "-help")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "--help"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinShowHelp();
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else if ( !stricmp(argv[iArg], "version")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/v")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "-v")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "/version")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "-version")
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync || !stricmp(argv[iArg], "--version"))
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinShowVersion(argc - iArg - 1, argv + iArg + 1);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync else
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync iArg--;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync iArg++;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync /*
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync * Dispatch it.
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync */
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync switch (enmAction)
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync {
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_RunIt:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinRunIt(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Create:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinCreate(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Delete:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinDelete(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Enable:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinEnable(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Disable:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinDisable(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_QueryConfig:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinQueryConfig(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_QueryDescription:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinQueryDescription(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Start:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinStart(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Pause:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinPause(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Continue:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinContinue(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Stop:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinStop(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync case kAutoSvcAction_Interrogate:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return autostartSvcWinInterrogate(argc - iArg, argv + iArg);
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync default:
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync AssertMsgFailed(("enmAction=%d\n", enmAction));
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync return RTEXITCODE_FAILURE;
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync }
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync}
2e3ce94efec87c786a0c87a6f7739faccb3a7e66vboxsync