7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/* $Id$ */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/** @file
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * VBoxService - Guest Additions Service Skeleton, Windows Specific Parts.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2009-2012 Oracle Corporation
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * available from http://www.virtualbox.org. This file is free software;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * you can redistribute it and/or modify it under the terms of the GNU
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * General Public License (GPL) as published by the Free Software
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/*******************************************************************************
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync* Header Files *
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync*******************************************************************************/
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <iprt/assert.h>
9d0256d0854254b2717550a64a6e5871a1123a0dvboxsync#include <iprt/err.h>
61c317bdbd990117ccf85c13366bfd60a439713evboxsync#include <iprt/system.h> /* For querying OS version. */
35396ee506ef68dd1c161f1ef2c3c0b68a146ff2vboxsync#include <VBox/VBoxGuestLib.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include "VBoxServiceInternal.h"
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <Windows.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <process.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync#include <aclapi.h>
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync/*******************************************************************************
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync* Internal Functions *
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync*******************************************************************************/
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic void WINAPI vboxServiceWinMain(DWORD argc, LPTSTR *argv);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync/*******************************************************************************
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync* Global Variables *
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync*******************************************************************************/
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic DWORD g_dwWinServiceLastStatus = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsyncSERVICE_STATUS_HANDLE g_hWinServiceStatus = NULL;
be7419fc81d1230c10ff0c51ac7835c5e25aee0avboxsync/** The semaphore for the dummy Windows service. */
be7419fc81d1230c10ff0c51ac7835c5e25aee0avboxsyncstatic RTSEMEVENT g_WindowsEvent = NIL_RTSEMEVENT;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic SERVICE_TABLE_ENTRY const g_aServiceTable[] =
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync { VBOXSERVICE_NAME, vboxServiceWinMain },
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync { NULL, NULL}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync};
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync/**
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * @todo Format code style.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * @todo Add full unicode support.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync * @todo Add event log capabilities / check return values.
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic DWORD vboxServiceWinAddAceToObjectsSecurityDescriptor(LPTSTR pszObjName,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SE_OBJECT_TYPE ObjectType,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync LPTSTR pszTrustee,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync TRUSTEE_FORM TrusteeForm,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync DWORD dwAccessRights,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync ACCESS_MODE AccessMode,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync DWORD dwInheritance)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync DWORD dwRes = 0;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync PACL pOldDACL = NULL, pNewDACL = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync PSECURITY_DESCRIPTOR pSD = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync EXPLICIT_ACCESS ea;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (NULL == pszObjName)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return ERROR_INVALID_PARAMETER;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Get a pointer to the existing DACL. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync dwRes = GetNamedSecurityInfo(pszObjName, ObjectType,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync DACL_SECURITY_INFORMATION,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync NULL, NULL, &pOldDACL, NULL, &pSD);
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync if (ERROR_SUCCESS != dwRes)
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync if (dwRes == ERROR_FILE_NOT_FOUND)
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: Object not found/installed: %s\n", pszObjName);
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync else
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: GetNamedSecurityInfo: Error %u\n", dwRes);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync goto l_Cleanup;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Initialize an EXPLICIT_ACCESS structure for the new ACE. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ea.grfAccessPermissions = dwAccessRights;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ea.grfAccessMode = AccessMode;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ea.grfInheritance= dwInheritance;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ea.Trustee.TrusteeForm = TrusteeForm;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ea.Trustee.ptstrName = pszTrustee;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Create a new ACL that merges the new ACE into the existing DACL. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync if (ERROR_SUCCESS != dwRes)
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetEntriesInAcl: Error %u\n", dwRes);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync goto l_Cleanup;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Attach the new ACL as the object's DACL. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync dwRes = SetNamedSecurityInfo(pszObjName, ObjectType,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync DACL_SECURITY_INFORMATION,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync NULL, NULL, pNewDACL, NULL);
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync if (ERROR_SUCCESS != dwRes)
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetNamedSecurityInfo: Error %u\n", dwRes);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync goto l_Cleanup;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync /** @todo get rid of that spaghetti jump ... */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncl_Cleanup:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if(pSD != NULL)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync LocalFree((HLOCAL) pSD);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if(pNewDACL != NULL)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync LocalFree((HLOCAL) pNewDACL);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return dwRes;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync
9b5bf00cddef78a2e5ab748a141ea830ce47abe2vboxsync/** Reports our current status to the SCM. */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic BOOL vboxServiceWinSetStatus(DWORD dwStatus, DWORD dwCheckPoint)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (g_hWinServiceStatus == NULL) /* Program could be in testing mode, so no service environment available. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return FALSE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync VBoxServiceVerbose(2, "Setting service status to: %ld\n", dwStatus);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync g_dwWinServiceLastStatus = dwStatus;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync SERVICE_STATUS ss;
61c317bdbd990117ccf85c13366bfd60a439713evboxsync RT_ZERO(ss);
61c317bdbd990117ccf85c13366bfd60a439713evboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync ss.dwCurrentState = dwStatus;
61c317bdbd990117ccf85c13366bfd60a439713evboxsync /* Don't accept controls when in start pending state. */
61c317bdbd990117ccf85c13366bfd60a439713evboxsync if (ss.dwCurrentState != SERVICE_START_PENDING)
61c317bdbd990117ccf85c13366bfd60a439713evboxsync {
61c317bdbd990117ccf85c13366bfd60a439713evboxsync ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync#ifndef TARGET_NT4
61c317bdbd990117ccf85c13366bfd60a439713evboxsync /* Don't use SERVICE_ACCEPT_SESSIONCHANGE on Windows 2000.
61c317bdbd990117ccf85c13366bfd60a439713evboxsync * This makes SCM angry. */
61c317bdbd990117ccf85c13366bfd60a439713evboxsync char szOSVersion[32];
61c317bdbd990117ccf85c13366bfd60a439713evboxsync int rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE,
61c317bdbd990117ccf85c13366bfd60a439713evboxsync szOSVersion, sizeof(szOSVersion));
61c317bdbd990117ccf85c13366bfd60a439713evboxsync if (RT_SUCCESS(rc))
61c317bdbd990117ccf85c13366bfd60a439713evboxsync {
61c317bdbd990117ccf85c13366bfd60a439713evboxsync if (RTStrVersionCompare(szOSVersion, "5.1") >= 0)
61c317bdbd990117ccf85c13366bfd60a439713evboxsync ss.dwControlsAccepted |= SERVICE_ACCEPT_SESSIONCHANGE;
61c317bdbd990117ccf85c13366bfd60a439713evboxsync }
61c317bdbd990117ccf85c13366bfd60a439713evboxsync else
61c317bdbd990117ccf85c13366bfd60a439713evboxsync VBoxServiceError("Error determining OS version, rc=%Rrc\n", rc);
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync#endif
61c317bdbd990117ccf85c13366bfd60a439713evboxsync }
61c317bdbd990117ccf85c13366bfd60a439713evboxsync
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync ss.dwWin32ExitCode = NO_ERROR;
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync ss.dwServiceSpecificExitCode = 0; /* Not used */
87719ea227ff5749eed4101abe8c06c86f24690dvboxsync ss.dwCheckPoint = dwCheckPoint;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync ss.dwWaitHint = 3000;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
61c317bdbd990117ccf85c13366bfd60a439713evboxsync BOOL fStatusSet = SetServiceStatus(g_hWinServiceStatus, &ss);
61c317bdbd990117ccf85c13366bfd60a439713evboxsync if (!fStatusSet)
61c317bdbd990117ccf85c13366bfd60a439713evboxsync VBoxServiceError("Error reporting service status=%ld (controls=%x, checkpoint=%ld) to SCM: %ld\n",
61c317bdbd990117ccf85c13366bfd60a439713evboxsync dwStatus, ss.dwControlsAccepted, dwCheckPoint, GetLastError());
61c317bdbd990117ccf85c13366bfd60a439713evboxsync return fStatusSet;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync/**
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * Reports SERVICE_STOP_PENDING to SCM.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync *
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * @param uCheckPoint Some number.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncvoid VBoxServiceWinSetStopPendingStatus(uint32_t uCheckPoint)
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync{
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinSetStatus(SERVICE_STOP_PENDING, uCheckPoint);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync}
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic RTEXITCODE vboxServiceWinSetDesc(SC_HANDLE hService)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync{
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync#ifndef TARGET_NT4
9b5bf00cddef78a2e5ab748a141ea830ce47abe2vboxsync /* On W2K+ there's ChangeServiceConfig2() which lets us set some fields
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync like a longer service description. */
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync /** @todo On Vista+ SERVICE_DESCRIPTION also supports localized strings! */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_DESCRIPTION desc;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync desc.lpDescription = VBOXSERVICE_DESCRIPTION;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (!ChangeServiceConfig2(hService,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_CONFIG_DESCRIPTION, /* Service info level */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync &desc))
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync {
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync VBoxServiceError("Cannot set the service description! Error: %ld\n", GetLastError());
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return RTEXITCODE_FAILURE;
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync }
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync#endif
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return RTEXITCODE_SUCCESS;
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync}
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync/**
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * Installs the service.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncRTEXITCODE VBoxServiceWinInstall(void)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceVerbose(1, "Installing service ...\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync TCHAR imagePath[MAX_PATH] = { 0 };
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync GetModuleFileName(NULL, imagePath, sizeof(imagePath));
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (hSCManager == NULL)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync {
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync VBoxServiceError("Could not open SCM! Error: %ld\n", GetLastError());
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return RTEXITCODE_FAILURE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync RTEXITCODE rc = RTEXITCODE_SUCCESS;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SC_HANDLE hService = CreateService(hSCManager,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBOXSERVICE_NAME, VBOXSERVICE_FRIENDLY_NAME,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_ALL_ACCESS,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync imagePath, NULL, NULL, NULL, NULL, NULL);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (hService != NULL)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceVerbose(0, "Service successfully installed!\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync {
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync DWORD dwErr = GetLastError();
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync switch (dwErr)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync case ERROR_SERVICE_EXISTS:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceVerbose(1, "Service already exists, just updating the service config.\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync hService = OpenService(hSCManager, VBOXSERVICE_NAME, SERVICE_ALL_ACCESS);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (hService)
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (ChangeServiceConfig (hService,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_DEMAND_START,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SERVICE_ERROR_NORMAL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync imagePath,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync NULL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync NULL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync NULL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync NULL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync NULL,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBOXSERVICE_FRIENDLY_NAME))
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceVerbose(1, "The service config has been successfully updated.\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rc = VBoxServiceError("Could not change service config! Error: %ld\n", GetLastError());
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync }
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rc = VBoxServiceError("Could not open service! Error: %ld\n", GetLastError());
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync default:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rc = VBoxServiceError("Could not create service! Error: %ld\n", dwErr);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (rc == RTEXITCODE_SUCCESS)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rc = vboxServiceWinSetDesc(hService);
da9272c38fc7a11fcc5ec5602341c5a98312dd51vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync CloseServiceHandle(hService);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync CloseServiceHandle(hSCManager);
3e9236d09cc802001f6afea8badd9b2cc1e86509vboxsync return rc;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync/**
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * Uninstalls the service.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncRTEXITCODE VBoxServiceWinUninstall(void)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceVerbose(1, "Uninstalling service ...\n");
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (hSCManager == NULL)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceError("Could not open SCM! Error: %d\n", GetLastError());
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return RTEXITCODE_FAILURE;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync RTEXITCODE rcExit;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SC_HANDLE hService = OpenService(hSCManager, VBOXSERVICE_NAME, SERVICE_ALL_ACCESS );
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (hService != NULL)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (DeleteService(hService))
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync /*
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * ???
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync HKEY hKey = NULL;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync "SYSTEM\\CurrentControlSet\\Services\\EventLog\\System",
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync 0,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync KEY_ALL_ACCESS,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync &hKey)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync == ERROR_SUCCESS)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync RegDeleteKey(hKey, VBOXSERVICE_NAME);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync RegCloseKey(hKey);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceVerbose(0, "Service successfully uninstalled!\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rcExit = RTEXITCODE_SUCCESS;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync }
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rcExit = VBoxServiceError("Could not remove service! Error: %d\n", GetLastError());
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync CloseServiceHandle(hService);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rcExit = VBoxServiceError("Could not open service! Error: %d\n", GetLastError());
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync CloseServiceHandle(hSCManager);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return rcExit;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic int vboxServiceWinStart(void)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync int rc = VINF_SUCCESS;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
36c5021c9ff03eb19d9818903cea95d2e43bd6bcvboxsync#ifndef TARGET_NT4
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync /* Create a well-known SID for the "Builtin Users" group. */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync PSID pBuiltinUsersSID = NULL;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_LOCAL_SID_AUTHORITY;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SECURITY_LOCAL_RID,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync 0, 0, 0, 0, 0, 0, 0,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync &pBuiltinUsersSID))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync rc = RTErrConvertFromWin32(GetLastError());
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync else
35396ee506ef68dd1c161f1ef2c3c0b68a146ff2vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync DWORD dwRes = vboxServiceWinAddAceToObjectsSecurityDescriptor(TEXT("\\\\.\\VBoxMiniRdrDN"),
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SE_FILE_OBJECT,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync (LPTSTR)pBuiltinUsersSID,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync TRUSTEE_IS_SID,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync FILE_GENERIC_READ | FILE_GENERIC_WRITE,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync SET_ACCESS,
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync NO_INHERITANCE);
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync if (dwRes != ERROR_SUCCESS)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync if (dwRes == ERROR_FILE_NOT_FOUND)
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync {
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync /* If we don't find our "VBoxMiniRdrDN" (for Shared Folders) object above,
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync don't report an error; it just might be not installed. Otherwise this
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync would cause the SCM to hang on starting up the service. */
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync rc = VINF_SUCCESS;
3b884f2d817ce2af98e0c2c3fed82ade29e991b8vboxsync }
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rc = RTErrConvertFromWin32(dwRes);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
36c5021c9ff03eb19d9818903cea95d2e43bd6bcvboxsync#endif
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (RT_SUCCESS(rc))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
61c317bdbd990117ccf85c13366bfd60a439713evboxsync vboxServiceWinSetStatus(SERVICE_START_PENDING, 0);
61c317bdbd990117ccf85c13366bfd60a439713evboxsync
be7419fc81d1230c10ff0c51ac7835c5e25aee0avboxsync rc = VBoxServiceStartServices();
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (RT_SUCCESS(rc))
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinSetStatus(SERVICE_RUNNING, 0);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceMainWait();
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync }
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
2ee72515fe39fc0773ec05ae6f486f42344e1a75vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinSetStatus(SERVICE_STOPPED, 0);
2ee72515fe39fc0773ec05ae6f486f42344e1a75vboxsync#if 0 /** @todo r=bird: Enable this if SERVICE_CONTROL_STOP isn't triggered automatically */
2ee72515fe39fc0773ec05ae6f486f42344e1a75vboxsync VBoxServiceStopServices();
2ee72515fe39fc0773ec05ae6f486f42344e1a75vboxsync#endif
2ee72515fe39fc0773ec05ae6f486f42344e1a75vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync else
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync vboxServiceWinSetStatus(SERVICE_STOPPED, 0);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync if (RT_FAILURE(rc))
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceError("Service failed to start with rc=%Rrc!\n", rc);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync return rc;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync/**
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * Call StartServiceCtrlDispatcher.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync *
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * The main() thread invokes this when not started in foreground mode. It
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * won't return till the service is being shutdown (unless start up fails).
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync *
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * @returns RTEXITCODE_SUCCESS on normal return after service shutdown.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync * Something else on failure, error will have been reported.
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync */
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncRTEXITCODE VBoxServiceWinEnterCtrlDispatcher(void)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync{
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (!StartServiceCtrlDispatcher(&g_aServiceTable[0]))
b3f11a895848f459d2c8a3012c62ecdb01810befvboxsync return VBoxServiceError("StartServiceCtrlDispatcher: %u. Please start %s with option -f (foreground)!\n",
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync GetLastError(), g_pszProgName);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return RTEXITCODE_SUCCESS;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync}
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync#ifndef TARGET_NT4
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsyncstatic const char* vboxServiceWTSStateToString(DWORD dwEvent)
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync{
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync switch (dwEvent)
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync {
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_CONSOLE_CONNECT:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session was connected to the console terminal";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_CONSOLE_DISCONNECT:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session was disconnected from the console terminal";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_REMOTE_CONNECT:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session connected to the remote terminal";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_REMOTE_DISCONNECT:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session was disconnected from the remote terminal";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_LOGON:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A user has logged on to a session";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_LOGOFF:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A user has logged off the session";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_LOCK:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session has been locked";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_UNLOCK:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session has been unlocked";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_REMOTE_CONTROL:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session has changed its remote controlled status";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync#if 0
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_CREATE:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "A session has been created";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case WTS_SESSION_TERMINATE:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "The session has been terminated";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync#endif
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync default:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync break;
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync }
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync return "Uknonwn state";
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync}
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync#endif /* !TARGET_NT4 */
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#ifdef TARGET_NT4
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic VOID WINAPI vboxServiceWinCtrlHandler(DWORD dwControl)
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic DWORD WINAPI vboxServiceWinCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#endif
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync DWORD rcRet = NO_ERROR;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync#ifdef TARGET_NT4
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceVerbose(2, "Control handler: Control=%#x\n", dwControl);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync#else
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync VBoxServiceVerbose(2, "Control handler: Control=%#x, EventType=%#x\n", dwControl, dwEventType);
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#endif
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync switch (dwControl)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync case SERVICE_CONTROL_INTERROGATE:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinSetStatus(g_dwWinServiceLastStatus, 0);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync case SERVICE_CONTROL_STOP:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync case SERVICE_CONTROL_SHUTDOWN:
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinSetStatus(SERVICE_STOP_PENDING, 0);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync int rc2 = VBoxServiceStopServices();
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (RT_FAILURE(rc2))
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rcRet = ERROR_GEN_FAILURE;
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync else
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync {
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync rc2 = VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated);
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync AssertRC(rc2);
348188d7b4dbc0e8fccd10c903eba81e068dfe87vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinSetStatus(SERVICE_STOPPED, 0);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync# ifndef TARGET_NT4
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync case SERVICE_CONTROL_SESSIONCHANGE: /* Only Windows 2000 and up. */
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync {
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync AssertPtr(lpEventData);
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync PWTSSESSION_NOTIFICATION pNotify = (PWTSSESSION_NOTIFICATION)lpEventData;
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync Assert(pNotify->cbSize == sizeof(WTSSESSION_NOTIFICATION));
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync VBoxServiceVerbose(1, "Control handler: %s (Session=%ld, Event=%#x)\n",
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync vboxServiceWTSStateToString(dwEventType),
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync pNotify->dwSessionId, dwEventType);
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync /* Handle all events, regardless of dwEventType. */
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync int rc2 = VBoxServiceVMInfoSignal();
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync AssertRC(rc2);
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync break;
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync }
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync# endif /* !TARGET_NT4 */
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync default:
aaa2d8be4f9e54279d4c4799f8a474e3dd4320efvboxsync VBoxServiceVerbose(1, "Control handler: Function not implemented: %#x\n", dwControl);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync rcRet = ERROR_CALL_NOT_IMPLEMENTED;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#ifndef TARGET_NT4
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync return rcRet;
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#endif
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync
942d1a32d70995e0b2d6fc8c109432e0613967acvboxsync
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsyncstatic void WINAPI vboxServiceWinMain(DWORD argc, LPTSTR *argv)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync{
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync VBoxServiceVerbose(2, "Registering service control handler ...\n");
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#ifdef TARGET_NT4
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync g_hWinServiceStatus = RegisterServiceCtrlHandler(VBOXSERVICE_NAME, vboxServiceWinCtrlHandler);
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#else
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync g_hWinServiceStatus = RegisterServiceCtrlHandlerEx(VBOXSERVICE_NAME, vboxServiceWinCtrlHandler, NULL);
1222ff94540f6426532c1f1714f0717fdcf92e46vboxsync#endif
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync if (g_hWinServiceStatus != NULL)
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceVerbose(2, "Service control handler registered.\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync vboxServiceWinStart();
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync }
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync else
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync DWORD dwErr = GetLastError();
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync switch (dwErr)
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync {
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync case ERROR_INVALID_NAME:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceError("Invalid service name!\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync case ERROR_SERVICE_DOES_NOT_EXIST:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceError("Service does not exist!\n");
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync default:
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync VBoxServiceError("Could not register service control handle! Error: %ld\n", dwErr);
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync break;
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync }
7a61a5714b9a39ac3bd59e52b0843ef498350a35vboxsync}
a8e64340afb42c4918e2d6faecdba928a0b2b45cvboxsync