Index: trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp	(revision 75323)
+++ trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp	(revision 75324)
@@ -1514,4 +1514,6 @@
         Assert(recordingSettings.isNotNull());
 
+        /** @todo r=andy Make the code below more compact -- too much redundancy here. */
+
         /* Save new 'Recording' data for online case: */
         if (isMachineOnline())
@@ -1529,9 +1531,12 @@
                 // We can still save the *screens* option.
                 /* Save recording screens: */
-                if (fSuccess && newDisplayData.m_vecRecordingScreens != oldDisplayData.m_vecRecordingScreens)
+                if (fSuccess)
                 {
                     CCaptureScreenSettingsVector captureScreenSettingsVector = recordingSettings.GetScreens();
                     for (int iScreenIndex = 0; fSuccess && iScreenIndex < captureScreenSettingsVector.size(); ++iScreenIndex)
                     {
+                        if (newDisplayData.m_vecRecordingScreens[iScreenIndex] == oldDisplayData.m_vecRecordingScreens[iScreenIndex])
+                            continue;
+
                         CCaptureScreenSettings recordingScreenSettings = captureScreenSettingsVector.at(iScreenIndex);
                         recordingScreenSettings.SetEnabled(newDisplayData.m_vecRecordingScreens[iScreenIndex]);
@@ -1543,14 +1548,10 @@
             else
             {
-                /* Save whether recording is enabled: */
-                if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
-                {
-                    recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
-                    fSuccess = recordingSettings.isOk();
-                }
-
                 CCaptureScreenSettingsVector recordingScreenSettingsVector = recordingSettings.GetScreens();
                 for (int iScreenIndex = 0; fSuccess && iScreenIndex < recordingScreenSettingsVector.size(); ++iScreenIndex)
                 {
+                    if (newDisplayData.m_vecRecordingScreens[iScreenIndex] == oldDisplayData.m_vecRecordingScreens[iScreenIndex])
+                        continue;
+
                     CCaptureScreenSettings recordingScreenSettings = recordingScreenSettingsVector.at(iScreenIndex);
 
@@ -1561,4 +1562,5 @@
                     {
                         recordingScreenSettings.SetFileName(newDisplayData.m_strRecordingFilePath);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
@@ -1567,4 +1569,5 @@
                     {
                         recordingScreenSettings.SetVideoWidth(newDisplayData.m_iRecordingVideoFrameWidth);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
@@ -1573,4 +1576,5 @@
                     {
                         recordingScreenSettings.SetVideoHeight(newDisplayData.m_iRecordingVideoFrameHeight);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
@@ -1579,4 +1583,5 @@
                     {
                         recordingScreenSettings.SetVideoFPS(newDisplayData.m_iRecordingVideoFrameRate);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
@@ -1585,4 +1590,5 @@
                     {
                         recordingScreenSettings.SetVideoRate(newDisplayData.m_iRecordingVideoBitRate);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
@@ -1591,13 +1597,25 @@
                     {
                         recordingScreenSettings.SetOptions(newDisplayData.m_strRecordingVideoOptions);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
-                    /* Save recording screens: */
+                    /* Finally, save the screen's recording state: */
+                    /* Note: Must come last, as modifying options with an enabled recording state is not possible. */
                     if (fSuccess && newDisplayData.m_vecRecordingScreens != oldDisplayData.m_vecRecordingScreens)
                     {
                         recordingScreenSettings.SetEnabled(newDisplayData.m_vecRecordingScreens[iScreenIndex]);
+                        Assert(recordingScreenSettings.isOk());
                         fSuccess = recordingScreenSettings.isOk();
                     }
                 }
+
+                /* Save whether recording is enabled:
+                 * Do this last, as after enabling recording no changes via API aren't allowed anymore. */
+                if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
+                {
+                    recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
+                    Assert(recordingSettings.isOk());
+                    fSuccess = recordingSettings.isOk();
+                }
             }
         }
@@ -1605,15 +1623,10 @@
         else
         {
-            // For 'offline', 'powered off' and 'saved' states the order is irrelevant.
-            /* Save whether recording is enabled: */
-            if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
-            {
-                recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
-                fSuccess = recordingSettings.isOk();
-            }
-
             CCaptureScreenSettingsVector recordingScreenSettingsVector = recordingSettings.GetScreens();
             for (int iScreenIndex = 0; fSuccess && iScreenIndex < recordingScreenSettingsVector.size(); ++iScreenIndex)
             {
+                if (newDisplayData.m_vecRecordingScreens[iScreenIndex] == oldDisplayData.m_vecRecordingScreens[iScreenIndex])
+                    continue;
+
                 CCaptureScreenSettings recordingScreenSettings = recordingScreenSettingsVector.at(iScreenIndex);
 
@@ -1622,4 +1635,5 @@
                 {
                     recordingScreenSettings.SetFileName(newDisplayData.m_strRecordingFilePath);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
@@ -1628,4 +1642,5 @@
                 {
                     recordingScreenSettings.SetVideoWidth(newDisplayData.m_iRecordingVideoFrameWidth);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
@@ -1634,4 +1649,5 @@
                 {
                     recordingScreenSettings.SetVideoHeight(newDisplayData.m_iRecordingVideoFrameHeight);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
@@ -1640,4 +1656,5 @@
                 {
                     recordingScreenSettings.SetVideoFPS(newDisplayData.m_iRecordingVideoFrameRate);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
@@ -1646,4 +1663,5 @@
                 {
                     recordingScreenSettings.SetVideoRate(newDisplayData.m_iRecordingVideoBitRate);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
@@ -1652,12 +1670,24 @@
                 {
                     recordingScreenSettings.SetOptions(newDisplayData.m_strRecordingVideoOptions);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
-                /* Save screen enabled state: */
+                /* Finally, save the screen's recording state: */
+                /* Note: Must come last, as modifying options with an enabled recording state is not possible. */
                 if (fSuccess && newDisplayData.m_vecRecordingScreens != oldDisplayData.m_vecRecordingScreens)
                 {
                     recordingScreenSettings.SetEnabled(newDisplayData.m_vecRecordingScreens[iScreenIndex]);
+                    Assert(recordingScreenSettings.isOk());
                     fSuccess = recordingScreenSettings.isOk();
                 }
+            }
+
+            /* Save whether recording is enabled:
+             * Do this last, as after enabling recording no changes via API aren't allowed anymore. */
+            if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
+            {
+                recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
+                Assert(recordingSettings.isOk());
+                fSuccess = recordingSettings.isOk();
             }
         }
Index: trunk/src/VBox/Main/include/CaptureScreenSettingsImpl.h
===================================================================
--- trunk/src/VBox/Main/include/CaptureScreenSettingsImpl.h	(revision 75323)
+++ trunk/src/VBox/Main/include/CaptureScreenSettingsImpl.h	(revision 75324)
@@ -23,4 +23,6 @@
 #include "CaptureScreenSettingsWrap.h"
 
+class CaptureSettings;
+
 namespace settings
 {
@@ -39,7 +41,7 @@
 
     // public initializer/uninitializer for internal purposes only
-    HRESULT init(Machine *aParent, uint32_t uScreenId, const settings::CaptureScreenSettings& data);
-    HRESULT init(Machine *aParent, CaptureScreenSettings *that);
-    HRESULT initCopy(Machine *aParent, CaptureScreenSettings *that);
+    HRESULT init(CaptureSettings *aParent, uint32_t uScreenId, const settings::CaptureScreenSettings& data);
+    HRESULT init(CaptureSettings *aParent, CaptureScreenSettings *that);
+    HRESULT initCopy(CaptureSettings *aParent, CaptureScreenSettings *that);
     void uninit();
 
@@ -102,5 +104,4 @@
 
     // internal methods
-    int  i_getDefaultFileName(Utf8Str &strFile);
     int  i_initInternal();
 
Index: trunk/src/VBox/Main/include/CaptureSettingsImpl.h
===================================================================
--- trunk/src/VBox/Main/include/CaptureSettingsImpl.h	(revision 75323)
+++ trunk/src/VBox/Main/include/CaptureSettingsImpl.h	(revision 75324)
@@ -56,7 +56,18 @@
     void i_applyDefaults(void);
 
+    int i_getDefaultFileName(Utf8Str &strFile);
+    bool i_canChangeSettings(void);
+    void i_onSettingsChanged(void);
+
 private:
 
-    int i_addScreen(uint32_t uScreenId, const settings::CaptureScreenSettings &data);
+    /** Map of screen settings objects. The key specifies the screen ID. */
+    typedef std::map <uint32_t, ComObjPtr<CaptureScreenSettings> > CaptureScreenSettingsMap;
+
+    void i_reset(void);
+    int i_syncToMachineDisplays(void);
+    int i_createScreenObj(CaptureScreenSettingsMap &screenSettingsMap, uint32_t uScreenId, const settings::CaptureScreenSettings &data);
+    int i_destroyScreenObj(CaptureScreenSettingsMap &screenSettingsMap, uint32_t uScreenId);
+    int i_destroyAllScreenObj(CaptureScreenSettingsMap &screenSettingsMap);
 
 private:
@@ -72,7 +83,4 @@
 private:
 
-    /** Map of screen settings objects. The key specifies the screen ID. */
-    typedef std::map <uint32_t, ComObjPtr<CaptureScreenSettings> > CaptureScreenSettingsMap;
-
     struct Data;
     Data *m;
Index: trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- trunk/src/VBox/Main/include/MachineImpl.h	(revision 75323)
+++ trunk/src/VBox/Main/include/MachineImpl.h	(revision 75324)
@@ -489,4 +489,5 @@
     Utf8Str i_getOSTypeId() const { return mUserData->s.strOsType; }
     ChipsetType_T i_getChipsetType() const { return mHWData->mChipsetType; }
+    ULONG i_getMonitorCount() const { return mHWData->mMonitorCount; }
     ParavirtProvider_T i_getParavirtProvider() const { return mHWData->mParavirtProvider; }
     Utf8Str i_getParavirtDebug() const { return mHWData->mParavirtDebug; }
Index: trunk/src/VBox/Main/src-server/CaptureScreenSettingsImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/CaptureScreenSettingsImpl.cpp	(revision 75323)
+++ trunk/src/VBox/Main/src-server/CaptureScreenSettingsImpl.cpp	(revision 75324)
@@ -17,5 +17,9 @@
  */
 
+#define LOG_GROUP LOG_GROUP_MAIN_CAPTURESCREENSETTINGS
+#include "LoggingNew.h"
+
 #include "CaptureScreenSettingsImpl.h"
+#include "CaptureSettingsImpl.h"
 #include "MachineImpl.h"
 
@@ -27,5 +31,4 @@
 #include "AutoCaller.h"
 #include "Global.h"
-#include "Logging.h"
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -38,8 +41,8 @@
 {
     Data()
-        : pMachine(NULL)
+        : pParent(NULL)
     { }
 
-    Machine * const                  pMachine;
+    CaptureSettings * const          pParent;
     ComObjPtr<CaptureScreenSettings> pPeer;
     uint32_t                         uScreenId;
@@ -73,5 +76,5 @@
  * @returns COM result indicator
  */
-HRESULT CaptureScreenSettings::init(Machine *aParent, uint32_t uScreenId, const settings::CaptureScreenSettings& data)
+HRESULT CaptureScreenSettings::init(CaptureSettings *aParent, uint32_t uScreenId, const settings::CaptureScreenSettings& data)
 {
     LogFlowThisFuncEnter();
@@ -86,6 +89,6 @@
     m = new Data();
 
-    /* Share the parent weakly. */
-    unconst(m->pMachine) = aParent;
+    /* Share the parent & machine weakly. */
+    unconst(m->pParent)  = aParent;
     /* mPeer is left null. */
 
@@ -120,5 +123,5 @@
  *  it shares data with is destroyed.
  */
-HRESULT CaptureScreenSettings::init(Machine *aParent, CaptureScreenSettings *that)
+HRESULT CaptureScreenSettings::init(CaptureSettings *aParent, CaptureScreenSettings *that)
 {
     LogFlowThisFuncEnter();
@@ -133,5 +136,5 @@
     m = new Data();
 
-    unconst(m->pMachine) = aParent;
+    unconst(m->pParent) = aParent;
     m->pPeer = that;
 
@@ -163,5 +166,5 @@
  *  of the original object passed as an argument.
  */
-HRESULT CaptureScreenSettings::initCopy(Machine *aParent, CaptureScreenSettings *that)
+HRESULT CaptureScreenSettings::initCopy(CaptureSettings *aParent, CaptureScreenSettings *that)
 {
     LogFlowThisFuncEnter();
@@ -176,5 +179,5 @@
     m = new Data();
 
-    unconst(m->pMachine) = aParent;
+    unconst(m->pParent) = aParent;
     /* mPeer is left null. */
 
@@ -217,5 +220,5 @@
 
     unconst(m->pPeer) = NULL;
-    unconst(m->pMachine) = NULL;
+    unconst(m->pParent) = NULL;
 
     delete m;
@@ -227,4 +230,9 @@
 HRESULT CaptureScreenSettings::isFeatureEnabled(CaptureFeature_T aFeature, BOOL *aEnabled)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     settings::CaptureFeatureMap::const_iterator itFeature = m->bd->featureMap.find(aFeature);
 
@@ -237,4 +245,7 @@
 HRESULT CaptureScreenSettings::getEnabled(BOOL *enabled)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -246,4 +257,12 @@
 HRESULT CaptureScreenSettings::setEnabled(BOOL enabled)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    LogFlowThisFunc(("Screen %RU32\n", m->uScreenId));
+
+    if (!m->pParent->i_canChangeSettings())
+        return setError(E_INVALIDARG, tr("Cannot change enabled state of screen while capturing is enabled"));
+
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -254,19 +273,8 @@
         alock.release();
 
-        AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-        m->pMachine->i_setModified(Machine::IsModified_Capture);
-        mlock.release();
-
-        HRESULT rc = m->pMachine->i_onCaptureChange();
-        if (FAILED(rc)) return rc;
-
-        /** Save settings if online - @todo why is this required? -- @bugref{6818} */
-        AutoAnyStateDependency adep(m->pMachine);
-        AssertComRCReturn(adep.rc(), E_UNEXPECTED);
-
-        if (Global::IsOnline(adep.machineState()))
-            m->pMachine->i_saveSettings(NULL);
+        m->pParent->i_onSettingsChanged();
     }
 
+    LogFlowThisFunc(("Screen %RU32\n", m->uScreenId));
     return S_OK;
 }
@@ -274,4 +282,7 @@
 HRESULT CaptureScreenSettings::getFeatures(ULONG *aFeatures)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -292,8 +303,11 @@
 HRESULT CaptureScreenSettings::setFeatures(ULONG aFeatures)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change features while capturing is enabled"));
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     m->bd.backup();
@@ -307,8 +321,4 @@
     alock.release();
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -316,4 +326,7 @@
 HRESULT CaptureScreenSettings::getDestination(CaptureDestination_T *aDestination)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -325,18 +338,15 @@
 HRESULT CaptureScreenSettings::setDestination(CaptureDestination_T aDestination)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change destination type while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->enmDest = aDestination;
 
-    alock.release();
-
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -344,4 +354,7 @@
 HRESULT CaptureScreenSettings::getFileName(com::Utf8Str &aFileName)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -353,8 +366,11 @@
 HRESULT CaptureScreenSettings::setFileName(const com::Utf8Str &aFileName)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change file name while capturing is enabled"));
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     Utf8Str strFile(aFileName);
@@ -366,10 +382,4 @@
     m->bd->File.strName = strFile;
 
-    alock.release();
-
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -377,4 +387,7 @@
 HRESULT CaptureScreenSettings::getMaxTime(ULONG *aMaxTimeS)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -386,16 +399,15 @@
 HRESULT CaptureScreenSettings::setMaxTime(ULONG aMaxTimeS)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change maximum time while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->ulMaxTimeS = aMaxTimeS;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -403,4 +415,7 @@
 HRESULT CaptureScreenSettings::getMaxFileSize(ULONG *aMaxFileSizeMB)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -412,16 +427,15 @@
 HRESULT CaptureScreenSettings::setMaxFileSize(ULONG aMaxFileSize)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change maximum file size while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->File.ulMaxSizeMB = aMaxFileSize;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -429,4 +443,7 @@
 HRESULT CaptureScreenSettings::getOptions(com::Utf8Str &aOptions)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -438,16 +455,15 @@
 HRESULT CaptureScreenSettings::setOptions(const com::Utf8Str &aOptions)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change options while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->strOptions = aOptions;
 
-    alock.release();
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-
     return S_OK;
 }
@@ -455,4 +471,7 @@
 HRESULT CaptureScreenSettings::getAudioCodec(CaptureAudioCodec_T *aCodec)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -464,16 +483,15 @@
 HRESULT CaptureScreenSettings::setAudioCodec(CaptureAudioCodec_T aCodec)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change audio codec while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Audio.enmAudioCodec = aCodec;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -481,4 +499,7 @@
 HRESULT CaptureScreenSettings::getAudioHz(ULONG *aHz)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -490,16 +511,15 @@
 HRESULT CaptureScreenSettings::setAudioHz(ULONG aHz)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change audio Hertz rate while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Audio.uHz = (uint16_t)aHz;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -507,4 +527,7 @@
 HRESULT CaptureScreenSettings::getAudioBits(ULONG *aBits)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -516,16 +539,15 @@
 HRESULT CaptureScreenSettings::setAudioBits(ULONG aBits)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change audio bits while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Audio.cBits = (uint8_t)aBits;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -533,4 +555,7 @@
 HRESULT CaptureScreenSettings::getAudioChannels(ULONG *aChannels)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -542,16 +567,15 @@
 HRESULT CaptureScreenSettings::setAudioChannels(ULONG aChannels)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change audio channels while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Audio.cChannels = (uint8_t)aChannels;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -559,4 +583,7 @@
 HRESULT CaptureScreenSettings::getVideoCodec(CaptureVideoCodec_T *aCodec)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -568,16 +595,15 @@
 HRESULT CaptureScreenSettings::setVideoCodec(CaptureVideoCodec_T aCodec)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video codec while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Video.enmCodec = aCodec;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -585,4 +611,7 @@
 HRESULT CaptureScreenSettings::getVideoWidth(ULONG *aVideoWidth)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -594,16 +623,15 @@
 HRESULT CaptureScreenSettings::setVideoWidth(ULONG aVideoWidth)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video width while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Video.ulWidth = aVideoWidth;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -611,4 +639,7 @@
 HRESULT CaptureScreenSettings::getVideoHeight(ULONG *aVideoHeight)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -620,16 +651,15 @@
 HRESULT CaptureScreenSettings::setVideoHeight(ULONG aVideoHeight)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video height while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Video.ulHeight = aVideoHeight;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -637,4 +667,7 @@
 HRESULT CaptureScreenSettings::getVideoRate(ULONG *aVideoRate)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -646,16 +679,15 @@
 HRESULT CaptureScreenSettings::setVideoRate(ULONG aVideoRate)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video rate while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Video.ulRate = aVideoRate;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -663,4 +695,7 @@
 HRESULT CaptureScreenSettings::getVideoRateControlMode(CaptureVideoRateControlMode_T *aMode)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -672,8 +707,11 @@
 HRESULT CaptureScreenSettings::setVideoRateControlMode(CaptureVideoRateControlMode_T aMode)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video rate control mode while capturing is enabled"));
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     /** @todo Implement this. */
@@ -685,4 +723,7 @@
 HRESULT CaptureScreenSettings::getVideoFPS(ULONG *aVideoFPS)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -694,16 +735,15 @@
 HRESULT CaptureScreenSettings::setVideoFPS(ULONG aVideoFPS)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video FPS while capturing is enabled"));
 
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
     m->bd.backup();
     m->bd->Video.ulFPS = aVideoFPS;
 
-    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
-    m->pMachine->i_setModified(Machine::IsModified_Capture);
-    mlock.release();
-
     return S_OK;
 }
@@ -711,4 +751,7 @@
 HRESULT CaptureScreenSettings::getVideoScalingMethod(CaptureVideoScalingMethod_T *aMode)
 {
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -720,8 +763,11 @@
 HRESULT CaptureScreenSettings::setVideoScalingMethod(CaptureVideoScalingMethod_T aMode)
 {
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (m->bd->fEnabled)
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    if (!m->pParent->i_canChangeSettings())
         return setError(E_INVALIDARG, tr("Cannot change video rate scaling method while capturing is enabled"));
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     /** @todo Implement this. */
@@ -729,18 +775,4 @@
 
     return E_NOTIMPL;
-}
-
-/**
- * Returns the full path to the default video capture file.
- */
-int CaptureScreenSettings::i_getDefaultFileName(Utf8Str &strFile)
-{
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    strFile = m->pMachine->i_getSettingsFileFull(); // path/to/machinesfolder/vmname/vmname.vbox
-    strFile.stripSuffix();                          // path/to/machinesfolder/vmname/vmname
-    strFile.append(".webm");                        // path/to/machinesfolder/vmname/vmname.webm
-
-    return VINF_SUCCESS;
 }
 
@@ -753,5 +785,21 @@
 {
     Assert(m);
-    return i_getDefaultFileName(m->bd->File.strName);
-}
-
+
+    int rc = VINF_SUCCESS;
+
+    switch (m->bd->enmDest)
+    {
+        case CaptureDestination_File:
+        {
+            if (m->bd->File.strName.isEmpty())
+                rc = m->pParent->i_getDefaultFileName(m->bd->File.strName);
+            break;
+        }
+
+        default:
+            break;
+    }
+
+    return rc;
+}
+
Index: trunk/src/VBox/Main/src-server/CaptureSettingsImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/CaptureSettingsImpl.cpp	(revision 75323)
+++ trunk/src/VBox/Main/src-server/CaptureSettingsImpl.cpp	(revision 75324)
@@ -17,4 +17,7 @@
  */
 
+#define LOG_GROUP LOG_GROUP_MAIN_CAPTURESETTINGS
+#include "LoggingNew.h"
+
 #include "CaptureSettingsImpl.h"
 #include "CaptureScreenSettingsImpl.h"
@@ -27,5 +30,4 @@
 #include "AutoCaller.h"
 #include "Global.h"
-#include "Logging.h"
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -43,5 +45,5 @@
     Machine * const             pMachine;
     ComObjPtr<CaptureSettings>  pPeer;
-    CaptureScreenSettingsMap    mapScreenSettings;
+    CaptureScreenSettingsMap    mapScreenObj;
     bool                        fHasMachineLock;
 
@@ -120,5 +122,5 @@
 
     m->bd.share(that->m->bd);
-    m->mapScreenSettings = that->m->mapScreenSettings;
+    m->mapScreenObj = that->m->mapScreenObj;
     m->fHasMachineLock = false;
 
@@ -153,5 +155,5 @@
 
     m->bd.attachCopy(that->m->bd);
-    m->mapScreenSettings = that->m->mapScreenSettings;
+    m->mapScreenObj = that->m->mapScreenObj;
     m->fHasMachineLock = false;
 
@@ -175,4 +177,7 @@
         return;
 
+    /* Note: Do *not* call i_reset() here, as the shared recording configuration
+     *       otherwise gets destructed when this object goes out of scope or is destroyed. */
+
     m->bd.free();
 
@@ -200,4 +205,6 @@
 HRESULT CaptureSettings::setEnabled(BOOL enable)
 {
+    LogFlowThisFuncEnter();
+
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
@@ -223,5 +230,4 @@
             alock.acquire();
             m->bd->fEnabled = m->bd.backedUpData()->fEnabled;
-            return rc;
         }
         else
@@ -247,12 +253,16 @@
 HRESULT CaptureSettings::getScreens(std::vector<ComPtr<ICaptureScreenSettings> > &aCaptureScreenSettings)
 {
+    LogFlowThisFuncEnter();
+
+    i_syncToMachineDisplays();
+
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
     aCaptureScreenSettings.clear();
-    aCaptureScreenSettings.resize(m->mapScreenSettings.size());
-
-    CaptureScreenSettingsMap::const_iterator itScreenSettings = m->mapScreenSettings.begin();
+    aCaptureScreenSettings.resize(m->mapScreenObj.size());
+
+    CaptureScreenSettingsMap::const_iterator itScreenSettings = m->mapScreenObj.begin();
     size_t i = 0;
-    while (itScreenSettings != m->mapScreenSettings.end())
+    while (itScreenSettings != m->mapScreenObj.end())
     {
         itScreenSettings->second.queryInterfaceTo(aCaptureScreenSettings[i].asOutParam());
@@ -262,5 +272,5 @@
     }
 
-    Assert(aCaptureScreenSettings.size() == m->mapScreenSettings.size());
+    Assert(aCaptureScreenSettings.size() == m->mapScreenObj.size());
 
     return S_OK;
@@ -269,9 +279,15 @@
 HRESULT CaptureSettings::getScreenSettings(ULONG uScreenId, ComPtr<ICaptureScreenSettings> &aCaptureScreenSettings)
 {
-    if (uScreenId + 1 > m->mapScreenSettings.size())
+    LogFlowThisFuncEnter();
+
+    i_syncToMachineDisplays();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (uScreenId + 1 > m->mapScreenObj.size())
         return setError(E_INVALIDARG, tr("Invalid screen ID specified"));
 
-    CaptureScreenSettingsMap::const_iterator itScreenSettings = m->mapScreenSettings.find(uScreenId);
-    if (itScreenSettings != m->mapScreenSettings.end())
+    CaptureScreenSettingsMap::const_iterator itScreenSettings = m->mapScreenObj.find(uScreenId);
+    if (itScreenSettings != m->mapScreenObj.end())
     {
         itScreenSettings->second.queryInterfaceTo(aCaptureScreenSettings.asOutParam());
@@ -289,13 +305,17 @@
 
 /**
- * Adds a screen settings object to the recording settings.
+ * Adds a screen settings object to a particular map.
  *
  * @returns IPRT status code. VERR_ALREADY_EXISTS if the object in question already exists.
+ * @param   screenSettingsMap   Map to add screen settings to.
  * @param   uScreenId           Screen ID to add settings for.
  * @param   data                Recording screen settings to use for that screen.
  */
-int CaptureSettings::i_addScreen(uint32_t uScreenId, const settings::CaptureScreenSettings &data)
-{
-    if (m->mapScreenSettings.find(uScreenId) != m->mapScreenSettings.end())
+int CaptureSettings::i_createScreenObj(CaptureScreenSettingsMap &screenSettingsMap,
+                                       uint32_t uScreenId, const settings::CaptureScreenSettings &data)
+{
+    LogFlowThisFunc(("Screen %RU32\n", uScreenId));
+
+    if (screenSettingsMap.find(uScreenId) != screenSettingsMap.end())
     {
         AssertFailed();
@@ -309,10 +329,10 @@
     if (SUCCEEDED(rc))
     {
-        rc = captureScreenSettings->init(m->pMachine, uScreenId, data);
+        rc = captureScreenSettings->init(this, uScreenId, data);
         if (SUCCEEDED(rc))
         {
             try
             {
-                m->mapScreenSettings[uScreenId] = captureScreenSettings;
+                screenSettingsMap[uScreenId] = captureScreenSettings;
             }
             catch (std::bad_alloc &)
@@ -327,4 +347,62 @@
 
 /**
+ * Removes a screen settings object from a particular map.
+ *
+ * @returns IPRT status code. VERR_NOT_FOUND if specified screen was not found.
+ * @param   screenSettingsMap   Map to remove screen settings from.
+ * @param   uScreenId           ID of screen to remove.
+ */
+int CaptureSettings::i_destroyScreenObj(CaptureScreenSettingsMap &screenSettingsMap, uint32_t uScreenId)
+{
+    LogFlowThisFunc(("Screen %RU32\n", uScreenId));
+
+    AssertReturn(uScreenId > 0, VERR_INVALID_PARAMETER); /* Removing screen 0 isn't a good idea. */
+
+    CaptureScreenSettingsMap::iterator itScreen = screenSettingsMap.find(uScreenId);
+    if (itScreen == screenSettingsMap.end())
+    {
+        AssertFailed();
+        return VERR_NOT_FOUND;
+    }
+
+    /* Make sure to consume the pointer before the one of the
+     * iterator gets released. */
+    ComObjPtr<CaptureScreenSettings> pScreenSettings = itScreen->second;
+
+    screenSettingsMap.erase(itScreen);
+
+    pScreenSettings.setNull();
+
+    return VINF_SUCCESS;
+}
+
+/**
+ * Destroys all screen settings objects of a particular map.
+ *
+ * @returns IPRT status code.
+ * @param   screenSettingsMap   Map to destroy screen settings objects for.
+ */
+int CaptureSettings::i_destroyAllScreenObj(CaptureScreenSettingsMap &screenSettingsMap)
+{
+    LogFlowThisFuncEnter();
+
+    CaptureScreenSettingsMap::const_iterator itScreen = screenSettingsMap.begin();
+    if (itScreen != screenSettingsMap.end())
+    {
+        /* Make sure to consume the pointer before the one of the
+         * iterator gets released. */
+        ComObjPtr<CaptureScreenSettings> pScreenSettings = itScreen->second;
+
+        screenSettingsMap.erase(itScreen);
+
+        pScreenSettings.setNull();
+
+        itScreen = screenSettingsMap.begin();
+    }
+
+    return VINF_SUCCESS;
+}
+
+/**
  * Loads settings from the given settings.
  * May be called once right after this object creation.
@@ -336,4 +414,6 @@
 HRESULT CaptureSettings::i_loadSettings(const settings::CaptureSettings &data)
 {
+    LogFlowThisFuncEnter();
+
     AutoCaller autoCaller(this);
     AssertComRCReturnRC(autoCaller.rc());
@@ -343,10 +423,13 @@
     HRESULT rc = S_OK;
 
-    m->mapScreenSettings.clear();
+    i_reset();
+
+    LogFlowThisFunc(("Data has %zu screens\n", data.mapScreens.size()));
 
     settings::CaptureScreenMap::const_iterator itScreen = data.mapScreens.begin();
     while (itScreen != data.mapScreens.end())
     {
-        int vrc = i_addScreen(itScreen->first /* uScreenId */, itScreen->second /* Settings */);
+        int vrc = i_createScreenObj(m->mapScreenObj,
+                                    itScreen->first /* uScreenId */, itScreen->second /* Settings */);
         if (RT_FAILURE(vrc))
         {
@@ -362,13 +445,25 @@
 
     ComAssertComRC(rc);
-    Assert(m->mapScreenSettings.size() == data.mapScreens.size());
+    Assert(m->mapScreenObj.size() == data.mapScreens.size());
 
     // simply copy
     m->bd.assignCopy(&data);
 
+    LogFlowThisFunc(("Returning %Rhrc\n", rc));
     return rc;
 }
 
 /**
+ * Resets the internal object state by destroying all screen settings objects.
+ */
+void CaptureSettings::i_reset(void)
+{
+    LogFlowThisFuncEnter();
+
+    i_destroyAllScreenObj(m->mapScreenObj);
+    m->bd->mapScreens.clear();
+}
+
+/**
  * Saves settings to the given settings.
  *
@@ -379,6 +474,11 @@
 HRESULT CaptureSettings::i_saveSettings(settings::CaptureSettings &data)
 {
+    LogFlowThisFuncEnter();
+
     AutoCaller autoCaller(this);
     AssertComRCReturnRC(autoCaller.rc());
+
+    int rc2 = i_syncToMachineDisplays();
+    AssertRC(rc2);
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -395,4 +495,5 @@
     }
 
+    LogFlowThisFuncLeave();
     return S_OK;
 }
@@ -462,2 +563,99 @@
 }
 
+/**
+ * Returns the full path to the default video capture file.
+ */
+int CaptureSettings::i_getDefaultFileName(Utf8Str &strFile)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    strFile = m->pMachine->i_getSettingsFileFull(); // path/to/machinesfolder/vmname/vmname.vbox
+    strFile.stripSuffix();                          // path/to/machinesfolder/vmname/vmname
+    strFile.append(".webm");                        // path/to/machinesfolder/vmname/vmname.webm
+
+    return VINF_SUCCESS;
+}
+
+/**
+ * Determines whether the recording settings currently can be changed or not.
+ *
+ * @returns \c true if the settings can be changed, \c false if not.
+ */
+bool CaptureSettings::i_canChangeSettings(void)
+{
+    AutoAnyStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc()))
+        return false;
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    /* Only allow settings to be changed when recording is disabled. */
+    return m->bd->fEnabled == false;
+}
+
+/**
+ * Gets called when the machine object needs to know that the recording settings
+ * have been changed.
+ */
+void CaptureSettings::i_onSettingsChanged(void)
+{
+    LogFlowThisFuncEnter();
+
+    AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
+    m->pMachine->i_setModified(Machine::IsModified_Capture);
+    mlock.release();
+
+    LogFlowThisFuncLeave();
+}
+
+/**
+ * Synchronizes the screen settings (COM) objects and configuration data
+ * to the number of the machine's configured displays.
+ */
+int CaptureSettings::i_syncToMachineDisplays(void)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    AssertPtr(m->pMachine);
+    const ULONG cMonitors = m->pMachine->i_getMonitorCount();
+
+    LogFlowThisFunc(("cMonitors=%RU32\n", cMonitors));
+    LogFlowThisFunc(("Data screen count = %zu, COM object count = %zu\n", m->bd->mapScreens.size(), m->mapScreenObj.size()));
+
+    /* If counts match, take a shortcut. */
+    if (cMonitors == m->mapScreenObj.size())
+        return VINF_SUCCESS;
+
+    /* Create all new screen settings objects which are not there yet. */
+    for (ULONG i = 0; i < cMonitors; i++)
+    {
+        if (m->mapScreenObj.find(i) == m->mapScreenObj.end())
+        {
+            settings::CaptureScreenMap::const_iterator itScreen = m->bd->mapScreens.find(i);
+            if (itScreen == m->bd->mapScreens.end())
+            {
+                settings::CaptureScreenSettings defaultScreenSettings; /* Apply default settings. */
+                m->bd->mapScreens[i] = defaultScreenSettings;
+            }
+
+            int vrc2 = i_createScreenObj(m->mapScreenObj, i /* Screen ID */, m->bd->mapScreens[i]);
+            AssertRC(vrc2);
+        }
+    }
+
+    /* Remove all left over screen settings objects which are not needed anymore. */
+    const ULONG cSettings = (ULONG)m->mapScreenObj.size();
+    for (ULONG i = cMonitors; i < cSettings; i++)
+    {
+        m->bd->mapScreens.erase(i);
+        int vrc2 = i_destroyScreenObj(m->mapScreenObj, i /* Screen ID */);
+        AssertRC(vrc2);
+    }
+
+    Assert(m->mapScreenObj.size() == cMonitors);
+    Assert(m->bd->mapScreens.size() == cMonitors);
+
+    LogFlowThisFuncLeave();
+    return VINF_SUCCESS;
+}
+
Index: trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- trunk/src/VBox/Main/xml/Settings.cpp	(revision 75323)
+++ trunk/src/VBox/Main/xml/Settings.cpp	(revision 75324)
@@ -4432,9 +4432,9 @@
             for (unsigned i = 0; i < hw.cMonitors; i++) /* Don't add more settings than we have monitors configured. */
             {
+                /* Add screen i to config in any case. */
+                hw.captureSettings.mapScreens[i] = screen0Settings;
+
                 if (u64VideoCaptureScreens & RT_BIT_64(i)) /* Screen i enabled? */
-                {
-                    hw.captureSettings.mapScreens[i] = screen0Settings;
                     hw.captureSettings.mapScreens[i].fEnabled = true;
-                }
             }
         }
