VirtualBox

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

Last change on this file since 3566 was 3566, checked in by vboxsync, 18 years ago

Async USB detach (for darwin) with async operation timeout (not enabled on windows). Drop the USBProxyService::reset method. (Hope I didn't break anything, it's only tested on Darwin...)

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

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