VirtualBox

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

Last change on this file since 7466 was 7442, checked in by vboxsync, 17 years ago

Main: Applied SATA changes from #2406. Increased XML settings version format from 1.2 to 1.3.pre.

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