68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync/** @file
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync *
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * VirtualBox COM class implementation
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync/*
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync * Copyright (C) 2014 Oracle Corporation
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync *
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * available from http://www.virtualbox.org. This file is free software;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * you can redistribute it and/or modify it under the terms of the GNU
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * General Public License (GPL) as published by the Free Software
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync#include "AdditionsFacilityImpl.h"
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync#include "Global.h"
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync#include "AutoCaller.h"
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync#include "Logging.h"
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync/* static */
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsyncconst AdditionsFacility::FacilityInfo AdditionsFacility::s_aFacilityInfo[8] =
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync /* NOTE: We assume that unknown is always the first entry! */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync { "Unknown", AdditionsFacilityType_None, AdditionsFacilityClass_None },
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync { "VirtualBox Base Driver", AdditionsFacilityType_VBoxGuestDriver, AdditionsFacilityClass_Driver },
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync { "Auto Logon", AdditionsFacilityType_AutoLogon, AdditionsFacilityClass_Feature },
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync { "VirtualBox System Service", AdditionsFacilityType_VBoxService, AdditionsFacilityClass_Service },
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync { "VirtualBox Desktop Integration", AdditionsFacilityType_VBoxTrayClient, AdditionsFacilityClass_Program },
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync { "Seamless Mode", AdditionsFacilityType_Seamless, AdditionsFacilityClass_Feature },
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync { "Graphics Mode", AdditionsFacilityType_Graphics, AdditionsFacilityClass_Feature },
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync};
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync// constructor / destructor
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync/////////////////////////////////////////////////////////////////////////////
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
5c3edb4f0121bd32e4f9945a7965b69756d0945fvboxsyncDEFINE_EMPTY_CTOR_DTOR(AdditionsFacility)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsyncHRESULT AdditionsFacility::FinalConstruct()
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFunc(("\n"));
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return BaseFinalConstruct();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsyncvoid AdditionsFacility::FinalRelease()
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncEnter();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync uninit();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync BaseFinalRelease();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncLeave();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync// public initializer/uninitializer for internal purposes only
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync/////////////////////////////////////////////////////////////////////////////
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsyncHRESULT AdditionsFacility::init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync LogFlowThisFunc(("a_pParent=%p\n", a_pParent));
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync /* Enclose the state transition NotReady->InInit->Ready. */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoInitSpan autoInitSpan(this);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync FacilityState state;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync state.mStatus = a_enmStatus;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync state.mTimestamp = *a_pTimeSpecTS;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync NOREF(a_fFlags);
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync Assert(mData.mStates.size() == 0);
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync mData.mStates.push_back(state);
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync mData.mType = a_enmFacility;
5c3edb4f0121bd32e4f9945a7965b69756d0945fvboxsync /** @todo mClass is not initialized here. */
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync NOREF(a_fFlags);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync /* Confirm a successful initialization when it's the case. */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync autoInitSpan.setSucceeded();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return S_OK;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync/**
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * Uninitializes the instance.
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync * Called from FinalRelease().
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsyncvoid AdditionsFacility::uninit()
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFunc(("\n"));
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync /* Enclose the state transition Ready->InUninit->NotReady. */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoUninitSpan autoUninitSpan(this);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync if (autoUninitSpan.uninitDone())
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync mData.mStates.clear();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncHRESULT AdditionsFacility::getClassType(AdditionsFacilityClass_T *aClassType)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncEnter();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync *aClassType = i_getClass();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return S_OK;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncHRESULT AdditionsFacility::getName(com::Utf8Str &aName)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncEnter();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync aName = i_getName();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return S_OK;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncHRESULT AdditionsFacility::getLastUpdated(LONG64 *aLastUpdated)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncEnter();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync *aLastUpdated = i_getLastUpdated();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return S_OK;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncHRESULT AdditionsFacility::getStatus(AdditionsFacilityStatus_T *aStatus)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncEnter();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync *aStatus = i_getStatus();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return S_OK;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncHRESULT AdditionsFacility::getType(AdditionsFacilityType_T *aType)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync LogFlowThisFuncEnter();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync *aType = i_getType();
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return S_OK;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncconst AdditionsFacility::FacilityInfo &AdditionsFacility::i_typeToInfo(AdditionsFacilityType_T aType)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync for (size_t i = 0; i < RT_ELEMENTS(s_aFacilityInfo); ++i)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync {
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync if (s_aFacilityInfo[i].mType == aType)
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync return s_aFacilityInfo[i];
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync }
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync return s_aFacilityInfo[0]; /* Return unknown type. */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncAdditionsFacilityClass_T AdditionsFacility::i_getClass() const
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync return AdditionsFacility::i_typeToInfo(mData.mType).mClass;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsynccom::Utf8Str AdditionsFacility::i_getName() const
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsync return AdditionsFacility::i_typeToInfo(mData.mType).mName;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncLONG64 AdditionsFacility::i_getLastUpdated() const
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync if (mData.mStates.size())
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync return RTTimeSpecGetMilli(&mData.mStates.front().mTimestamp);
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync AssertMsgFailed(("Unknown timestamp of facility!\n"));
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync return 0; /* Should never happen! */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncAdditionsFacilityStatus_T AdditionsFacility::i_getStatus() const
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync if (mData.mStates.size())
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync return mData.mStates.back().mStatus;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync AssertMsgFailed(("Unknown status of facility!\n"));
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync return AdditionsFacilityStatus_Unknown; /* Should never happen! */
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncAdditionsFacilityType_T AdditionsFacility::i_getType() const
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync return mData.mType;
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync/**
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync * Method used by IGuest::facilityUpdate to make updates.
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync */
99ed66b1a390b4f20a1a921c6f8b4d3d2d251adbvboxsyncvoid AdditionsFacility::i_update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync{
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync FacilityState state;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync state.mStatus = a_enmStatus;
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync state.mTimestamp = *a_pTimeSpecTS;
db4e05173041f696b1362c454bbf7e3a41fbe955vboxsync NOREF(a_fFlags);
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync mData.mStates.push_back(state);
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync if (mData.mStates.size() > 10) /* Only keep the last 10 states. */
2b2d2111baf3a01b7144b5b3ed0b19007bf08a50vboxsync mData.mStates.erase(mData.mStates.begin());
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync}
68e0b366071a6dd88182866e8852ec5ec90a8b66vboxsync