VBoxService-win.cpp revision 87719ea227ff5749eed4101abe8c06c86f24690d
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/* $Id$ */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/** @file
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * VBoxService - Guest Additions Service Skeleton, Windows Specific Parts.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/*
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Copyright (C) 2009 Sun Microsystems, Inc.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync *
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * available from http://www.virtualbox.org. This file is free software;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * General Public License (GPL) as published by the Free Software
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync *
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * additional information or have any questions.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/*******************************************************************************
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync* Header Files *
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync*******************************************************************************/
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include <iprt/assert.h>
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include <iprt/err.h>
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include <VBox/VBoxGuestLib.h>
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include "VBoxServiceInternal.h"
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include <Windows.h>
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include <process.h>
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#include <aclapi.h>
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncDWORD g_rcWinService = 0;
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsyncSERVICE_STATUS_HANDLE g_hWinServiceStatus = NULL;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncvoid WINAPI VBoxServiceWinMain (DWORD argc, LPTSTR *argv);
88acfa6629a7976c0583c1712d2b5b22a87a5121vboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncstatic SERVICE_TABLE_ENTRY const g_aServiceTable[]=
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync{
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync {VBOXSERVICE_NAME, VBoxServiceWinMain},
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync {NULL,NULL}
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync};
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync/**
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync * @todo Format code style.
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync * @todo Add full unicode support.
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync * @todo Add event log capabilities / check return values.
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync */
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsyncDWORD VBoxServiceWinAddAceToObjectsSecurityDescriptor (LPTSTR pszObjName,
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync SE_OBJECT_TYPE ObjectType,
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync LPTSTR pszTrustee,
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync TRUSTEE_FORM TrusteeForm,
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync DWORD dwAccessRights,
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync ACCESS_MODE AccessMode,
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync DWORD dwInheritance)
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync{
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync DWORD dwRes = 0;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync PACL pOldDACL = NULL, pNewDACL = NULL;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync PSECURITY_DESCRIPTOR pSD = NULL;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync EXPLICIT_ACCESS ea;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (NULL == pszObjName)
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync return ERROR_INVALID_PARAMETER;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync /* Get a pointer to the existing DACL. */
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync dwRes = GetNamedSecurityInfo(pszObjName, ObjectType,
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync DACL_SECURITY_INFORMATION,
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync NULL, NULL, &pOldDACL, NULL, &pSD);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync if (ERROR_SUCCESS != dwRes)
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync {
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (dwRes == ERROR_FILE_NOT_FOUND)
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: Object not found/installed: %s\n", pszObjName);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync else
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: GetNamedSecurityInfo: Error %u\n", dwRes);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync goto Cleanup;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync /* Initialize an EXPLICIT_ACCESS structure for the new ACE. */
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync ea.grfAccessPermissions = dwAccessRights;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync ea.grfAccessMode = AccessMode;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync ea.grfInheritance= dwInheritance;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync ea.Trustee.TrusteeForm = TrusteeForm;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync ea.Trustee.ptstrName = pszTrustee;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync /* Create a new ACL that merges the new ACE into the existing DACL. */
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (ERROR_SUCCESS != dwRes)
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync {
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetEntriesInAcl: Error %u\n", dwRes);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync goto Cleanup;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync }
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync /* Attach the new ACL as the object's DACL. */
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync dwRes = SetNamedSecurityInfo(pszObjName, ObjectType,
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync DACL_SECURITY_INFORMATION,
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync NULL, NULL, pNewDACL, NULL);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (ERROR_SUCCESS != dwRes)
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync {
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetNamedSecurityInfo: Error %u\n", dwRes);
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync goto Cleanup;
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync }
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync /** @todo get rid of that spaghetti jump ... */
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsyncCleanup:
8077a3fb4024022d405598797d3ed75c667a912fvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync if(pSD != NULL)
8077a3fb4024022d405598797d3ed75c667a912fvboxsync LocalFree((HLOCAL) pSD);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if(pNewDACL != NULL)
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync LocalFree((HLOCAL) pNewDACL);
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync return dwRes;
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync}
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsyncBOOL VBoxServiceWinSetStatus (DWORD dwStatus, DWORD dwCheckPoint /*= 0 */)
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync{
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync if (NULL == g_hWinServiceStatus) /* Program could be in testing mode, so no service environment available. */
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync return FALSE;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync VBoxServiceVerbose(2, "Setting service status to: %ld\n", dwStatus);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync g_rcWinService = dwStatus;
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync SERVICE_STATUS ss;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync ss.dwCurrentState = g_rcWinService;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync ss.dwWin32ExitCode = NO_ERROR;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync ss.dwServiceSpecificExitCode = 0; /* Not used */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync ss.dwCheckPoint = dwCheckPoint;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync ss.dwWaitHint = 3000;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync return SetServiceStatus (g_hWinServiceStatus, &ss);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync}
c0ae9fb031e70c0e5f4098a46ab11262097c88f9vboxsync
c0ae9fb031e70c0e5f4098a46ab11262097c88f9vboxsyncint VBoxServiceWinInstall ()
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync{
c0ae9fb031e70c0e5f4098a46ab11262097c88f9vboxsync SC_HANDLE hService, hSCManager;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync TCHAR imagePath[MAX_PATH] = { 0 };
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync GetModuleFileName(NULL,imagePath,MAX_PATH);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceVerbose(1, "Installing service ...\n");
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync if (NULL == hSCManager) {
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceError("Could not open SCM! Error: %d\n", GetLastError());
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync return 1;
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync }
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync hService = ::CreateService (hSCManager,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBOXSERVICE_NAME, VBOXSERVICE_FRIENDLY_NAME,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync SERVICE_ALL_ACCESS,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,
8077a3fb4024022d405598797d3ed75c667a912fvboxsync imagePath, NULL, NULL, NULL, NULL, NULL);
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync if (NULL == hService) {
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync VBoxServiceError("Could not create service! Error: %d\n", GetLastError());
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync CloseServiceHandle(hSCManager);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync return 1;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync else
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync {
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync VBoxServiceVerbose(0, "Service successfully installed!\n");
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync CloseServiceHandle(hService);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync CloseServiceHandle(hSCManager);
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync return 0;
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync}
3cd31efc45d9b3b5118748be299da2f298307cddvboxsync
3cd31efc45d9b3b5118748be299da2f298307cddvboxsyncint VBoxServiceWinUninstall ()
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync{
a44a181b748735a02cc0e8c192f3ec1fac1af796vboxsync SC_HANDLE hService, hSCManager;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync VBoxServiceVerbose(1, "Uninstalling service ...\n");
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (NULL == hSCManager) {
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync VBoxServiceError("Could not open SCM! Error: %d\n", GetLastError());
a44a181b748735a02cc0e8c192f3ec1fac1af796vboxsync return 1;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync hService = OpenService (hSCManager, VBOXSERVICE_NAME, SERVICE_ALL_ACCESS );
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync if (NULL == hService) {
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync VBoxServiceError("Could not open service! Error: %d\n", GetLastError());
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync CloseServiceHandle (hSCManager);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync return 1;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (FALSE == DeleteService (hService))
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync {
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync VBoxServiceError("Could not remove service! Error: %d\n", GetLastError());
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync CloseServiceHandle (hService);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync CloseServiceHandle (hSCManager);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync return 1;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync else
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync {
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync HKEY hKey = NULL;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\System", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync RegDeleteKey(hKey, VBOXSERVICE_NAME);
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync RegCloseKey(hKey);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync VBoxServiceVerbose(0, "Service successfully uninstalled!\n");
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
2b14f26c96a20e40e9a0c9e3c41b41315f6c6e96vboxsync
8077a3fb4024022d405598797d3ed75c667a912fvboxsync CloseServiceHandle(hService);
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync CloseServiceHandle(hSCManager);
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync return 0;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync}
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsyncint VBoxServiceWinStart()
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync{
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync int rc = VINF_SUCCESS;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync#ifndef TARGET_NT4
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync /* Create a well-known SID for the "Builtin Users" group. */
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync PSID pBuiltinUsersSID = NULL;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_LOCAL_SID_AUTHORITY;
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync
c0ae9fb031e70c0e5f4098a46ab11262097c88f9vboxsync if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
c0ae9fb031e70c0e5f4098a46ab11262097c88f9vboxsync SECURITY_LOCAL_RID,
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync 0, 0, 0, 0, 0, 0, 0,
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync &pBuiltinUsersSID))
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync {
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync VBoxServiceError("AllocateAndInitializeSid: Error %u\n", GetLastError());
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync }
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync else
fb846a5cde5068b8fc9880a7b59ab1dbc01c1680vboxsync {
4b0369e0c9bcae37f2801e0f7b92509bbbaf4becvboxsync DWORD dwRes = VBoxServiceWinAddAceToObjectsSecurityDescriptor (TEXT("\\\\.\\VBoxMiniRdrDN"),
fb846a5cde5068b8fc9880a7b59ab1dbc01c1680vboxsync SE_FILE_OBJECT,
8077a3fb4024022d405598797d3ed75c667a912fvboxsync (LPTSTR)pBuiltinUsersSID,
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync TRUSTEE_IS_SID,
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync FILE_GENERIC_READ | FILE_GENERIC_WRITE,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync SET_ACCESS,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync NO_INHERITANCE);
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync if (dwRes != ERROR_SUCCESS)
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync {
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync if (dwRes == ERROR_FILE_NOT_FOUND)
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync {
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync /* If we don't find our "VBoxMiniRdrDN" (for Shared Folders) object above,
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync don't report an error; it just might be not installed. Otherwise this
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync would cause the SCM to hang on starting up the service. */
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync rc = VINF_SUCCESS;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync }
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync else rc = RTErrConvertFromWin32(dwRes);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync }
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync }
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#endif
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync if (RT_SUCCESS(rc))
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync {
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync /* Notify SCM *before* we're starting the services, because the last services
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync always starts in main thread (which causes the SCM to wait because of the non-responding
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync service). */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceWinSetStatus (SERVICE_RUNNING);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync /*
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Check that at least one service is enabled.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync */
2805b95732a8d26015a397626b96049a6e6573e7vboxsync unsigned iMain = VBoxServiceGetStartedServices();
2805b95732a8d26015a397626b96049a6e6573e7vboxsync rc = VBoxServiceStartServices(iMain); /* Start all the services. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
2805b95732a8d26015a397626b96049a6e6573e7vboxsync if (RT_FAILURE(rc))
2805b95732a8d26015a397626b96049a6e6573e7vboxsync VBoxServiceWinSetStatus (SERVICE_STOPPED);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync }
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
cb5363b6fa48f10b080cb6195f56c0823f7c0b0fvboxsync if (RT_FAILURE(rc))
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceError("Service failed to start with rc=%Rrc!\n", rc);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync return rc;
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync}
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#ifdef TARGET_NT4
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncVOID WINAPI VBoxServiceWinCtrlHandler (DWORD dwControl)
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#else
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsyncDWORD WINAPI VBoxServiceWinCtrlHandler (DWORD dwControl,
cb5363b6fa48f10b080cb6195f56c0823f7c0b0fvboxsync DWORD dwEventType,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync LPVOID lpEventData,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync LPVOID lpContext)
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#endif
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync{
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync DWORD rc = NO_ERROR;
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceVerbose(2, "Control handler: Control=%ld\n", dwControl);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#ifndef TARGET_NT4
f2af1be3e27a2fefe95332260d360f4b26cffbcfvboxsync VBoxServiceVerbose(2, "Control handler: EventType=%ld\n", dwEventType);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#endif
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
2805b95732a8d26015a397626b96049a6e6573e7vboxsync switch (dwControl)
2805b95732a8d26015a397626b96049a6e6573e7vboxsync {
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
2805b95732a8d26015a397626b96049a6e6573e7vboxsync case SERVICE_CONTROL_INTERROGATE:
2805b95732a8d26015a397626b96049a6e6573e7vboxsync VBoxServiceWinSetStatus(g_rcWinService);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync break;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync case SERVICE_CONTROL_STOP:
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync case SERVICE_CONTROL_SHUTDOWN:
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync {
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceWinSetStatus(SERVICE_STOP_PENDING);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
eaae6c3ce81916ccc4e74af4b55972ba956cf5c8vboxsync rc = VBoxServiceStopServices();
cb5363b6fa48f10b080cb6195f56c0823f7c0b0fvboxsync
cb5363b6fa48f10b080cb6195f56c0823f7c0b0fvboxsync VBoxServiceWinSetStatus(SERVICE_STOPPED);
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync }
cb5363b6fa48f10b080cb6195f56c0823f7c0b0fvboxsync break;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync case SERVICE_CONTROL_SESSIONCHANGE: /* Only Win XP and up. */
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
8077a3fb4024022d405598797d3ed75c667a912fvboxsync#ifndef TARGET_NT4
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync switch (dwEventType)
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync {
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync /*case WTS_SESSION_LOGON:
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceVerbose(2, "A user has logged on to the session.\n");
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync break;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
8077a3fb4024022d405598797d3ed75c667a912fvboxsync case WTS_SESSION_LOGOFF:
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceVerbose(2, "A user has logged off from the session.\n");
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync break;*/
8077a3fb4024022d405598797d3ed75c667a912fvboxsync default:
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync break;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync }
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#endif /* TARGET_NT4 */
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync break;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync default:
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync VBoxServiceVerbose(1, "Service control function not implemented: %ld\n", dwControl);
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync rc = ERROR_CALL_NOT_IMPLEMENTED;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync break;
08870164da59f90379b1ea9b5a2476296c362217vboxsync }
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync#ifndef TARGET_NT4
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync return rc;
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync#endif
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync}
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncvoid WINAPI VBoxServiceWinMain (DWORD argc, LPTSTR *argv)
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync{
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync int rc = VINF_SUCCESS;
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceVerbose(2, "Registering service control handler ...\n");
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync#ifdef TARGET_NT4
08870164da59f90379b1ea9b5a2476296c362217vboxsync g_hWinServiceStatus = RegisterServiceCtrlHandler (VBOXSERVICE_NAME, VBoxServiceWinCtrlHandler);
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync#else
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync g_hWinServiceStatus = RegisterServiceCtrlHandlerEx (VBOXSERVICE_NAME, VBoxServiceWinCtrlHandler, NULL);
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync#endif
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync if (NULL == g_hWinServiceStatus)
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync {
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync DWORD dwErr = GetLastError();
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync switch (dwErr)
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync {
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync case ERROR_INVALID_NAME:
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceError("Invalid service name!\n");
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync break;
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync case ERROR_SERVICE_DOES_NOT_EXIST:
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceError("Service does not exist!\n");
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync break;
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync default:
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceError("Could not register service control handle! Error: %ld\n", dwErr);
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync break;
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync }
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync }
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync else
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync {
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync VBoxServiceVerbose(2, "Service control handler registered.\n");
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync rc = VBoxServiceWinStart();
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync }
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync}
2f8244f574b4b9f99af99b7472984f3e60ea93d0vboxsync
e75313c24325ec7bec84fa349abb39e246b6cc86vboxsync