VirtualBox

source: vbox/trunk/src/VBox/Main/include/MachineImpl.h@ 17113

Last change on this file since 17113 was 17073, checked in by vboxsync, 16 years ago

Main: typo

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.6 KB
Line 
1/* $Id: MachineImpl.h 17073 2009-02-24 14:43:29Z vboxsync $ */
2
3/** @file
4 *
5 * VirtualBox COM class declaration
6 */
7
8/*
9 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#ifndef ____H_MACHINEIMPL
25#define ____H_MACHINEIMPL
26
27#include "VirtualBoxBase.h"
28#include "ProgressImpl.h"
29#include "SnapshotImpl.h"
30#include "VRDPServerImpl.h"
31#include "DVDDriveImpl.h"
32#include "FloppyDriveImpl.h"
33#include "HardDiskAttachmentImpl.h"
34#include "Collection.h"
35#include "NetworkAdapterImpl.h"
36#include "AudioAdapterImpl.h"
37#include "SerialPortImpl.h"
38#include "ParallelPortImpl.h"
39#include "BIOSSettingsImpl.h"
40#include "SATAControllerImpl.h"
41#ifdef VBOX_WITH_RESOURCE_USAGE_API
42#include "PerformanceImpl.h"
43#endif /* VBOX_WITH_RESOURCE_USAGE_API */
44
45// generated header
46#include "SchemaDefs.h"
47
48#include <VBox/types.h>
49
50#include <iprt/file.h>
51#include <iprt/thread.h>
52#include <iprt/time.h>
53
54#include <list>
55
56// defines
57////////////////////////////////////////////////////////////////////////////////
58
59// helper declarations
60////////////////////////////////////////////////////////////////////////////////
61
62class IAppliance;
63class VirtualBox;
64class Progress;
65class CombinedProgress;
66class Keyboard;
67class Mouse;
68class Display;
69class MachineDebugger;
70class USBController;
71class Snapshot;
72class SharedFolder;
73class HostUSBDevice;
74
75class SessionMachine;
76
77// Machine class
78////////////////////////////////////////////////////////////////////////////////
79
80class ATL_NO_VTABLE Machine :
81 public VirtualBoxBaseWithChildrenNEXT,
82 public VirtualBoxSupportErrorInfoImpl <Machine, IMachine>,
83 public VirtualBoxSupportTranslation <Machine>,
84 public IMachine
85{
86 Q_OBJECT
87
88public:
89
90 enum InstanceType { IsMachine, IsSessionMachine, IsSnapshotMachine };
91
92 /**
93 * Internal machine data.
94 *
95 * Only one instance of this data exists per every machine --
96 * it is shared by the Machine, SessionMachine and all SnapshotMachine
97 * instances associated with the given machine using the util::Shareable
98 * template through the mData variable.
99 *
100 * @note |const| members are persistent during lifetime so can be
101 * accessed without locking.
102 *
103 * @note There is no need to lock anything inside init() or uninit()
104 * methods, because they are always serialized (see AutoCaller).
105 */
106 struct Data
107 {
108 /**
109 * Data structure to hold information about sessions opened for the
110 * given machine.
111 */
112 struct Session
113 {
114 /** Control of the direct session opened by openSession() */
115 ComPtr <IInternalSessionControl> mDirectControl;
116
117 typedef std::list <ComPtr <IInternalSessionControl> > RemoteControlList;
118
119 /** list of controls of all opened remote sessions */
120 RemoteControlList mRemoteControls;
121
122 /** openRemoteSession() and OnSessionEnd() progress indicator */
123 ComObjPtr <Progress> mProgress;
124
125 /**
126 * PID of the session object that must be passed to openSession()
127 * to finalize the openRemoteSession() request
128 * (i.e., PID of the process created by openRemoteSession())
129 */
130 RTPROCESS mPid;
131
132 /** Current session state */
133 SessionState_T mState;
134
135 /** Session type string (for indirect sessions) */
136 Bstr mType;
137
138 /** Session machine object */
139 ComObjPtr <SessionMachine> mMachine;
140 };
141
142 Data();
143 ~Data();
144
145 const Guid mUuid;
146 BOOL mRegistered;
147
148 Bstr mConfigFile;
149 Bstr mConfigFileFull;
150
151 Utf8Str mSettingsFileVersion;
152
153 BOOL mAccessible;
154 com::ErrorInfo mAccessError;
155
156 MachineState_T mMachineState;
157 RTTIMESPEC mLastStateChange;
158
159 /* Note: These are guarded by VirtualBoxBase::stateLockHandle() */
160 uint32_t mMachineStateDeps;
161 RTSEMEVENTMULTI mMachineStateDepsSem;
162 uint32_t mMachineStateChangePending;
163
164 BOOL mCurrentStateModified;
165
166 RTFILE mHandleCfgFile;
167
168 Session mSession;
169
170 ComObjPtr <Snapshot> mFirstSnapshot;
171 ComObjPtr <Snapshot> mCurrentSnapshot;
172
173 };
174
175 /**
176 * Saved state data.
177 *
178 * It's actually only the state file path string, but it needs to be
179 * separate from Data, because Machine and SessionMachine instances
180 * share it, while SnapshotMachine does not.
181 *
182 * The data variable is |mSSData|.
183 */
184 struct SSData
185 {
186 Bstr mStateFilePath;
187 };
188
189 /**
190 * User changeable machine data.
191 *
192 * This data is common for all machine snapshots, i.e. it is shared
193 * by all SnapshotMachine instances associated with the given machine
194 * using the util::Backupable template through the |mUserData| variable.
195 *
196 * SessionMachine instances can alter this data and discard changes.
197 *
198 * @note There is no need to lock anything inside init() or uninit()
199 * methods, because they are always serialized (see AutoCaller).
200 */
201 struct UserData
202 {
203 UserData();
204 ~UserData();
205
206 bool operator== (const UserData &that) const
207 {
208 return this == &that ||
209 (mName == that.mName &&
210 mNameSync == that.mNameSync &&
211 mDescription == that.mDescription &&
212 mOSTypeId == that.mOSTypeId &&
213 mSnapshotFolderFull == that.mSnapshotFolderFull);
214 }
215
216 Bstr mName;
217 BOOL mNameSync;
218 Bstr mDescription;
219 Bstr mOSTypeId;
220 Bstr mSnapshotFolder;
221 Bstr mSnapshotFolderFull;
222 };
223
224 /**
225 * Hardware data.
226 *
227 * This data is unique for a machine and for every machine snapshot.
228 * Stored using the util::Backupable template in the |mHWData| variable.
229 *
230 * SessionMachine instances can alter this data and discard changes.
231 */
232 struct HWData
233 {
234 /**
235 * Data structure to hold information about a guest property.
236 */
237 struct GuestProperty {
238 /** Property name */
239 Bstr mName;
240 /** Property value */
241 Bstr mValue;
242 /** Property timestamp */
243 ULONG64 mTimestamp;
244 /** Property flags */
245 ULONG mFlags;
246 };
247
248 HWData();
249 ~HWData();
250
251 bool operator== (const HWData &that) const;
252
253 Bstr mHWVersion;
254 ULONG mMemorySize;
255 ULONG mMemoryBalloonSize;
256 ULONG mStatisticsUpdateInterval;
257 ULONG mVRAMSize;
258 ULONG mMonitorCount;
259 TSBool_T mHWVirtExEnabled;
260 BOOL mHWVirtExNestedPagingEnabled;
261 BOOL mHWVirtExVPIDEnabled;
262 BOOL mAccelerate3DEnabled;
263 BOOL mPAEEnabled;
264 ULONG mCPUCount;
265
266 DeviceType_T mBootOrder [SchemaDefs::MaxBootPosition];
267
268 typedef std::list <ComObjPtr <SharedFolder> > SharedFolderList;
269 SharedFolderList mSharedFolders;
270 ClipboardMode_T mClipboardMode;
271 typedef std::list <GuestProperty> GuestPropertyList;
272 GuestPropertyList mGuestProperties;
273 BOOL mPropertyServiceActive;
274 Bstr mGuestPropertyNotificationPatterns;
275 };
276
277 /**
278 * Hard disk data.
279 *
280 * The usage policy is the same as for HWData, but a separate structure
281 * is necessary because hard disk data requires different procedures when
282 * taking or discarding snapshots, etc.
283 *
284 * The data variable is |mHWData|.
285 */
286 struct HDData
287 {
288 HDData();
289 ~HDData();
290
291 bool operator== (const HDData &that) const;
292
293 typedef std::list< ComObjPtr<HardDiskAttachment> > AttachmentList;
294 AttachmentList mAttachments;
295 };
296
297 enum StateDependency
298 {
299 AnyStateDep = 0, MutableStateDep, MutableOrSavedStateDep
300 };
301
302 /**
303 * Helper class that safely manages the machine state dependency by
304 * calling Machine::addStateDependency() on construction and
305 * Machine::releaseStateDependency() on destruction. Intended for Machine
306 * children. The usage pattern is:
307 *
308 * @code
309 * AutoCaller autoCaller (this);
310 * CheckComRCReturnRC (autoCaller.rc());
311 *
312 * Machine::AutoStateDependency <MutableStateDep> adep (mParent);
313 * CheckComRCReturnRC (stateDep.rc());
314 * ...
315 * // code that depends on the particular machine state
316 * ...
317 * @endcode
318 *
319 * Note that it is more convenient to use the following individual
320 * shortcut classes instead of using this template directly:
321 * AutoAnyStateDependency, AutoMutableStateDependency and
322 * AutoMutableOrSavedStateDependency. The usage pattern is exactly the
323 * same as above except that there is no need to specify the template
324 * argument because it is already done by the shortcut class.
325 *
326 * @param taDepType Dependecy type to manage.
327 */
328 template <StateDependency taDepType = AnyStateDep>
329 class AutoStateDependency
330 {
331 public:
332
333 AutoStateDependency (Machine *aThat)
334 : mThat (aThat), mRC (S_OK)
335 , mMachineState (MachineState_Null)
336 , mRegistered (FALSE)
337 {
338 Assert (aThat);
339 mRC = aThat->addStateDependency (taDepType, &mMachineState,
340 &mRegistered);
341 }
342 ~AutoStateDependency()
343 {
344 if (SUCCEEDED (mRC))
345 mThat->releaseStateDependency();
346 }
347
348 /** Decreases the number of dependencies before the instance is
349 * destroyed. Note that will reset #rc() to E_FAIL. */
350 void release()
351 {
352 AssertReturnVoid (SUCCEEDED (mRC));
353 mThat->releaseStateDependency();
354 mRC = E_FAIL;
355 }
356
357 /** Restores the number of callers after by #release(). #rc() will be
358 * reset to the result of calling addStateDependency() and must be
359 * rechecked to ensure the operation succeeded. */
360 void add()
361 {
362 AssertReturnVoid (!SUCCEEDED (mRC));
363 mRC = mThat->addStateDependency (taDepType, &mMachineState,
364 &mRegistered);
365 }
366
367 /** Returns the result of Machine::addStateDependency(). */
368 HRESULT rc() const { return mRC; }
369
370 /** Shortcut to SUCCEEDED (rc()). */
371 bool isOk() const { return SUCCEEDED (mRC); }
372
373 /** Returns the machine state value as returned by
374 * Machine::addStateDependency(). */
375 MachineState_T machineState() const { return mMachineState; }
376
377 /** Returns the machine state value as returned by
378 * Machine::addStateDependency(). */
379 BOOL machineRegistered() const { return mRegistered; }
380
381 protected:
382
383 Machine *mThat;
384 HRESULT mRC;
385 MachineState_T mMachineState;
386 BOOL mRegistered;
387
388 private:
389
390 DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (AutoStateDependency)
391 DECLARE_CLS_NEW_DELETE_NOOP (AutoStateDependency)
392 };
393
394 /**
395 * Shortcut to AutoStateDependency <AnyStateDep>.
396 * See AutoStateDependency to get the usage pattern.
397 *
398 * Accepts any machine state and guarantees the state won't change before
399 * this object is destroyed. If the machine state cannot be protected (as
400 * a result of the state change currently in progress), this instance's
401 * #rc() method will indicate a failure, and the caller is not allowed to
402 * rely on any particular machine state and should return the failed
403 * result code to the upper level.
404 */
405 typedef AutoStateDependency <AnyStateDep> AutoAnyStateDependency;
406
407 /**
408 * Shortcut to AutoStateDependency <MutableStateDep>.
409 * See AutoStateDependency to get the usage pattern.
410 *
411 * Succeeds only if the machine state is in one of the mutable states, and
412 * guarantees the given mutable state won't change before this object is
413 * destroyed. If the machine is not mutable, this instance's #rc() method
414 * will indicate a failure, and the caller is not allowed to rely on any
415 * particular machine state and should return the failed result code to
416 * the upper level.
417 *
418 * Intended to be used within all setter methods of IMachine
419 * children objects (DVDDrive, NetworkAdapter, AudioAdapter, etc.) to
420 * provide data protection and consistency.
421 */
422 typedef AutoStateDependency <MutableStateDep> AutoMutableStateDependency;
423
424 /**
425 * Shortcut to AutoStateDependency <MutableOrSavedStateDep>.
426 * See AutoStateDependency to get the usage pattern.
427 *
428 * Succeeds only if the machine state is in one of the mutable states, or
429 * if the machine is in the Saved state, and guarantees the given mutable
430 * state won't change before this object is destroyed. If the machine is
431 * not mutable, this instance's #rc() method will indicate a failure, and
432 * the caller is not allowed to rely on any particular machine state and
433 * should return the failed result code to the upper level.
434 *
435 * Intended to be used within setter methods of IMachine
436 * children objects that may also operate on Saved machines.
437 */
438 typedef AutoStateDependency <MutableOrSavedStateDep> AutoMutableOrSavedStateDependency;
439
440
441 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (Machine)
442
443 DECLARE_NOT_AGGREGATABLE(Machine)
444
445 DECLARE_PROTECT_FINAL_CONSTRUCT()
446
447 BEGIN_COM_MAP(Machine)
448 COM_INTERFACE_ENTRY(ISupportErrorInfo)
449 COM_INTERFACE_ENTRY(IMachine)
450 END_COM_MAP()
451
452 NS_DECL_ISUPPORTS
453
454 DECLARE_EMPTY_CTOR_DTOR (Machine)
455
456 HRESULT FinalConstruct();
457 void FinalRelease();
458
459 enum InitMode { Init_New, Init_Existing, Init_Registered };
460
461 // public initializer/uninitializer for internal purposes only
462 HRESULT init (VirtualBox *aParent, CBSTR aConfigFile,
463 InitMode aMode, CBSTR aName = NULL,
464 GuestOSType *aOsType = NULL,
465 BOOL aNameSync = TRUE, const Guid *aId = NULL);
466 void uninit();
467
468 // IMachine properties
469 STDMETHOD(COMGETTER(Parent))(IVirtualBox **aParent);
470 STDMETHOD(COMGETTER(Accessible)) (BOOL *aAccessible);
471 STDMETHOD(COMGETTER(AccessError)) (IVirtualBoxErrorInfo **aAccessError);
472 STDMETHOD(COMGETTER(Name))(BSTR *aName);
473 STDMETHOD(COMSETTER(Name))(IN_BSTR aName);
474 STDMETHOD(COMGETTER(Description))(BSTR *aDescription);
475 STDMETHOD(COMSETTER(Description))(IN_BSTR aDescription);
476 STDMETHOD(COMGETTER(Id))(OUT_GUID aId);
477 STDMETHOD(COMGETTER(OSTypeId)) (BSTR *aOSTypeId);
478 STDMETHOD(COMSETTER(OSTypeId)) (IN_BSTR aOSTypeId);
479 STDMETHOD(COMGETTER(HardwareVersion))(BSTR *aVersion);
480 STDMETHOD(COMSETTER(HardwareVersion))(IN_BSTR aVersion);
481 STDMETHOD(COMGETTER(MemorySize))(ULONG *memorySize);
482 STDMETHOD(COMSETTER(MemorySize))(ULONG memorySize);
483 STDMETHOD(COMGETTER(CPUCount))(ULONG *cpuCount);
484 STDMETHOD(COMSETTER(CPUCount))(ULONG cpuCount);
485 STDMETHOD(COMGETTER(MemoryBalloonSize))(ULONG *memoryBalloonSize);
486 STDMETHOD(COMSETTER(MemoryBalloonSize))(ULONG memoryBalloonSize);
487 STDMETHOD(COMGETTER(StatisticsUpdateInterval))(ULONG *statisticsUpdateInterval);
488 STDMETHOD(COMSETTER(StatisticsUpdateInterval))(ULONG statisticsUpdateInterval);
489 STDMETHOD(COMGETTER(VRAMSize))(ULONG *memorySize);
490 STDMETHOD(COMSETTER(VRAMSize))(ULONG memorySize);
491 STDMETHOD(COMGETTER(MonitorCount))(ULONG *monitorCount);
492 STDMETHOD(COMSETTER(MonitorCount))(ULONG monitorCount);
493 STDMETHOD(COMGETTER(Accelerate3DEnabled))(BOOL *enabled);
494 STDMETHOD(COMSETTER(Accelerate3DEnabled))(BOOL enabled);
495 STDMETHOD(COMGETTER(BIOSSettings))(IBIOSSettings **biosSettings);
496 STDMETHOD(COMGETTER(HWVirtExEnabled))(TSBool_T *enabled);
497 STDMETHOD(COMSETTER(HWVirtExEnabled))(TSBool_T enabled);
498 STDMETHOD(COMGETTER(HWVirtExNestedPagingEnabled))(BOOL *enabled);
499 STDMETHOD(COMSETTER(HWVirtExNestedPagingEnabled))(BOOL enabled);
500 STDMETHOD(COMGETTER(HWVirtExVPIDEnabled))(BOOL *enabled);
501 STDMETHOD(COMSETTER(HWVirtExVPIDEnabled))(BOOL enabled);
502 STDMETHOD(COMGETTER(PAEEnabled))(BOOL *enabled);
503 STDMETHOD(COMSETTER(PAEEnabled))(BOOL enabled);
504 STDMETHOD(COMGETTER(SnapshotFolder))(BSTR *aSavedStateFolder);
505 STDMETHOD(COMSETTER(SnapshotFolder))(IN_BSTR aSavedStateFolder);
506 STDMETHOD(COMGETTER(HardDiskAttachments))(ComSafeArrayOut (IHardDiskAttachment *, aAttachments));
507 STDMETHOD(COMGETTER(VRDPServer))(IVRDPServer **vrdpServer);
508 STDMETHOD(COMGETTER(DVDDrive))(IDVDDrive **dvdDrive);
509 STDMETHOD(COMGETTER(FloppyDrive))(IFloppyDrive **floppyDrive);
510 STDMETHOD(COMGETTER(AudioAdapter))(IAudioAdapter **audioAdapter);
511 STDMETHOD(COMGETTER(USBController)) (IUSBController * *aUSBController);
512 STDMETHOD(COMGETTER(SATAController)) (ISATAController **aSATAController);
513 STDMETHOD(COMGETTER(SettingsFilePath)) (BSTR *aFilePath);
514 STDMETHOD(COMGETTER(SettingsFileVersion)) (BSTR *aSettingsFileVersion);
515 STDMETHOD(COMGETTER(SettingsModified)) (BOOL *aModified);
516 STDMETHOD(COMGETTER(SessionState)) (SessionState_T *aSessionState);
517 STDMETHOD(COMGETTER(SessionType)) (BSTR *aSessionType);
518 STDMETHOD(COMGETTER(SessionPid)) (ULONG *aSessionPid);
519 STDMETHOD(COMGETTER(State)) (MachineState_T *machineState);
520 STDMETHOD(COMGETTER(LastStateChange)) (LONG64 *aLastStateChange);
521 STDMETHOD(COMGETTER(StateFilePath)) (BSTR *aStateFilePath);
522 STDMETHOD(COMGETTER(LogFolder)) (BSTR *aLogFolder);
523 STDMETHOD(COMGETTER(CurrentSnapshot)) (ISnapshot **aCurrentSnapshot);
524 STDMETHOD(COMGETTER(SnapshotCount)) (ULONG *aSnapshotCount);
525 STDMETHOD(COMGETTER(CurrentStateModified))(BOOL *aCurrentStateModified);
526 STDMETHOD(COMGETTER(SharedFolders)) (ComSafeArrayOut (ISharedFolder *, aSharedFolders));
527 STDMETHOD(COMGETTER(ClipboardMode)) (ClipboardMode_T *aClipboardMode);
528 STDMETHOD(COMSETTER(ClipboardMode)) (ClipboardMode_T aClipboardMode);
529 STDMETHOD(COMGETTER(GuestPropertyNotificationPatterns)) (BSTR *aPattern);
530 STDMETHOD(COMSETTER(GuestPropertyNotificationPatterns)) (IN_BSTR aPattern);
531
532 // IMachine methods
533 STDMETHOD(SetBootOrder)(ULONG aPosition, DeviceType_T aDevice);
534 STDMETHOD(GetBootOrder)(ULONG aPosition, DeviceType_T *aDevice);
535 STDMETHOD(AttachHardDisk)(IN_GUID aId, StorageBus_T aBus,
536 LONG aChannel, LONG aDevice);
537 STDMETHOD(GetHardDisk)(StorageBus_T aBus, LONG aChannel, LONG aDevice,
538 IHardDisk **aHardDisk);
539 STDMETHOD(DetachHardDisk)(StorageBus_T aBus, LONG aChannel, LONG aDevice);
540 STDMETHOD(GetSerialPort) (ULONG slot, ISerialPort **port);
541 STDMETHOD(GetParallelPort) (ULONG slot, IParallelPort **port);
542 STDMETHOD(GetNetworkAdapter) (ULONG slot, INetworkAdapter **adapter);
543 STDMETHOD(GetNextExtraDataKey)(IN_BSTR aKey, BSTR *aNextKey, BSTR *aNextValue);
544 STDMETHOD(GetExtraData)(IN_BSTR aKey, BSTR *aValue);
545 STDMETHOD(SetExtraData)(IN_BSTR aKey, IN_BSTR aValue);
546 STDMETHOD(SaveSettings)();
547 STDMETHOD(SaveSettingsWithBackup) (BSTR *aBakFileName);
548 STDMETHOD(DiscardSettings)();
549 STDMETHOD(DeleteSettings)();
550 STDMETHOD(Export)(IAppliance *appliance);
551 STDMETHOD(GetSnapshot) (IN_GUID aId, ISnapshot **aSnapshot);
552 STDMETHOD(FindSnapshot) (IN_BSTR aName, ISnapshot **aSnapshot);
553 STDMETHOD(SetCurrentSnapshot) (IN_GUID aId);
554 STDMETHOD(CreateSharedFolder) (IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable);
555 STDMETHOD(RemoveSharedFolder) (IN_BSTR aName);
556 STDMETHOD(CanShowConsoleWindow) (BOOL *aCanShow);
557 STDMETHOD(ShowConsoleWindow) (ULONG64 *aWinId);
558 STDMETHOD(GetGuestProperty) (IN_BSTR aName, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags);
559 STDMETHOD(GetGuestPropertyValue) (IN_BSTR aName, BSTR *aValue);
560 STDMETHOD(GetGuestPropertyTimestamp) (IN_BSTR aName, ULONG64 *aTimestamp);
561 STDMETHOD(SetGuestProperty) (IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags);
562 STDMETHOD(SetGuestPropertyValue) (IN_BSTR aName, IN_BSTR aValue);
563 STDMETHOD(EnumerateGuestProperties) (IN_BSTR aPattern, ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues), ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
564
565 // public methods only for internal purposes
566
567 InstanceType type() const { return mType; }
568
569 /// @todo (dmik) add lock and make non-inlined after revising classes
570 // that use it. Note: they should enter Machine lock to keep the returned
571 // information valid!
572 bool isRegistered() { return !!mData->mRegistered; }
573
574 // unsafe inline public methods for internal purposes only (ensure there is
575 // a caller and a read lock before calling them!)
576
577 /**
578 * Returns the VirtualBox object this machine belongs to.
579 *
580 * @note This method doesn't check this object's readiness. Intended to be
581 * used by ready Machine children (whose readiness is bound to the parent's
582 * one) or after doing addCaller() manually.
583 */
584 const ComObjPtr <VirtualBox, ComWeakRef> &virtualBox() const { return mParent; }
585
586 /**
587 * Returns this machine ID.
588 *
589 * @note This method doesn't check this object's readiness. Intended to be
590 * used by ready Machine children (whose readiness is bound to the parent's
591 * one) or after adding a caller manually.
592 */
593 const Guid &id() const { return mData->mUuid; }
594
595 /**
596 * Returns the snapshot ID this machine represents or an empty UUID if this
597 * instance is not SnapshotMachine.
598 *
599 * @note This method doesn't check this object's readiness. Intended to be
600 * used by ready Machine children (whose readiness is bound to the parent's
601 * one) or after adding a caller manually.
602 */
603 inline const Guid &snapshotId() const;
604
605 /**
606 * Returns this machine's full settings file path.
607 *
608 * @note This method doesn't lock this object or check its readiness.
609 * Intended to be used only after doing addCaller() manually and locking it
610 * for reading.
611 */
612 const Bstr &settingsFileFull() const { return mData->mConfigFileFull; }
613
614 /**
615 * Returns this machine name.
616 *
617 * @note This method doesn't lock this object or check its readiness.
618 * Intended to be used only after doing addCaller() manually and locking it
619 * for reading.
620 */
621 const Bstr &name() const { return mUserData->mName; }
622
623 // callback handlers
624 virtual HRESULT onDVDDriveChange() { return S_OK; }
625 virtual HRESULT onFloppyDriveChange() { return S_OK; }
626 virtual HRESULT onNetworkAdapterChange(INetworkAdapter *networkAdapter) { return S_OK; }
627 virtual HRESULT onSerialPortChange(ISerialPort *serialPort) { return S_OK; }
628 virtual HRESULT onParallelPortChange(IParallelPort *ParallelPort) { return S_OK; }
629 virtual HRESULT onVRDPServerChange() { return S_OK; }
630 virtual HRESULT onUSBControllerChange() { return S_OK; }
631 virtual HRESULT onSATAControllerChange() { return S_OK; }
632 virtual HRESULT onSharedFolderChange() { return S_OK; }
633
634 HRESULT saveRegistryEntry (settings::Key &aEntryNode);
635
636 int calculateFullPath (const char *aPath, Utf8Str &aResult);
637 void calculateRelativePath (const char *aPath, Utf8Str &aResult);
638
639 void getLogFolder (Utf8Str &aLogFolder);
640
641 HRESULT openSession (IInternalSessionControl *aControl);
642 HRESULT openRemoteSession (IInternalSessionControl *aControl,
643 IN_BSTR aType, IN_BSTR aEnvironment,
644 Progress *aProgress);
645 HRESULT openExistingSession (IInternalSessionControl *aControl);
646
647#if defined (RT_OS_WINDOWS)
648
649 bool isSessionOpen (ComObjPtr <SessionMachine> &aMachine,
650 ComPtr <IInternalSessionControl> *aControl = NULL,
651 HANDLE *aIPCSem = NULL, bool aAllowClosing = false);
652 bool isSessionSpawning (RTPROCESS *aPID = NULL);
653
654 bool isSessionOpenOrClosing (ComObjPtr <SessionMachine> &aMachine,
655 ComPtr <IInternalSessionControl> *aControl = NULL,
656 HANDLE *aIPCSem = NULL)
657 { return isSessionOpen (aMachine, aControl, aIPCSem, true /* aAllowClosing */); }
658
659#elif defined (RT_OS_OS2)
660
661 bool isSessionOpen (ComObjPtr <SessionMachine> &aMachine,
662 ComPtr <IInternalSessionControl> *aControl = NULL,
663 HMTX *aIPCSem = NULL, bool aAllowClosing = false);
664
665 bool isSessionSpawning (RTPROCESS *aPID = NULL);
666
667 bool isSessionOpenOrClosing (ComObjPtr <SessionMachine> &aMachine,
668 ComPtr <IInternalSessionControl> *aControl = NULL,
669 HMTX *aIPCSem = NULL)
670 { return isSessionOpen (aMachine, aControl, aIPCSem, true /* aAllowClosing */); }
671
672#else
673
674 bool isSessionOpen (ComObjPtr <SessionMachine> &aMachine,
675 ComPtr <IInternalSessionControl> *aControl = NULL,
676 bool aAllowClosing = false);
677 bool isSessionSpawning();
678
679 bool isSessionOpenOrClosing (ComObjPtr <SessionMachine> &aMachine,
680 ComPtr <IInternalSessionControl> *aControl = NULL)
681 { return isSessionOpen (aMachine, aControl, true /* aAllowClosing */); }
682
683#endif
684
685 bool checkForSpawnFailure();
686
687 HRESULT trySetRegistered (BOOL aRegistered);
688
689 HRESULT getSharedFolder (CBSTR aName,
690 ComObjPtr <SharedFolder> &aSharedFolder,
691 bool aSetError = false)
692 {
693 AutoWriteLock alock (this);
694 return findSharedFolder (aName, aSharedFolder, aSetError);
695 }
696
697 HRESULT addStateDependency (StateDependency aDepType = AnyStateDep,
698 MachineState_T *aState = NULL,
699 BOOL *aRegistered = NULL);
700 void releaseStateDependency();
701
702 // for VirtualBoxSupportErrorInfoImpl
703 static const wchar_t *getComponentName() { return L"Machine"; }
704
705protected:
706
707 HRESULT registeredInit();
708
709 HRESULT checkStateDependency (StateDependency aDepType);
710
711 inline Machine *machine();
712
713 HRESULT initDataAndChildObjects();
714 void uninitDataAndChildObjects();
715
716 void ensureNoStateDependencies();
717
718 virtual HRESULT setMachineState (MachineState_T aMachineState);
719
720 HRESULT findSharedFolder (CBSTR aName,
721 ComObjPtr <SharedFolder> &aSharedFolder,
722 bool aSetError = false);
723
724 HRESULT loadSettings (bool aRegistered);
725 HRESULT loadSnapshot (const settings::Key &aNode, const Guid &aCurSnapshotId,
726 Snapshot *aParentSnapshot);
727 HRESULT loadHardware (const settings::Key &aNode);
728 HRESULT loadHardDisks (const settings::Key &aNode, bool aRegistered,
729 const Guid *aSnapshotId = NULL);
730
731 HRESULT findSnapshotNode (Snapshot *aSnapshot, settings::Key &aMachineNode,
732 settings::Key *aSnapshotsNode,
733 settings::Key *aSnapshotNode);
734
735 HRESULT findSnapshot (const Guid &aId, ComObjPtr <Snapshot> &aSnapshot,
736 bool aSetError = false);
737 HRESULT findSnapshot (IN_BSTR aName, ComObjPtr <Snapshot> &aSnapshot,
738 bool aSetError = false);
739
740 enum
741 {
742 /* flags for #saveSettings() */
743 SaveS_ResetCurStateModified = 0x01,
744 SaveS_InformCallbacksAnyway = 0x02,
745 /* ops for #saveSnapshotSettings() */
746 SaveSS_NoOp = 0x00, SaveSS_AddOp = 0x01,
747 SaveSS_UpdateAttrsOp = 0x02, SaveSS_UpdateAllOp = 0x03,
748 SaveSS_OpMask = 0xF,
749 /* flags for #saveSnapshotSettings() */
750 SaveSS_CurStateModified = 0x40,
751 SaveSS_CurrentId = 0x80,
752 /* flags for #saveStateSettings() */
753 SaveSTS_CurStateModified = 0x20,
754 SaveSTS_StateFilePath = 0x40,
755 SaveSTS_StateTimeStamp = 0x80,
756 };
757
758 HRESULT prepareSaveSettings (bool &aRenamed, bool &aNew);
759 HRESULT saveSettings (int aFlags = 0);
760
761 HRESULT saveSnapshotSettings (Snapshot *aSnapshot, int aOpFlags);
762 HRESULT saveSnapshotSettingsWorker (settings::Key &aMachineNode,
763 Snapshot *aSnapshot, int aOpFlags);
764
765 HRESULT saveSnapshot (settings::Key &aNode, Snapshot *aSnapshot, bool aAttrsOnly);
766 HRESULT saveHardware (settings::Key &aNode);
767 HRESULT saveHardDisks (settings::Key &aNode);
768
769 HRESULT saveStateSettings (int aFlags);
770
771 HRESULT createImplicitDiffs (const Bstr &aFolder,
772 ComObjPtr <Progress> &aProgress,
773 bool aOnline);
774 HRESULT deleteImplicitDiffs();
775
776 void fixupHardDisks(bool aCommit, bool aOnline = false);
777
778 HRESULT lockConfig();
779 HRESULT unlockConfig();
780
781 /** @note This method is not thread safe */
782 BOOL isConfigLocked()
783 {
784 return !!mData && mData->mHandleCfgFile != NIL_RTFILE;
785 }
786
787 bool isInOwnDir (Utf8Str *aSettingsDir = NULL);
788
789 bool isModified();
790 bool isReallyModified (bool aIgnoreUserData = false);
791 void rollback (bool aNotify);
792 void commit();
793 void copyFrom (Machine *aThat);
794
795#ifdef VBOX_WITH_RESOURCE_USAGE_API
796 void registerMetrics (PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid);
797 void unregisterMetrics (PerformanceCollector *aCollector, Machine *aMachine);
798#endif /* VBOX_WITH_RESOURCE_USAGE_API */
799
800 const InstanceType mType;
801
802 const ComObjPtr <Machine, ComWeakRef> mPeer;
803
804 const ComObjPtr <VirtualBox, ComWeakRef> mParent;
805
806 Shareable <Data> mData;
807 Shareable <SSData> mSSData;
808
809 Backupable <UserData> mUserData;
810 Backupable <HWData> mHWData;
811 Backupable <HDData> mHDData;
812
813 // the following fields need special backup/rollback/commit handling,
814 // so they cannot be a part of HWData
815
816 const ComObjPtr <VRDPServer> mVRDPServer;
817 const ComObjPtr <DVDDrive> mDVDDrive;
818 const ComObjPtr <FloppyDrive> mFloppyDrive;
819 const ComObjPtr <SerialPort>
820 mSerialPorts [SchemaDefs::SerialPortCount];
821 const ComObjPtr <ParallelPort>
822 mParallelPorts [SchemaDefs::ParallelPortCount];
823 const ComObjPtr <AudioAdapter> mAudioAdapter;
824 const ComObjPtr <USBController> mUSBController;
825 const ComObjPtr <SATAController> mSATAController;
826 const ComObjPtr <BIOSSettings> mBIOSSettings;
827 const ComObjPtr <NetworkAdapter>
828 mNetworkAdapters [SchemaDefs::NetworkAdapterCount];
829
830 friend class SessionMachine;
831 friend class SnapshotMachine;
832};
833
834// SessionMachine class
835////////////////////////////////////////////////////////////////////////////////
836
837/**
838 * @note Notes on locking objects of this class:
839 * SessionMachine shares some data with the primary Machine instance (pointed
840 * to by the |mPeer| member). In order to provide data consistency it also
841 * shares its lock handle. This means that whenever you lock a SessionMachine
842 * instance using Auto[Reader]Lock or AutoMultiLock, the corresponding Machine
843 * instance is also locked in the same lock mode. Keep it in mind.
844 */
845class ATL_NO_VTABLE SessionMachine :
846 public VirtualBoxSupportTranslation <SessionMachine>,
847 public Machine,
848 public IInternalMachineControl
849{
850public:
851
852 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(SessionMachine)
853
854 DECLARE_NOT_AGGREGATABLE(SessionMachine)
855
856 DECLARE_PROTECT_FINAL_CONSTRUCT()
857
858 BEGIN_COM_MAP(SessionMachine)
859 COM_INTERFACE_ENTRY(ISupportErrorInfo)
860 COM_INTERFACE_ENTRY(IMachine)
861 COM_INTERFACE_ENTRY(IInternalMachineControl)
862 END_COM_MAP()
863
864 NS_DECL_ISUPPORTS
865
866 DECLARE_EMPTY_CTOR_DTOR (SessionMachine)
867
868 HRESULT FinalConstruct();
869 void FinalRelease();
870
871 // public initializer/uninitializer for internal purposes only
872 HRESULT init (Machine *aMachine);
873 void uninit() { uninit (Uninit::Unexpected); }
874
875 // util::Lockable interface
876 RWLockHandle *lockHandle() const;
877
878 // IInternalMachineControl methods
879 STDMETHOD(UpdateState)(MachineState_T machineState);
880 STDMETHOD(GetIPCId)(BSTR *id);
881 STDMETHOD(RunUSBDeviceFilters) (IUSBDevice *aUSBDevice, BOOL *aMatched, ULONG *aMaskedIfs);
882 STDMETHOD(CaptureUSBDevice) (IN_GUID aId);
883 STDMETHOD(DetachUSBDevice) (IN_GUID aId, BOOL aDone);
884 STDMETHOD(AutoCaptureUSBDevices)();
885 STDMETHOD(DetachAllUSBDevices)(BOOL aDone);
886 STDMETHOD(OnSessionEnd)(ISession *aSession, IProgress **aProgress);
887 STDMETHOD(BeginSavingState) (IProgress *aProgress, BSTR *aStateFilePath);
888 STDMETHOD(EndSavingState) (BOOL aSuccess);
889 STDMETHOD(AdoptSavedState) (IN_BSTR aSavedStateFile);
890 STDMETHOD(BeginTakingSnapshot) (IConsole *aInitiator,
891 IN_BSTR aName, IN_BSTR aDescription,
892 IProgress *aProgress, BSTR *aStateFilePath,
893 IProgress **aServerProgress);
894 STDMETHOD(EndTakingSnapshot) (BOOL aSuccess);
895 STDMETHOD(DiscardSnapshot) (IConsole *aInitiator, IN_GUID aId,
896 MachineState_T *aMachineState, IProgress **aProgress);
897 STDMETHOD(DiscardCurrentState) (
898 IConsole *aInitiator, MachineState_T *aMachineState, IProgress **aProgress);
899 STDMETHOD(DiscardCurrentSnapshotAndState) (
900 IConsole *aInitiator, MachineState_T *aMachineState, IProgress **aProgress);
901 STDMETHOD(PullGuestProperties) (ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(BSTR, aValues),
902 ComSafeArrayOut(ULONG64, aTimestamps), ComSafeArrayOut(BSTR, aFlags));
903 STDMETHOD(PushGuestProperties) (ComSafeArrayIn(IN_BSTR, aNames), ComSafeArrayIn(IN_BSTR, aValues),
904 ComSafeArrayIn(ULONG64, aTimestamps), ComSafeArrayIn(IN_BSTR, aFlags));
905 STDMETHOD(PushGuestProperty) (IN_BSTR aName, IN_BSTR aValue,
906 ULONG64 aTimestamp, IN_BSTR aFlags);
907
908 // public methods only for internal purposes
909
910 bool checkForDeath();
911
912 HRESULT onDVDDriveChange();
913 HRESULT onFloppyDriveChange();
914 HRESULT onNetworkAdapterChange(INetworkAdapter *networkAdapter);
915 HRESULT onSerialPortChange(ISerialPort *serialPort);
916 HRESULT onParallelPortChange(IParallelPort *parallelPort);
917 HRESULT onVRDPServerChange();
918 HRESULT onUSBControllerChange();
919 HRESULT onUSBDeviceAttach (IUSBDevice *aDevice,
920 IVirtualBoxErrorInfo *aError,
921 ULONG aMaskedIfs);
922 HRESULT onUSBDeviceDetach (IN_GUID aId,
923 IVirtualBoxErrorInfo *aError);
924 HRESULT onSharedFolderChange();
925
926 bool hasMatchingUSBFilter (const ComObjPtr <HostUSBDevice> &aDevice, ULONG *aMaskedIfs);
927
928private:
929
930 struct SnapshotData
931 {
932 SnapshotData() : mLastState (MachineState_Null) {}
933
934 MachineState_T mLastState;
935
936 // used when taking snapshot
937 ComObjPtr <Snapshot> mSnapshot;
938 ComObjPtr <Progress> mServerProgress;
939 ComObjPtr <CombinedProgress> mCombinedProgress;
940
941 // used when saving state
942 Guid mProgressId;
943 Bstr mStateFilePath;
944 };
945
946 struct Uninit
947 {
948 enum Reason { Unexpected, Abnormal, Normal };
949 };
950
951 struct Task;
952 struct TakeSnapshotTask;
953 struct DiscardSnapshotTask;
954 struct DiscardCurrentStateTask;
955
956 friend struct TakeSnapshotTask;
957 friend struct DiscardSnapshotTask;
958 friend struct DiscardCurrentStateTask;
959
960 void uninit (Uninit::Reason aReason);
961
962 HRESULT endSavingState (BOOL aSuccess);
963 HRESULT endTakingSnapshot (BOOL aSuccess);
964
965 typedef std::map <ComObjPtr <Machine>, MachineState_T> AffectedMachines;
966
967 void takeSnapshotHandler (TakeSnapshotTask &aTask);
968 void discardSnapshotHandler (DiscardSnapshotTask &aTask);
969 void discardCurrentStateHandler (DiscardCurrentStateTask &aTask);
970
971 HRESULT setMachineState (MachineState_T aMachineState);
972 HRESULT updateMachineStateOnClient();
973
974 SnapshotData mSnapshotData;
975
976 /** interprocess semaphore handle for this machine */
977#if defined (RT_OS_WINDOWS)
978 HANDLE mIPCSem;
979 Bstr mIPCSemName;
980 friend bool Machine::isSessionOpen (ComObjPtr <SessionMachine> &aMachine,
981 ComPtr <IInternalSessionControl> *aControl,
982 HANDLE *aIPCSem, bool aAllowClosing);
983#elif defined (RT_OS_OS2)
984 HMTX mIPCSem;
985 Bstr mIPCSemName;
986 friend bool Machine::isSessionOpen (ComObjPtr <SessionMachine> &aMachine,
987 ComPtr <IInternalSessionControl> *aControl,
988 HMTX *aIPCSem, bool aAllowClosing);
989#elif defined (VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
990 int mIPCSem;
991#else
992# error "Port me!"
993#endif
994
995 static DECLCALLBACK(int) taskHandler (RTTHREAD thread, void *pvUser);
996};
997
998// SnapshotMachine class
999////////////////////////////////////////////////////////////////////////////////
1000
1001/**
1002 * @note Notes on locking objects of this class:
1003 * SnapshotMachine shares some data with the primary Machine instance (pointed
1004 * to by the |mPeer| member). In order to provide data consistency it also
1005 * shares its lock handle. This means that whenever you lock a SessionMachine
1006 * instance using Auto[Reader]Lock or AutoMultiLock, the corresponding Machine
1007 * instance is also locked in the same lock mode. Keep it in mind.
1008 */
1009class ATL_NO_VTABLE SnapshotMachine :
1010 public VirtualBoxSupportTranslation <SnapshotMachine>,
1011 public Machine
1012{
1013public:
1014
1015 VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(SnapshotMachine)
1016
1017 DECLARE_NOT_AGGREGATABLE(SnapshotMachine)
1018
1019 DECLARE_PROTECT_FINAL_CONSTRUCT()
1020
1021 BEGIN_COM_MAP(SnapshotMachine)
1022 COM_INTERFACE_ENTRY(ISupportErrorInfo)
1023 COM_INTERFACE_ENTRY(IMachine)
1024 END_COM_MAP()
1025
1026 NS_DECL_ISUPPORTS
1027
1028 DECLARE_EMPTY_CTOR_DTOR (SnapshotMachine)
1029
1030 HRESULT FinalConstruct();
1031 void FinalRelease();
1032
1033 // public initializer/uninitializer for internal purposes only
1034 HRESULT init (SessionMachine *aSessionMachine,
1035 IN_GUID aSnapshotId, IN_BSTR aStateFilePath);
1036 HRESULT init (Machine *aMachine,
1037 const settings::Key &aHWNode, const settings::Key &aHDAsNode,
1038 IN_GUID aSnapshotId, IN_BSTR aStateFilePath);
1039 void uninit();
1040
1041 // util::Lockable interface
1042 RWLockHandle *lockHandle() const;
1043
1044 // public methods only for internal purposes
1045
1046 HRESULT onSnapshotChange (Snapshot *aSnapshot);
1047
1048 // unsafe inline public methods for internal purposes only (ensure there is
1049 // a caller and a read lock before calling them!)
1050
1051 const Guid &snapshotId() const { return mSnapshotId; }
1052
1053private:
1054
1055 Guid mSnapshotId;
1056
1057 friend class Snapshot;
1058};
1059
1060// third party methods that depend on SnapshotMachine definiton
1061
1062inline const Guid &Machine::snapshotId() const
1063{
1064 return mType != IsSnapshotMachine ? Guid::Empty :
1065 static_cast <const SnapshotMachine *> (this)->snapshotId();
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069
1070/**
1071 * Returns a pointer to the Machine object for this machine that acts like a
1072 * parent for complex machine data objects such as shared folders, etc.
1073 *
1074 * For primary Machine objects and for SnapshotMachine objects, returns this
1075 * object's pointer itself. For SessoinMachine objects, returns the peer
1076 * (primary) machine pointer.
1077 */
1078inline Machine *Machine::machine()
1079{
1080 if (mType == IsSessionMachine)
1081 return mPeer;
1082 return this;
1083}
1084
1085#endif // ____H_MACHINEIMPL
1086/* 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