VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: AdditionsFacilityImpl.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Additions facility class.
4 */
5
6/*
7 * Copyright (C) 2014-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define LOG_GROUP LOG_GROUP_MAIN_ADDITIONSFACILITY
29#include "LoggingNew.h"
30
31#include "AdditionsFacilityImpl.h"
32#include "Global.h"
33
34#include "AutoCaller.h"
35
36
37/**
38 * @note We ASSUME that unknown is the first entry!
39 */
40/* static */
41const AdditionsFacility::FacilityInfo AdditionsFacility::s_aFacilityInfo[8] =
42{
43 { "Unknown", AdditionsFacilityType_None, AdditionsFacilityClass_None },
44 { "VirtualBox Base Driver", AdditionsFacilityType_VBoxGuestDriver, AdditionsFacilityClass_Driver },
45 { "Auto Logon", AdditionsFacilityType_AutoLogon, AdditionsFacilityClass_Feature },
46 { "VirtualBox System Service", AdditionsFacilityType_VBoxService, AdditionsFacilityClass_Service },
47 { "VirtualBox Desktop Integration", AdditionsFacilityType_VBoxTrayClient, AdditionsFacilityClass_Program },
48 { "Seamless Mode", AdditionsFacilityType_Seamless, AdditionsFacilityClass_Feature },
49 { "Graphics Mode", AdditionsFacilityType_Graphics, AdditionsFacilityClass_Feature },
50 { "Guest Monitor Attach", AdditionsFacilityType_MonitorAttach, AdditionsFacilityClass_Feature },
51};
52
53// constructor / destructor
54/////////////////////////////////////////////////////////////////////////////
55
56DEFINE_EMPTY_CTOR_DTOR(AdditionsFacility)
57
58HRESULT AdditionsFacility::FinalConstruct()
59{
60 LogFlowThisFunc(("\n"));
61 return BaseFinalConstruct();
62}
63
64void AdditionsFacility::FinalRelease()
65{
66 LogFlowThisFuncEnter();
67 uninit();
68 BaseFinalRelease();
69 LogFlowThisFuncLeave();
70}
71
72// public initializer/uninitializer for internal purposes only
73/////////////////////////////////////////////////////////////////////////////
74
75HRESULT AdditionsFacility::init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
76 uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
77{
78 RT_NOREF(a_pParent); /** @todo r=bird: For locking perhaps? */
79 LogFlowThisFunc(("a_pParent=%p\n", a_pParent));
80
81 /* Enclose the state transition NotReady->InInit->Ready. */
82 AutoInitSpan autoInitSpan(this);
83 AssertReturn(autoInitSpan.isOk(), E_FAIL);
84
85 /* Initialize the data: */
86 mData.mType = a_enmFacility;
87 mData.mStatus = a_enmStatus;
88 mData.mTimestamp = *a_pTimeSpecTS;
89 mData.mfFlags = a_fFlags;
90 mData.midxInfo = 0;
91 for (size_t i = 0; i < RT_ELEMENTS(s_aFacilityInfo); ++i)
92 if (s_aFacilityInfo[i].mType == a_enmFacility)
93 {
94 mData.midxInfo = i;
95 break;
96 }
97
98 /* Confirm a successful initialization when it's the case. */
99 autoInitSpan.setSucceeded();
100
101 return S_OK;
102}
103
104/**
105 * Uninitializes the instance.
106 *
107 * Called from FinalRelease().
108 */
109void AdditionsFacility::uninit()
110{
111 LogFlowThisFunc(("\n"));
112
113 /* Enclose the state transition Ready->InUninit->NotReady. */
114 AutoUninitSpan autoUninitSpan(this);
115 if (autoUninitSpan.uninitDone())
116 return;
117}
118
119HRESULT AdditionsFacility::getClassType(AdditionsFacilityClass_T *aClassType)
120{
121 LogFlowThisFuncEnter();
122
123 /* midxInfo is static, so no need to lock anything. */
124 size_t idxInfo = mData.midxInfo;
125 AssertStmt(idxInfo < RT_ELEMENTS(s_aFacilityInfo), idxInfo = 0);
126 *aClassType = s_aFacilityInfo[idxInfo].mClass;
127 return S_OK;
128}
129
130HRESULT AdditionsFacility::getName(com::Utf8Str &aName)
131{
132 LogFlowThisFuncEnter();
133
134 /* midxInfo is static, so no need to lock anything. */
135 size_t idxInfo = mData.midxInfo;
136 AssertStmt(idxInfo < RT_ELEMENTS(s_aFacilityInfo), idxInfo = 0);
137 int vrc = aName.assignNoThrow(s_aFacilityInfo[idxInfo].mName);
138 return RT_SUCCESS(vrc) ? S_OK : E_OUTOFMEMORY;
139}
140
141HRESULT AdditionsFacility::getLastUpdated(LONG64 *aLastUpdated)
142{
143 LogFlowThisFuncEnter();
144
145 /** @todo r=bird: Should take parent (Guest) lock here, see i_update(). */
146 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
147 *aLastUpdated = RTTimeSpecGetMilli(&mData.mTimestamp);
148 return S_OK;
149}
150
151HRESULT AdditionsFacility::getStatus(AdditionsFacilityStatus_T *aStatus)
152{
153 LogFlowThisFuncEnter();
154
155 /** @todo r=bird: Should take parent (Guest) lock here, see i_update(). */
156 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
157 *aStatus = mData.mStatus;
158 return S_OK;
159}
160
161HRESULT AdditionsFacility::getType(AdditionsFacilityType_T *aType)
162{
163 LogFlowThisFuncEnter();
164
165 /* mType is static, so no need to lock anything. */
166 *aType = mData.mType;
167 return S_OK;
168}
169
170#if 0 /* unused */
171
172AdditionsFacilityType_T AdditionsFacility::i_getType() const
173{
174 return mData.mType;
175}
176
177AdditionsFacilityClass_T AdditionsFacility::i_getClass() const
178{
179 size_t idxInfo = mData.midxInfo;
180 AssertStmt(idxInfo < RT_ELEMENTS(s_aFacilityInfo), idxInfo = 0);
181 return s_aFacilityInfo[idxInfo].mClass;
182}
183
184const char *AdditionsFacility::i_getName() const
185{
186 size_t idxInfo = mData.midxInfo;
187 AssertStmt(idxInfo < RT_ELEMENTS(s_aFacilityInfo), idxInfo = 0);
188 return s_aFacilityInfo[idxInfo].mName;
189}
190
191#endif /* unused */
192
193/**
194 * @note Caller should read lock the Guest object.
195 */
196LONG64 AdditionsFacility::i_getLastUpdated() const
197{
198 return RTTimeSpecGetMilli(&mData.mTimestamp);
199}
200
201/**
202 * @note Caller should read lock the Guest object.
203 */
204AdditionsFacilityStatus_T AdditionsFacility::i_getStatus() const
205{
206 return mData.mStatus;
207}
208
209/**
210 * Method used by IGuest::facilityUpdate to make updates.
211 *
212 * @returns change indicator.
213 *
214 * @todo r=bird: Locking here isn't quite sane. While updating is serialized
215 * by the caller holding down the Guest object lock, this code doesn't
216 * serialize with this object. So, the read locking done in the getter
217 * methods is utterly pointless. OTOH, the getter methods only get
218 * single values, so there isn't really much to be worried about here,
219 * especially with 32-bit hosts no longer being supported.
220 */
221bool AdditionsFacility::i_update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
222{
223 bool const fChanged = mData.mStatus != a_enmStatus;
224
225 mData.mTimestamp = *a_pTimeSpecTS;
226 mData.mStatus = a_enmStatus;
227 mData.mfFlags = a_fFlags;
228
229 return fChanged;
230}
231
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use