VirtualBox

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

Last change on this file since 14959 was 14949, checked in by vboxsync, 16 years ago

Appended vim modeline to set tabstop and expand tabs (in the way
suggested by our coding guidelines).

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