VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/GuestImpl.cpp@ 35753

Last change on this file since 35753 was 35638, checked in by vboxsync, 14 years ago

Main. QT/FE: fix long standing COM issue

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.3 KB
Line 
1/* $Id: GuestImpl.cpp 35638 2011-01-19 19:10:49Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation: Guest
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "GuestImpl.h"
19
20#include "Global.h"
21#include "ConsoleImpl.h"
22#include "ProgressImpl.h"
23#include "VMMDev.h"
24
25#include "AutoCaller.h"
26#include "Logging.h"
27
28#include <VBox/VMMDev.h>
29#ifdef VBOX_WITH_GUEST_CONTROL
30# include <VBox/com/array.h>
31# include <VBox/com/ErrorInfo.h>
32#endif
33#include <iprt/cpp/utils.h>
34#include <VBox/vmm/pgm.h>
35
36// defines
37/////////////////////////////////////////////////////////////////////////////
38
39// constructor / destructor
40/////////////////////////////////////////////////////////////////////////////
41
42DEFINE_EMPTY_CTOR_DTOR (Guest)
43
44HRESULT Guest::FinalConstruct()
45{
46 return BaseFinalConstruct();
47}
48
49void Guest::FinalRelease()
50{
51 uninit ();
52 BaseFinalRelease();
53}
54
55// public methods only for internal purposes
56/////////////////////////////////////////////////////////////////////////////
57
58/**
59 * Initializes the guest object.
60 */
61HRESULT Guest::init(Console *aParent)
62{
63 LogFlowThisFunc(("aParent=%p\n", aParent));
64
65 ComAssertRet(aParent, E_INVALIDARG);
66
67 /* Enclose the state transition NotReady->InInit->Ready */
68 AutoInitSpan autoInitSpan(this);
69 AssertReturn(autoInitSpan.isOk(), E_FAIL);
70
71 unconst(mParent) = aParent;
72
73 /* Confirm a successful initialization when it's the case */
74 autoInitSpan.setSucceeded();
75
76 ULONG aMemoryBalloonSize;
77 HRESULT ret = mParent->machine()->COMGETTER(MemoryBalloonSize)(&aMemoryBalloonSize);
78 if (ret == S_OK)
79 mMemoryBalloonSize = aMemoryBalloonSize;
80 else
81 mMemoryBalloonSize = 0; /* Default is no ballooning */
82
83 BOOL fPageFusionEnabled;
84 ret = mParent->machine()->COMGETTER(PageFusionEnabled)(&fPageFusionEnabled);
85 if (ret == S_OK)
86 mfPageFusionEnabled = fPageFusionEnabled;
87 else
88 mfPageFusionEnabled = false; /* Default is no page fusion*/
89
90 mStatUpdateInterval = 0; /* Default is not to report guest statistics at all */
91
92 /* Clear statistics. */
93 for (unsigned i = 0 ; i < GUESTSTATTYPE_MAX; i++)
94 mCurrentGuestStat[i] = 0;
95
96#ifdef VBOX_WITH_GUEST_CONTROL
97 /* Init the context ID counter at 1000. */
98 mNextContextID = 1000;
99#endif
100
101 return S_OK;
102}
103
104/**
105 * Uninitializes the instance and sets the ready flag to FALSE.
106 * Called either from FinalRelease() or by the parent when it gets destroyed.
107 */
108void Guest::uninit()
109{
110 LogFlowThisFunc(("\n"));
111
112#ifdef VBOX_WITH_GUEST_CONTROL
113 /* Scope write lock as much as possible. */
114 {
115 /*
116 * Cleanup must be done *before* AutoUninitSpan to cancel all
117 * all outstanding waits in API functions (which hold AutoCaller
118 * ref counts).
119 */
120 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
121
122 /* Clean up callback data. */
123 CallbackMapIter it;
124 for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++)
125 destroyCtrlCallbackContext(it);
126
127 /* Clear process map. */
128 mGuestProcessMap.clear();
129 }
130#endif
131
132 /* Enclose the state transition Ready->InUninit->NotReady */
133 AutoUninitSpan autoUninitSpan(this);
134 if (autoUninitSpan.uninitDone())
135 return;
136
137 unconst(mParent) = NULL;
138}
139
140// IGuest properties
141/////////////////////////////////////////////////////////////////////////////
142
143STDMETHODIMP Guest::COMGETTER(OSTypeId) (BSTR *aOSTypeId)
144{
145 CheckComArgOutPointerValid(aOSTypeId);
146
147 AutoCaller autoCaller(this);
148 if (FAILED(autoCaller.rc())) return autoCaller.rc();
149
150 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
151
152 /* Redirect the call to IMachine if no additions are installed. */
153 if (mData.mAdditionsVersion.isEmpty())
154 return mParent->machine()->COMGETTER(OSTypeId)(aOSTypeId);
155
156 mData.mOSTypeId.cloneTo(aOSTypeId);
157
158 return S_OK;
159}
160
161STDMETHODIMP Guest::COMGETTER(AdditionsRunLevel) (AdditionsRunLevelType_T *aRunLevel)
162{
163 AutoCaller autoCaller(this);
164 if (FAILED(autoCaller.rc())) return autoCaller.rc();
165
166 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
167
168 *aRunLevel = mData.mAdditionsRunLevel;
169
170 return S_OK;
171}
172
173STDMETHODIMP Guest::COMGETTER(AdditionsVersion) (BSTR *aAdditionsVersion)
174{
175 CheckComArgOutPointerValid(aAdditionsVersion);
176
177 AutoCaller autoCaller(this);
178 if (FAILED(autoCaller.rc())) return autoCaller.rc();
179
180 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
181
182 HRESULT hr = S_OK;
183 if ( mData.mAdditionsVersion.isEmpty()
184 /* Only try alternative way if GA are active! */
185 && mData.mAdditionsRunLevel > AdditionsRunLevelType_None)
186 {
187 /*
188 * If we got back an empty string from GetAdditionsVersion() we either
189 * really don't have the Guest Additions version yet or the guest is running
190 * older Guest Additions (< 3.2.0) which don't provide VMMDevReq_ReportGuestInfo2,
191 * so get the version + revision from the (hopefully) provided guest properties
192 * instead.
193 */
194 Bstr addVersion;
195 LONG64 u64Timestamp;
196 Bstr flags;
197 hr = mParent->machine()->GetGuestProperty(Bstr("/VirtualBox/GuestAdd/Version").raw(),
198 addVersion.asOutParam(), &u64Timestamp, flags.asOutParam());
199 if (hr == S_OK)
200 {
201 Bstr addRevision;
202 hr = mParent->machine()->GetGuestProperty(Bstr("/VirtualBox/GuestAdd/Revision").raw(),
203 addRevision.asOutParam(), &u64Timestamp, flags.asOutParam());
204 if ( hr == S_OK
205 && !addVersion.isEmpty()
206 && !addRevision.isEmpty())
207 {
208 /* Some Guest Additions versions had interchanged version + revision values,
209 * so check if the version value at least has a dot to identify it and change
210 * both values to reflect the right content. */
211 if (!Utf8Str(addVersion).contains("."))
212 {
213 Bstr addTemp = addVersion;
214 addVersion = addRevision;
215 addRevision = addTemp;
216 }
217
218 Bstr additionsVersion = BstrFmt("%ls r%ls",
219 addVersion.raw(), addRevision.raw());
220 additionsVersion.cloneTo(aAdditionsVersion);
221 }
222 /** @todo r=bird: else: Should not return failure! */
223 }
224 else
225 {
226 /* If getting the version + revision above fails or they simply aren't there
227 * because of *really* old Guest Additions we only can report the interface
228 * version to at least have something. */
229 mData.mInterfaceVersion.cloneTo(aAdditionsVersion);
230 /** @todo r=bird: hr is still indicating failure! */
231 }
232 }
233 else
234 mData.mAdditionsVersion.cloneTo(aAdditionsVersion);
235
236 return hr;
237}
238
239STDMETHODIMP Guest::COMGETTER(SupportsSeamless) (BOOL *aSupportsSeamless)
240{
241 CheckComArgOutPointerValid(aSupportsSeamless);
242
243 AutoCaller autoCaller(this);
244 if (FAILED(autoCaller.rc())) return autoCaller.rc();
245
246 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
247
248 *aSupportsSeamless = mData.mSupportsSeamless;
249
250 return S_OK;
251}
252
253STDMETHODIMP Guest::COMGETTER(SupportsGraphics) (BOOL *aSupportsGraphics)
254{
255 CheckComArgOutPointerValid(aSupportsGraphics);
256
257 AutoCaller autoCaller(this);
258 if (FAILED(autoCaller.rc())) return autoCaller.rc();
259
260 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
261
262 *aSupportsGraphics = mData.mSupportsGraphics;
263
264 return S_OK;
265}
266
267BOOL Guest::isPageFusionEnabled()
268{
269 AutoCaller autoCaller(this);
270 if (FAILED(autoCaller.rc())) return false;
271
272 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
273
274 return mfPageFusionEnabled;
275}
276
277STDMETHODIMP Guest::COMGETTER(MemoryBalloonSize) (ULONG *aMemoryBalloonSize)
278{
279 CheckComArgOutPointerValid(aMemoryBalloonSize);
280
281 AutoCaller autoCaller(this);
282 if (FAILED(autoCaller.rc())) return autoCaller.rc();
283
284 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
285
286 *aMemoryBalloonSize = mMemoryBalloonSize;
287
288 return S_OK;
289}
290
291STDMETHODIMP Guest::COMSETTER(MemoryBalloonSize) (ULONG aMemoryBalloonSize)
292{
293 AutoCaller autoCaller(this);
294 if (FAILED(autoCaller.rc())) return autoCaller.rc();
295
296 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
297
298 /* We must be 100% sure that IMachine::COMSETTER(MemoryBalloonSize)
299 * does not call us back in any way! */
300 HRESULT ret = mParent->machine()->COMSETTER(MemoryBalloonSize)(aMemoryBalloonSize);
301 if (ret == S_OK)
302 {
303 mMemoryBalloonSize = aMemoryBalloonSize;
304 /* forward the information to the VMM device */
305 VMMDev *pVMMDev = mParent->getVMMDev();
306 /* MUST release all locks before calling VMM device as its critsect
307 * has higher lock order than anything in Main. */
308 alock.release();
309 if (pVMMDev)
310 {
311 PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
312 if (pVMMDevPort)
313 pVMMDevPort->pfnSetMemoryBalloon(pVMMDevPort, aMemoryBalloonSize);
314 }
315 }
316
317 return ret;
318}
319
320STDMETHODIMP Guest::COMGETTER(StatisticsUpdateInterval)(ULONG *aUpdateInterval)
321{
322 CheckComArgOutPointerValid(aUpdateInterval);
323
324 AutoCaller autoCaller(this);
325 if (FAILED(autoCaller.rc())) return autoCaller.rc();
326
327 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
328
329 *aUpdateInterval = mStatUpdateInterval;
330 return S_OK;
331}
332
333STDMETHODIMP Guest::COMSETTER(StatisticsUpdateInterval)(ULONG aUpdateInterval)
334{
335 AutoCaller autoCaller(this);
336 if (FAILED(autoCaller.rc())) return autoCaller.rc();
337
338 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
339
340 mStatUpdateInterval = aUpdateInterval;
341 /* forward the information to the VMM device */
342 VMMDev *pVMMDev = mParent->getVMMDev();
343 /* MUST release all locks before calling VMM device as its critsect
344 * has higher lock order than anything in Main. */
345 alock.release();
346 if (pVMMDev)
347 {
348 PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
349 if (pVMMDevPort)
350 pVMMDevPort->pfnSetStatisticsInterval(pVMMDevPort, aUpdateInterval);
351 }
352
353 return S_OK;
354}
355
356STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle,
357 ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared,
358 ULONG *aMemCache, ULONG *aPageTotal,
359 ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal)
360{
361 CheckComArgOutPointerValid(aCpuUser);
362 CheckComArgOutPointerValid(aCpuKernel);
363 CheckComArgOutPointerValid(aCpuIdle);
364 CheckComArgOutPointerValid(aMemTotal);
365 CheckComArgOutPointerValid(aMemFree);
366 CheckComArgOutPointerValid(aMemBalloon);
367 CheckComArgOutPointerValid(aMemShared);
368 CheckComArgOutPointerValid(aMemCache);
369 CheckComArgOutPointerValid(aPageTotal);
370 CheckComArgOutPointerValid(aMemAllocTotal);
371 CheckComArgOutPointerValid(aMemFreeTotal);
372 CheckComArgOutPointerValid(aMemBalloonTotal);
373 CheckComArgOutPointerValid(aMemSharedTotal);
374
375 AutoCaller autoCaller(this);
376 if (FAILED(autoCaller.rc())) return autoCaller.rc();
377
378 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
379
380 *aCpuUser = mCurrentGuestStat[GUESTSTATTYPE_CPUUSER];
381 *aCpuKernel = mCurrentGuestStat[GUESTSTATTYPE_CPUKERNEL];
382 *aCpuIdle = mCurrentGuestStat[GUESTSTATTYPE_CPUIDLE];
383 *aMemTotal = mCurrentGuestStat[GUESTSTATTYPE_MEMTOTAL] * (_4K/_1K); /* page (4K) -> 1KB units */
384 *aMemFree = mCurrentGuestStat[GUESTSTATTYPE_MEMFREE] * (_4K/_1K); /* page (4K) -> 1KB units */
385 *aMemBalloon = mCurrentGuestStat[GUESTSTATTYPE_MEMBALLOON] * (_4K/_1K); /* page (4K) -> 1KB units */
386 *aMemCache = mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K); /* page (4K) -> 1KB units */
387 *aPageTotal = mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K); /* page (4K) -> 1KB units */
388
389 /* MUST release all locks before calling any PGM statistics queries,
390 * as they are executed by EMT and that might deadlock us by VMM device
391 * activity which waits for the Guest object lock. */
392 alock.release();
393 Console::SafeVMPtr pVM (mParent);
394 if (pVM.isOk())
395 {
396 uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
397 *aMemFreeTotal = 0;
398 int rc = PGMR3QueryVMMMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
399 AssertRC(rc);
400 if (rc == VINF_SUCCESS)
401 {
402 *aMemAllocTotal = (ULONG)(uAllocTotal / _1K); /* bytes -> KB */
403 *aMemFreeTotal = (ULONG)(uFreeTotal / _1K);
404 *aMemBalloonTotal = (ULONG)(uBalloonedTotal / _1K);
405 *aMemSharedTotal = (ULONG)(uSharedTotal / _1K);
406 }
407
408 /* Query the missing per-VM memory statistics. */
409 *aMemShared = 0;
410 uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem;
411 rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem);
412 if (rc == VINF_SUCCESS)
413 {
414 *aMemShared = (ULONG)(uSharedMem / _1K);
415 }
416 }
417 else
418 {
419 *aMemFreeTotal = 0;
420 *aMemShared = 0;
421 }
422
423 return S_OK;
424}
425
426HRESULT Guest::setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal)
427{
428 AutoCaller autoCaller(this);
429 if (FAILED(autoCaller.rc())) return autoCaller.rc();
430
431 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
432
433 if (enmType >= GUESTSTATTYPE_MAX)
434 return E_INVALIDARG;
435
436 mCurrentGuestStat[enmType] = aVal;
437 return S_OK;
438}
439
440STDMETHODIMP Guest::GetAdditionsStatus(AdditionsRunLevelType_T aLevel, BOOL *aActive)
441{
442 AutoCaller autoCaller(this);
443 if (FAILED(autoCaller.rc())) return autoCaller.rc();
444
445 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
446
447 HRESULT rc = S_OK;
448 switch (aLevel)
449 {
450 case AdditionsRunLevelType_System:
451 *aActive = (mData.mAdditionsRunLevel > AdditionsRunLevelType_None);
452 break;
453
454 case AdditionsRunLevelType_Userland:
455 *aActive = (mData.mAdditionsRunLevel >= AdditionsRunLevelType_Userland);
456 break;
457
458 case AdditionsRunLevelType_Desktop:
459 *aActive = (mData.mAdditionsRunLevel >= AdditionsRunLevelType_Desktop);
460 break;
461
462 default:
463 rc = setError(VBOX_E_NOT_SUPPORTED,
464 tr("Invalid status level defined: %u"), aLevel);
465 break;
466 }
467
468 return rc;
469}
470
471STDMETHODIMP Guest::SetCredentials(IN_BSTR aUserName, IN_BSTR aPassword,
472 IN_BSTR aDomain, BOOL aAllowInteractiveLogon)
473{
474 AutoCaller autoCaller(this);
475 if (FAILED(autoCaller.rc())) return autoCaller.rc();
476
477 /* forward the information to the VMM device */
478 VMMDev *pVMMDev = mParent->getVMMDev();
479 if (pVMMDev)
480 {
481 PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
482 if (pVMMDevPort)
483 {
484 uint32_t u32Flags = VMMDEV_SETCREDENTIALS_GUESTLOGON;
485 if (!aAllowInteractiveLogon)
486 u32Flags = VMMDEV_SETCREDENTIALS_NOLOCALLOGON;
487
488 pVMMDevPort->pfnSetCredentials(pVMMDevPort,
489 Utf8Str(aUserName).c_str(),
490 Utf8Str(aPassword).c_str(),
491 Utf8Str(aDomain).c_str(),
492 u32Flags);
493 return S_OK;
494 }
495 }
496
497 return setError(VBOX_E_VM_ERROR,
498 tr("VMM device is not available (is the VM running?)"));
499}
500
501// public methods only for internal purposes
502/////////////////////////////////////////////////////////////////////////////
503
504/**
505 * Sets the general Guest Additions information like
506 * API (interface) version and OS type. Gets called by
507 * vmmdevUpdateGuestInfo.
508 *
509 * @param aInterfaceVersion
510 * @param aOsType
511 */
512void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
513{
514 AutoCaller autoCaller(this);
515 AssertComRCReturnVoid(autoCaller.rc());
516
517 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
518
519 /*
520 * Note: The Guest Additions API (interface) version is deprecated
521 * and will not be used anymore! We might need it to at least report
522 * something as version number if *really* ancient Guest Additions are
523 * installed (without the guest version + revision properties having set).
524 */
525 mData.mInterfaceVersion = aInterfaceVersion;
526
527 /*
528 * Older Additions rely on the Additions API version whether they
529 * are assumed to be active or not. Since newer Additions do report
530 * the Additions version *before* calling this function (by calling
531 * VMMDevReportGuestInfo2, VMMDevReportGuestStatus, VMMDevReportGuestInfo,
532 * in that order) we can tell apart old and new Additions here. Old
533 * Additions never would set VMMDevReportGuestInfo2 (which set mData.mAdditionsVersion)
534 * so they just rely on the aInterfaceVersion string (which gets set by
535 * VMMDevReportGuestInfo).
536 *
537 * So only mark the Additions as being active (run level = system) when we
538 * don't have the Additions version set.
539 */
540 if (mData.mAdditionsVersion.isEmpty())
541 {
542 if (aInterfaceVersion.isEmpty())
543 mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
544 else
545 mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
546 }
547
548 /*
549 * Older Additions didn't have this finer grained capability bit,
550 * so enable it by default. Newer Additions will not enable this here
551 * and use the setSupportedFeatures function instead.
552 */
553 mData.mSupportsGraphics = mData.mAdditionsRunLevel > AdditionsRunLevelType_None;
554
555 /*
556 * Note! There is a race going on between setting mAdditionsRunLevel and
557 * mSupportsGraphics here and disabling/enabling it later according to
558 * its real status when using new(er) Guest Additions.
559 */
560 mData.mOSTypeId = Global::OSTypeId (aOsType);
561}
562
563/**
564 * Sets the Guest Additions version information details.
565 * Gets called by vmmdevUpdateGuestInfo2.
566 *
567 * @param aAdditionsVersion
568 * @param aVersionName
569 */
570void Guest::setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision)
571{
572 AutoCaller autoCaller(this);
573 AssertComRCReturnVoid(autoCaller.rc());
574
575 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
576
577 if (!aVersionName.isEmpty())
578 /*
579 * aVersionName could be "x.y.z_BETA1_FOOBAR", so append revision manually to
580 * become "x.y.z_BETA1_FOOBAR r12345".
581 */
582 mData.mAdditionsVersion = BstrFmt("%ls r%ls", aVersionName.raw(), aRevision.raw());
583 else /* aAdditionsVersion is in x.y.zr12345 format. */
584 mData.mAdditionsVersion = aAdditionsVersion;
585}
586
587/**
588 * Sets the status of a certain Guest Additions facility.
589 * Gets called by vmmdevUpdateGuestStatus.
590 *
591 * @param Facility
592 * @param Status
593 * @param ulFlags
594 */
595void Guest::setAdditionsStatus(VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent Status, ULONG ulFlags)
596{
597 AutoCaller autoCaller(this);
598 AssertComRCReturnVoid(autoCaller.rc());
599
600 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
601
602 uint32_t uCurFacility = Facility + (Status == VBoxGuestStatusCurrent_Active ? 0 : -1);
603
604 /* First check for disabled status. */
605 if ( Facility < VBoxGuestStatusFacility_VBoxGuestDriver
606 || ( Facility == VBoxGuestStatusFacility_All
607 && ( Status == VBoxGuestStatusCurrent_Inactive
608 || Status == VBoxGuestStatusCurrent_Disabled
609 )
610 )
611 )
612 {
613 mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
614 }
615 else if (uCurFacility >= VBoxGuestStatusFacility_VBoxTray)
616 {
617 mData.mAdditionsRunLevel = AdditionsRunLevelType_Desktop;
618 }
619 else if (uCurFacility >= VBoxGuestStatusFacility_VBoxService)
620 {
621 mData.mAdditionsRunLevel = AdditionsRunLevelType_Userland;
622 }
623 else if (uCurFacility >= VBoxGuestStatusFacility_VBoxGuestDriver)
624 {
625 mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
626 }
627 else /* Should never happen! */
628 AssertMsgFailed(("Invalid facility status/run level detected! uCurFacility=%ld\n", uCurFacility));
629}
630
631/**
632 * Sets the supported features (and whether they are active or not).
633 *
634 * @param fCaps Guest capability bit mask (VMMDEV_GUEST_SUPPORTS_XXX).
635 * @param fActive No idea what this is supposed to be, it's always 0 and
636 * not references by this method.
637 */
638void Guest::setSupportedFeatures(uint32_t fCaps, uint32_t fActive)
639{
640 AutoCaller autoCaller(this);
641 AssertComRCReturnVoid(autoCaller.rc());
642
643 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
644
645 mData.mSupportsSeamless = (fCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS);
646 /** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */
647 mData.mSupportsGraphics = (fCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS);
648}
649/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette