VirtualBox

source: vbox/trunk/src/VBox/Main/include/ConsoleImpl.h@ 55422

Last change on this file since 55422 was 55214, checked in by vboxsync, 10 years ago

Main/Console+Machine+Session+Snapshot: move the save state and snapshot related methods from IConsole to IMachine, with lots of unavoidable code restructuring and cleanup. Also define two new machine states (so that the "Saving" one is specifically for saving state now) which requires more changes everywhere
Frontends: necessary adjustments
doc/SDK: document the changes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 42.5 KB
Line 
1/* $Id: ConsoleImpl.h 55214 2015-04-13 15:53:01Z vboxsync $ */
2/** @file
3 * VBox Console COM Class definition
4 */
5
6/*
7 * Copyright (C) 2005-2015 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#ifndef ____H_CONSOLEIMPL
19#define ____H_CONSOLEIMPL
20
21#include "VirtualBoxBase.h"
22#include "VBox/com/array.h"
23#include "EventImpl.h"
24#include "SecretKeyStore.h"
25#include "ConsoleWrap.h"
26
27class Guest;
28class Keyboard;
29class Mouse;
30class Display;
31class MachineDebugger;
32class TeleporterStateSrc;
33class OUSBDevice;
34class RemoteUSBDevice;
35class SharedFolder;
36class VRDEServerInfo;
37class EmulatedUSB;
38#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
39class AudioVRDE;
40#else
41class AudioSniffer;
42#endif
43class AudioVRDE;
44class Nvram;
45#ifdef VBOX_WITH_USB_CARDREADER
46class UsbCardReader;
47#endif
48class ConsoleVRDPServer;
49class VMMDev;
50class Progress;
51class BusAssignmentManager;
52COM_STRUCT_OR_CLASS(IEventListener);
53#ifdef VBOX_WITH_EXTPACK
54class ExtPackManager;
55#endif
56class VMMDevMouseInterface;
57class DisplayMouseInterface;
58
59#include <iprt/uuid.h>
60#include <iprt/memsafer.h>
61#include <VBox/RemoteDesktop/VRDE.h>
62#include <VBox/vmm/pdmdrv.h>
63#ifdef VBOX_WITH_GUEST_PROPS
64# include <VBox/HostServices/GuestPropertySvc.h> /* For the property notification callback */
65#endif
66
67#ifdef RT_OS_WINDOWS
68# include "../src-server/win/VBoxComEvents.h"
69#endif
70
71struct VUSBIRHCONFIG;
72typedef struct VUSBIRHCONFIG *PVUSBIRHCONFIG;
73
74#include <list>
75#include <vector>
76
77// defines
78///////////////////////////////////////////////////////////////////////////////
79
80/**
81 * Checks the availability of the underlying VM device driver corresponding
82 * to the COM interface (IKeyboard, IMouse, IDisplay, etc.). When the driver is
83 * not available (NULL), sets error info and returns returns E_ACCESSDENIED.
84 * The translatable error message is defined in null context.
85 *
86 * Intended to used only within Console children (i.e. Keyboard, Mouse,
87 * Display, etc.).
88 *
89 * @param drv driver pointer to check (compare it with NULL)
90 */
91#define CHECK_CONSOLE_DRV(drv) \
92 do { \
93 if (!(drv)) \
94 return setError(E_ACCESSDENIED, tr("The console is not powered up")); \
95 } while (0)
96
97// Console
98///////////////////////////////////////////////////////////////////////////////
99
100class ConsoleMouseInterface
101{
102public:
103 virtual VMMDevMouseInterface *i_getVMMDevMouseInterface(){return NULL;}
104 virtual DisplayMouseInterface *i_getDisplayMouseInterface(){return NULL;}
105 virtual void i_onMouseCapabilityChange(BOOL supportsAbsolute,
106 BOOL supportsRelative,
107 BOOL supportsMT,
108 BOOL needsHostCursor){NOREF(supportsAbsolute); NOREF(supportsRelative); NOREF(supportsMT); NOREF(needsHostCursor);}
109};
110
111/** IConsole implementation class */
112class ATL_NO_VTABLE Console :
113 public ConsoleWrap,
114 public ConsoleMouseInterface
115{
116
117public:
118
119 DECLARE_EMPTY_CTOR_DTOR(Console)
120
121 HRESULT FinalConstruct();
122 void FinalRelease();
123
124 // public initializers/uninitializers for internal purposes only
125 HRESULT init(IMachine *aMachine, IInternalMachineControl *aControl, LockType_T aLockType);
126 void uninit();
127
128
129 // public methods for internal purposes only
130
131 /*
132 * Note: the following methods do not increase refcount. intended to be
133 * called only by the VM execution thread.
134 */
135
136 Guest *i_getGuest() const { return mGuest; }
137 Keyboard *i_getKeyboard() const { return mKeyboard; }
138 Mouse *i_getMouse() const { return mMouse; }
139 Display *i_getDisplay() const { return mDisplay; }
140 MachineDebugger *i_getMachineDebugger() const { return mDebugger; }
141#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
142 AudioVRDE *i_getAudioVRDE() const { return mAudioVRDE; }
143#else
144 AudioSniffer *i_getAudioSniffer() const { return mAudioSniffer; }
145#endif
146
147 const ComPtr<IMachine> &i_machine() const { return mMachine; }
148
149 bool i_useHostClipboard() { return mfUseHostClipboard; }
150
151 /** Method is called only from ConsoleVRDPServer */
152 IVRDEServer *i_getVRDEServer() const { return mVRDEServer; }
153
154 ConsoleVRDPServer *i_consoleVRDPServer() const { return mConsoleVRDPServer; }
155
156 HRESULT i_updateMachineState(MachineState_T aMachineState);
157 HRESULT i_getNominalState(MachineState_T &aNominalState);
158
159 // events from IInternalSessionControl
160 HRESULT i_onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL changeAdapter);
161 HRESULT i_onSerialPortChange(ISerialPort *aSerialPort);
162 HRESULT i_onParallelPortChange(IParallelPort *aParallelPort);
163 HRESULT i_onStorageControllerChange();
164 HRESULT i_onMediumChange(IMediumAttachment *aMediumAttachment, BOOL aForce);
165 HRESULT i_onCPUChange(ULONG aCPU, BOOL aRemove);
166 HRESULT i_onCPUExecutionCapChange(ULONG aExecutionCap);
167 HRESULT i_onClipboardModeChange(ClipboardMode_T aClipboardMode);
168 HRESULT i_onDnDModeChange(DnDMode_T aDnDMode);
169 HRESULT i_onVRDEServerChange(BOOL aRestart);
170 HRESULT i_onVideoCaptureChange();
171 HRESULT i_onUSBControllerChange();
172 HRESULT i_onSharedFolderChange(BOOL aGlobal);
173 HRESULT i_onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs,
174 const Utf8Str &aCaptureFilename);
175 HRESULT i_onUSBDeviceDetach(IN_BSTR aId, IVirtualBoxErrorInfo *aError);
176 HRESULT i_onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
177 HRESULT i_onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove, BOOL aSilent);
178 HRESULT i_onExtraDataChange(IN_BSTR aMachineId, IN_BSTR aKey, IN_BSTR aVal);
179
180 HRESULT i_getGuestProperty(const Utf8Str &aName, Utf8Str *aValue, LONG64 *aTimestamp, Utf8Str *aFlags);
181 HRESULT i_setGuestProperty(const Utf8Str &aName, const Utf8Str &aValue, const Utf8Str &aFlags);
182 HRESULT i_deleteGuestProperty(const Utf8Str &aName);
183 HRESULT i_enumerateGuestProperties(const Utf8Str &aPatterns,
184 std::vector<Utf8Str> &aNames,
185 std::vector<Utf8Str> &aValues,
186 std::vector<LONG64> &aTimestamps,
187 std::vector<Utf8Str> &aFlags);
188 HRESULT i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
189 ULONG aSourceIdx, ULONG aTargetIdx,
190 IProgress *aProgress);
191 HRESULT i_reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments);
192 int i_hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName);
193 VMMDev *i_getVMMDev() { return m_pVMMDev; }
194#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
195 AudioVRDE *i_getAudioVRDE() { return mAudioVRDE; }
196#else
197 AudioSniffer *i_getAudioSniffer() { return mAudioSniffer; }
198#endif
199
200#ifdef VBOX_WITH_EXTPACK
201 ExtPackManager *i_getExtPackManager();
202#endif
203 EventSource *i_getEventSource() { return mEventSource; }
204#ifdef VBOX_WITH_USB_CARDREADER
205 UsbCardReader *i_getUsbCardReader() { return mUsbCardReader; }
206#endif
207
208 int i_VRDPClientLogon(uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain);
209 void i_VRDPClientStatusChange(uint32_t u32ClientId, const char *pszStatus);
210 void i_VRDPClientConnect(uint32_t u32ClientId);
211 void i_VRDPClientDisconnect(uint32_t u32ClientId, uint32_t fu32Intercepted);
212 void i_VRDPInterceptAudio(uint32_t u32ClientId);
213 void i_VRDPInterceptUSB(uint32_t u32ClientId, void **ppvIntercept);
214 void i_VRDPInterceptClipboard(uint32_t u32ClientId);
215
216 void i_processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList, bool fDescExt);
217 void i_reportVmStatistics(ULONG aValidStats, ULONG aCpuUser,
218 ULONG aCpuKernel, ULONG aCpuIdle,
219 ULONG aMemTotal, ULONG aMemFree,
220 ULONG aMemBalloon, ULONG aMemShared,
221 ULONG aMemCache, ULONG aPageTotal,
222 ULONG aAllocVMM, ULONG aFreeVMM,
223 ULONG aBalloonedVMM, ULONG aSharedVMM,
224 ULONG aVmNetRx, ULONG aVmNetTx)
225 {
226 mControl->ReportVmStatistics(aValidStats, aCpuUser, aCpuKernel, aCpuIdle,
227 aMemTotal, aMemFree, aMemBalloon, aMemShared,
228 aMemCache, aPageTotal, aAllocVMM, aFreeVMM,
229 aBalloonedVMM, aSharedVMM, aVmNetRx, aVmNetTx);
230 }
231 void i_enableVMMStatistics(BOOL aEnable);
232
233 HRESULT i_pause(Reason_T aReason);
234 HRESULT i_resume(Reason_T aReason, AutoWriteLock &alock);
235 HRESULT i_saveState(Reason_T aReason, const ComPtr<IProgress> &aProgress, const Utf8Str &aStateFilePath, bool fPauseVM, bool &fLeftPaused);
236 HRESULT i_cancelSaveState();
237
238 // callback callers (partly; for some events console callbacks are notified
239 // directly from IInternalSessionControl event handlers declared above)
240 void i_onMousePointerShapeChange(bool fVisible, bool fAlpha,
241 uint32_t xHot, uint32_t yHot,
242 uint32_t width, uint32_t height,
243 const uint8_t *pu8Shape,
244 uint32_t cbShape);
245 void i_onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative,
246 BOOL supportsMT, BOOL needsHostCursor);
247 void i_onStateChange(MachineState_T aMachineState);
248 void i_onAdditionsStateChange();
249 void i_onAdditionsOutdated();
250 void i_onKeyboardLedsChange(bool fNumLock, bool fCapsLock, bool fScrollLock);
251 void i_onUSBDeviceStateChange(IUSBDevice *aDevice, bool aAttached,
252 IVirtualBoxErrorInfo *aError);
253 void i_onRuntimeError(BOOL aFatal, IN_BSTR aErrorID, IN_BSTR aMessage);
254 HRESULT i_onShowWindow(BOOL aCheck, BOOL *aCanShow, LONG64 *aWinId);
255 void i_onVRDEServerInfoChange();
256 HRESULT i_sendACPIMonitorHotPlugEvent();
257
258 static const PDMDRVREG DrvStatusReg;
259
260 static HRESULT i_setErrorStatic(HRESULT aResultCode, const char *pcsz, ...);
261 HRESULT i_setInvalidMachineStateError();
262
263 static const char *i_convertControllerTypeToDev(StorageControllerType_T enmCtrlType);
264 static HRESULT i_convertBusPortDeviceToLun(StorageBus_T enmBus, LONG port, LONG device, unsigned &uLun);
265 // Called from event listener
266 HRESULT i_onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
267 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort);
268 HRESULT i_onNATDnsChanged();
269
270 // Mouse interface
271 VMMDevMouseInterface *i_getVMMDevMouseInterface();
272 DisplayMouseInterface *i_getDisplayMouseInterface();
273
274 EmulatedUSB *i_getEmulatedUSB(void) { return mEmulatedUSB; }
275
276 /**
277 * Sets the disk encryption keys.
278 *
279 * @returns COM status code.
280 * @þaram strCfg The config for the disks.
281 *
282 * @note: One line in the config string contains all required data for one disk.
283 * The format for one disk is some sort of comma separated value using
284 * key=value pairs.
285 * There are two keys defined at the moment:
286 * - uuid: The uuid of the base image the key is for (with or without)
287 * the curly braces.
288 * - dek: The data encryption key in base64 encoding
289 */
290 HRESULT i_setDiskEncryptionKeys(const Utf8Str &strCfg);
291
292private:
293
294 // wraped IConsole properties
295 HRESULT getMachine(ComPtr<IMachine> &aMachine);
296 HRESULT getState(MachineState_T *aState);
297 HRESULT getGuest(ComPtr<IGuest> &aGuest);
298 HRESULT getKeyboard(ComPtr<IKeyboard> &aKeyboard);
299 HRESULT getMouse(ComPtr<IMouse> &aMouse);
300 HRESULT getDisplay(ComPtr<IDisplay> &aDisplay);
301 HRESULT getDebugger(ComPtr<IMachineDebugger> &aDebugger);
302 HRESULT getUSBDevices(std::vector<ComPtr<IUSBDevice> > &aUSBDevices);
303 HRESULT getRemoteUSBDevices(std::vector<ComPtr<IHostUSBDevice> > &aRemoteUSBDevices);
304 HRESULT getSharedFolders(std::vector<ComPtr<ISharedFolder> > &aSharedFolders);
305 HRESULT getVRDEServerInfo(ComPtr<IVRDEServerInfo> &aVRDEServerInfo);
306 HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
307 HRESULT getAttachedPCIDevices(std::vector<ComPtr<IPCIDeviceAttachment> > &aAttachedPCIDevices);
308 HRESULT getUseHostClipboard(BOOL *aUseHostClipboard);
309 HRESULT setUseHostClipboard(BOOL aUseHostClipboard);
310 HRESULT getEmulatedUSB(ComPtr<IEmulatedUSB> &aEmulatedUSB);
311
312 // wraped IConsole methods
313 HRESULT powerUp(ComPtr<IProgress> &aProgress);
314 HRESULT powerUpPaused(ComPtr<IProgress> &aProgress);
315 HRESULT powerDown(ComPtr<IProgress> &aProgress);
316 HRESULT reset();
317 HRESULT pause();
318 HRESULT resume();
319 HRESULT powerButton();
320 HRESULT sleepButton();
321 HRESULT getPowerButtonHandled(BOOL *aHandled);
322 HRESULT getGuestEnteredACPIMode(BOOL *aEntered);
323 HRESULT getDeviceActivity(const std::vector<DeviceType_T> &aType,
324 std::vector<DeviceActivity_T> &aActivity);
325 HRESULT attachUSBDevice(const com::Guid &aId, const com::Utf8Str &aCaptureFilename);
326 HRESULT detachUSBDevice(const com::Guid &aId,
327 ComPtr<IUSBDevice> &aDevice);
328 HRESULT findUSBDeviceByAddress(const com::Utf8Str &aName,
329 ComPtr<IUSBDevice> &aDevice);
330 HRESULT findUSBDeviceById(const com::Guid &aId,
331 ComPtr<IUSBDevice> &aDevice);
332 HRESULT createSharedFolder(const com::Utf8Str &aName,
333 const com::Utf8Str &aHostPath,
334 BOOL aWritable,
335 BOOL aAutomount);
336 HRESULT removeSharedFolder(const com::Utf8Str &aName);
337 HRESULT teleport(const com::Utf8Str &aHostname,
338 ULONG aTcpport,
339 const com::Utf8Str &aPassword,
340 ULONG aMaxDowntime,
341 ComPtr<IProgress> &aProgress);
342 HRESULT addDiskEncryptionPassword(const com::Utf8Str &aId, const com::Utf8Str &aPassword,
343 BOOL aClearOnSuspend);
344 HRESULT addDiskEncryptionPasswords(const std::vector<com::Utf8Str> &aIds, const std::vector<com::Utf8Str> &aPasswords,
345 BOOL aClearOnSuspend);
346 HRESULT removeDiskEncryptionPassword(const com::Utf8Str &aId);
347 HRESULT clearAllDiskEncryptionPasswords();
348
349 void notifyNatDnsChange(PUVM pUVM, const char *pszDevice, ULONG ulInstanceMax);
350
351 /**
352 * Base template for AutoVMCaller and SafeVMPtr. Template arguments
353 * have the same meaning as arguments of Console::addVMCaller().
354 */
355 template <bool taQuiet = false, bool taAllowNullVM = false>
356 class AutoVMCallerBase
357 {
358 public:
359 AutoVMCallerBase(Console *aThat) : mThat(aThat), mRC(E_FAIL)
360 {
361 Assert(aThat);
362 mRC = aThat->i_addVMCaller(taQuiet, taAllowNullVM);
363 }
364 ~AutoVMCallerBase()
365 {
366 doRelease();
367 }
368 /** Decreases the number of callers before the instance is destroyed. */
369 void releaseCaller()
370 {
371 Assert(SUCCEEDED(mRC));
372 doRelease();
373 }
374 /** Restores the number of callers after by #release(). #rc() must be
375 * rechecked to ensure the operation succeeded. */
376 void addYY()
377 {
378 AssertReturnVoid(!SUCCEEDED(mRC));
379 mRC = mThat->i_addVMCaller(taQuiet, taAllowNullVM);
380 }
381 /** Returns the result of Console::addVMCaller() */
382 HRESULT rc() const { return mRC; }
383 /** Shortcut to SUCCEEDED(rc()) */
384 bool isOk() const { return SUCCEEDED(mRC); }
385 protected:
386 Console *mThat;
387 void doRelease()
388 {
389 if (SUCCEEDED(mRC))
390 {
391 mThat->i_releaseVMCaller();
392 mRC = E_FAIL;
393 }
394 }
395 private:
396 HRESULT mRC; /* Whether the caller was added. */
397 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoVMCallerBase)
398 };
399
400#if 0
401 /**
402 * Helper class that protects sections of code using the mpUVM pointer by
403 * automatically calling addVMCaller() on construction and
404 * releaseVMCaller() on destruction. Intended for Console methods dealing
405 * with mpUVM. The usage pattern is:
406 * <code>
407 * AutoVMCaller autoVMCaller(this);
408 * if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
409 * ...
410 * VMR3ReqCall (mpUVM, ...
411 * </code>
412 *
413 * @note Temporarily locks the argument for writing.
414 *
415 * @sa SafeVMPtr, SafeVMPtrQuiet
416 * @obsolete Use SafeVMPtr
417 */
418 typedef AutoVMCallerBase<false, false> AutoVMCaller;
419#endif
420
421 /**
422 * Same as AutoVMCaller but doesn't set extended error info on failure.
423 *
424 * @note Temporarily locks the argument for writing.
425 * @obsolete Use SafeVMPtrQuiet
426 */
427 typedef AutoVMCallerBase<true, false> AutoVMCallerQuiet;
428
429 /**
430 * Same as AutoVMCaller but allows a null VM pointer (to trigger an error
431 * instead of assertion).
432 *
433 * @note Temporarily locks the argument for writing.
434 * @obsolete Use SafeVMPtr
435 */
436 typedef AutoVMCallerBase<false, true> AutoVMCallerWeak;
437
438 /**
439 * Same as AutoVMCaller but doesn't set extended error info on failure
440 * and allows a null VM pointer (to trigger an error instead of
441 * assertion).
442 *
443 * @note Temporarily locks the argument for writing.
444 * @obsolete Use SafeVMPtrQuiet
445 */
446 typedef AutoVMCallerBase<true, true> AutoVMCallerQuietWeak;
447
448 /**
449 * Base template for SafeVMPtr and SafeVMPtrQuiet.
450 */
451 template<bool taQuiet = false>
452 class SafeVMPtrBase : public AutoVMCallerBase<taQuiet, true>
453 {
454 typedef AutoVMCallerBase<taQuiet, true> Base;
455 public:
456 SafeVMPtrBase(Console *aThat) : Base(aThat), mRC(E_FAIL), mpUVM(NULL)
457 {
458 if (Base::isOk())
459 mRC = aThat->i_safeVMPtrRetainer(&mpUVM, taQuiet);
460 }
461 ~SafeVMPtrBase()
462 {
463 doRelease();
464 }
465 /** Direct PUVM access. */
466 PUVM rawUVM() const { return mpUVM; }
467 /** Release the handles. */
468 void release()
469 {
470 Assert(SUCCEEDED(mRC));
471 doRelease();
472 }
473
474 /** The combined result of Console::addVMCaller() and Console::safeVMPtrRetainer */
475 HRESULT rc() const { return Base::isOk()? mRC: Base::rc(); }
476 /** Shortcut to SUCCEEDED(rc()) */
477 bool isOk() const { return SUCCEEDED(mRC) && Base::isOk(); }
478
479 private:
480 void doRelease()
481 {
482 if (SUCCEEDED(mRC))
483 {
484 Base::mThat->i_safeVMPtrReleaser(&mpUVM);
485 mRC = E_FAIL;
486 }
487 Base::doRelease();
488 }
489 HRESULT mRC; /* Whether the VM ptr was retained. */
490 PUVM mpUVM;
491 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeVMPtrBase)
492 };
493
494public:
495
496 /*
497 * Helper class that safely manages the Console::mpUVM pointer
498 * by calling addVMCaller() on construction and releaseVMCaller() on
499 * destruction. Intended for Console children. The usage pattern is:
500 * <code>
501 * Console::SafeVMPtr ptrVM(mParent);
502 * if (!ptrVM.isOk())
503 * return ptrVM.rc();
504 * ...
505 * VMR3ReqCall(ptrVM.rawUVM(), ...
506 * ...
507 * printf("%p\n", ptrVM.rawUVM());
508 * </code>
509 *
510 * @note Temporarily locks the argument for writing.
511 *
512 * @sa SafeVMPtrQuiet, AutoVMCaller
513 */
514 typedef SafeVMPtrBase<false> SafeVMPtr;
515
516 /**
517 * A deviation of SafeVMPtr that doesn't set the error info on failure.
518 * Intended for pieces of code that don't need to return the VM access
519 * failure to the caller. The usage pattern is:
520 * <code>
521 * Console::SafeVMPtrQuiet pVM(mParent);
522 * if (pVM.rc())
523 * VMR3ReqCall(pVM, ...
524 * return S_OK;
525 * </code>
526 *
527 * @note Temporarily locks the argument for writing.
528 *
529 * @sa SafeVMPtr, AutoVMCaller
530 */
531 typedef SafeVMPtrBase<true> SafeVMPtrQuiet;
532
533 class SharedFolderData
534 {
535 public:
536 SharedFolderData()
537 { }
538
539 SharedFolderData(const Utf8Str &aHostPath,
540 bool aWritable,
541 bool aAutoMount)
542 : m_strHostPath(aHostPath),
543 m_fWritable(aWritable),
544 m_fAutoMount(aAutoMount)
545 { }
546
547 // copy constructor
548 SharedFolderData(const SharedFolderData& aThat)
549 : m_strHostPath(aThat.m_strHostPath),
550 m_fWritable(aThat.m_fWritable),
551 m_fAutoMount(aThat.m_fAutoMount)
552 { }
553
554 Utf8Str m_strHostPath;
555 bool m_fWritable;
556 bool m_fAutoMount;
557 };
558
559 /**
560 * Class for managing emulated USB MSDs.
561 */
562 class USBStorageDevice
563 {
564 public:
565 USBStorageDevice()
566 { }
567 /** The UUID associated with the USB device. */
568 RTUUID mUuid;
569 /** Port of the storage device. */
570 LONG iPort;
571 };
572
573 typedef std::map<Utf8Str, ComObjPtr<SharedFolder> > SharedFolderMap;
574 typedef std::map<Utf8Str, SharedFolderData> SharedFolderDataMap;
575 typedef std::map<Utf8Str, ComPtr<IMediumAttachment> > MediumAttachmentMap;
576 typedef std::list <USBStorageDevice> USBStorageDeviceList;
577
578private:
579
580 typedef std::list <ComObjPtr<OUSBDevice> > USBDeviceList;
581 typedef std::list <ComObjPtr<RemoteUSBDevice> > RemoteUSBDeviceList;
582
583 HRESULT i_addVMCaller(bool aQuiet = false, bool aAllowNullVM = false);
584 void i_releaseVMCaller();
585 HRESULT i_safeVMPtrRetainer(PUVM *a_ppUVM, bool aQuiet);
586 void i_safeVMPtrReleaser(PUVM *a_ppUVM);
587
588 HRESULT i_consoleInitReleaseLog(const ComPtr<IMachine> aMachine);
589
590 HRESULT i_powerUp(IProgress **aProgress, bool aPaused);
591 HRESULT i_powerDown(IProgress *aProgress = NULL);
592
593/* Note: FreeBSD needs this whether netflt is used or not. */
594#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
595 HRESULT i_attachToTapInterface(INetworkAdapter *networkAdapter);
596 HRESULT i_detachFromTapInterface(INetworkAdapter *networkAdapter);
597#endif
598 HRESULT i_powerDownHostInterfaces();
599
600 HRESULT i_setMachineState(MachineState_T aMachineState, bool aUpdateServer = true);
601 HRESULT i_setMachineStateLocally(MachineState_T aMachineState)
602 {
603 return i_setMachineState(aMachineState, false /* aUpdateServer */);
604 }
605
606 HRESULT i_findSharedFolder(const Utf8Str &strName,
607 ComObjPtr<SharedFolder> &aSharedFolder,
608 bool aSetError = false);
609
610 HRESULT i_fetchSharedFolders(BOOL aGlobal);
611 bool i_findOtherSharedFolder(const Utf8Str &straName,
612 SharedFolderDataMap::const_iterator &aIt);
613
614 HRESULT i_createSharedFolder(const Utf8Str &strName, const SharedFolderData &aData);
615 HRESULT i_removeSharedFolder(const Utf8Str &strName);
616
617 HRESULT i_suspendBeforeConfigChange(PUVM pUVM, AutoWriteLock *pAlock, bool *pfResume);
618 void i_resumeAfterConfigChange(PUVM pUVM);
619
620 static DECLCALLBACK(int) i_configConstructor(PUVM pUVM, PVM pVM, void *pvConsole);
621 int i_configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock);
622 int i_configCfgmOverlay(PCFGMNODE pRoot, IVirtualBox *pVirtualBox, IMachine *pMachine);
623 int i_configDumpAPISettingsTweaks(IVirtualBox *pVirtualBox, IMachine *pMachine);
624
625 int i_configGraphicsController(PCFGMNODE pDevices,
626 const GraphicsControllerType_T graphicsController,
627 BusAssignmentManager *pBusMgr,
628 const ComPtr<IMachine> &ptrMachine,
629 const ComPtr<IBIOSSettings> &ptrBiosSettings,
630 bool fHMEnabled);
631 int i_configMediumAttachment(const char *pcszDevice,
632 unsigned uInstance,
633 StorageBus_T enmBus,
634 bool fUseHostIOCache,
635 bool fBuiltinIoCache,
636 bool fSetupMerge,
637 unsigned uMergeSource,
638 unsigned uMergeTarget,
639 IMediumAttachment *pMediumAtt,
640 MachineState_T aMachineState,
641 HRESULT *phrc,
642 bool fAttachDetach,
643 bool fForceUnmount,
644 bool fHotplug,
645 PUVM pUVM,
646 DeviceType_T *paLedDevType,
647 PCFGMNODE *ppLunL0);
648 int i_configMedium(PCFGMNODE pLunL0,
649 bool fPassthrough,
650 DeviceType_T enmType,
651 bool fUseHostIOCache,
652 bool fBuiltinIoCache,
653 bool fSetupMerge,
654 unsigned uMergeSource,
655 unsigned uMergeTarget,
656 const char *pcszBwGroup,
657 bool fDiscard,
658 IMedium *pMedium,
659 MachineState_T aMachineState,
660 HRESULT *phrc);
661 int i_configMediumProperties(PCFGMNODE pCur, IMedium *pMedium, bool *pfHostIP, bool *pfEncrypted);
662 static DECLCALLBACK(int) i_reconfigureMediumAttachment(Console *pThis,
663 PUVM pUVM,
664 const char *pcszDevice,
665 unsigned uInstance,
666 StorageBus_T enmBus,
667 bool fUseHostIOCache,
668 bool fBuiltinIoCache,
669 bool fSetupMerge,
670 unsigned uMergeSource,
671 unsigned uMergeTarget,
672 IMediumAttachment *aMediumAtt,
673 MachineState_T aMachineState,
674 HRESULT *phrc);
675 static DECLCALLBACK(int) i_changeRemovableMedium(Console *pThis,
676 PUVM pUVM,
677 const char *pcszDevice,
678 unsigned uInstance,
679 StorageBus_T enmBus,
680 bool fUseHostIOCache,
681 IMediumAttachment *aMediumAtt,
682 bool fForce);
683
684 HRESULT i_attachRawPCIDevices(PUVM pUVM, BusAssignmentManager *BusMgr, PCFGMNODE pDevices);
685 void i_attachStatusDriver(PCFGMNODE pCtlInst, PPDMLED *papLeds,
686 uint64_t uFirst, uint64_t uLast,
687 Console::MediumAttachmentMap *pmapMediumAttachments,
688 const char *pcszDevice, unsigned uInstance);
689
690 int i_configNetwork(const char *pszDevice, unsigned uInstance, unsigned uLun,
691 INetworkAdapter *aNetworkAdapter, PCFGMNODE pCfg,
692 PCFGMNODE pLunL0, PCFGMNODE pInst,
693 bool fAttachDetach, bool fIgnoreConnectFailure);
694
695 static DECLCALLBACK(int) i_configGuestProperties(void *pvConsole, PUVM pUVM);
696 static DECLCALLBACK(int) i_configGuestControl(void *pvConsole);
697 static DECLCALLBACK(void) i_vmstateChangeCallback(PUVM pUVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
698 static DECLCALLBACK(int) i_unplugCpu(Console *pThis, PUVM pUVM, VMCPUID idCpu);
699 static DECLCALLBACK(int) i_plugCpu(Console *pThis, PUVM pUVM, VMCPUID idCpu);
700 HRESULT i_doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PUVM pUVM);
701 HRESULT i_doCPURemove(ULONG aCpu, PUVM pUVM);
702 HRESULT i_doCPUAdd(ULONG aCpu, PUVM pUVM);
703
704 HRESULT i_doNetworkAdapterChange(PUVM pUVM, const char *pszDevice, unsigned uInstance,
705 unsigned uLun, INetworkAdapter *aNetworkAdapter);
706 static DECLCALLBACK(int) i_changeNetworkAttachment(Console *pThis, PUVM pUVM, const char *pszDevice,
707 unsigned uInstance, unsigned uLun,
708 INetworkAdapter *aNetworkAdapter);
709
710 void i_changeClipboardMode(ClipboardMode_T aClipboardMode);
711 int i_changeDnDMode(DnDMode_T aDnDMode);
712
713#ifdef VBOX_WITH_USB
714 HRESULT i_attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs, const Utf8Str &aCaptureFilename);
715 HRESULT i_detachUSBDevice(const ComObjPtr<OUSBDevice> &aHostDevice);
716
717 static DECLCALLBACK(int) i_usbAttachCallback(Console *that, PUVM pUVM, IUSBDevice *aHostDevice, PCRTUUID aUuid,
718 bool aRemote, const char *aAddress, void *pvRemoteBackend,
719 USHORT aPortVersion, ULONG aMaskedIfs, const char *pszCaptureFilename);
720 static DECLCALLBACK(int) i_usbDetachCallback(Console *that, PUVM pUVM, PCRTUUID aUuid);
721#endif
722
723 static DECLCALLBACK(int) i_attachStorageDevice(Console *pThis,
724 PUVM pUVM,
725 const char *pcszDevice,
726 unsigned uInstance,
727 StorageBus_T enmBus,
728 bool fUseHostIOCache,
729 IMediumAttachment *aMediumAtt,
730 bool fSilent);
731 static DECLCALLBACK(int) i_detachStorageDevice(Console *pThis,
732 PUVM pUVM,
733 const char *pcszDevice,
734 unsigned uInstance,
735 StorageBus_T enmBus,
736 IMediumAttachment *aMediumAtt,
737 bool fSilent);
738 HRESULT i_doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUVM pUVM, bool fSilent);
739 HRESULT i_doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUVM pUVM, bool fSilent);
740
741 static DECLCALLBACK(int) i_stateProgressCallback(PUVM pUVM, unsigned uPercent, void *pvUser);
742
743 static DECLCALLBACK(void) i_genericVMSetErrorCallback(PUVM pUVM, void *pvUser, int rc, RT_SRC_POS_DECL,
744 const char *pszErrorFmt, va_list va);
745
746 void i_setVMRuntimeErrorCallbackF(uint32_t fFatal, const char *pszErrorId, const char *pszFormat, ...);
747 static DECLCALLBACK(void) i_setVMRuntimeErrorCallback(PUVM pUVM, void *pvUser, uint32_t fFatal,
748 const char *pszErrorId, const char *pszFormat, va_list va);
749
750 HRESULT i_captureUSBDevices(PUVM pUVM);
751 void i_detachAllUSBDevices(bool aDone);
752
753 static DECLCALLBACK(int) i_powerUpThread(RTTHREAD Thread, void *pvUser);
754 static DECLCALLBACK(int) i_powerDownThread(RTTHREAD Thread, void *pvUser);
755
756 static DECLCALLBACK(int) i_vmm2User_SaveState(PCVMM2USERMETHODS pThis, PUVM pUVM);
757 static DECLCALLBACK(void) i_vmm2User_NotifyEmtInit(PCVMM2USERMETHODS pThis, PUVM pUVM, PUVMCPU pUVCpu);
758 static DECLCALLBACK(void) i_vmm2User_NotifyEmtTerm(PCVMM2USERMETHODS pThis, PUVM pUVM, PUVMCPU pUVCpu);
759 static DECLCALLBACK(void) i_vmm2User_NotifyPdmtInit(PCVMM2USERMETHODS pThis, PUVM pUVM);
760 static DECLCALLBACK(void) i_vmm2User_NotifyPdmtTerm(PCVMM2USERMETHODS pThis, PUVM pUVM);
761 static DECLCALLBACK(void) i_vmm2User_NotifyResetTurnedIntoPowerOff(PCVMM2USERMETHODS pThis, PUVM pUVM);
762
763 static DECLCALLBACK(void *) i_drvStatus_QueryInterface(PPDMIBASE pInterface, const char *pszIID);
764 static DECLCALLBACK(void) i_drvStatus_UnitChanged(PPDMILEDCONNECTORS pInterface, unsigned iLUN);
765 static DECLCALLBACK(int) i_drvStatus_MediumEjected(PPDMIMEDIANOTIFY pInterface, unsigned iLUN);
766 static DECLCALLBACK(void) i_drvStatus_Destruct(PPDMDRVINS pDrvIns);
767 static DECLCALLBACK(int) i_drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
768
769 static DECLCALLBACK(int) i_pdmIfSecKey_KeyRetain(PPDMISECKEY pInterface, const char *pszId, const uint8_t **ppbKey,
770 size_t *pcbKey);
771 static DECLCALLBACK(int) i_pdmIfSecKey_KeyRelease(PPDMISECKEY pInterface, const char *pszId);
772 static DECLCALLBACK(int) i_pdmIfSecKey_PasswordRetain(PPDMISECKEY pInterface, const char *pszId, const char **ppszPassword);
773 static DECLCALLBACK(int) i_pdmIfSecKey_PasswordRelease(PPDMISECKEY pInterface, const char *pszId);
774
775 static DECLCALLBACK(int) i_pdmIfSecKeyHlp_KeyMissingNotify(PPDMISECKEYHLP pInterface);
776
777 int mcAudioRefs;
778 volatile uint32_t mcVRDPClients;
779 uint32_t mu32SingleRDPClientId; /* The id of a connected client in the single connection mode. */
780 volatile bool mcGuestCredentialsProvided;
781
782 static const char *sSSMConsoleUnit;
783 static uint32_t sSSMConsoleVer;
784
785 HRESULT i_loadDataFromSavedState();
786 int i_loadStateFileExecInternal(PSSMHANDLE pSSM, uint32_t u32Version);
787
788 static DECLCALLBACK(void) i_saveStateFileExec(PSSMHANDLE pSSM, void *pvUser);
789 static DECLCALLBACK(int) i_loadStateFileExec(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32_t uPass);
790
791#ifdef VBOX_WITH_GUEST_PROPS
792 static DECLCALLBACK(int) i_doGuestPropNotification(void *pvExtension, uint32_t, void *pvParms, uint32_t cbParms);
793 HRESULT i_doEnumerateGuestProperties(const Utf8Str &aPatterns,
794 std::vector<Utf8Str> &aNames,
795 std::vector<Utf8Str> &aValues,
796 std::vector<LONG64> &aTimestamps,
797 std::vector<Utf8Str> &aFlags);
798
799 void i_guestPropertiesHandleVMReset(void);
800 bool i_guestPropertiesVRDPEnabled(void);
801 void i_guestPropertiesVRDPUpdateLogon(uint32_t u32ClientId, const char *pszUser, const char *pszDomain);
802 void i_guestPropertiesVRDPUpdateActiveClient(uint32_t u32ClientId);
803 void i_guestPropertiesVRDPUpdateClientAttach(uint32_t u32ClientId, bool fAttached);
804 void i_guestPropertiesVRDPUpdateNameChange(uint32_t u32ClientId, const char *pszName);
805 void i_guestPropertiesVRDPUpdateIPAddrChange(uint32_t u32ClientId, const char *pszIPAddr);
806 void i_guestPropertiesVRDPUpdateLocationChange(uint32_t u32ClientId, const char *pszLocation);
807 void i_guestPropertiesVRDPUpdateOtherInfoChange(uint32_t u32ClientId, const char *pszOtherInfo);
808 void i_guestPropertiesVRDPUpdateDisconnect(uint32_t u32ClientId);
809#endif
810
811 bool i_isResetTurnedIntoPowerOff(void);
812
813 /** @name Disk encryption support
814 * @{ */
815 HRESULT i_consoleParseDiskEncryption(const char *psz, const char **ppszEnd);
816 HRESULT i_configureEncryptionForDisk(const Utf8Str &strId, unsigned *pcDisksConfigured);
817 HRESULT i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(const Utf8Str &strId);
818 HRESULT i_initSecretKeyIfOnAllAttachments(void);
819 int i_consoleParseKeyValue(const char *psz, const char **ppszEnd,
820 char **ppszKey, char **ppszVal);
821 void i_removeSecretKeysOnSuspend();
822 /** @} */
823
824 /** @name Teleporter support
825 * @{ */
826 static DECLCALLBACK(int) i_teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser);
827 HRESULT i_teleporterSrc(TeleporterStateSrc *pState);
828 HRESULT i_teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL);
829 HRESULT i_teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck = true);
830 HRESULT i_teleporterTrg(PUVM pUVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
831 Progress *pProgress, bool *pfPowerOffOnFailure);
832 static DECLCALLBACK(int) i_teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser);
833 /** @} */
834
835 bool mSavedStateDataLoaded : 1;
836
837 const ComPtr<IMachine> mMachine;
838 const ComPtr<IInternalMachineControl> mControl;
839
840 const ComPtr<IVRDEServer> mVRDEServer;
841
842 ConsoleVRDPServer * const mConsoleVRDPServer;
843 bool mfVRDEChangeInProcess;
844 bool mfVRDEChangePending;
845
846 const ComObjPtr<Guest> mGuest;
847 const ComObjPtr<Keyboard> mKeyboard;
848 const ComObjPtr<Mouse> mMouse;
849 const ComObjPtr<Display> mDisplay;
850 const ComObjPtr<MachineDebugger> mDebugger;
851 const ComObjPtr<VRDEServerInfo> mVRDEServerInfo;
852 /** This can safely be used without holding any locks.
853 * An AutoCaller suffices to prevent it being destroy while in use and
854 * internally there is a lock providing the necessary serialization. */
855 const ComObjPtr<EventSource> mEventSource;
856#ifdef VBOX_WITH_EXTPACK
857 const ComObjPtr<ExtPackManager> mptrExtPackManager;
858#endif
859 const ComObjPtr<EmulatedUSB> mEmulatedUSB;
860
861 USBDeviceList mUSBDevices;
862 RemoteUSBDeviceList mRemoteUSBDevices;
863
864 SharedFolderDataMap m_mapGlobalSharedFolders;
865 SharedFolderDataMap m_mapMachineSharedFolders;
866 SharedFolderMap m_mapSharedFolders; // the console instances
867
868 /** The user mode VM handle. */
869 PUVM mpUVM;
870 /** Holds the number of "readonly" mpUVM callers (users). */
871 uint32_t mVMCallers;
872 /** Semaphore posted when the number of mpUVM callers drops to zero. */
873 RTSEMEVENT mVMZeroCallersSem;
874 /** true when Console has entered the mpUVM destruction phase. */
875 bool mVMDestroying : 1;
876 /** true when power down is initiated by vmstateChangeCallback (EMT). */
877 bool mVMPoweredOff : 1;
878 /** true when vmstateChangeCallback shouldn't initiate a power down. */
879 bool mVMIsAlreadyPoweringOff : 1;
880 /** true if we already showed the snapshot folder size warning. */
881 bool mfSnapshotFolderSizeWarningShown : 1;
882 /** true if we already showed the snapshot folder ext4/xfs bug warning. */
883 bool mfSnapshotFolderExt4WarningShown : 1;
884 /** true if we already listed the disk type of the snapshot folder. */
885 bool mfSnapshotFolderDiskTypeShown : 1;
886 /** true if a USB controller is available (i.e. USB devices can be attached). */
887 bool mfVMHasUsbController : 1;
888 /** true if the VM power off was caused by reset. */
889 bool mfPowerOffCausedByReset : 1;
890
891 /** Pointer to the VMM -> User (that's us) callbacks. */
892 struct MYVMM2USERMETHODS : public VMM2USERMETHODS
893 {
894 Console *pConsole;
895 } *mpVmm2UserMethods;
896
897 /** The current network attachment type in the VM.
898 * This doesn't have to match the network attachment type maintained in the
899 * NetworkAdapter. This is needed to change the network attachment
900 * dynamically.
901 */
902 typedef std::vector<NetworkAttachmentType_T> NetworkAttachmentTypeVector;
903 NetworkAttachmentTypeVector meAttachmentType;
904
905 VMMDev * m_pVMMDev;
906#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
907 AudioVRDE * const mAudioVRDE;
908#else
909 AudioSniffer * const mAudioSniffer;
910#endif
911 Nvram * const mNvram;
912#ifdef VBOX_WITH_USB_CARDREADER
913 UsbCardReader * const mUsbCardReader;
914#endif
915 BusAssignmentManager* mBusMgr;
916
917 enum
918 {
919 iLedFloppy = 0,
920 cLedFloppy = 2,
921 iLedIde = iLedFloppy + cLedFloppy,
922 cLedIde = 4,
923 iLedSata = iLedIde + cLedIde,
924 cLedSata = 30,
925 iLedScsi = iLedSata + cLedSata,
926 cLedScsi = 16,
927 iLedSas = iLedScsi + cLedScsi,
928 cLedSas = 8,
929 iLedUsb = iLedSas + cLedSas,
930 cLedUsb = 8,
931 cLedStorage = cLedFloppy + cLedIde + cLedSata + cLedScsi + cLedSas + cLedUsb
932 };
933 DeviceType_T maStorageDevType[cLedStorage];
934 PPDMLED mapStorageLeds[cLedStorage];
935 PPDMLED mapNetworkLeds[36]; /**< @todo adapt this to the maximum network card count */
936 PPDMLED mapSharedFolderLed;
937 PPDMLED mapUSBLed[2];
938 PPDMLED mapCrOglLed;
939
940 MediumAttachmentMap mapMediumAttachments;
941
942 /** List of attached USB storage devices. */
943 USBStorageDeviceList mUSBStorageDevices;
944
945 /** Store for secret keys. */
946 SecretKeyStore * const m_pKeyStore;
947 /** Number of disks configured for encryption. */
948 unsigned m_cDisksEncrypted;
949 /** Number of disks which have the key in the map. */
950 unsigned m_cDisksPwProvided;
951
952 /** Pointer to the key consumer -> provider (that's us) callbacks. */
953 struct MYPDMISECKEY : public PDMISECKEY
954 {
955 Console *pConsole;
956 } *mpIfSecKey;
957
958 /** Pointer to the key helpers -> provider (that's us) callbacks. */
959 struct MYPDMISECKEYHLP : public PDMISECKEYHLP
960 {
961 Console *pConsole;
962 } *mpIfSecKeyHlp;
963
964/* Note: FreeBSD needs this whether netflt is used or not. */
965#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
966 Utf8Str maTAPDeviceName[8];
967 RTFILE maTapFD[8];
968#endif
969
970 bool mVMStateChangeCallbackDisabled;
971
972 bool mfUseHostClipboard;
973
974 /** Local machine state value. */
975 MachineState_T mMachineState;
976
977 /** Pointer to the progress object of a live cancelable task.
978 *
979 * This is currently only used by Console::Teleport(), but is intended to later
980 * be used by the live snapshot code path as well. Actions like
981 * Console::PowerDown, which automatically cancels out the running snapshot /
982 * teleportation operation, will cancel the teleportation / live snapshot
983 * operation before starting. */
984 ComPtr<IProgress> mptrCancelableProgress;
985
986 ComPtr<IEventListener> mVmListener;
987
988 friend struct VMTask;
989};
990
991#endif // !____H_CONSOLEIMPL
992/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

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