VirtualBox

source: vbox/trunk/src/VBox/Main/GuestImpl.cpp@ 35263

Last change on this file since 35263 was 35170, checked in by vboxsync, 13 years ago

Main: Moved Guest Control code to own file for better separation.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use