VirtualBox

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

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

Main: Corrected getProcessorUsage() impl (docs, spacing etc).

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