summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/include')
-rw-r--r--src/VBox/Main/include/AdditionsFacilityImpl.h110
-rw-r--r--src/VBox/Main/include/ApplianceImpl.h366
-rw-r--r--src/VBox/Main/include/ApplianceImplPrivate.h571
-rw-r--r--src/VBox/Main/include/AudioAdapterImpl.h94
-rw-r--r--src/VBox/Main/include/AudioDriver.h144
-rw-r--r--src/VBox/Main/include/AudioSettingsImpl.h84
-rw-r--r--src/VBox/Main/include/AuthLibrary.h54
-rw-r--r--src/VBox/Main/include/AutoCaller.h537
-rw-r--r--src/VBox/Main/include/AutoStateDep.h214
-rw-r--r--src/VBox/Main/include/AutostartDb.h109
-rw-r--r--src/VBox/Main/include/BIOSSettingsImpl.h102
-rw-r--r--src/VBox/Main/include/BandwidthControlImpl.h111
-rw-r--r--src/VBox/Main/include/BandwidthGroupImpl.h115
-rw-r--r--src/VBox/Main/include/BusAssignmentManager.h90
-rw-r--r--src/VBox/Main/include/CPUProfileImpl.h75
-rw-r--r--src/VBox/Main/include/CertificateImpl.h112
-rw-r--r--src/VBox/Main/include/ClientToken.h118
-rw-r--r--src/VBox/Main/include/ClientTokenHolder.h112
-rw-r--r--src/VBox/Main/include/ClientWatcher.h146
-rw-r--r--src/VBox/Main/include/CloudGateway.h103
-rw-r--r--src/VBox/Main/include/CloudNetworkImpl.h79
-rw-r--r--src/VBox/Main/include/CloudProviderManagerImpl.h82
-rw-r--r--src/VBox/Main/include/ConsoleImpl.h1222
-rw-r--r--src/VBox/Main/include/ConsoleSharedFolderImpl.h124
-rw-r--r--src/VBox/Main/include/ConsoleVRDPServer.h428
-rw-r--r--src/VBox/Main/include/CryptoUtils.h141
-rw-r--r--src/VBox/Main/include/DHCPConfigImpl.h529
-rw-r--r--src/VBox/Main/include/DHCPServerImpl.h130
-rw-r--r--src/VBox/Main/include/DataStreamImpl.h78
-rw-r--r--src/VBox/Main/include/DisplayImpl.h562
-rw-r--r--src/VBox/Main/include/DisplayUtils.h57
-rw-r--r--src/VBox/Main/include/DrvAudioRec.h79
-rw-r--r--src/VBox/Main/include/DrvAudioVRDE.h87
-rw-r--r--src/VBox/Main/include/EBMLWriter.h135
-rw-r--r--src/VBox/Main/include/EBML_MKV.h106
-rw-r--r--src/VBox/Main/include/EmulatedUSBImpl.h103
-rw-r--r--src/VBox/Main/include/EventImpl.h188
-rw-r--r--src/VBox/Main/include/ExtPackManagerImpl.h322
-rw-r--r--src/VBox/Main/include/ExtPackUtil.h158
-rw-r--r--src/VBox/Main/include/Global.h255
-rw-r--r--src/VBox/Main/include/GraphicsAdapterImpl.h88
-rw-r--r--src/VBox/Main/include/GuestCtrlImplPrivate.h1459
-rw-r--r--src/VBox/Main/include/GuestDebugControlImpl.h82
-rw-r--r--src/VBox/Main/include/GuestDirectoryImpl.h108
-rw-r--r--src/VBox/Main/include/GuestDnDPrivate.h1108
-rw-r--r--src/VBox/Main/include/GuestDnDSourceImpl.h131
-rw-r--r--src/VBox/Main/include/GuestDnDTargetImpl.h128
-rw-r--r--src/VBox/Main/include/GuestFileImpl.h161
-rw-r--r--src/VBox/Main/include/GuestFsObjInfoImpl.h86
-rw-r--r--src/VBox/Main/include/GuestImpl.h282
-rw-r--r--src/VBox/Main/include/GuestOSTypeImpl.h131
-rw-r--r--src/VBox/Main/include/GuestProcessImpl.h310
-rw-r--r--src/VBox/Main/include/GuestSessionImpl.h460
-rw-r--r--src/VBox/Main/include/GuestSessionImplTasks.h436
-rw-r--r--src/VBox/Main/include/HGCM.h69
-rw-r--r--src/VBox/Main/include/HGCMObjects.h138
-rw-r--r--src/VBox/Main/include/HGCMThread.h238
-rw-r--r--src/VBox/Main/include/HashedPw.h40
-rw-r--r--src/VBox/Main/include/HostAudioDeviceImpl.h58
-rw-r--r--src/VBox/Main/include/HostDriveImpl.h86
-rw-r--r--src/VBox/Main/include/HostDrivePartitionImpl.h126
-rw-r--r--src/VBox/Main/include/HostHardwareLinux.h209
-rw-r--r--src/VBox/Main/include/HostImpl.h227
-rw-r--r--src/VBox/Main/include/HostNetworkInterfaceImpl.h145
-rw-r--r--src/VBox/Main/include/HostOnlyNetworkImpl.h80
-rw-r--r--src/VBox/Main/include/HostPower.h136
-rw-r--r--src/VBox/Main/include/HostUSBDeviceImpl.h327
-rw-r--r--src/VBox/Main/include/HostVideoInputDeviceImpl.h82
-rw-r--r--src/VBox/Main/include/KeyboardImpl.h110
-rw-r--r--src/VBox/Main/include/LoggingNew.h60
-rw-r--r--src/VBox/Main/include/MachineDebuggerImpl.h176
-rw-r--r--src/VBox/Main/include/MachineImpl.h1691
-rw-r--r--src/VBox/Main/include/MachineImplCloneVM.h63
-rw-r--r--src/VBox/Main/include/MachineImplMoveVM.h146
-rw-r--r--src/VBox/Main/include/MachineLaunchVMCommonWorker.h49
-rw-r--r--src/VBox/Main/include/Makefile.kup0
-rw-r--r--src/VBox/Main/include/Matching.h540
-rw-r--r--src/VBox/Main/include/MediumAttachmentImpl.h146
-rw-r--r--src/VBox/Main/include/MediumFormatImpl.h125
-rw-r--r--src/VBox/Main/include/MediumIOImpl.h92
-rw-r--r--src/VBox/Main/include/MediumImpl.h474
-rw-r--r--src/VBox/Main/include/MediumLock.h354
-rw-r--r--src/VBox/Main/include/MouseImpl.h175
-rw-r--r--src/VBox/Main/include/NATEngineImpl.h124
-rw-r--r--src/VBox/Main/include/NATNetworkImpl.h143
-rw-r--r--src/VBox/Main/include/NetworkAdapterImpl.h141
-rw-r--r--src/VBox/Main/include/NetworkServiceRunner.h87
-rw-r--r--src/VBox/Main/include/NvramStoreImpl.h156
-rw-r--r--src/VBox/Main/include/ObjectState.h150
-rw-r--r--src/VBox/Main/include/PCIDeviceAttachmentImpl.h79
-rw-r--r--src/VBox/Main/include/PCIRawDevImpl.h64
-rw-r--r--src/VBox/Main/include/ParallelPortImpl.h87
-rw-r--r--src/VBox/Main/include/Performance.h915
-rw-r--r--src/VBox/Main/include/PerformanceImpl.h206
-rw-r--r--src/VBox/Main/include/ProgressImpl.h259
-rw-r--r--src/VBox/Main/include/ProgressProxyImpl.h130
-rw-r--r--src/VBox/Main/include/QMTranslator.h79
-rw-r--r--src/VBox/Main/include/Recording.h174
-rw-r--r--src/VBox/Main/include/RecordingInternals.h504
-rw-r--r--src/VBox/Main/include/RecordingScreenSettingsImpl.h141
-rw-r--r--src/VBox/Main/include/RecordingSettingsImpl.h102
-rw-r--r--src/VBox/Main/include/RecordingStream.h234
-rw-r--r--src/VBox/Main/include/RecordingUtils.h217
-rw-r--r--src/VBox/Main/include/RemoteUSBBackend.h153
-rw-r--r--src/VBox/Main/include/RemoteUSBDeviceImpl.h136
-rw-r--r--src/VBox/Main/include/SecretKeyStore.h216
-rw-r--r--src/VBox/Main/include/SerialPortImpl.h102
-rw-r--r--src/VBox/Main/include/SessionImpl.h188
-rw-r--r--src/VBox/Main/include/SharedFolderImpl.h125
-rw-r--r--src/VBox/Main/include/SnapshotImpl.h142
-rw-r--r--src/VBox/Main/include/StorageControllerImpl.h107
-rw-r--r--src/VBox/Main/include/SystemPropertiesImpl.h220
-rw-r--r--src/VBox/Main/include/TextScript.h251
-rw-r--r--src/VBox/Main/include/ThreadTask.h78
-rw-r--r--src/VBox/Main/include/TokenImpl.h118
-rw-r--r--src/VBox/Main/include/TrustAnchorsAndCerts.h53
-rw-r--r--src/VBox/Main/include/TrustedPlatformModuleImpl.h84
-rw-r--r--src/VBox/Main/include/USBControllerImpl.h88
-rw-r--r--src/VBox/Main/include/USBDeviceFilterImpl.h240
-rw-r--r--src/VBox/Main/include/USBDeviceFiltersImpl.h97
-rw-r--r--src/VBox/Main/include/USBDeviceImpl.h118
-rw-r--r--src/VBox/Main/include/USBGetDevices.h114
-rw-r--r--src/VBox/Main/include/USBIdDatabase.h226
-rw-r--r--src/VBox/Main/include/USBProxyBackend.h448
-rw-r--r--src/VBox/Main/include/USBProxyService.h147
-rw-r--r--src/VBox/Main/include/UefiVariableStoreImpl.h105
-rw-r--r--src/VBox/Main/include/UnattendedImpl.h318
-rw-r--r--src/VBox/Main/include/UnattendedInstaller.h932
-rw-r--r--src/VBox/Main/include/UnattendedScript.h193
-rw-r--r--src/VBox/Main/include/UpdateAgentImpl.h220
-rw-r--r--src/VBox/Main/include/UsbCardReader.h87
-rw-r--r--src/VBox/Main/include/UsbWebcamInterface.h79
-rw-r--r--src/VBox/Main/include/VBoxNls.h65
-rw-r--r--src/VBox/Main/include/VFSExplorerImpl.h101
-rw-r--r--src/VBox/Main/include/VMMDev.h115
-rw-r--r--src/VBox/Main/include/VRDEServerImpl.h98
-rw-r--r--src/VBox/Main/include/VirtualBoxBase.h1118
-rw-r--r--src/VBox/Main/include/VirtualBoxClientImpl.h144
-rw-r--r--src/VBox/Main/include/VirtualBoxErrorInfoImpl.h175
-rw-r--r--src/VBox/Main/include/VirtualBoxImpl.h502
-rw-r--r--src/VBox/Main/include/VirtualBoxSDSImpl.h161
-rw-r--r--src/VBox/Main/include/VirtualBoxTranslator.h165
-rw-r--r--src/VBox/Main/include/WebMWriter.h579
-rw-r--r--src/VBox/Main/include/Wrapper.h504
-rw-r--r--src/VBox/Main/include/netif.h145
-rw-r--r--src/VBox/Main/include/objectslist.h224
-rw-r--r--src/VBox/Main/include/ovfreader.h732
-rw-r--r--src/VBox/Main/include/vbox-libhal.h80
-rw-r--r--src/VBox/Main/include/vector.h372
-rw-r--r--src/VBox/Main/include/win/resource.h43
150 files changed, 34064 insertions, 0 deletions
diff --git a/src/VBox/Main/include/AdditionsFacilityImpl.h b/src/VBox/Main/include/AdditionsFacilityImpl.h
new file mode 100644
index 00000000..c6e565b1
--- /dev/null
+++ b/src/VBox/Main/include/AdditionsFacilityImpl.h
@@ -0,0 +1,110 @@
+/* $Id: AdditionsFacilityImpl.h $ */
+/** @file
+ * VirtualBox Main - Additions facility class.
+ */
+
+/*
+ * Copyright (C) 2014-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AdditionsFacilityImpl_h
+#define MAIN_INCLUDED_AdditionsFacilityImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/time.h>
+#include "AdditionsFacilityWrap.h"
+
+class Guest;
+
+/**
+ * A Guest Additions facility.
+ */
+class ATL_NO_VTABLE AdditionsFacility :
+ public AdditionsFacilityWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(AdditionsFacility)
+
+ /** @name Initializer & uninitializer methods
+ * @{ */
+ HRESULT init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
+ void uninit();
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ /** @} */
+
+public:
+ /** @name public internal methods
+ * @{ */
+ LONG64 i_getLastUpdated() const;
+#if 0 /* unused */
+ AdditionsFacilityType_T i_getType() const;
+ AdditionsFacilityClass_T i_getClass() const;
+ const char *i_getName() const;
+#endif
+ AdditionsFacilityStatus_T i_getStatus() const;
+ bool i_update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
+ /** @} */
+
+private:
+
+ /** @name Wrapped IAdditionsFacility properties
+ * @{ */
+ HRESULT getClassType(AdditionsFacilityClass_T *aClassType);
+ HRESULT getLastUpdated(LONG64 *aLastUpdated);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getStatus(AdditionsFacilityStatus_T *aStatus);
+ HRESULT getType(AdditionsFacilityType_T *aType);
+ /** @} */
+
+ struct Data
+ {
+ /** Last update timestamp. */
+ RTTIMESPEC mTimestamp;
+ /** The facilitie's current status. */
+ AdditionsFacilityStatus_T mStatus;
+ /** Flags. */
+ uint32_t mfFlags;
+ /** The facilitie's ID/type (static). */
+ AdditionsFacilityType_T mType;
+ /** Index into s_aFacilityInfo. */
+ size_t midxInfo;
+ } mData;
+
+ /** Facility <-> string mappings. */
+ struct FacilityInfo
+ {
+ /** The facilitie's name. */
+ const char *mName; /* utf-8 */
+ /** The facilitie's type. */
+ AdditionsFacilityType_T mType;
+ /** The facilitie's class. */
+ AdditionsFacilityClass_T mClass;
+ };
+ static const FacilityInfo s_aFacilityInfo[8];
+};
+
+#endif /* !MAIN_INCLUDED_AdditionsFacilityImpl_h */
+
diff --git a/src/VBox/Main/include/ApplianceImpl.h b/src/VBox/Main/include/ApplianceImpl.h
new file mode 100644
index 00000000..08b44549
--- /dev/null
+++ b/src/VBox/Main/include/ApplianceImpl.h
@@ -0,0 +1,366 @@
+/* $Id: ApplianceImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ApplianceImpl_h
+#define MAIN_INCLUDED_ApplianceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/* VBox includes */
+#include "VirtualSystemDescriptionWrap.h"
+#include "ApplianceWrap.h"
+#include "MediumFormatImpl.h"
+
+/** @todo This file needs massive cleanup. Split IAppliance in a public and
+ * private classes. */
+#include "ovfreader.h"
+#include <set>
+
+/* VBox forward declarations */
+class Certificate;
+class Progress;
+class VirtualSystemDescription;
+struct VirtualSystemDescriptionEntry;
+struct LocationInfo;
+typedef struct VDINTERFACE *PVDINTERFACE;
+typedef struct VDINTERFACEIO *PVDINTERFACEIO;
+typedef struct SHASTORAGE *PSHASTORAGE;
+
+namespace ovf
+{
+ struct HardDiskController;
+ struct VirtualSystem;
+ class OVFReader;
+ struct DiskImage;
+ struct EnvelopeData;
+}
+
+namespace xml
+{
+ class Document;
+ class ElementNode;
+}
+
+namespace settings
+{
+ class MachineConfigFile;
+}
+
+class ATL_NO_VTABLE Appliance :
+ public ApplianceWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(Appliance)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+
+ HRESULT init(VirtualBox *aVirtualBox);
+ void uninit();
+
+ /* public methods only for internal purposes */
+
+ static HRESULT i_setErrorStatic(HRESULT aResultCode, const char *aText, ...)
+ {
+ va_list va;
+ va_start(va, aText);
+ HRESULT hrc = setErrorInternalV(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, va, false, true);
+ va_end(va);
+ return hrc;
+ }
+
+ /* private instance data */
+private:
+ // wrapped IAppliance properties
+ HRESULT getPath(com::Utf8Str &aPath);
+ HRESULT getDisks(std::vector<com::Utf8Str> &aDisks);
+ HRESULT getCertificate(ComPtr<ICertificate> &aCertificateInfo);
+ HRESULT getVirtualSystemDescriptions(std::vector<ComPtr<IVirtualSystemDescription> > &aVirtualSystemDescriptions);
+ HRESULT getMachines(std::vector<com::Utf8Str> &aMachines);
+
+ // wrapped IAppliance methods
+ HRESULT read(const com::Utf8Str &aFile,
+ ComPtr<IProgress> &aProgress);
+ HRESULT interpret();
+ HRESULT importMachines(const std::vector<ImportOptions_T> &aOptions,
+ ComPtr<IProgress> &aProgress);
+ HRESULT createVFSExplorer(const com::Utf8Str &aURI,
+ ComPtr<IVFSExplorer> &aExplorer);
+ HRESULT write(const com::Utf8Str &aFormat,
+ const std::vector<ExportOptions_T> &aOptions,
+ const com::Utf8Str &aPath,
+ ComPtr<IProgress> &aProgress);
+ HRESULT getWarnings(std::vector<com::Utf8Str> &aWarnings);
+ HRESULT getPasswordIds(std::vector<com::Utf8Str> &aIdentifiers);
+ HRESULT getMediumIdsForPasswordId(const com::Utf8Str &aPasswordId, std::vector<com::Guid> &aIdentifiers);
+ HRESULT addPasswords(const std::vector<com::Utf8Str> &aIdentifiers,
+ const std::vector<com::Utf8Str> &aPasswords);
+ HRESULT createVirtualSystemDescriptions(ULONG aRequested, ULONG *aCreated);
+ /** weak VirtualBox parent */
+ VirtualBox* const mVirtualBox;
+
+ struct ImportStack;
+ class TaskOVF;
+ class TaskOPC;
+ class TaskCloud;
+
+ struct Data; // opaque, defined in ApplianceImpl.cpp
+ Data *m;
+
+ enum SetUpProgressMode { ImportFile, ImportS3, WriteFile, WriteS3, ExportCloud, ImportCloud };
+
+ enum ApplianceState { ApplianceIdle, ApplianceImporting, ApplianceExporting };
+ void i_setApplianceState(const ApplianceState &state);
+ /** @name General stuff
+ * @{
+ */
+ bool i_isApplianceIdle();
+ HRESULT i_searchUniqueVMName(Utf8Str &aName) const;
+ HRESULT i_ensureUniqueImageFilePath(const Utf8Str &aMachineFolder,
+ DeviceType_T aDeviceType,
+ Utf8Str &aName) const;
+ HRESULT i_setUpProgress(ComObjPtr<Progress> &pProgress,
+ const Utf8Str &strDescription,
+ SetUpProgressMode mode);
+ void i_addWarning(const char* aWarning, ...);
+ void i_disksWeight();
+ void i_parseBucket(Utf8Str &aPath, Utf8Str &aBucket);
+
+ static void i_importOrExportThreadTask(TaskOVF *pTask);
+ static void i_exportOPCThreadTask(TaskOPC *pTask);
+ static void i_importOrExportCloudThreadTask(TaskCloud *pTask);
+
+ HRESULT i_initBackendNames();
+
+ Utf8Str i_typeOfVirtualDiskFormatFromURI(Utf8Str type) const;
+
+#if 0 /* unused */
+ std::set<Utf8Str> i_URIFromTypeOfVirtualDiskFormat(Utf8Str type);
+#endif
+
+ HRESULT i_findMediumFormatFromDiskImage(const ovf::DiskImage &di, ComObjPtr<MediumFormat>& mf);
+
+ RTVFSIOSTREAM i_manifestSetupDigestCalculationForGivenIoStream(RTVFSIOSTREAM hVfsIos, const char *pszManifestEntry,
+ bool fRead = true);
+ /** @} */
+
+ /** @name Read stuff
+ * @{
+ */
+ HRESULT i_readImpl(const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
+
+ HRESULT i_readFS(TaskOVF *pTask);
+ HRESULT i_readFSOVF(TaskOVF *pTask);
+ HRESULT i_readFSOVA(TaskOVF *pTask);
+ HRESULT i_readOVFFile(TaskOVF *pTask, RTVFSIOSTREAM hIosOvf, const char *pszManifestEntry);
+ HRESULT i_readManifestFile(TaskOVF *pTask, RTVFSIOSTREAM hIosMf, const char *pszSubFileNm);
+ HRESULT i_readSignatureFile(TaskOVF *pTask, RTVFSIOSTREAM hIosCert, const char *pszSubFileNm);
+ HRESULT i_readTailProcessing(TaskOVF *pTask);
+ HRESULT i_readTailProcessingGetManifestData(void **ppvData, size_t *pcbData);
+ HRESULT i_readTailProcessingSignedData(PRTERRINFOSTATIC pErrInfo);
+ HRESULT i_readTailProcessingVerifySelfSignedOvfCert(TaskOVF *pTask, RTCRSTORE hTrustedCerts, PRTERRINFOSTATIC pErrInfo);
+ HRESULT i_readTailProcessingVerifyIssuedOvfCert(TaskOVF *pTask, RTCRSTORE hTrustedStore, PRTERRINFOSTATIC pErrInfo);
+ HRESULT i_readTailProcessingVerifyContentInfoCerts(void const *pvData, size_t cbData,
+ RTCRSTORE hTrustedStore, PRTERRINFOSTATIC pErrInfo);
+ HRESULT i_readTailProcessingVerifyAnalyzeSignerInfo(void const *pvData, size_t cbData, RTCRSTORE hTrustedStore,
+ uint32_t iSigner, PRTTIMESPEC pNow, int vrc,
+ PRTERRINFOSTATIC pErrInfo, PRTCRSTORE phTrustedStore2);
+ HRESULT i_readTailProcessingVerifyContentInfoFailOne(const char *pszSignature, int vrc, PRTERRINFOSTATIC pErrInfo);
+
+ HRESULT i_gettingCloudData(TaskCloud *pTask);
+ /** @} */
+
+ /** @name Import stuff
+ * @{
+ */
+ HRESULT i_importImpl(const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
+
+ HRESULT i_importFS(TaskOVF *pTask);
+ HRESULT i_importFSOVF(TaskOVF *pTask, AutoWriteLockBase &rWriteLock);
+ HRESULT i_importFSOVA(TaskOVF *pTask, AutoWriteLockBase &rWriteLock);
+ HRESULT i_importDoIt(TaskOVF *pTask, AutoWriteLockBase &rWriteLock, RTVFSFSSTREAM hVfsFssOva = NIL_RTVFSFSSTREAM);
+
+ HRESULT i_verifyManifestFile(ImportStack &stack);
+
+ void i_convertDiskAttachmentValues(const ovf::HardDiskController &hdc,
+ uint32_t ulAddressOnParent,
+ Utf8Str &controllerName,
+ int32_t &lControllerPort,
+ int32_t &lDevice);
+
+ void i_importOneDiskImage(const ovf::DiskImage &di,
+ const Utf8Str &strDstPath,
+ ComObjPtr<Medium> &pTargetMedium,
+ ImportStack &stack);
+
+ void i_importMachineGeneric(const ovf::VirtualSystem &vsysThis,
+ ComObjPtr<VirtualSystemDescription> &vsdescThis,
+ ComPtr<IMachine> &pNewMachineRet,
+ ImportStack &stack);
+ void i_importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis,
+ ComPtr<IMachine> &pNewMachine,
+ ImportStack &stack);
+ void i_importMachines(ImportStack &stack);
+ HRESULT i_verifyStorageControllerPortValid(const StorageControllerType_T aStorageControllerType,
+ const uint32_t aControllerPort,
+ ULONG *ulMaxPorts);
+
+ HRESULT i_preCheckImageAvailability(ImportStack &stack);
+ bool i_importEnsureOvaLookAhead(ImportStack &stack);
+ RTVFSIOSTREAM i_importOpenSourceFile(ImportStack &stack, Utf8Str const &rstrSrcPath, const char *pszManifestEntry);
+ HRESULT i_importCreateAndWriteDestinationFile(Utf8Str const &rstrDstPath,
+ RTVFSIOSTREAM hVfsIosSrc, Utf8Str const &rstrSrcLogNm);
+
+ void i_importCopyFile(ImportStack &stack, Utf8Str const &rstrSrcPath, Utf8Str const &rstrDstPath,
+ const char *pszManifestEntry);
+ void i_importDecompressFile(ImportStack &stack, Utf8Str const &rstrSrcPath, Utf8Str const &rstrDstPath,
+ const char *pszManifestEntry);
+ HRESULT i_importCloudImpl(TaskCloud *pTask);
+ /** @} */
+
+ /** @name Write stuff
+ * @{
+ */
+ HRESULT i_writeImpl(ovf::OVFVersion_T aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
+ HRESULT i_writeOPCImpl(ovf::OVFVersion_T aFormat, const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
+ HRESULT i_writeCloudImpl(const LocationInfo &aLocInfo, ComObjPtr<Progress> &aProgress);
+
+ HRESULT i_writeFS(TaskOVF *pTask);
+ HRESULT i_writeFSOVF(TaskOVF *pTask, AutoWriteLockBase& writeLock);
+ HRESULT i_writeFSOVA(TaskOVF *pTask, AutoWriteLockBase& writeLock);
+ HRESULT i_writeFSOPC(TaskOPC *pTask);
+ HRESULT i_exportCloudImpl(TaskCloud *pTask);
+ HRESULT i_writeFSImpl(TaskOVF *pTask, AutoWriteLockBase &writeLock, RTVFSFSSTREAM hVfsFssDst);
+ HRESULT i_writeBufferToFile(RTVFSFSSTREAM hVfsFssDst, const char *pszFilename, const void *pvContent, size_t cbContent);
+
+ struct XMLStack;
+
+ void i_buildXML(AutoWriteLockBase& writeLock,
+ xml::Document &doc,
+ XMLStack &stack,
+ const Utf8Str &strPath,
+ ovf::OVFVersion_T enFormat);
+ void i_buildXMLForOneVirtualSystem(AutoWriteLockBase& writeLock,
+ xml::ElementNode &elmToAddVirtualSystemsTo,
+ std::list<xml::ElementNode*> *pllElementsWithUuidAttributes,
+ ComObjPtr<VirtualSystemDescription> &vsdescThis,
+ ovf::OVFVersion_T enFormat,
+ XMLStack &stack);
+ /** @} */
+
+ friend class Machine;
+ friend class Certificate;
+};
+
+void i_parseURI(Utf8Str strUri, LocationInfo &locInfo);
+
+struct VirtualSystemDescriptionEntry
+{
+ uint32_t ulIndex; ///< zero-based index of this entry within array
+ VirtualSystemDescriptionType_T type; ///< type of this entry
+ Utf8Str strRef; ///< reference number (hard disk controllers only)
+ Utf8Str strOvf; ///< original OVF value (type-dependent)
+ Utf8Str strVBoxSuggested; ///< configuration value (type-dependent); original value suggested by interpret()
+ Utf8Str strVBoxCurrent; ///< configuration value (type-dependent); current value, either from interpret() or setFinalValue()
+ Utf8Str strExtraConfigSuggested; ///< extra configuration key=value strings (type-dependent); original value suggested by interpret()
+ Utf8Str strExtraConfigCurrent; ///< extra configuration key=value strings (type-dependent); current value, either from interpret() or setFinalValue()
+
+ uint32_t ulSizeMB; ///< hard disk images only: a copy of ovf::DiskImage::ulSuggestedSizeMB
+ bool skipIt; ///< used during export to skip some parts if it's needed
+};
+
+class ATL_NO_VTABLE VirtualSystemDescription :
+ public VirtualSystemDescriptionWrap
+{
+ friend class Appliance;
+
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(VirtualSystemDescription)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init();
+ void uninit();
+
+ /* public methods only for internal purposes */
+ void i_addEntry(VirtualSystemDescriptionType_T aType,
+ const Utf8Str &strRef,
+ const Utf8Str &aOvfValue,
+ const Utf8Str &aVBoxValue,
+ uint32_t ulSizeMB = 0,
+ const Utf8Str &strExtraConfig = "");
+
+ std::list<VirtualSystemDescriptionEntry*> i_findByType(VirtualSystemDescriptionType_T aType);
+ const VirtualSystemDescriptionEntry* i_findControllerFromID(const Utf8Str &id);
+ const VirtualSystemDescriptionEntry* i_findByIndex(const uint32_t aIndex);
+
+ void i_importVBoxMachineXML(const xml::ElementNode &elmMachine);
+ const settings::MachineConfigFile* i_getMachineConfig() const;
+
+ /* private instance data */
+private:
+
+ // wrapped IVirtualSystemDescription properties
+ HRESULT getCount(ULONG *aCount);
+
+ // wrapped IVirtualSystemDescription methods
+ HRESULT getDescription(std::vector<VirtualSystemDescriptionType_T> &aTypes,
+ std::vector<com::Utf8Str> &aRefs,
+ std::vector<com::Utf8Str> &aOVFValues,
+ std::vector<com::Utf8Str> &aVBoxValues,
+ std::vector<com::Utf8Str> &aExtraConfigValues);
+ HRESULT getDescriptionByType(VirtualSystemDescriptionType_T aType,
+ std::vector<VirtualSystemDescriptionType_T> &aTypes,
+ std::vector<com::Utf8Str> &aRefs,
+ std::vector<com::Utf8Str> &aOVFValues,
+ std::vector<com::Utf8Str> &aVBoxValues,
+ std::vector<com::Utf8Str> &aExtraConfigValues);
+ HRESULT getValuesByType(VirtualSystemDescriptionType_T aType,
+ VirtualSystemDescriptionValueType_T aWhich,
+ std::vector<com::Utf8Str> &aValues);
+ HRESULT setFinalValues(const std::vector<BOOL> &aEnabled,
+ const std::vector<com::Utf8Str> &aVBoxValues,
+ const std::vector<com::Utf8Str> &aExtraConfigValues);
+ HRESULT addDescription(VirtualSystemDescriptionType_T aType,
+ const com::Utf8Str &aVBoxValue,
+ const com::Utf8Str &aExtraConfigValue);
+ HRESULT removeDescriptionByType(VirtualSystemDescriptionType_T aType);
+ void i_removeByType(VirtualSystemDescriptionType_T aType);
+
+ struct Data;
+ Data *m;
+
+ friend class Machine;
+};
+
+#endif /* !MAIN_INCLUDED_ApplianceImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ApplianceImplPrivate.h b/src/VBox/Main/include/ApplianceImplPrivate.h
new file mode 100644
index 00000000..87712811
--- /dev/null
+++ b/src/VBox/Main/include/ApplianceImplPrivate.h
@@ -0,0 +1,571 @@
+/* $Id: ApplianceImplPrivate.h $ */
+/** @file
+ * VirtualBox Appliance private data definitions
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ApplianceImplPrivate_h
+#define MAIN_INCLUDED_ApplianceImplPrivate_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+class VirtualSystemDescription;
+
+#include "ovfreader.h"
+#include "SecretKeyStore.h"
+#include "ThreadTask.h"
+#include "CertificateImpl.h"
+#include <map>
+#include <vector>
+#include <iprt/manifest.h>
+#include <iprt/vfs.h>
+#include <iprt/crypto/x509.h>
+#include <iprt/crypto/pkcs7.h>
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Appliance data definition
+//
+////////////////////////////////////////////////////////////////////////////////
+
+namespace settings
+{
+ struct AttachedDevice;
+}
+
+typedef std::pair<Utf8Str, Utf8Str> STRPAIR;
+
+typedef std::vector<com::Guid> GUIDVEC;
+
+/* Describe a location for the import/export. The location could be a file on a
+ * local hard disk or a remote target based on the supported inet protocols. */
+struct LocationInfo
+{
+ LocationInfo()
+ : storageType(VFSType_File) {}
+ VFSType_T storageType; /* Which type of storage should be handled */
+ Utf8Str strProvider; /* cloud provider name in case of export/import to Cloud */
+ Utf8Str strPath; /* File path for the import/export */
+ Utf8Str strHostname; /* Hostname on remote storage locations (could be empty) */
+ Utf8Str strUsername; /* Username on remote storage locations (could be empty) */
+ Utf8Str strPassword; /* Password on remote storage locations (could be empty) */
+};
+
+/**
+ * opaque private instance data of Appliance class
+ */
+struct Appliance::Data
+{
+ enum digest_T {SHA1, SHA256};
+
+ Data()
+ : state(Appliance::ApplianceIdle)
+ , fDigestTypes(0)
+ , hOurManifest(NIL_RTMANIFEST)
+ , fManifest(true)
+ , fDeterminedDigestTypes(false)
+ , hTheirManifest(NIL_RTMANIFEST)
+ , hMemFileTheirManifest(NIL_RTVFSFILE)
+ , fSignerCertLoaded(false)
+ , fCertificateIsSelfSigned(false)
+ , fSignatureValid(false)
+ , fCertificateValid(false)
+ , fCertificateMissingPath(true)
+ , fCertificateValidTime(false)
+ , pbSignedDigest(NULL)
+ , cbSignedDigest(0)
+ , enmSignedDigestType(RTDIGESTTYPE_INVALID)
+ , fContentInfoLoaded(false)
+ , fContentInfoOkay(false)
+ , fContentInfoSameCert(false)
+ , fContentInfoValidSignature(false)
+ , fExportISOImages(false)
+ , pReader(NULL)
+ , ulWeightForXmlOperation(0)
+ , ulWeightForManifestOperation(0)
+ , ulTotalDisksMB(0)
+ , cDisks(0)
+ , m_cPwProvided(0)
+ {
+ RT_ZERO(SignerCert);
+ RT_ZERO(ContentInfo);
+ }
+
+ ~Data()
+ {
+ if (pReader)
+ {
+ delete pReader;
+ pReader = NULL;
+ }
+ resetReadData();
+ }
+
+ /**
+ * Resets data used by read.
+ */
+ void resetReadData(void)
+ {
+ strOvfManifestEntry.setNull();
+ if (hOurManifest != NIL_RTMANIFEST)
+ {
+ RTManifestRelease(hOurManifest);
+ hOurManifest = NIL_RTMANIFEST;
+ }
+ if (hTheirManifest != NIL_RTMANIFEST)
+ {
+ RTManifestRelease(hTheirManifest);
+ hTheirManifest = NIL_RTMANIFEST;
+ }
+ if (hMemFileTheirManifest)
+ {
+ RTVfsFileRelease(hMemFileTheirManifest);
+ hMemFileTheirManifest = NIL_RTVFSFILE;
+ }
+ if (pbSignedDigest)
+ {
+ RTMemFree(pbSignedDigest);
+ pbSignedDigest = NULL;
+ cbSignedDigest = 0;
+ }
+ if (fSignerCertLoaded)
+ {
+ RTCrX509Certificate_Delete(&SignerCert);
+ fSignerCertLoaded = false;
+ }
+ RT_ZERO(SignerCert);
+ enmSignedDigestType = RTDIGESTTYPE_INVALID;
+ fCertificateIsSelfSigned = false;
+ fSignatureValid = false;
+ fCertificateValid = false;
+ fCertificateMissingPath = true;
+ fCertificateValidTime = false;
+ fDeterminedDigestTypes = false;
+ fDigestTypes = RTMANIFEST_ATTR_SHA1 | RTMANIFEST_ATTR_SHA256 | RTMANIFEST_ATTR_SHA512;
+ ptrCertificateInfo.setNull();
+ strCertError.setNull();
+ if (fContentInfoLoaded)
+ {
+ RTCrPkcs7ContentInfo_Delete(&ContentInfo);
+ fContentInfoLoaded = false;
+ }
+ RT_ZERO(ContentInfo);
+ }
+
+ Appliance::ApplianceState state;
+
+ LocationInfo locInfo; // location info for the currently processed OVF
+ /** The digests types to calculate (RTMANIFEST_ATTR_XXX) for the manifest.
+ * This will be a single value when exporting. Zero, one or two. */
+ uint32_t fDigestTypes;
+ /** Manifest created while importing or exporting. */
+ RTMANIFEST hOurManifest;
+
+ /** @name Write data
+ * @{ */
+ bool fManifest; // Create a manifest file on export
+ /** @} */
+
+ /** @name Read data
+ * @{ */
+ /** The manifest entry name of the OVF-file. */
+ Utf8Str strOvfManifestEntry;
+
+ /** Set if we've parsed the manifest and determined the digest types. */
+ bool fDeterminedDigestTypes;
+
+ /** Manifest read in during read() and kept around for later verification. */
+ RTMANIFEST hTheirManifest;
+ /** Memorized copy of the manifest file for signature checking purposes. */
+ RTVFSFILE hMemFileTheirManifest;
+
+ /** The signer certificate from the signature file (.cert).
+ * This will be used in the future provide information about the signer via
+ * the API. */
+ RTCRX509CERTIFICATE SignerCert;
+ /** Set if the SignerCert member contains usable data. */
+ bool fSignerCertLoaded;
+ /** Cached RTCrX509Validity_IsValidAtTimeSpec result set by read(). */
+ bool fCertificateIsSelfSigned;
+ /** Set by read() if pbSignedDigest verified correctly against SignerCert. */
+ bool fSignatureValid;
+ /** Set by read() when the SignerCert checked out fine. */
+ bool fCertificateValid;
+ /** Set by read() when the SignerCert certificate path couldn't be built. */
+ bool fCertificateMissingPath;
+ /** Set by read() when the SignerCert (+path) is valid in the temporal sense. */
+ bool fCertificateValidTime;
+ /** For keeping certificate error messages we delay from read() to import(). */
+ Utf8Str strCertError;
+ /** The signed digest of the manifest. */
+ uint8_t *pbSignedDigest;
+ /** The size of the signed digest. */
+ size_t cbSignedDigest;
+ /** The digest type used to sign the manifest. */
+ RTDIGESTTYPE enmSignedDigestType;
+ /** The certificate info object. This is NULL if no signature and
+ * successfully loaded certificate. */
+ ComObjPtr<Certificate> ptrCertificateInfo;
+
+ /** The PKCS\#7/CMS signed data signing manifest, optional VBox extension.
+ * This contains at least one signature using the same certificate as above
+ * (SignerCert), but should preferrably use a different digest. The PKCS\#7/CMS
+ * format is a lot more versatile, allow multiple signatures using different
+ * digests and certificates, optionally with counter signed timestamps.
+ * Additional intermediate certificates can also be shipped, helping to bridge
+ * the gap to a trusted root certificate installed on the recieving system. */
+ RTCRPKCS7CONTENTINFO ContentInfo;
+ /** Set if the ContentInfo member contains usable data. */
+ bool fContentInfoLoaded;
+ /** Set by read() if the ContentInfo member checked out okay (says nothing about
+ * the signature or certificates within it). */
+ bool fContentInfoOkay;
+ /** Set by read() if the ContentInfo member is using the SignerCert too. */
+ bool fContentInfoSameCert;
+ /** Set by read() if the ContentInfo member contains valid signatures (not
+ * saying anything about valid signing certificates). */
+ bool fContentInfoValidSignature;
+ /** Set by read() if we've already verified the signed data signature(s). */
+ bool fContentInfoDoneVerification;
+
+ bool fContentInfoVerifiedOkay;
+ /** @} */
+
+ bool fExportISOImages;// when 1 the ISO images are exported
+
+ RTCList<ImportOptions_T> optListImport;
+ RTCList<ExportOptions_T> optListExport;
+
+ ovf::OVFReader *pReader;
+
+ std::list< ComObjPtr<VirtualSystemDescription> >
+ virtualSystemDescriptions;
+
+ std::list<Utf8Str> llWarnings;
+
+ ULONG ulWeightForXmlOperation;
+ ULONG ulWeightForManifestOperation;
+ ULONG ulTotalDisksMB;
+ ULONG cDisks;
+
+ std::list<Guid> llGuidsMachinesCreated;
+
+ /** Sequence of password identifiers to encrypt disk images during export. */
+ std::vector<com::Utf8Str> m_vecPasswordIdentifiers;
+ /** Map to get all medium identifiers assoicated with a given password identifier. */
+ std::map<com::Utf8Str, GUIDVEC> m_mapPwIdToMediumIds;
+ /** Secret key store used to hold the passwords during export. */
+ SecretKeyStore *m_pSecretKeyStore;
+ /** Number of passwords provided. */
+ uint32_t m_cPwProvided;
+};
+
+struct Appliance::XMLStack
+{
+ std::map<Utf8Str, const VirtualSystemDescriptionEntry*> mapDisks;
+ std::list<Utf8Str> mapDiskSequence;
+ std::list<Utf8Str> mapDiskSequenceForOneVM;//temporary keeps all disks attached to one exported VM
+ std::map<Utf8Str, bool> mapNetworks;
+};
+
+class Appliance::TaskOVF : public ThreadTask
+{
+public:
+ enum TaskType
+ {
+ Read,
+ Import,
+ Write
+ };
+
+ TaskOVF(Appliance *aThat,
+ TaskType aType,
+ LocationInfo aLocInfo,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskOVF")
+ , pAppliance(aThat)
+ , taskType(aType)
+ , locInfo(aLocInfo)
+ , pProgress(aProgress)
+ , enFormat(ovf::OVFVersion_unknown)
+ , hrc(S_OK)
+ {
+ switch (taskType)
+ {
+ case TaskOVF::Read: m_strTaskName = "ApplRead"; break;
+ case TaskOVF::Import: m_strTaskName = "ApplImp"; break;
+ case TaskOVF::Write: m_strTaskName = "ApplWrit"; break;
+ default: m_strTaskName = "ApplTask"; break;
+ }
+ }
+
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+
+ Appliance *pAppliance;
+ TaskType taskType;
+ const LocationInfo locInfo;
+ ComObjPtr<Progress> pProgress;
+
+ ovf::OVFVersion_T enFormat;
+
+ HRESULT hrc;
+
+ void handler()
+ {
+ Appliance::i_importOrExportThreadTask(this);
+ }
+};
+
+class Appliance::TaskOPC : public ThreadTask
+{
+public:
+ enum TaskType
+ {
+ Export
+ };
+
+ TaskOPC(Appliance *aThat,
+ TaskType aType,
+ LocationInfo aLocInfo,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskOPC")
+ , pAppliance(aThat)
+ , taskType(aType)
+ , locInfo(aLocInfo)
+ , pProgress(aProgress)
+ , hrc(S_OK)
+ {
+ m_strTaskName = "OPCExpt";
+ }
+
+ ~TaskOPC()
+ {
+ }
+
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+
+ Appliance *pAppliance;
+ TaskType taskType;
+ const LocationInfo locInfo;
+ ComObjPtr<Progress> pProgress;
+
+ HRESULT hrc;
+
+ void handler()
+ {
+ Appliance::i_exportOPCThreadTask(this);
+ }
+};
+
+
+class Appliance::TaskCloud : public ThreadTask
+{
+public:
+ enum TaskType
+ {
+ Export,
+ Import,
+ ReadData
+ };
+
+ TaskCloud(Appliance *aThat,
+ TaskType aType,
+ LocationInfo aLocInfo,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskCloud")
+ , pAppliance(aThat)
+ , taskType(aType)
+ , locInfo(aLocInfo)
+ , pProgress(aProgress)
+ , hrc(S_OK)
+ {
+ switch (taskType)
+ {
+ case TaskCloud::Export: m_strTaskName = "CloudExpt"; break;
+ case TaskCloud::Import: m_strTaskName = "CloudImpt"; break;
+ case TaskCloud::ReadData: m_strTaskName = "CloudRead"; break;
+ default: m_strTaskName = "CloudTask"; break;
+ }
+ }
+
+ ~TaskCloud()
+ {
+ }
+
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+
+ Appliance *pAppliance;
+ TaskType taskType;
+ const LocationInfo locInfo;
+ ComObjPtr<Progress> pProgress;
+
+ HRESULT hrc;
+
+ void handler()
+ {
+ Appliance::i_importOrExportCloudThreadTask(this);
+ }
+};
+
+struct MyHardDiskAttachment
+{
+ ComPtr<IMachine> pMachine;
+ Utf8Str controllerName;
+ int32_t lControllerPort; // 0-29 for SATA
+ int32_t lDevice; // IDE: 0 or 1, otherwise 0 always
+};
+
+/**
+ * Used by Appliance::importMachineGeneric() to store
+ * input parameters and rollback information.
+ */
+struct Appliance::ImportStack
+{
+ // input pointers
+ const LocationInfo &locInfo; // ptr to location info from Appliance::importFS()
+ Utf8Str strSourceDir; // directory where source files reside
+ const ovf::DiskImagesMap &mapDisks; // ptr to disks map in OVF
+ ComObjPtr<Progress> &pProgress; // progress object passed into Appliance::importFS()
+
+ // input parameters from VirtualSystemDescriptions
+ Utf8Str strNameVBox; // VM name
+ Utf8Str strSettingsFilename; // Absolute path to VM config file
+ Utf8Str strMachineFolder; // Absolute path to VM folder (derived from strSettingsFilename)
+ Utf8Str strOsTypeVBox; // VirtualBox guest OS type as string
+ Utf8Str strPrimaryGroup; // VM primary group as string
+ Utf8Str strDescription;
+ uint32_t cCPUs; // CPU count
+ bool fForceHWVirt; // if true, we force enabling hardware virtualization
+ bool fForceIOAPIC; // if true, we force enabling the IOAPIC
+ uint32_t ulMemorySizeMB; // virtual machine RAM in megabytes
+ Utf8Str strFirmwareType; //Firmware - BIOS or EFI
+#ifdef VBOX_WITH_USB
+ bool fUSBEnabled;
+#endif
+ Utf8Str strAudioAdapter; // if not empty, then the guest has audio enabled, and this is the decimal
+ // representation of the audio adapter (should always be "0" for AC97 presently)
+
+ // session (not initially created)
+ ComPtr<ISession> pSession; // session opened in Appliance::importFS() for machine manipulation
+ bool fSessionOpen; // true if the pSession is currently open and needs closing
+
+ /** @name File access related stuff (TAR stream)
+ * @{ */
+ /** OVA file system stream handle. NIL if not OVA. */
+ RTVFSFSSTREAM hVfsFssOva;
+ /** OVA lookahead I/O stream object. */
+ RTVFSIOSTREAM hVfsIosOvaLookAhead;
+ /** OVA lookahead I/O stream object name. */
+ char *pszOvaLookAheadName;
+ /** @} */
+
+ // a list of images that we created/imported; this is initially empty
+ // and will be cleaned up on errors
+ std::list<MyHardDiskAttachment> llHardDiskAttachments; // disks that were attached
+ std::map<Utf8Str, Utf8Str> mapNewUUIDsToOriginalUUIDs;
+
+ ImportStack(const LocationInfo &aLocInfo,
+ const ovf::DiskImagesMap &aMapDisks,
+ ComObjPtr<Progress> &aProgress,
+ RTVFSFSSTREAM aVfsFssOva)
+ : locInfo(aLocInfo),
+ mapDisks(aMapDisks),
+ pProgress(aProgress),
+ cCPUs(1),
+ fForceHWVirt(false),
+ fForceIOAPIC(false),
+ ulMemorySizeMB(0),
+ fSessionOpen(false),
+ hVfsFssOva(aVfsFssOva),
+ hVfsIosOvaLookAhead(NIL_RTVFSIOSTREAM),
+ pszOvaLookAheadName(NULL)
+ {
+ if (hVfsFssOva != NIL_RTVFSFSSTREAM)
+ RTVfsFsStrmRetain(hVfsFssOva);
+
+ // disk images have to be on the same place as the OVF file. So
+ // strip the filename out of the full file path
+ strSourceDir = aLocInfo.strPath;
+ strSourceDir.stripFilename();
+ }
+
+ ~ImportStack()
+ {
+ if (hVfsFssOva != NIL_RTVFSFSSTREAM)
+ {
+ RTVfsFsStrmRelease(hVfsFssOva);
+ hVfsFssOva = NIL_RTVFSFSSTREAM;
+ }
+ if (hVfsIosOvaLookAhead != NIL_RTVFSIOSTREAM)
+ {
+ RTVfsIoStrmRelease(hVfsIosOvaLookAhead);
+ hVfsIosOvaLookAhead = NIL_RTVFSIOSTREAM;
+ }
+ if (pszOvaLookAheadName)
+ {
+ RTStrFree(pszOvaLookAheadName);
+ pszOvaLookAheadName = NULL;
+ }
+ }
+
+ HRESULT restoreOriginalUUIDOfAttachedDevice(settings::MachineConfigFile *config);
+ HRESULT saveOriginalUUIDOfAttachedDevice(settings::AttachedDevice &device, const Utf8Str &newlyUuid);
+ RTVFSIOSTREAM claimOvaLookAHead(void);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualSystemDescription data definition
+//
+////////////////////////////////////////////////////////////////////////////////
+
+struct VirtualSystemDescription::Data
+{
+ /** item descriptions */
+ std::vector<VirtualSystemDescriptionEntry> maDescriptions;
+
+ /** VirtualBox machine this description was exported from (export only) */
+ ComPtr<Machine> pMachine;
+
+ /** machine config created from <vbox:Machine> element if found (import only) */
+ settings::MachineConfigFile *pConfig;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Internal helpers
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void convertCIMOSType2VBoxOSType(Utf8Str &strType, ovf::CIMOSType_T c, const Utf8Str &cStr);
+
+ovf::CIMOSType_T convertVBoxOSType2CIMOSType(const char *pcszVBox, BOOL fLongMode);
+
+Utf8Str convertNetworkAttachmentTypeToString(NetworkAttachmentType_T type);
+
+
+#endif /* !MAIN_INCLUDED_ApplianceImplPrivate_h */
+
diff --git a/src/VBox/Main/include/AudioAdapterImpl.h b/src/VBox/Main/include/AudioAdapterImpl.h
new file mode 100644
index 00000000..43dcf845
--- /dev/null
+++ b/src/VBox/Main/include/AudioAdapterImpl.h
@@ -0,0 +1,94 @@
+/* $Id: AudioAdapterImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AudioAdapterImpl_h
+#define MAIN_INCLUDED_AudioAdapterImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+class AudioSettings;
+
+#include "AudioAdapterWrap.h"
+namespace settings
+{
+ struct AudioAdapter;
+}
+
+class ATL_NO_VTABLE AudioAdapter :
+ public AudioAdapterWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS (AudioAdapter)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(AudioSettings *aParent);
+ HRESULT init(AudioSettings *aParent, AudioAdapter *aThat);
+ HRESULT initCopy(AudioSettings *aParent, AudioAdapter *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::AudioAdapter &data);
+ HRESULT i_saveSettings(settings::AudioAdapter &data);
+
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(AudioAdapter *aThat);
+
+private:
+
+ // wrapped IAudioAdapter properties
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getEnabledIn(BOOL *aEnabled);
+ HRESULT setEnabledIn(BOOL aEnabled);
+ HRESULT getEnabledOut(BOOL *aEnabled);
+ HRESULT setEnabledOut(BOOL aEnabled);
+ HRESULT getAudioDriver(AudioDriverType_T *aAudioDriver);
+ HRESULT setAudioDriver(AudioDriverType_T aAudioDriver);
+ HRESULT getAudioController(AudioControllerType_T *aAudioController);
+ HRESULT setAudioController(AudioControllerType_T aAudioController);
+ HRESULT getAudioCodec(AudioCodecType_T *aAudioCodec);
+ HRESULT setAudioCodec(AudioCodecType_T aAudioCodec);
+ HRESULT getPropertiesList(std::vector<com::Utf8Str>& aProperties);
+ HRESULT getProperty(const com::Utf8Str &aKey, com::Utf8Str &aValue);
+ HRESULT setProperty(const com::Utf8Str &aKey, const com::Utf8Str &aValue);
+
+private:
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_AudioAdapterImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/AudioDriver.h b/src/VBox/Main/include/AudioDriver.h
new file mode 100644
index 00000000..fbfba494
--- /dev/null
+++ b/src/VBox/Main/include/AudioDriver.h
@@ -0,0 +1,144 @@
+/* $Id: AudioDriver.h $ */
+/** @file
+ * VirtualBox audio base class for Main audio drivers.
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AudioDriver_h
+#define MAIN_INCLUDED_AudioDriver_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/ptr.h>
+#include <VBox/com/string.h>
+#include <VBox/com/AutoLock.h>
+
+using namespace com;
+
+/**
+ * Audio driver configuration for audio drivers implemented
+ * in Main.
+ */
+struct AudioDriverCfg
+{
+ AudioDriverCfg(Utf8Str a_strDev = "", unsigned a_uInst = 0, unsigned a_uLUN = 0, Utf8Str a_strName = "",
+ bool a_fEnabledIn = false, bool a_fEnabledOut = false)
+ : strDev(a_strDev)
+ , uInst(a_uInst)
+ , uLUN(a_uLUN)
+ , strName(a_strName)
+ , fEnabledIn(a_fEnabledIn)
+ , fEnabledOut(a_fEnabledOut)
+ { }
+
+ /** Copy assignment operator. */
+ AudioDriverCfg& operator=(AudioDriverCfg const &a_rThat) RT_NOEXCEPT
+ {
+ this->strDev = a_rThat.strDev;
+ this->uInst = a_rThat.uInst;
+ this->uLUN = a_rThat.uLUN;
+ this->strName = a_rThat.strName;
+ this->fEnabledIn = a_rThat.fEnabledIn;
+ this->fEnabledOut = a_rThat.fEnabledOut;
+
+ return *this;
+ }
+
+ /** The device name. */
+ Utf8Str strDev;
+ /** The device instance. */
+ unsigned uInst;
+ /** The LUN the driver is attached to.
+ * Set the UINT8_MAX if not attached. */
+ unsigned uLUN;
+ /** The driver name. */
+ Utf8Str strName;
+ /** Whether input is enabled. */
+ bool fEnabledIn;
+ /** Whether output is enabled. */
+ bool fEnabledOut;
+};
+
+class Console;
+
+/**
+ * Base class for all audio drivers implemented in Main.
+ */
+class AudioDriver
+{
+
+public:
+ AudioDriver(Console *pConsole);
+ virtual ~AudioDriver();
+
+ /** Copy assignment operator. */
+ AudioDriver &operator=(AudioDriver const &a_rThat) RT_NOEXCEPT;
+
+ Console *GetParent(void) { return mpConsole; }
+
+ AudioDriverCfg *GetConfig(void) { return &mCfg; }
+ int InitializeConfig(AudioDriverCfg *pCfg);
+
+ /** Checks if audio is configured or not. */
+ bool isConfigured() const { return mCfg.strName.isNotEmpty(); }
+
+ bool IsAttached(void) { return mfAttached; }
+
+ int doAttachDriverViaEmt(PUVM pUVM, PCVMMR3VTABLE pVMM, util::AutoWriteLock *pAutoLock);
+ int doDetachDriverViaEmt(PUVM pUVM, PCVMMR3VTABLE pVMM, util::AutoWriteLock *pAutoLock);
+
+protected:
+ static DECLCALLBACK(int) attachDriverOnEmt(AudioDriver *pThis);
+ static DECLCALLBACK(int) detachDriverOnEmt(AudioDriver *pThis);
+
+ int configure(unsigned uLUN, bool fAttach);
+
+ /**
+ * Virtual function for child specific driver configuration.
+ *
+ * This is called at the end of AudioDriver::configure().
+ *
+ * @returns VBox status code.
+ * @param pLunCfg CFGM configuration node of the driver.
+ * @param pVMM The VMM ring-3 vtable.
+ */
+ virtual int configureDriver(PCFGMNODE pLunCfg, PCVMMR3VTABLE pVMM)
+ {
+ RT_NOREF(pLunCfg, pVMM);
+ return VINF_SUCCESS;
+ }
+
+protected:
+
+ /** Pointer to parent. */
+ Console *mpConsole;
+ /** The driver's configuration. */
+ AudioDriverCfg mCfg;
+ /** Whether the driver is attached or not. */
+ bool mfAttached;
+};
+
+#endif /* !MAIN_INCLUDED_AudioDriver_h */
+
diff --git a/src/VBox/Main/include/AudioSettingsImpl.h b/src/VBox/Main/include/AudioSettingsImpl.h
new file mode 100644
index 00000000..e5ec0b31
--- /dev/null
+++ b/src/VBox/Main/include/AudioSettingsImpl.h
@@ -0,0 +1,84 @@
+/* $Id: AudioSettingsImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2022-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AudioSettingsImpl_h
+#define MAIN_INCLUDED_AudioSettingsImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "AudioAdapterImpl.h"
+#include "GuestOSTypeImpl.h"
+
+#include "AudioSettingsWrap.h"
+namespace settings
+{
+ struct AudioSettings;
+}
+
+class ATL_NO_VTABLE AudioSettings :
+ public AudioSettingsWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(AudioSettings)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent);
+ HRESULT init(Machine *aParent, AudioSettings *aThat);
+ HRESULT initCopy(Machine *aParent, AudioSettings *aThat);
+ void uninit();
+
+ HRESULT getHostAudioDevice(AudioDirection_T aUsage, ComPtr<IHostAudioDevice> &aDevice);
+ HRESULT setHostAudioDevice(const ComPtr<IHostAudioDevice> &aDevice, AudioDirection_T aUsage);
+ HRESULT getAdapter(ComPtr<IAudioAdapter> &aAdapter);
+
+ // public methods only for internal purposes
+ bool i_canChangeSettings(void);
+ void i_onAdapterChanged(IAudioAdapter *pAdapter);
+ void i_onHostDeviceChanged(IHostAudioDevice *pDevice, bool fIsNew, AudioDeviceState_T enmState, IVirtualBoxErrorInfo *pErrInfo);
+ void i_onSettingsChanged(void);
+ HRESULT i_loadSettings(const settings::AudioAdapter &data);
+ HRESULT i_saveSettings(settings::AudioAdapter &data);
+ void i_copyFrom(AudioSettings *aThat);
+ HRESULT i_applyDefaults(ComObjPtr<GuestOSType> &aGuestOsType);
+
+ void i_rollback();
+ void i_commit();
+
+private:
+
+ struct Data;
+ Data *m;
+};
+#endif /* !MAIN_INCLUDED_AudioSettingsImpl_h */
+
diff --git a/src/VBox/Main/include/AuthLibrary.h b/src/VBox/Main/include/AuthLibrary.h
new file mode 100644
index 00000000..8d22b937
--- /dev/null
+++ b/src/VBox/Main/include/AuthLibrary.h
@@ -0,0 +1,54 @@
+/* $Id: AuthLibrary.h $ */
+/** @file
+ * Main - external authentication library interface.
+ */
+
+/*
+ * Copyright (C) 2015-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AuthLibrary_h
+#define MAIN_INCLUDED_AuthLibrary_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/VBoxAuth.h>
+#include <iprt/types.h>
+
+typedef struct AUTHLIBRARYCONTEXT
+{
+ RTLDRMOD hAuthLibrary;
+ PAUTHENTRY pfnAuthEntry;
+ PAUTHENTRY2 pfnAuthEntry2;
+ PAUTHENTRY3 pfnAuthEntry3;
+} AUTHLIBRARYCONTEXT;
+
+int AuthLibLoad(AUTHLIBRARYCONTEXT *pAuthLibCtx, const char *pszLibrary);
+void AuthLibUnload(AUTHLIBRARYCONTEXT *pAuthLibCtx);
+
+AuthResult AuthLibAuthenticate(const AUTHLIBRARYCONTEXT *pAuthLibCtx,
+ PCRTUUID pUuid, AuthGuestJudgement guestJudgement,
+ const char *pszUser, const char *pszPassword, const char *pszDomain,
+ uint32_t u32ClientId);
+void AuthLibDisconnect(const AUTHLIBRARYCONTEXT *pAuthLibCtx, PCRTUUID pUuid, uint32_t u32ClientId);
+
+#endif /* !MAIN_INCLUDED_AuthLibrary_h */
diff --git a/src/VBox/Main/include/AutoCaller.h b/src/VBox/Main/include/AutoCaller.h
new file mode 100644
index 00000000..d8bf6cc5
--- /dev/null
+++ b/src/VBox/Main/include/AutoCaller.h
@@ -0,0 +1,537 @@
+/* $Id: AutoCaller.h $ */
+/** @file
+ *
+ * VirtualBox object caller handling definitions
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AutoCaller_h
+#define MAIN_INCLUDED_AutoCaller_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "ObjectState.h"
+
+#include "VBox/com/AutoLock.h"
+
+// Forward declaration needed, but nothing more.
+class VirtualBoxBase;
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutoCaller* classes
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Smart class that automatically increases the number of normal (non-limited)
+ * callers of the given VirtualBoxBase object when an instance is constructed
+ * and decreases it back when the created instance goes out of scope (i.e. gets
+ * destroyed).
+ *
+ * If #hrc() returns a failure after the instance creation, it means that
+ * the managed VirtualBoxBase object is not Ready, or in any other invalid
+ * state, so that the caller must not use the object and can return this
+ * failed result code to the upper level.
+ *
+ * See ObjectState::addCaller() and ObjectState::releaseCaller() for more
+ * details about object callers.
+ *
+ * A typical usage pattern to declare a normal method of some object (i.e. a
+ * method that is valid only when the object provides its full
+ * functionality) is:
+ * <code>
+ * STDMETHODIMP Component::Foo()
+ * {
+ * AutoCaller autoCaller(this);
+ * HRESULT hrc = autoCaller.hrc();
+ * if (SUCCEEDED(hrc))
+ * {
+ * ...
+ * }
+ * return hrc;
+ * }
+ * </code>
+ */
+class AutoCaller
+{
+public:
+ /**
+ * Default constructor. Not terribly useful, but it's valid to create
+ * an instance without associating it with an object. It's a no-op,
+ * like the more useful constructor below when NULL is passed to it.
+ */
+ AutoCaller()
+ {
+ init(NULL, false);
+ }
+
+ /**
+ * Increases the number of callers of the given object by calling
+ * ObjectState::addCaller() for the corresponding member instance.
+ *
+ * @param aObj Object to add a normal caller to. If NULL, this
+ * instance is effectively turned to no-op (where
+ * hrc() will return S_OK).
+ */
+ AutoCaller(VirtualBoxBase *aObj)
+ {
+ init(aObj, false);
+ }
+
+ /**
+ * If the number of callers was successfully increased, decreases it
+ * using ObjectState::releaseCaller(), otherwise does nothing.
+ */
+ ~AutoCaller()
+ {
+ if (mObj && SUCCEEDED(mRC))
+ mObj->getObjectState().releaseCaller();
+ }
+
+ /**
+ * Returns the stored result code returned by ObjectState::addCaller() after
+ * instance creation or after the last #add() call.
+ *
+ * A successful result code means the number of callers was successfully
+ * increased.
+ */
+ HRESULT hrc() const { return mRC; }
+
+ /**
+ * Returns |true| if |SUCCEEDED(hrc())| is |true|, for convenience. |true| means
+ * the number of callers was successfully increased.
+ */
+ bool isOk() const { return SUCCEEDED(mRC); }
+
+ /**
+ * Returns |true| if |FAILED(hrc())| is |true|, for convenience. |true| means
+ * the number of callers was _not_ successfully increased.
+ */
+ bool isNotOk() const { return FAILED(mRC); }
+
+ /**
+ * Temporarily decreases the number of callers of the managed object.
+ * May only be called if #isOk() returns |true|. Note that #hrc() will return
+ * E_FAIL after this method succeeds.
+ */
+ void release()
+ {
+ Assert(SUCCEEDED(mRC));
+ if (SUCCEEDED(mRC))
+ {
+ if (mObj)
+ mObj->getObjectState().releaseCaller();
+ mRC = E_FAIL;
+ }
+ }
+
+ /**
+ * Restores the number of callers decreased by #release(). May only be
+ * called after #release().
+ */
+ void add()
+ {
+ Assert(!SUCCEEDED(mRC));
+ if (mObj && !SUCCEEDED(mRC))
+ mRC = mObj->getObjectState().addCaller(mLimited);
+ }
+
+ /**
+ * Attaches another object to this caller instance.
+ * The previous object's caller is released before the new one is added.
+ *
+ * @param aObj New object to attach, may be @c NULL.
+ */
+ void attach(VirtualBoxBase *aObj)
+ {
+ /* detect simple self-reattachment */
+ if (mObj != aObj)
+ {
+ if (mObj && SUCCEEDED(mRC))
+ release();
+ else if (!mObj)
+ {
+ /* Fix up the success state when nothing is attached. Otherwise
+ * there are a couple of assertion which would trigger. */
+ mRC = E_FAIL;
+ }
+ mObj = aObj;
+ add();
+ }
+ }
+
+ /** Verbose equivalent to <tt>attach(NULL)</tt>. */
+ void detach() { attach(NULL); }
+
+protected:
+ /**
+ * Internal constructor: Increases the number of callers of the given
+ * object (either normal or limited variant) by calling
+ * ObjectState::addCaller() for the corresponding member instance.
+ *
+ * @param aObj Object to add a caller to. If NULL, this
+ * instance is effectively turned to no-op (where hrc() will
+ * return S_OK).
+ * @param aLimited If |false|, then it's a regular caller, otherwise a
+ * limited caller.
+ */
+ void init(VirtualBoxBase *aObj, bool aLimited)
+ {
+ mObj = aObj;
+ mRC = S_OK;
+ mLimited = aLimited;
+ if (mObj)
+ mRC = mObj->getObjectState().addCaller(mLimited);
+ }
+
+private:
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoCaller);
+ DECLARE_CLS_NEW_DELETE_NOOP(AutoCaller);
+
+ VirtualBoxBase *mObj;
+ HRESULT mRC;
+ bool mLimited;
+};
+
+/**
+ * Smart class that automatically increases the number of limited callers of
+ * the given VirtualBoxBase object when an instance is constructed and
+ * decreases it back when the created instance goes out of scope (i.e. gets
+ * destroyed).
+ *
+ * A typical usage pattern to declare a limited method of some object (i.e.
+ * a method that is valid even if the object doesn't provide its full
+ * functionality) is:
+ * <code>
+ * STDMETHODIMP Component::Bar()
+ * {
+ * AutoLimitedCaller autoCaller(this);
+ * HRESULT hrc = autoCaller.hrc();
+ * if (SUCCEEDED(hrc))
+ * {
+ * ...
+ * }
+ * return hrc;
+ * </code>
+ *
+ * See AutoCaller for more information about auto caller functionality.
+ */
+class AutoLimitedCaller : public AutoCaller
+{
+public:
+ /**
+ * Default constructor. Not terribly useful, but it's valid to create
+ * an instance without associating it with an object. It's a no-op,
+ * like the more useful constructor below when NULL is passed to it.
+ */
+ AutoLimitedCaller()
+ {
+ AutoCaller::init(NULL, true);
+ }
+
+ /**
+ * Increases the number of callers of the given object by calling
+ * ObjectState::addCaller() for the corresponding member instance.
+ *
+ * @param aObj Object to add a limited caller to. If NULL, this
+ * instance is effectively turned to no-op (where hrc() will
+ * return S_OK).
+ */
+ AutoLimitedCaller(VirtualBoxBase *aObj)
+ {
+ AutoCaller::init(aObj, true);
+ }
+
+private:
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoLimitedCaller); /* Shuts up MSC warning C4625. */
+};
+
+/**
+ * Smart class to enclose the state transition NotReady->InInit->Ready.
+ *
+ * The purpose of this span is to protect object initialization.
+ *
+ * Instances must be created as a stack-based variable taking |this| pointer
+ * as the argument at the beginning of init() methods of VirtualBoxBase
+ * subclasses. When this variable is created it automatically places the
+ * object to the InInit state.
+ *
+ * When the created variable goes out of scope (i.e. gets destroyed) then,
+ * depending on the result status of this initialization span, it either
+ * places the object to Ready or Limited state or calls the object's
+ * VirtualBoxBase::uninit() method which is supposed to place the object
+ * back to the NotReady state using the AutoUninitSpan class.
+ *
+ * The initial result status of the initialization span is determined by the
+ * @a aResult argument of the AutoInitSpan constructor (Result::Failed by
+ * default). Inside the initialization span, the success status can be set
+ * to Result::Succeeded using #setSucceeded(), to to Result::Limited using
+ * #setLimited() or to Result::Failed using #setFailed(). Please don't
+ * forget to set the correct success status before getting the AutoInitSpan
+ * variable destroyed (for example, by performing an early return from
+ * the init() method)!
+ *
+ * Note that if an instance of this class gets constructed when the object
+ * is in the state other than NotReady, #isOk() returns |false| and methods
+ * of this class do nothing: the state transition is not performed.
+ *
+ * A typical usage pattern is:
+ * <code>
+ * HRESULT Component::init()
+ * {
+ * AutoInitSpan autoInitSpan(this);
+ * AssertReturn(autoInitSpan.isOk(), E_FAIL);
+ * ...
+ * if (FAILED(rc))
+ * return rc;
+ * ...
+ * if (SUCCEEDED(rc))
+ * autoInitSpan.setSucceeded();
+ * return rc;
+ * }
+ * </code>
+ *
+ * @note Never create instances of this class outside init() methods of
+ * VirtualBoxBase subclasses and never pass anything other than |this|
+ * as the argument to the constructor!
+ */
+class AutoInitSpan
+{
+public:
+
+ enum Result { Failed = 0x0, Succeeded = 0x1, Limited = 0x2 };
+
+ AutoInitSpan(VirtualBoxBase *aObj, Result aResult = Failed);
+ ~AutoInitSpan();
+
+ /**
+ * Returns |true| if this instance has been created at the right moment
+ * (when the object was in the NotReady state) and |false| otherwise.
+ */
+ bool isOk() const { return mOk; }
+
+ /**
+ * Sets the initialization status to Succeeded to indicates successful
+ * initialization. The AutoInitSpan destructor will place the managed
+ * VirtualBoxBase object to the Ready state.
+ */
+ void setSucceeded() { mResult = Succeeded; }
+
+ /**
+ * Sets the initialization status to Succeeded to indicate limited
+ * (partly successful) initialization. The AutoInitSpan destructor will
+ * place the managed VirtualBoxBase object to the Limited state.
+ */
+ void setLimited() { mResult = Limited; }
+
+ /**
+ * Sets the initialization status to Succeeded to indicate limited
+ * (partly successful) initialization but also adds the initialization
+ * error if required for further reporting. The AutoInitSpan destructor
+ * will place the managed VirtualBoxBase object to the Limited state.
+ */
+ void setLimited(HRESULT rc)
+ {
+ mResult = Limited;
+ mFailedRC = rc;
+ mpFailedEI = new ErrorInfo();
+ }
+
+ /**
+ * Sets the initialization status to Failure to indicates failed
+ * initialization. The AutoInitSpan destructor will place the managed
+ * VirtualBoxBase object to the InitFailed state and will automatically
+ * call its uninit() method which is supposed to place the object back
+ * to the NotReady state using AutoUninitSpan.
+ */
+ void setFailed(HRESULT rc = E_ACCESSDENIED)
+ {
+ mResult = Failed;
+ mFailedRC = rc;
+ mpFailedEI = new ErrorInfo();
+ }
+
+ /** Returns the current initialization result. */
+ Result result() { return mResult; }
+
+private:
+
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoInitSpan);
+ DECLARE_CLS_NEW_DELETE_NOOP(AutoInitSpan);
+
+ VirtualBoxBase *mObj;
+ Result mResult : 3; // must be at least total number of bits + 1 (sign)
+ bool mOk : 1;
+ HRESULT mFailedRC;
+ ErrorInfo *mpFailedEI;
+};
+
+/**
+ * Smart class to enclose the state transition Limited->InInit->Ready.
+ *
+ * The purpose of this span is to protect object re-initialization.
+ *
+ * Instances must be created as a stack-based variable taking |this| pointer
+ * as the argument at the beginning of methods of VirtualBoxBase
+ * subclasses that try to re-initialize the object to bring it to the Ready
+ * state (full functionality) after partial initialization (limited
+ * functionality). When this variable is created, it automatically places
+ * the object to the InInit state.
+ *
+ * When the created variable goes out of scope (i.e. gets destroyed),
+ * depending on the success status of this initialization span, it either
+ * places the object to the Ready state or brings it back to the Limited
+ * state.
+ *
+ * The initial success status of the re-initialization span is |false|. In
+ * order to make it successful, #setSucceeded() must be called before the
+ * instance is destroyed.
+ *
+ * Note that if an instance of this class gets constructed when the object
+ * is in the state other than Limited, #isOk() returns |false| and methods
+ * of this class do nothing: the state transition is not performed.
+ *
+ * A typical usage pattern is:
+ * <code>
+ * HRESULT Component::reinit()
+ * {
+ * AutoReinitSpan autoReinitSpan(this);
+ * AssertReturn(autoReinitSpan.isOk(), E_FAIL);
+ * ...
+ * if (FAILED(rc))
+ * return rc;
+ * ...
+ * if (SUCCEEDED(rc))
+ * autoReinitSpan.setSucceeded();
+ * return rc;
+ * }
+ * </code>
+ *
+ * @note Never create instances of this class outside re-initialization
+ * methods of VirtualBoxBase subclasses and never pass anything other than
+ * |this| as the argument to the constructor!
+ */
+class AutoReinitSpan
+{
+public:
+
+ AutoReinitSpan(VirtualBoxBase *aObj);
+ ~AutoReinitSpan();
+
+ /**
+ * Returns |true| if this instance has been created at the right moment
+ * (when the object was in the Limited state) and |false| otherwise.
+ */
+ bool isOk() const { return mOk; }
+
+ /**
+ * Sets the re-initialization status to Succeeded to indicates
+ * successful re-initialization. The AutoReinitSpan destructor will place
+ * the managed VirtualBoxBase object to the Ready state.
+ */
+ void setSucceeded() { mSucceeded = true; }
+
+private:
+
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoReinitSpan);
+ DECLARE_CLS_NEW_DELETE_NOOP(AutoReinitSpan);
+
+ VirtualBoxBase *mObj;
+ bool mSucceeded : 1;
+ bool mOk : 1;
+};
+
+/**
+ * Smart class to enclose the state transition Ready->InUninit->NotReady,
+ * InitFailed->InUninit->NotReady.
+ *
+ * The purpose of this span is to protect object uninitialization.
+ *
+ * Instances must be created as a stack-based variable taking |this| pointer
+ * as the argument at the beginning of uninit() methods of VirtualBoxBase
+ * subclasses. When this variable is created it automatically places the
+ * object to the InUninit state, unless it is already in the NotReady state
+ * as indicated by #uninitDone() returning |true|. In the latter case, the
+ * uninit() method must immediately return because there should be nothing
+ * to uninitialize.
+ *
+ * When this variable goes out of scope (i.e. gets destroyed), it places the
+ * object to NotReady state.
+ *
+ * A typical usage pattern is:
+ * <code>
+ * void Component::uninit()
+ * {
+ * AutoUninitSpan autoUninitSpan(this);
+ * if (autoUninitSpan.uninitDone())
+ * return;
+ * ...
+ * }
+ * </code>
+ *
+ * @note The constructor of this class blocks the current thread execution
+ * until the number of callers added to the object using
+ * ObjectState::addCaller() or AutoCaller drops to zero. For this reason,
+ * it is forbidden to create instances of this class (or call uninit())
+ * within the AutoCaller or ObjectState::addCaller() scope because it is
+ * a guaranteed deadlock.
+ *
+ * @note Never create instances of this class outside uninit() methods and
+ * never pass anything other than |this| as the argument to the
+ * constructor!
+ */
+class AutoUninitSpan
+{
+public:
+
+ AutoUninitSpan(VirtualBoxBase *aObj, bool fTry = false);
+ ~AutoUninitSpan();
+
+ /** |true| when uninit() is called as a result of init() failure */
+ bool initFailed() { return mInitFailed; }
+
+ /** |true| when uninit() has already been called (so the object is NotReady) */
+ bool uninitDone() { return mUninitDone; }
+
+ /** |true| when uninit() has failed, relevant only if it was a "try uninit" */
+ bool uninitFailed() { return mUninitFailed; }
+
+ void setSucceeded();
+
+private:
+
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoUninitSpan);
+ DECLARE_CLS_NEW_DELETE_NOOP(AutoUninitSpan);
+
+ VirtualBoxBase *mObj;
+ bool mInitFailed : 1;
+ bool mUninitDone : 1;
+ bool mUninitFailed : 1;
+};
+
+#endif /* !MAIN_INCLUDED_AutoCaller_h */
diff --git a/src/VBox/Main/include/AutoStateDep.h b/src/VBox/Main/include/AutoStateDep.h
new file mode 100644
index 00000000..7de2ef41
--- /dev/null
+++ b/src/VBox/Main/include/AutoStateDep.h
@@ -0,0 +1,214 @@
+/* $Id: AutoStateDep.h $ */
+
+#ifndef MAIN_INCLUDED_AutoStateDep_h
+#define MAIN_INCLUDED_AutoStateDep_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/** @file
+ *
+ * AutoStateDep template classes, formerly in MachineImpl.h. Use these if
+ * you need to ensure that the machine state does not change over a certain
+ * period of time.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+ /**
+ * Helper class that safely manages the machine state dependency by
+ * calling Machine::addStateDependency() on construction and
+ * Machine::releaseStateDependency() on destruction. Intended for Machine
+ * children. The usage pattern is:
+ *
+ * @code
+ * AutoCaller autoCaller(this);
+ * if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
+ *
+ * Machine::AutoStateDependency<MutableStateDep> adep(mParent);
+ * if (FAILED(stateDep.hrc())) return stateDep.hrc();
+ * ...
+ * // code that depends on the particular machine state
+ * ...
+ * @endcode
+ *
+ * Note that it is more convenient to use the following individual
+ * shortcut classes instead of using this template directly:
+ * AutoAnyStateDependency, AutoMutableStateDependency,
+ * AutoMutableOrSavedStateDependency, AutoMutableOrRunningStateDependency
+ * or AutoMutableOrSavedOrRunningStateDependency. The usage pattern is
+ * exactly the same as above except that there is no need to specify the
+ * template argument because it is already done by the shortcut class.
+ *
+ * @param taDepType Dependency type to manage.
+ */
+ template <Machine::StateDependency taDepType = Machine::AnyStateDep>
+ class AutoStateDependency
+ {
+ public:
+
+ AutoStateDependency(Machine *aThat)
+ : mThat(aThat), mRC(S_OK),
+ mMachineState(MachineState_Null),
+ mRegistered(FALSE)
+ {
+ Assert(aThat);
+ mRC = aThat->i_addStateDependency(taDepType, &mMachineState,
+ &mRegistered);
+ }
+ ~AutoStateDependency()
+ {
+ if (SUCCEEDED(mRC))
+ mThat->i_releaseStateDependency();
+ }
+
+ /** Decreases the number of dependencies before the instance is
+ * destroyed. Note that will reset #hrc() to E_FAIL. */
+ void release()
+ {
+ AssertReturnVoid(SUCCEEDED(mRC));
+ mThat->i_releaseStateDependency();
+ mRC = E_FAIL;
+ }
+
+ /** Restores the number of callers after by #release(). #hrc() will be
+ * reset to the result of calling addStateDependency() and must be
+ * rechecked to ensure the operation succeeded. */
+ void add()
+ {
+ AssertReturnVoid(!SUCCEEDED(mRC));
+ mRC = mThat->i_addStateDependency(taDepType, &mMachineState,
+ &mRegistered);
+ }
+
+ /** Returns the result of Machine::addStateDependency(). */
+ HRESULT hrc() const { return mRC; }
+
+ /** Shortcut to SUCCEEDED(hrc()). */
+ bool isOk() const { return SUCCEEDED(mRC); }
+
+ /** Returns the machine state value as returned by
+ * Machine::addStateDependency(). */
+ MachineState_T machineState() const { return mMachineState; }
+
+ /** Returns the machine state value as returned by
+ * Machine::addStateDependency(). */
+ BOOL machineRegistered() const { return mRegistered; }
+
+ protected:
+
+ Machine *mThat;
+ HRESULT mRC;
+ MachineState_T mMachineState;
+ BOOL mRegistered;
+
+ private:
+
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoStateDependency);
+ DECLARE_CLS_NEW_DELETE_NOOP(AutoStateDependency);
+ };
+
+ /**
+ * Shortcut to AutoStateDependency<AnyStateDep>.
+ * See AutoStateDependency to get the usage pattern.
+ *
+ * Accepts any machine state and guarantees the state won't change before
+ * this object is destroyed. If the machine state cannot be protected (as
+ * a result of the state change currently in progress), this instance's
+ * #hrc() method will indicate a failure, and the caller is not allowed to
+ * rely on any particular machine state and should return the failed
+ * result code to the upper level.
+ */
+ typedef AutoStateDependency<Machine::AnyStateDep> AutoAnyStateDependency;
+
+ /**
+ * Shortcut to AutoStateDependency<MutableStateDep>.
+ * See AutoStateDependency to get the usage pattern.
+ *
+ * Succeeds only if the machine state is in one of the mutable states, and
+ * guarantees the given mutable state won't change before this object is
+ * destroyed. If the machine is not mutable, this instance's #hrc() method
+ * will indicate a failure, and the caller is not allowed to rely on any
+ * particular machine state and should return the failed result code to
+ * the upper level.
+ *
+ * Intended to be used within all setter methods of IMachine
+ * children objects (DVDDrive, NetworkAdapter, AudioAdapter, etc.) to
+ * provide data protection and consistency. There must be no VM process,
+ * i.e. use for settings changes which are valid when the VM is shut down.
+ */
+ typedef AutoStateDependency<Machine::MutableStateDep> AutoMutableStateDependency;
+
+ /**
+ * Shortcut to AutoStateDependency<MutableOrSavedStateDep>.
+ * See AutoStateDependency to get the usage pattern.
+ *
+ * Succeeds only if the machine state is in one of the mutable states, or
+ * if the machine is in the Saved state, and guarantees the given mutable
+ * state won't change before this object is destroyed. If the machine is
+ * not mutable, this instance's #hrc() method will indicate a failure, and
+ * the caller is not allowed to rely on any particular machine state and
+ * should return the failed result code to the upper level.
+ *
+ * Intended to be used within setter methods of IMachine
+ * children objects that may operate on shut down or Saved machines.
+ */
+ typedef AutoStateDependency<Machine::MutableOrSavedStateDep> AutoMutableOrSavedStateDependency;
+
+ /**
+ * Shortcut to AutoStateDependency<MutableOrRunningStateDep>.
+ * See AutoStateDependency to get the usage pattern.
+ *
+ * Succeeds only if the machine state is in one of the mutable states, or
+ * if the machine is in the Running or Paused state, and guarantees the
+ * given mutable state won't change before this object is destroyed. If
+ * the machine is not mutable, this instance's #hrc() method will indicate
+ * a failure, and the caller is not allowed to rely on any particular
+ * machine state and should return the failed result code to the upper
+ * level.
+ *
+ * Intended to be used within setter methods of IMachine
+ * children objects that may operate on shut down or running machines.
+ */
+ typedef AutoStateDependency<Machine::MutableOrRunningStateDep> AutoMutableOrRunningStateDependency;
+
+ /**
+ * Shortcut to AutoStateDependency<MutableOrSavedOrRunningStateDep>.
+ * See AutoStateDependency to get the usage pattern.
+ *
+ * Succeeds only if the machine state is in one of the mutable states, or
+ * if the machine is in the Running, Paused or Saved state, and guarantees
+ * the given mutable state won't change before this object is destroyed.
+ * If the machine is not mutable, this instance's #hrc() method will
+ * indicate a failure, and the caller is not allowed to rely on any
+ * particular machine state and should return the failed result code to
+ * the upper level.
+ *
+ * Intended to be used within setter methods of IMachine
+ * children objects that may operate on shut down, running or saved
+ * machines.
+ */
+ typedef AutoStateDependency<Machine::MutableOrSavedOrRunningStateDep> AutoMutableOrSavedOrRunningStateDependency;
+
+#endif /* !MAIN_INCLUDED_AutoStateDep_h */
+
diff --git a/src/VBox/Main/include/AutostartDb.h b/src/VBox/Main/include/AutostartDb.h
new file mode 100644
index 00000000..c939f220
--- /dev/null
+++ b/src/VBox/Main/include/AutostartDb.h
@@ -0,0 +1,109 @@
+/* $Id: AutostartDb.h $ */
+/** @file
+ * Main - Autostart database Interfaces.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_AutostartDb_h
+#define MAIN_INCLUDED_AutostartDb_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/critsect.h>
+
+class AutostartDb
+{
+ public:
+
+ AutostartDb();
+ ~AutostartDb();
+
+ /**
+ * Sets the path to the autostart database.
+ *
+ * @returns VBox status code.
+ * @param pszAutostartDbPathNew Path to the autostart database.
+ */
+ int setAutostartDbPath(const char *pszAutostartDbPathNew);
+
+ /**
+ * Add a autostart VM to the global database.
+ *
+ * @returns VBox status code.
+ * @retval VERR_PATH_NOT_FOUND if the autostart database directory is not set.
+ * @param pszVMId ID of the VM to add.
+ */
+ int addAutostartVM(const char *pszVMId);
+
+ /**
+ * Remove a autostart VM from the global database.
+ *
+ * @returns VBox status code.
+ * @retval VERR_PATH_NOT_FOUND if the autostart database directory is not set.
+ * @param pszVMId ID of the VM to remove.
+ */
+ int removeAutostartVM(const char *pszVMId);
+
+ /**
+ * Add a autostop VM to the global database.
+ *
+ * @returns VBox status code.
+ * @retval VERR_PATH_NOT_FOUND if the autostart database directory is not set.
+ * @param pszVMId ID of the VM to add.
+ */
+ int addAutostopVM(const char *pszVMId);
+
+ /**
+ * Remove a autostop VM from the global database.
+ *
+ * @returns VBox status code.
+ * @retval VERR_PATH_NOT_FOUND if the autostart database directory is not set.
+ * @param pszVMId ID of the VM to remove.
+ */
+ int removeAutostopVM(const char *pszVMId);
+
+ private:
+
+#ifdef RT_OS_LINUX
+ /** Critical section protecting the database against concurrent access. */
+ RTCRITSECT CritSect;
+ /** Path to the autostart database. */
+ char *m_pszAutostartDbPath;
+
+ /**
+ * Autostart database modification worker.
+ *
+ * @returns VBox status code.
+ * @param fAutostart Flag whether the autostart or autostop database is modified.
+ * @param fAddVM Flag whether a VM is added or removed from the database.
+ */
+ int autostartModifyDb(bool fAutostart, bool fAddVM);
+#endif
+};
+
+#endif /* !MAIN_INCLUDED_AutostartDb_h */
+
diff --git a/src/VBox/Main/include/BIOSSettingsImpl.h b/src/VBox/Main/include/BIOSSettingsImpl.h
new file mode 100644
index 00000000..efa01de4
--- /dev/null
+++ b/src/VBox/Main/include/BIOSSettingsImpl.h
@@ -0,0 +1,102 @@
+/* $Id: BIOSSettingsImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation - Machine BIOS settings.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_BIOSSettingsImpl_h
+#define MAIN_INCLUDED_BIOSSettingsImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "BIOSSettingsWrap.h"
+
+class GuestOSType;
+
+namespace settings
+{
+ struct BIOSSettings;
+}
+
+class ATL_NO_VTABLE BIOSSettings :
+ public BIOSSettingsWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(BIOSSettings)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *parent);
+ HRESULT init(Machine *parent, BIOSSettings *that);
+ HRESULT initCopy(Machine *parent, BIOSSettings *that);
+ void uninit();
+
+ // public methods for internal purposes only
+ HRESULT i_loadSettings(const settings::BIOSSettings &data);
+ HRESULT i_saveSettings(settings::BIOSSettings &data);
+
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(BIOSSettings *aThat);
+ void i_applyDefaults(GuestOSType *aOsType);
+
+private:
+
+ // wrapped IBIOSettings properties
+ HRESULT getLogoFadeIn(BOOL *enabled);
+ HRESULT setLogoFadeIn(BOOL enable);
+ HRESULT getLogoFadeOut(BOOL *enabled);
+ HRESULT setLogoFadeOut(BOOL enable);
+ HRESULT getLogoDisplayTime(ULONG *displayTime);
+ HRESULT setLogoDisplayTime(ULONG displayTime);
+ HRESULT getLogoImagePath(com::Utf8Str &imagePath);
+ HRESULT setLogoImagePath(const com::Utf8Str &imagePath);
+ HRESULT getBootMenuMode(BIOSBootMenuMode_T *bootMenuMode);
+ HRESULT setBootMenuMode(BIOSBootMenuMode_T bootMenuMode);
+ HRESULT getACPIEnabled(BOOL *enabled);
+ HRESULT setACPIEnabled(BOOL enable);
+ HRESULT getIOAPICEnabled(BOOL *aIOAPICEnabled);
+ HRESULT setIOAPICEnabled(BOOL aIOAPICEnabled);
+ HRESULT getAPICMode(APICMode_T *aAPICMode);
+ HRESULT setAPICMode(APICMode_T aAPICMode);
+ HRESULT getTimeOffset(LONG64 *offset);
+ HRESULT setTimeOffset(LONG64 offset);
+ HRESULT getPXEDebugEnabled(BOOL *enabled);
+ HRESULT setPXEDebugEnabled(BOOL enable);
+ HRESULT getSMBIOSUuidLittleEndian(BOOL *enabled);
+ HRESULT setSMBIOSUuidLittleEndian(BOOL enable);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_BIOSSettingsImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/BandwidthControlImpl.h b/src/VBox/Main/include/BandwidthControlImpl.h
new file mode 100644
index 00000000..ceb8c452
--- /dev/null
+++ b/src/VBox/Main/include/BandwidthControlImpl.h
@@ -0,0 +1,111 @@
+/* $Id: BandwidthControlImpl.h $ */
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_BandwidthControlImpl_h
+#define MAIN_INCLUDED_BandwidthControlImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "BandwidthControlWrap.h"
+
+class BandwidthGroup;
+
+namespace settings
+{
+ struct IOSettings;
+}
+
+class ATL_NO_VTABLE BandwidthControl :
+ public BandwidthControlWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(BandwidthControl)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent);
+ HRESULT init(Machine *aParent, BandwidthControl *aThat);
+ HRESULT initCopy(Machine *aParent, BandwidthControl *aThat);
+ void uninit();
+
+ // public internal methods
+ HRESULT i_loadSettings(const settings::IOSettings &data);
+ HRESULT i_saveSettings(settings::IOSettings &data);
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(BandwidthControl *aThat);
+ Machine *i_getMachine() const;
+ HRESULT i_getBandwidthGroupByName(const Utf8Str &aName,
+ ComObjPtr<BandwidthGroup> &aBandwidthGroup,
+ bool aSetError /* = false */);
+
+private:
+
+ // wrapped IBandwidthControl properties
+ HRESULT getNumGroups(ULONG *aNumGroups);
+
+ // wrapped IBandwidthControl methods
+ HRESULT createBandwidthGroup(const com::Utf8Str &aName,
+ BandwidthGroupType_T aType,
+ LONG64 aMaxBytesPerSec);
+ HRESULT deleteBandwidthGroup(const com::Utf8Str &aName);
+ HRESULT getBandwidthGroup(const com::Utf8Str &aName,
+ ComPtr<IBandwidthGroup> &aBandwidthGroup);
+ HRESULT getAllBandwidthGroups(std::vector<ComPtr<IBandwidthGroup> > &aBandwidthGroups);
+
+ // Data
+ typedef std::list< ComObjPtr<BandwidthGroup> > BandwidthGroupList;
+
+ struct Data
+ {
+ Data(Machine *pMachine)
+ : pParent(pMachine)
+ { }
+
+ ~Data()
+ {};
+
+ Machine * const pParent;
+
+ // peer machine's bandwidth control
+ const ComObjPtr<BandwidthControl> pPeer;
+
+ // the following fields need special backup/rollback/commit handling,
+ // so they cannot be a part of BackupableData
+ Backupable<BandwidthGroupList> llBandwidthGroups;
+ };
+
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_BandwidthControlImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/BandwidthGroupImpl.h b/src/VBox/Main/include/BandwidthGroupImpl.h
new file mode 100644
index 00000000..9bd56a98
--- /dev/null
+++ b/src/VBox/Main/include/BandwidthGroupImpl.h
@@ -0,0 +1,115 @@
+/* $Id: BandwidthGroupImpl.h $ */
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_BandwidthGroupImpl_h
+#define MAIN_INCLUDED_BandwidthGroupImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/settings.h>
+#include "BandwidthControlImpl.h"
+#include "BandwidthGroupWrap.h"
+
+
+class ATL_NO_VTABLE BandwidthGroup :
+ public BandwidthGroupWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(BandwidthGroup)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(BandwidthControl *aParent,
+ const com::Utf8Str &aName,
+ BandwidthGroupType_T aType,
+ LONG64 aMaxBytesPerSec);
+ HRESULT init(BandwidthControl *aParent, BandwidthGroup *aThat, bool aReshare = false);
+ HRESULT initCopy(BandwidthControl *aParent, BandwidthGroup *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ void i_rollback();
+ void i_commit();
+ void i_unshare();
+ void i_reference();
+ void i_release();
+
+ ComObjPtr<BandwidthGroup> i_getPeer() { return m->pPeer; }
+ const Utf8Str &i_getName() const { return m->bd->mData.strName; }
+ BandwidthGroupType_T i_getType() const { return m->bd->mData.enmType; }
+ LONG64 i_getMaxBytesPerSec() const { return (LONG64)m->bd->mData.cMaxBytesPerSec; }
+ ULONG i_getReferences() const { return m->bd->cReferences; }
+
+private:
+
+ // wrapped IBandwidthGroup properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getType(BandwidthGroupType_T *aType);
+ HRESULT getReference(ULONG *aReferences);
+ HRESULT getMaxBytesPerSec(LONG64 *aMaxBytesPerSec);
+ HRESULT setMaxBytesPerSec(LONG64 MaxBytesPerSec);
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////
+ //// private member data definition
+ ////
+ //////////////////////////////////////////////////////////////////////////////////
+ //
+ struct BackupableBandwidthGroupData
+ {
+ BackupableBandwidthGroupData()
+ : cReferences(0)
+ { }
+
+ settings::BandwidthGroup mData;
+ ULONG cReferences;
+ };
+
+ struct Data
+ {
+ Data(BandwidthControl * const aBandwidthControl)
+ : pParent(aBandwidthControl),
+ pPeer(NULL)
+ { }
+
+ BandwidthControl * const pParent;
+ ComObjPtr<BandwidthGroup> pPeer;
+
+ // use the XML settings structure in the members for simplicity
+ Backupable<BackupableBandwidthGroupData> bd;
+ };
+
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_BandwidthGroupImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/BusAssignmentManager.h b/src/VBox/Main/include/BusAssignmentManager.h
new file mode 100644
index 00000000..d3bff5cd
--- /dev/null
+++ b/src/VBox/Main/include/BusAssignmentManager.h
@@ -0,0 +1,90 @@
+/* $Id: BusAssignmentManager.h $ */
+/** @file
+ * VirtualBox bus slots assignment manager
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_BusAssignmentManager_h
+#define MAIN_INCLUDED_BusAssignmentManager_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VBox/types.h"
+#include "VBox/pci.h"
+#include "VirtualBoxBase.h"
+#include <vector>
+
+class BusAssignmentManager
+{
+private:
+ struct State;
+ State *pState;
+
+ BusAssignmentManager();
+ virtual ~BusAssignmentManager();
+
+ HRESULT assignPCIDeviceImpl(const char *pszDevName, PCFGMNODE pCfg, PCIBusAddress& GuestAddress,
+ PCIBusAddress HostAddress, bool fGuestAddressRequired = false);
+
+public:
+ struct PCIDeviceInfo
+ {
+ com::Utf8Str strDeviceName;
+ PCIBusAddress guestAddress;
+ PCIBusAddress hostAddress;
+ };
+
+ static BusAssignmentManager *createInstance(PCVMMR3VTABLE pVMM, ChipsetType_T chipsetType, IommuType_T iommuType);
+ virtual void AddRef();
+ virtual void Release();
+
+ virtual HRESULT assignHostPCIDevice(const char *pszDevName, PCFGMNODE pCfg, PCIBusAddress HostAddress,
+ PCIBusAddress& GuestAddress, bool fAddressRequired = false)
+ {
+ return assignPCIDeviceImpl(pszDevName, pCfg, GuestAddress, HostAddress, fAddressRequired);
+ }
+
+ virtual HRESULT assignPCIDevice(const char *pszDevName, PCFGMNODE pCfg, PCIBusAddress& Address, bool fAddressRequired = false)
+ {
+ PCIBusAddress HostAddress;
+ return assignPCIDeviceImpl(pszDevName, pCfg, Address, HostAddress, fAddressRequired);
+ }
+
+ virtual HRESULT assignPCIDevice(const char *pszDevName, PCFGMNODE pCfg)
+ {
+ PCIBusAddress GuestAddress;
+ PCIBusAddress HostAddress;
+ return assignPCIDeviceImpl(pszDevName, pCfg, GuestAddress, HostAddress, false);
+ }
+ virtual bool findPCIAddress(const char *pszDevName, int iInstance, PCIBusAddress& Address);
+ virtual bool hasPCIDevice(const char *pszDevName, int iInstance)
+ {
+ PCIBusAddress Address;
+ return findPCIAddress(pszDevName, iInstance, Address);
+ }
+ virtual void listAttachedPCIDevices(std::vector<PCIDeviceInfo> &aAttached);
+};
+
+#endif /* !MAIN_INCLUDED_BusAssignmentManager_h */
diff --git a/src/VBox/Main/include/CPUProfileImpl.h b/src/VBox/Main/include/CPUProfileImpl.h
new file mode 100644
index 00000000..bf8aa73a
--- /dev/null
+++ b/src/VBox/Main/include/CPUProfileImpl.h
@@ -0,0 +1,75 @@
+/* $Id: CPUProfileImpl.h $ */
+/** @file
+ * VirtualBox Main - interface for CPU profiles, VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2020-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_CPUProfileImpl_h
+#define MAIN_INCLUDED_CPUProfileImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "CPUProfileWrap.h"
+
+struct CPUMDBENTRY;
+
+/**
+ * A CPU profile.
+ */
+class ATL_NO_VTABLE CPUProfile
+ : public CPUProfileWrap
+{
+public:
+ /** @name COM and internal init/term/mapping cruft
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(CPUProfile)
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ HRESULT initFromDbEntry(struct CPUMDBENTRY const *a_pDbEntry) RT_NOEXCEPT;
+ void uninit();
+ /** @} */
+
+ bool i_match(CPUArchitecture_T a_enmArchitecture, CPUArchitecture_T a_enmSecondaryArch,
+ const com::Utf8Str &a_strNamePattern) const RT_NOEXCEPT;
+
+private:
+ /** @name Wrapped ICPUProfile attributes
+ * @{ */
+ HRESULT getName(com::Utf8Str &aName) RT_OVERRIDE;
+ HRESULT getFullName(com::Utf8Str &aFullName) RT_OVERRIDE;
+ HRESULT getArchitecture(CPUArchitecture_T *aArchitecture) RT_OVERRIDE;
+ /** @} */
+
+ /** @name Data
+ * @{ */
+ com::Utf8Str m_strName;
+ com::Utf8Str m_strFullName;
+ CPUArchitecture_T m_enmArchitecture;
+ /** @} */
+};
+
+#endif /* !MAIN_INCLUDED_CPUProfileImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/CertificateImpl.h b/src/VBox/Main/include/CertificateImpl.h
new file mode 100644
index 00000000..51f7ecf9
--- /dev/null
+++ b/src/VBox/Main/include/CertificateImpl.h
@@ -0,0 +1,112 @@
+/* $Id: CertificateImpl.h $ */
+/** @file
+ * VirtualBox COM ICertificate implementation.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_CertificateImpl_h
+#define MAIN_INCLUDED_CertificateImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/* VBox includes */
+#include <iprt/crypto/x509.h>
+#include "CertificateWrap.h"
+
+#include <vector>
+
+using namespace std;
+
+/**
+ * Implemenation of ICertificate.
+ *
+ * This implemenation is a very thin wrapper around an immutable
+ * RTCRX509CERTIFICATE and a few caller stated views.
+ *
+ * The views are whether the caller thinks the certificate is trustworthly, and
+ * whether the caller thinks it's expired or not. The caller could be sitting
+ * on more information, like timestamp and intermediate certificates, that helps
+ * inform the caller's view on these two topics.
+ *
+ * @remarks It could be helpful to let the caller also add certificate paths
+ * showing how this certificate ends up being trusted. However, that's
+ * possibly quite some work and will have to wait till required...
+ */
+class ATL_NO_VTABLE Certificate
+ : public CertificateWrap
+{
+
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(Certificate)
+
+ HRESULT initCertificate(PCRTCRX509CERTIFICATE a_pCert, bool a_fTrusted, bool a_fExpired);
+ void uninit();
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+private:
+ // Wrapped ICertificate properties
+ HRESULT getVersionNumber(CertificateVersion_T *aVersionNumber);
+ HRESULT getSerialNumber(com::Utf8Str &aSerialNumber);
+ HRESULT getSignatureAlgorithmOID(com::Utf8Str &aSignatureAlgorithmOID);
+ HRESULT getSignatureAlgorithmName(com::Utf8Str &aSignatureAlgorithmName);
+ HRESULT getPublicKeyAlgorithmOID(com::Utf8Str &aPublicKeyAlgorithmOID);
+ HRESULT getPublicKeyAlgorithm(com::Utf8Str &aPublicKeyAlgorithm);
+ HRESULT getIssuerName(std::vector<com::Utf8Str> &aIssuerName);
+ HRESULT getSubjectName(std::vector<com::Utf8Str> &aSubjectName);
+ HRESULT getFriendlyName(com::Utf8Str &aFriendlyName);
+ HRESULT getValidityPeriodNotBefore(com::Utf8Str &aValidityPeriodNotBefore);
+ HRESULT getValidityPeriodNotAfter(com::Utf8Str &aValidityPeriodNotAfter);
+ HRESULT getSubjectPublicKey(std::vector<BYTE> &aSubjectPublicKey);
+ HRESULT getIssuerUniqueIdentifier(com::Utf8Str &aIssuerUniqueIdentifier);
+ HRESULT getSubjectUniqueIdentifier(com::Utf8Str &aSubjectUniqueIdentifier);
+ HRESULT getCertificateAuthority(BOOL *aCertificateAuthority);
+ HRESULT getKeyUsage(ULONG *aKeyUsage);
+ HRESULT getExtendedKeyUsage(std::vector<com::Utf8Str> &aExtendedKeyUsage);
+ HRESULT getRawCertData(std::vector<BYTE> &aRawCertData);
+ HRESULT getSelfSigned(BOOL *aSelfSigned);
+ HRESULT getTrusted(BOOL *aTrusted);
+ HRESULT getExpired(BOOL *aExpired);
+
+ // Wrapped ICertificate methods
+ HRESULT isCurrentlyExpired(BOOL *aResult);
+ HRESULT queryInfo(LONG aWhat, com::Utf8Str &aResult);
+
+ // Methods extracting COM data from the certificate object
+ HRESULT i_getAlgorithmName(PCRTCRX509ALGORITHMIDENTIFIER a_pAlgId, com::Utf8Str &a_rReturn);
+ HRESULT i_getX509Name(PCRTCRX509NAME a_pName, std::vector<com::Utf8Str> &a_rReturn);
+ HRESULT i_getTime(PCRTASN1TIME a_pTime, com::Utf8Str &a_rReturn);
+ HRESULT i_getUniqueIdentifier(PCRTCRX509UNIQUEIDENTIFIER a_pUniqueId, com::Utf8Str &a_rReturn);
+ HRESULT i_getEncodedBytes(PRTASN1CORE a_pAsn1Obj, std::vector<BYTE> &a_rReturn);
+
+ struct Data;
+ /** Pointer to the private instance data */
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_CertificateImpl_h */
+
diff --git a/src/VBox/Main/include/ClientToken.h b/src/VBox/Main/include/ClientToken.h
new file mode 100644
index 00000000..52f1e2f1
--- /dev/null
+++ b/src/VBox/Main/include/ClientToken.h
@@ -0,0 +1,118 @@
+/* $Id: ClientToken.h $ */
+
+/** @file
+ *
+ * VirtualBox API client session token abstraction
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ClientToken_h
+#define MAIN_INCLUDED_ClientToken_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/ptr.h>
+#include <VBox/com/AutoLock.h>
+
+#include "MachineImpl.h"
+#ifdef VBOX_WITH_GENERIC_SESSION_WATCHER
+# include "TokenImpl.h"
+#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+
+#if defined(RT_OS_WINDOWS)
+# define CTTOKENARG NULL
+# define CTTOKENTYPE HANDLE
+#elif defined(RT_OS_OS2)
+# define CTTOKENARG NULLHANDLE
+# define CTTOKENTYPE HMTX
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+# define CTTOKENARG -1
+# define CTTOKENTYPE int
+#elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
+# define CTTOKENARG NULL
+# define CTTOKENTYPE MachineToken *
+#else
+# error "Port me!"
+#endif
+
+/**
+ * Class which represents a token which can be used to check for client
+ * crashes and similar purposes.
+ */
+class Machine::ClientToken
+{
+public:
+ /**
+ * Constructor which creates a usable instance
+ *
+ * @param pMachine Reference to Machine object
+ * @param pSessionMachine Reference to corresponding SessionMachine object
+ */
+ ClientToken(const ComObjPtr<Machine> &pMachine, SessionMachine *pSessionMachine);
+
+ /**
+ * Default destructor. Cleans everything up.
+ */
+ ~ClientToken();
+
+ /**
+ * Check if object contains a usable token.
+ */
+ bool isReady();
+
+ /**
+ * Query token ID, which is a unique string value for this token. Do not
+ * assume any specific content/format, it is opaque information.
+ */
+ void getId(Utf8Str &strId);
+
+ /**
+ * Query token, which is platform dependent.
+ */
+ CTTOKENTYPE getToken();
+
+#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
+ /**
+ * Release token now. Returns information if the client has terminated.
+ */
+ bool release();
+#endif /* !VBOX_WITH_GENERIC_SESSION_WATCHER */
+
+private:
+ /**
+ * Default constructor. Don't use, will not create a sensible instance.
+ */
+ ClientToken();
+
+ Machine *mMachine;
+ CTTOKENTYPE mClientToken;
+ Utf8Str mClientTokenId;
+#ifdef VBOX_WITH_GENERIC_SESSION_WATCHER
+ bool mClientTokenPassed;
+#endif
+};
+
+#endif /* !MAIN_INCLUDED_ClientToken_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ClientTokenHolder.h b/src/VBox/Main/include/ClientTokenHolder.h
new file mode 100644
index 00000000..a6bf3262
--- /dev/null
+++ b/src/VBox/Main/include/ClientTokenHolder.h
@@ -0,0 +1,112 @@
+/* $Id: ClientTokenHolder.h $ */
+
+/** @file
+ *
+ * VirtualBox API client session token holder (in the client process)
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ClientTokenHolder_h
+#define MAIN_INCLUDED_ClientTokenHolder_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SessionImpl.h"
+
+#if defined(RT_OS_WINDOWS)
+# define CTHSEMARG NULL
+# define CTHSEMTYPE HANDLE
+/* this second semaphore is only used on Windows */
+# define CTHTHREADSEMARG NULL
+# define CTHTHREADSEMTYPE HANDLE
+#elif defined(RT_OS_OS2)
+# define CTHSEMARG NIL_RTSEMEVENT
+# define CTHSEMTYPE RTSEMEVENT
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
+# define CTHSEMARG -1
+# define CTHSEMTYPE int
+#elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
+/* the token object based implementation needs no semaphores */
+#else
+# error "Port me!"
+#endif
+
+
+/**
+ * Class which holds a client token.
+ */
+class Session::ClientTokenHolder
+{
+public:
+#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
+ /**
+ * Constructor which creates a usable instance
+ *
+ * @param strTokenId String with identifier of the token
+ */
+ ClientTokenHolder(const Utf8Str &strTokenId);
+#else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+ /**
+ * Constructor which creates a usable instance
+ *
+ * @param aToken Reference to token object
+ */
+ ClientTokenHolder(IToken *aToken);
+#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+
+ /**
+ * Default destructor. Cleans everything up.
+ */
+ ~ClientTokenHolder();
+
+ /**
+ * Check if object contains a usable token.
+ */
+ bool isReady();
+
+private:
+ /**
+ * Default constructor. Don't use, will not create a sensible instance.
+ */
+ ClientTokenHolder();
+
+#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
+ Utf8Str mClientTokenId;
+#else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+ ComPtr<IToken> mToken;
+#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+#ifdef CTHSEMTYPE
+ CTHSEMTYPE mSem;
+#endif
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+ RTTHREAD mThread;
+#endif
+#ifdef RT_OS_WINDOWS
+ CTHTHREADSEMTYPE mThreadSem;
+#endif
+};
+
+#endif /* !MAIN_INCLUDED_ClientTokenHolder_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ClientWatcher.h b/src/VBox/Main/include/ClientWatcher.h
new file mode 100644
index 00000000..962817eb
--- /dev/null
+++ b/src/VBox/Main/include/ClientWatcher.h
@@ -0,0 +1,146 @@
+/* $Id: ClientWatcher.h $ */
+/** @file
+ * VirtualBox API client session watcher
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ClientWatcher_h
+#define MAIN_INCLUDED_ClientWatcher_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+#include <list>
+#include <VBox/com/ptr.h>
+#include <VBox/com/AutoLock.h>
+
+#include "VirtualBoxImpl.h"
+
+#if defined(RT_OS_WINDOWS)
+# define CWUPDATEREQARG NULL
+# define CWUPDATEREQTYPE HANDLE
+# define CW_MAX_CLIENTS _16K /**< Max number of clients we can watch (windows). */
+# ifndef DEBUG /* The debug version triggers worker thread code much much earlier. */
+# define CW_MAX_CLIENTS_PER_THREAD 63 /**< Max clients per watcher thread (windows). */
+# else
+# define CW_MAX_CLIENTS_PER_THREAD 3 /**< Max clients per watcher thread (windows). */
+# endif
+# define CW_MAX_HANDLES_PER_THREAD (CW_MAX_CLIENTS_PER_THREAD + 1) /**< Max handles per thread. */
+
+#elif defined(RT_OS_OS2)
+# define CWUPDATEREQARG NIL_RTSEMEVENT
+# define CWUPDATEREQTYPE RTSEMEVENT
+
+#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
+# define CWUPDATEREQARG NIL_RTSEMEVENT
+# define CWUPDATEREQTYPE RTSEMEVENT
+
+#else
+# error "Port me!"
+#endif
+
+/**
+ * Class which checks for API clients which have crashed/exited, and takes
+ * the necessary cleanup actions. Singleton.
+ */
+class VirtualBox::ClientWatcher
+{
+public:
+ /**
+ * Constructor which creates a usable instance
+ *
+ * @param pVirtualBox Reference to VirtualBox object
+ */
+ ClientWatcher(const ComObjPtr<VirtualBox> &pVirtualBox);
+
+ /**
+ * Default destructor. Cleans everything up.
+ */
+ ~ClientWatcher();
+
+ bool isReady();
+
+ void update();
+ void addProcess(RTPROCESS pid);
+
+private:
+ /**
+ * Default constructor. Don't use, will not create a sensible instance.
+ */
+ ClientWatcher();
+
+ static DECLCALLBACK(int) worker(RTTHREAD hThreadSelf, void *pvUser);
+ uint32_t reapProcesses(void);
+
+ VirtualBox *mVirtualBox;
+ RTTHREAD mThread;
+ CWUPDATEREQTYPE mUpdateReq;
+ util::RWLockHandle mLock;
+
+ typedef std::list<RTPROCESS> ProcessList;
+ ProcessList mProcesses;
+
+#if defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER) || defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
+ uint8_t mUpdateAdaptCtr;
+#endif
+#ifdef RT_OS_WINDOWS
+ /** Indicate a real update request is pending.
+ * To avoid race conditions this must be set before mUpdateReq is signalled and
+ * read after resetting mUpdateReq. */
+ volatile bool mfUpdateReq;
+ /** Set when the worker threads are supposed to shut down. */
+ volatile bool mfTerminate;
+ /** Number of active subworkers.
+ * When decremented to 0, subworker zero is signalled. */
+ uint32_t volatile mcActiveSubworkers;
+ /** Number of valid handles in mahWaitHandles. */
+ uint32_t mcWaitHandles;
+ /** The wait interval (usually INFINITE). */
+ uint32_t mcMsWait;
+ /** Per subworker data. Subworker 0 is the main worker and does not have a
+ * pReq pointer since. */
+ struct PerSubworker
+ {
+ /** The wait result. */
+ DWORD dwWait;
+ /** The subworker index. */
+ uint32_t iSubworker;
+ /** The subworker thread handle. */
+ RTTHREAD hThread;
+ /** Self pointer (for worker thread). */
+ VirtualBox::ClientWatcher *pSelf;
+ } maSubworkers[(CW_MAX_CLIENTS + CW_MAX_CLIENTS_PER_THREAD - 1) / CW_MAX_CLIENTS_PER_THREAD];
+ /** Wait handle array. The mUpdateReq manual reset event handle is inserted
+ * every 64 entries, first entry being 0. */
+ HANDLE mahWaitHandles[CW_MAX_CLIENTS + (CW_MAX_CLIENTS + CW_MAX_CLIENTS_PER_THREAD - 1) / CW_MAX_CLIENTS_PER_THREAD];
+
+ void subworkerWait(VirtualBox::ClientWatcher::PerSubworker *pSubworker, uint32_t cMsWait);
+ static DECLCALLBACK(int) subworkerThread(RTTHREAD hThreadSelf, void *pvUser);
+ void winResetHandleArray(uint32_t cProcHandles);
+#endif
+};
+
+#endif /* !MAIN_INCLUDED_ClientWatcher_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/CloudGateway.h b/src/VBox/Main/include/CloudGateway.h
new file mode 100644
index 00000000..06863d61
--- /dev/null
+++ b/src/VBox/Main/include/CloudGateway.h
@@ -0,0 +1,103 @@
+/* $Id: CloudGateway.h $ */
+/** @file
+ * Implementation of local and cloud gateway management.
+ */
+
+/*
+ * Copyright (C) 2019-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_CloudGateway_h
+#define MAIN_INCLUDED_CloudGateway_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+struct GatewayInfo
+{
+ Bstr mTargetVM;
+ Utf8Str mGatewayInstanceId;
+ Utf8Str mPublicSshKey;
+ Utf8Str mPrivateSshKey;
+ Bstr mCloudProvider;
+ Bstr mCloudProfile;
+ Utf8Str mCloudPublicIp;
+ Utf8Str mCloudSecondaryPublicIp;
+ RTMAC mCloudMacAddress;
+ RTMAC mLocalMacAddress;
+ int mAdapterSlot;
+
+ HRESULT setCloudMacAddress(const Utf8Str& mac);
+ HRESULT setLocalMacAddress(const Utf8Str& mac);
+
+ GatewayInfo() {}
+
+ GatewayInfo(const GatewayInfo& other)
+ : mGatewayInstanceId(other.mGatewayInstanceId),
+ mPublicSshKey(other.mPublicSshKey),
+ mPrivateSshKey(other.mPrivateSshKey),
+ mCloudProvider(other.mCloudProvider),
+ mCloudProfile(other.mCloudProfile),
+ mCloudPublicIp(other.mCloudPublicIp),
+ mCloudSecondaryPublicIp(other.mCloudSecondaryPublicIp),
+ mCloudMacAddress(other.mCloudMacAddress),
+ mLocalMacAddress(other.mLocalMacAddress),
+ mAdapterSlot(other.mAdapterSlot)
+ {}
+
+ GatewayInfo& operator=(const GatewayInfo& other)
+ {
+ mGatewayInstanceId = other.mGatewayInstanceId;
+ mPublicSshKey = other.mPublicSshKey;
+ mPrivateSshKey = other.mPrivateSshKey;
+ mCloudProvider = other.mCloudProvider;
+ mCloudProfile = other.mCloudProfile;
+ mCloudPublicIp = other.mCloudPublicIp;
+ mCloudSecondaryPublicIp = other.mCloudSecondaryPublicIp;
+ mCloudMacAddress = other.mCloudMacAddress;
+ mLocalMacAddress = other.mLocalMacAddress;
+ mAdapterSlot = other.mAdapterSlot;
+ return *this;
+ }
+
+ void setNull()
+ {
+ mGatewayInstanceId.setNull();
+ mPublicSshKey.setNull();
+ mPrivateSshKey.setNull();
+ mCloudProvider.setNull();
+ mCloudProfile.setNull();
+ mCloudPublicIp.setNull();
+ mCloudSecondaryPublicIp.setNull();
+ memset(&mCloudMacAddress, 0, sizeof(mCloudMacAddress));
+ memset(&mLocalMacAddress, 0, sizeof(mLocalMacAddress));
+ mAdapterSlot = -1;
+ }
+};
+
+class CloudNetwork;
+
+HRESULT startCloudGateway(ComPtr<IVirtualBox> virtualBox, ComPtr<ICloudNetwork> network, GatewayInfo& pGateways);
+HRESULT stopCloudGateway(ComPtr<IVirtualBox> virtualBox, GatewayInfo& gateways);
+HRESULT generateKeys(GatewayInfo& gateways);
+
+#endif /* !MAIN_INCLUDED_CloudGateway_h */
+
diff --git a/src/VBox/Main/include/CloudNetworkImpl.h b/src/VBox/Main/include/CloudNetworkImpl.h
new file mode 100644
index 00000000..cde8314a
--- /dev/null
+++ b/src/VBox/Main/include/CloudNetworkImpl.h
@@ -0,0 +1,79 @@
+/* $Id: CloudNetworkImpl.h $ */
+/** @file
+ * ICloudNetwork implementation header, lives in VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2019-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_CloudNetworkImpl_h
+#define MAIN_INCLUDED_CloudNetworkImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "CloudNetworkWrap.h"
+
+namespace settings
+{
+ struct CloudNetwork;
+}
+
+class ATL_NO_VTABLE CloudNetwork :
+ public CloudNetworkWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(CloudNetwork)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(VirtualBox *aVirtualBox, com::Utf8Str aName);
+ HRESULT i_loadSettings(const settings::CloudNetwork &data);
+ void uninit();
+ HRESULT i_saveSettings(settings::CloudNetwork &data);
+
+ // Internal methods
+ Utf8Str i_getNetworkName();
+ Utf8Str i_getProvider();
+ Utf8Str i_getProfile();
+ Utf8Str i_getNetworkId();
+private:
+
+ // Wrapped ICloudNetwork properties
+ HRESULT getNetworkName(com::Utf8Str &aNetworkName);
+ HRESULT setNetworkName(const com::Utf8Str &aNetworkName);
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getProvider(com::Utf8Str &aProvider);
+ HRESULT setProvider(const com::Utf8Str &aProvider);
+ HRESULT getProfile(com::Utf8Str &aProfile);
+ HRESULT setProfile(const com::Utf8Str &aProfile);
+ HRESULT getNetworkId(com::Utf8Str &aNetworkId);
+ HRESULT setNetworkId(const com::Utf8Str &aNetworkId);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_CloudNetworkImpl_h */
diff --git a/src/VBox/Main/include/CloudProviderManagerImpl.h b/src/VBox/Main/include/CloudProviderManagerImpl.h
new file mode 100644
index 00000000..67f08c14
--- /dev/null
+++ b/src/VBox/Main/include/CloudProviderManagerImpl.h
@@ -0,0 +1,82 @@
+/* $Id: CloudProviderManagerImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_CloudProviderManagerImpl_h
+#define MAIN_INCLUDED_CloudProviderManagerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "CloudProviderManagerWrap.h"
+
+class ATL_NO_VTABLE CloudProviderManager
+ : public CloudProviderManagerWrap
+{
+public:
+ CloudProviderManager();
+ virtual ~CloudProviderManager();
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(VirtualBox *aVirtualBox);
+ void uninit();
+
+#ifdef VBOX_WITH_EXTPACK
+ // Safe helpers, take care of caller and lock themselves.
+ bool i_canRemoveExtPack(IExtPack *aExtPack);
+ void i_addExtPack(IExtPack *aExtPack);
+#endif
+
+private:
+ // wrapped ICloudProviderManager attributes and methods
+ HRESULT getProviders(std::vector<ComPtr<ICloudProvider> > &aProviders);
+ HRESULT getProviderById(const com::Guid &aProviderId,
+ ComPtr<ICloudProvider> &aProvider);
+ HRESULT getProviderByShortName(const com::Utf8Str &aProviderName,
+ ComPtr<ICloudProvider> &aProvider);
+ HRESULT getProviderByName(const com::Utf8Str &aProviderName,
+ ComPtr<ICloudProvider> &aProvider);
+
+private:
+#ifdef VBOX_WITH_EXTPACK
+ typedef std::map<com::Utf8Str, ComPtr<ICloudProviderManager> > ExtPackNameCloudProviderManagerMap;
+ ExtPackNameCloudProviderManagerMap m_mapCloudProviderManagers;
+
+ typedef std::vector<com::Utf8Str> ExtPackNameVec;
+ ExtPackNameVec m_astrExtPackNames;
+#endif
+
+ typedef std::vector<ComPtr<ICloudProvider> > CloudProviderVec;
+ CloudProviderVec m_apCloudProviders;
+
+ VirtualBox * const m_pVirtualBox;
+};
+
+#endif /* !MAIN_INCLUDED_CloudProviderManagerImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ConsoleImpl.h b/src/VBox/Main/include/ConsoleImpl.h
new file mode 100644
index 00000000..fdea838f
--- /dev/null
+++ b/src/VBox/Main/include/ConsoleImpl.h
@@ -0,0 +1,1222 @@
+/* $Id: ConsoleImpl.h $ */
+/** @file
+ * VBox Console COM Class definition
+ */
+
+/*
+ * Copyright (C) 2005-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ConsoleImpl_h
+#define MAIN_INCLUDED_ConsoleImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include "VBox/com/array.h"
+#include "EventImpl.h"
+#include "SecretKeyStore.h"
+#include "ConsoleWrap.h"
+#ifdef VBOX_WITH_RECORDING
+# include "Recording.h"
+#endif
+#ifdef VBOX_WITH_CLOUD_NET
+#include "CloudGateway.h"
+#endif /* VBOX_WITH_CLOUD_NET */
+
+class Guest;
+class Keyboard;
+class Mouse;
+class Display;
+class MachineDebugger;
+class TeleporterStateSrc;
+class OUSBDevice;
+class RemoteUSBDevice;
+class ConsoleSharedFolder;
+class VRDEServerInfo;
+class EmulatedUSB;
+class AudioVRDE;
+#ifdef VBOX_WITH_AUDIO_RECORDING
+class AudioVideoRec;
+#endif
+#ifdef VBOX_WITH_USB_CARDREADER
+class UsbCardReader;
+#endif
+class ConsoleVRDPServer;
+class VMMDev;
+class Progress;
+class BusAssignmentManager;
+COM_STRUCT_OR_CLASS(IEventListener);
+#ifdef VBOX_WITH_EXTPACK
+class ExtPackManager;
+#endif
+class VMMDevMouseInterface;
+class DisplayMouseInterface;
+class VMPowerUpTask;
+class VMPowerDownTask;
+class NvramStore;
+
+#include <iprt/uuid.h>
+#include <iprt/log.h>
+#include <iprt/memsafer.h>
+#include <VBox/RemoteDesktop/VRDE.h>
+#include <VBox/vmm/pdmdrv.h>
+#ifdef VBOX_WITH_GUEST_PROPS
+# include <VBox/HostServices/GuestPropertySvc.h> /* For the property notification callback */
+#endif
+#ifdef VBOX_WITH_USB
+# include <VBox/vrdpusb.h>
+#endif
+#include <VBox/VBoxCryptoIf.h>
+
+#if defined(VBOX_WITH_GUEST_PROPS) || defined(VBOX_WITH_SHARED_CLIPBOARD) \
+ || defined(VBOX_WITH_DRAG_AND_DROP)
+# include "HGCM.h" /** @todo It should be possible to register a service
+ * extension using a VMMDev callback. */
+#endif
+
+struct VUSBIRHCONFIG;
+typedef struct VUSBIRHCONFIG *PVUSBIRHCONFIG;
+
+#include <list>
+#include <vector>
+
+// defines
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Checks the availability of the underlying VM device driver corresponding
+ * to the COM interface (IKeyboard, IMouse, IDisplay, etc.). When the driver is
+ * not available (NULL), sets error info and returns returns E_ACCESSDENIED.
+ * The translatable error message is defined in null context.
+ *
+ * Intended to used only within Console children (i.e. Keyboard, Mouse,
+ * Display, etc.).
+ *
+ * @param drv driver pointer to check (compare it with NULL)
+ */
+#define CHECK_CONSOLE_DRV(drv) \
+ do { \
+ if (!!(drv)) {} \
+ else return setError(E_ACCESSDENIED, Console::tr("The console is not powered up (%Rfn)"), __FUNCTION__); \
+ } while (0)
+
+// Console
+///////////////////////////////////////////////////////////////////////////////
+
+class ConsoleMouseInterface
+{
+public:
+ virtual ~ConsoleMouseInterface() { }
+ virtual VMMDevMouseInterface *i_getVMMDevMouseInterface(){return NULL;}
+ virtual DisplayMouseInterface *i_getDisplayMouseInterface(){return NULL;}
+ virtual void i_onMouseCapabilityChange(BOOL supportsAbsolute,
+ BOOL supportsRelative,
+ BOOL supportsTouchScreen,
+ BOOL supportsTouchPad,
+ BOOL needsHostCursor)
+ {
+ RT_NOREF(supportsAbsolute, supportsRelative, supportsTouchScreen, supportsTouchPad, needsHostCursor);
+ }
+};
+
+/** IConsole implementation class */
+class ATL_NO_VTABLE Console :
+ public ConsoleWrap,
+ public ConsoleMouseInterface
+{
+
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(Console)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializers/uninitializers for internal purposes only
+ HRESULT initWithMachine(IMachine *aMachine, IInternalMachineControl *aControl, LockType_T aLockType);
+ void uninit();
+
+
+ // public methods for internal purposes only
+
+ /*
+ * Note: the following methods do not increase refcount. intended to be
+ * called only by the VM execution thread.
+ */
+
+ PCVMMR3VTABLE i_getVMMVTable() const RT_NOEXCEPT { return mpVMM; }
+ Guest *i_getGuest() const { return mGuest; }
+ Keyboard *i_getKeyboard() const { return mKeyboard; }
+ Mouse *i_getMouse() const { return mMouse; }
+ Display *i_getDisplay() const { return mDisplay; }
+ MachineDebugger *i_getMachineDebugger() const { return mDebugger; }
+#ifdef VBOX_WITH_AUDIO_VRDE
+ AudioVRDE *i_getAudioVRDE() const { return mAudioVRDE; }
+#endif
+#ifdef VBOX_WITH_RECORDING
+ int i_recordingCreate(void);
+ void i_recordingDestroy(void);
+ int i_recordingEnable(BOOL fEnable, util::AutoWriteLock *pAutoLock);
+ int i_recordingGetSettings(settings::RecordingSettings &recording);
+ int i_recordingStart(util::AutoWriteLock *pAutoLock = NULL);
+ int i_recordingStop(util::AutoWriteLock *pAutoLock = NULL);
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ AudioVideoRec *i_recordingGetAudioDrv(void) const { return mRecording.mAudioRec; }
+# endif
+ RecordingContext *i_recordingGetContext(void) { return &mRecording.mCtx; }
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ HRESULT i_recordingSendAudio(const void *pvData, size_t cbData, uint64_t uDurationMs);
+# endif
+#endif
+
+ const ComPtr<IMachine> &i_machine() const { return mMachine; }
+ const Bstr &i_getId() const { return mstrUuid; }
+
+ bool i_useHostClipboard() { return mfUseHostClipboard; }
+
+ /** Method is called only from ConsoleVRDPServer */
+ IVRDEServer *i_getVRDEServer() const { return mVRDEServer; }
+
+ ConsoleVRDPServer *i_consoleVRDPServer() const { return mConsoleVRDPServer; }
+
+ HRESULT i_updateMachineState(MachineState_T aMachineState);
+ HRESULT i_getNominalState(MachineState_T &aNominalState);
+ Utf8Str i_getAudioAdapterDeviceName(IAudioAdapter *aAudioAdapter);
+
+ // events from IInternalSessionControl
+ HRESULT i_onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL changeAdapter);
+ HRESULT i_onAudioAdapterChange(IAudioAdapter *aAudioAdapter);
+ HRESULT i_onHostAudioDeviceChange(IHostAudioDevice *aDevice, BOOL aNew, AudioDeviceState_T aState,
+ IVirtualBoxErrorInfo *aErrInfo);
+ HRESULT i_onSerialPortChange(ISerialPort *aSerialPort);
+ HRESULT i_onParallelPortChange(IParallelPort *aParallelPort);
+ HRESULT i_onStorageControllerChange(const com::Guid& aMachineId, const com::Utf8Str& aControllerName);
+ HRESULT i_onMediumChange(IMediumAttachment *aMediumAttachment, BOOL aForce);
+ HRESULT i_onCPUChange(ULONG aCPU, BOOL aRemove);
+ HRESULT i_onCPUExecutionCapChange(ULONG aExecutionCap);
+ HRESULT i_onClipboardModeChange(ClipboardMode_T aClipboardMode);
+ HRESULT i_onClipboardFileTransferModeChange(bool aEnabled);
+ HRESULT i_onDnDModeChange(DnDMode_T aDnDMode);
+ HRESULT i_onVRDEServerChange(BOOL aRestart);
+ HRESULT i_onRecordingChange(BOOL fEnable);
+ HRESULT i_onUSBControllerChange();
+ HRESULT i_onSharedFolderChange(BOOL aGlobal);
+ HRESULT i_onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs,
+ const Utf8Str &aCaptureFilename);
+ HRESULT i_onUSBDeviceDetach(IN_BSTR aId, IVirtualBoxErrorInfo *aError);
+ HRESULT i_onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
+ HRESULT i_onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove, BOOL aSilent);
+ HRESULT i_onExtraDataChange(const Bstr &aMachineId, const Bstr &aKey, const Bstr &aVal);
+ HRESULT i_onGuestDebugControlChange(IGuestDebugControl *aGuestDebugControl);
+
+ HRESULT i_getGuestProperty(const Utf8Str &aName, Utf8Str *aValue, LONG64 *aTimestamp, Utf8Str *aFlags);
+ HRESULT i_setGuestProperty(const Utf8Str &aName, const Utf8Str &aValue, const Utf8Str &aFlags);
+ HRESULT i_deleteGuestProperty(const Utf8Str &aName);
+ HRESULT i_enumerateGuestProperties(const Utf8Str &aPatterns,
+ std::vector<Utf8Str> &aNames,
+ std::vector<Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<Utf8Str> &aFlags);
+ HRESULT i_onlineMergeMedium(IMediumAttachment *aMediumAttachment,
+ ULONG aSourceIdx, ULONG aTargetIdx,
+ IProgress *aProgress);
+ HRESULT i_reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments);
+ HRESULT i_onVMProcessPriorityChange(VMProcPriority_T priority);
+ int i_hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName);
+ VMMDev *i_getVMMDev() { return m_pVMMDev; }
+
+#ifdef VBOX_WITH_EXTPACK
+ ExtPackManager *i_getExtPackManager();
+#endif
+ EventSource *i_getEventSource() { return mEventSource; }
+#ifdef VBOX_WITH_USB_CARDREADER
+ UsbCardReader *i_getUsbCardReader() { return mUsbCardReader; }
+#endif
+
+ int i_VRDPClientLogon(uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain);
+ void i_VRDPClientStatusChange(uint32_t u32ClientId, const char *pszStatus);
+ void i_VRDPClientConnect(uint32_t u32ClientId);
+ void i_VRDPClientDisconnect(uint32_t u32ClientId, uint32_t fu32Intercepted);
+ void i_VRDPInterceptAudio(uint32_t u32ClientId);
+ void i_VRDPInterceptUSB(uint32_t u32ClientId, void **ppvIntercept);
+ void i_VRDPInterceptClipboard(uint32_t u32ClientId);
+
+ void i_processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList, bool fDescExt);
+ void i_reportVmStatistics(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM,
+ ULONG aVmNetRx, ULONG aVmNetTx)
+ {
+ mControl->ReportVmStatistics(aValidStats, aCpuUser, aCpuKernel, aCpuIdle,
+ aMemTotal, aMemFree, aMemBalloon, aMemShared,
+ aMemCache, aPageTotal, aAllocVMM, aFreeVMM,
+ aBalloonedVMM, aSharedVMM, aVmNetRx, aVmNetTx);
+ }
+ void i_enableVMMStatistics(BOOL aEnable);
+
+ HRESULT i_pause(Reason_T aReason);
+ HRESULT i_resume(Reason_T aReason, AutoWriteLock &alock);
+ HRESULT i_saveState(Reason_T aReason, const ComPtr<IProgress> &aProgress,
+ const ComPtr<ISnapshot> &aSnapshot,
+ const Utf8Str &aStateFilePath, bool fPauseVM, bool &fLeftPaused);
+ HRESULT i_cancelSaveState();
+
+ // callback callers (partly; for some events console callbacks are notified
+ // directly from IInternalSessionControl event handlers declared above)
+ void i_onMousePointerShapeChange(bool fVisible, bool fAlpha,
+ uint32_t xHot, uint32_t yHot,
+ uint32_t width, uint32_t height,
+ const uint8_t *pu8Shape,
+ uint32_t cbShape);
+ void i_onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative,
+ BOOL supportsTouchScreen, BOOL supportsTouchPad,
+ BOOL needsHostCursor);
+ void i_onStateChange(MachineState_T aMachineState);
+ void i_onAdditionsStateChange();
+ void i_onAdditionsOutdated();
+ void i_onKeyboardLedsChange(bool fNumLock, bool fCapsLock, bool fScrollLock);
+ void i_onUSBDeviceStateChange(IUSBDevice *aDevice, bool aAttached,
+ IVirtualBoxErrorInfo *aError);
+ void i_onRuntimeError(BOOL aFatal, IN_BSTR aErrorID, IN_BSTR aMessage);
+ HRESULT i_onShowWindow(BOOL aCheck, BOOL *aCanShow, LONG64 *aWinId);
+ void i_onVRDEServerInfoChange();
+ HRESULT i_sendACPIMonitorHotPlugEvent();
+
+ static const PDMDRVREG DrvStatusReg;
+
+ static HRESULT i_setErrorStatic(HRESULT aResultCode, const char *pcsz, ...);
+ static HRESULT i_setErrorStaticBoth(HRESULT aResultCode, int vrc, const char *pcsz, ...);
+ HRESULT i_setInvalidMachineStateError();
+
+ static const char *i_storageControllerTypeToStr(StorageControllerType_T enmCtrlType);
+ static HRESULT i_storageBusPortDeviceToLun(StorageBus_T enmBus, LONG port, LONG device, unsigned &uLun);
+ // Called from event listener
+ HRESULT i_onNATRedirectRuleChanged(ULONG ulInstance, BOOL aNatRuleRemove,
+ NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort);
+ HRESULT i_onNATDnsChanged();
+
+ // Mouse interface
+ VMMDevMouseInterface *i_getVMMDevMouseInterface();
+ DisplayMouseInterface *i_getDisplayMouseInterface();
+
+ EmulatedUSB *i_getEmulatedUSB(void) { return mEmulatedUSB; }
+
+ /**
+ * Sets the disk encryption keys.
+ *
+ * @returns COM status code.
+ * @param strCfg The config for the disks.
+ *
+ * @note One line in the config string contains all required data for one disk.
+ * The format for one disk is some sort of comma separated value using
+ * key=value pairs.
+ * There are two keys defined at the moment:
+ * - uuid: The uuid of the base image the key is for (with or without)
+ * the curly braces.
+ * - dek: The data encryption key in base64 encoding
+ */
+ HRESULT i_setDiskEncryptionKeys(const Utf8Str &strCfg);
+
+ int i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf);
+ int i_releaseCryptoIf(PCVBOXCRYPTOIF pCryptoIf);
+ HRESULT i_unloadCryptoIfModule(void);
+
+#ifdef VBOX_WITH_GUEST_PROPS
+ // VMMDev needs:
+ HRESULT i_pullGuestProperties(ComSafeArrayOut(BSTR, names), ComSafeArrayOut(BSTR, values),
+ ComSafeArrayOut(LONG64, timestamps), ComSafeArrayOut(BSTR, flags));
+ static DECLCALLBACK(int) i_doGuestPropNotification(void *pvExtension, uint32_t, void *pvParms, uint32_t cbParms);
+#endif
+
+private:
+
+ // wrapped IConsole properties
+ HRESULT getMachine(ComPtr<IMachine> &aMachine);
+ HRESULT getState(MachineState_T *aState);
+ HRESULT getGuest(ComPtr<IGuest> &aGuest);
+ HRESULT getKeyboard(ComPtr<IKeyboard> &aKeyboard);
+ HRESULT getMouse(ComPtr<IMouse> &aMouse);
+ HRESULT getDisplay(ComPtr<IDisplay> &aDisplay);
+ HRESULT getDebugger(ComPtr<IMachineDebugger> &aDebugger);
+ HRESULT getUSBDevices(std::vector<ComPtr<IUSBDevice> > &aUSBDevices);
+ HRESULT getRemoteUSBDevices(std::vector<ComPtr<IHostUSBDevice> > &aRemoteUSBDevices);
+ HRESULT getSharedFolders(std::vector<ComPtr<ISharedFolder> > &aSharedFolders);
+ HRESULT getVRDEServerInfo(ComPtr<IVRDEServerInfo> &aVRDEServerInfo);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getAttachedPCIDevices(std::vector<ComPtr<IPCIDeviceAttachment> > &aAttachedPCIDevices);
+ HRESULT getUseHostClipboard(BOOL *aUseHostClipboard);
+ HRESULT setUseHostClipboard(BOOL aUseHostClipboard);
+ HRESULT getEmulatedUSB(ComPtr<IEmulatedUSB> &aEmulatedUSB);
+
+ // wrapped IConsole methods
+ HRESULT powerUp(ComPtr<IProgress> &aProgress);
+ HRESULT powerUpPaused(ComPtr<IProgress> &aProgress);
+ HRESULT powerDown(ComPtr<IProgress> &aProgress);
+ HRESULT reset();
+ HRESULT pause();
+ HRESULT resume();
+ HRESULT powerButton();
+ HRESULT sleepButton();
+ HRESULT getPowerButtonHandled(BOOL *aHandled);
+ HRESULT getGuestEnteredACPIMode(BOOL *aEntered);
+ HRESULT getDeviceActivity(const std::vector<DeviceType_T> &aType,
+ std::vector<DeviceActivity_T> &aActivity);
+ HRESULT attachUSBDevice(const com::Guid &aId, const com::Utf8Str &aCaptureFilename);
+ HRESULT detachUSBDevice(const com::Guid &aId,
+ ComPtr<IUSBDevice> &aDevice);
+ HRESULT findUSBDeviceByAddress(const com::Utf8Str &aName,
+ ComPtr<IUSBDevice> &aDevice);
+ HRESULT findUSBDeviceById(const com::Guid &aId,
+ ComPtr<IUSBDevice> &aDevice);
+ HRESULT createSharedFolder(const com::Utf8Str &aName,
+ const com::Utf8Str &aHostPath,
+ BOOL aWritable,
+ BOOL aAutomount,
+ const com::Utf8Str &aAutoMountPoint);
+ HRESULT removeSharedFolder(const com::Utf8Str &aName);
+ HRESULT teleport(const com::Utf8Str &aHostname,
+ ULONG aTcpport,
+ const com::Utf8Str &aPassword,
+ ULONG aMaxDowntime,
+ ComPtr<IProgress> &aProgress);
+ HRESULT addEncryptionPassword(const com::Utf8Str &aId, const com::Utf8Str &aPassword,
+ BOOL aClearOnSuspend);
+ HRESULT addEncryptionPasswords(const std::vector<com::Utf8Str> &aIds, const std::vector<com::Utf8Str> &aPasswords,
+ BOOL aClearOnSuspend);
+ HRESULT removeEncryptionPassword(const com::Utf8Str &aId);
+ HRESULT clearAllEncryptionPasswords();
+
+ void notifyNatDnsChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, ULONG ulInstanceMax);
+ Utf8Str VRDPServerErrorToMsg(int vrc);
+
+ /**
+ * Base template for AutoVMCaller and SafeVMPtr. Template arguments
+ * have the same meaning as arguments of Console::addVMCaller().
+ */
+ template <bool taQuiet = false, bool taAllowNullVM = false>
+ class AutoVMCallerBase
+ {
+ public:
+ AutoVMCallerBase(Console *aThat) : mThat(aThat), mRC(E_FAIL)
+ {
+ Assert(aThat);
+ mRC = aThat->i_addVMCaller(taQuiet, taAllowNullVM);
+ }
+ ~AutoVMCallerBase()
+ {
+ doRelease();
+ }
+ /** Decreases the number of callers before the instance is destroyed. */
+ void releaseCaller()
+ {
+ Assert(SUCCEEDED(mRC));
+ doRelease();
+ }
+ /** Restores the number of callers after by #release(). #hrc() must be
+ * rechecked to ensure the operation succeeded. */
+ void addYY()
+ {
+ AssertReturnVoid(!SUCCEEDED(mRC));
+ mRC = mThat->i_addVMCaller(taQuiet, taAllowNullVM);
+ }
+ /** Returns the result of Console::addVMCaller() */
+ HRESULT hrc() const { return mRC; }
+ /** Shortcut to SUCCEEDED(hrc()) */
+ bool isOk() const { return SUCCEEDED(mRC); }
+ protected:
+ Console *mThat;
+ void doRelease()
+ {
+ if (SUCCEEDED(mRC))
+ {
+ mThat->i_releaseVMCaller();
+ mRC = E_FAIL;
+ }
+ }
+ private:
+ HRESULT mRC; /* Whether the caller was added. */
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(AutoVMCallerBase);
+ };
+
+#if 0
+ /**
+ * Helper class that protects sections of code using the mpUVM pointer by
+ * automatically calling addVMCaller() on construction and
+ * releaseVMCaller() on destruction. Intended for Console methods dealing
+ * with mpUVM. The usage pattern is:
+ * <code>
+ * AutoVMCaller autoVMCaller(this);
+ * if (FAILED(autoVMCaller.hrc())) return autoVMCaller.hrc();
+ * ...
+ * VMR3ReqCall (mpUVM, ...
+ * </code>
+ *
+ * @note Temporarily locks the argument for writing.
+ *
+ * @sa SafeVMPtr, SafeVMPtrQuiet
+ * @note Obsolete, use SafeVMPtr
+ */
+ typedef AutoVMCallerBase<false, false> AutoVMCaller;
+#endif
+
+ /**
+ * Same as AutoVMCaller but doesn't set extended error info on failure.
+ *
+ * @note Temporarily locks the argument for writing.
+ * @note Obsolete, use SafeVMPtrQuiet
+ */
+ typedef AutoVMCallerBase<true, false> AutoVMCallerQuiet;
+
+ /**
+ * Same as AutoVMCaller but allows a null VM pointer (to trigger an error
+ * instead of assertion).
+ *
+ * @note Temporarily locks the argument for writing.
+ * @note Obsolete, use SafeVMPtr
+ */
+ typedef AutoVMCallerBase<false, true> AutoVMCallerWeak;
+
+ /**
+ * Same as AutoVMCaller but doesn't set extended error info on failure
+ * and allows a null VM pointer (to trigger an error instead of
+ * assertion).
+ *
+ * @note Temporarily locks the argument for writing.
+ * @note Obsolete, use SafeVMPtrQuiet
+ */
+ typedef AutoVMCallerBase<true, true> AutoVMCallerQuietWeak;
+
+ /**
+ * Base template for SafeVMPtr and SafeVMPtrQuiet.
+ */
+ template<bool taQuiet = false>
+ class SafeVMPtrBase : public AutoVMCallerBase<taQuiet, true>
+ {
+ typedef AutoVMCallerBase<taQuiet, true> Base;
+ public:
+ SafeVMPtrBase(Console *aThat) : Base(aThat), mRC(E_FAIL), mpUVM(NULL), mpVMM(NULL)
+ {
+ if (Base::isOk())
+ mRC = aThat->i_safeVMPtrRetainer(&mpUVM, &mpVMM, taQuiet);
+ }
+ ~SafeVMPtrBase()
+ {
+ doRelease();
+ }
+ /** Direct PUVM access. */
+ PUVM rawUVM() const { return mpUVM; }
+ /** Direct PCVMMR3VTABLE access. */
+ PCVMMR3VTABLE vtable() const { return mpVMM; }
+ /** Release the handles. */
+ void release()
+ {
+ Assert(SUCCEEDED(mRC));
+ doRelease();
+ }
+
+ /** The combined result of Console::addVMCaller() and Console::safeVMPtrRetainer */
+ HRESULT hrc() const { return Base::isOk() ? mRC : Base::hrc(); }
+ /** Shortcut to SUCCEEDED(hrc()) */
+ bool isOk() const { return SUCCEEDED(mRC) && Base::isOk(); }
+
+ private:
+ void doRelease()
+ {
+ if (SUCCEEDED(mRC))
+ {
+ Base::mThat->i_safeVMPtrReleaser(&mpUVM);
+ mRC = E_FAIL;
+ }
+ Base::doRelease();
+ }
+ HRESULT mRC; /* Whether the VM ptr was retained. */
+ PUVM mpUVM;
+ PCVMMR3VTABLE mpVMM;
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeVMPtrBase);
+ };
+
+public:
+
+ /*
+ * Helper class that safely manages the Console::mpUVM pointer
+ * by calling addVMCaller() on construction and releaseVMCaller() on
+ * destruction. Intended for Console children. The usage pattern is:
+ * <code>
+ * Console::SafeVMPtr ptrVM(mParent);
+ * if (!ptrVM.isOk())
+ * return ptrVM.hrc();
+ * ...
+ * VMR3ReqCall(ptrVM.rawUVM(), ...
+ * ...
+ * printf("%p\n", ptrVM.rawUVM());
+ * </code>
+ *
+ * @note Temporarily locks the argument for writing.
+ *
+ * @sa SafeVMPtrQuiet, AutoVMCaller
+ */
+ typedef SafeVMPtrBase<false> SafeVMPtr;
+
+ /**
+ * A deviation of SafeVMPtr that doesn't set the error info on failure.
+ * Intended for pieces of code that don't need to return the VM access
+ * failure to the caller. The usage pattern is:
+ * <code>
+ * Console::SafeVMPtrQuiet pVM(mParent);
+ * if (pVM.hrc())
+ * VMR3ReqCall(pVM, ...
+ * return S_OK;
+ * </code>
+ *
+ * @note Temporarily locks the argument for writing.
+ *
+ * @sa SafeVMPtr, AutoVMCaller
+ */
+ typedef SafeVMPtrBase<true> SafeVMPtrQuiet;
+
+ class SharedFolderData
+ {
+ public:
+ SharedFolderData()
+ { }
+
+ SharedFolderData(const Utf8Str &aHostPath,
+ bool aWritable,
+ bool aAutoMount,
+ const Utf8Str &aAutoMountPoint)
+ : m_strHostPath(aHostPath)
+ , m_fWritable(aWritable)
+ , m_fAutoMount(aAutoMount)
+ , m_strAutoMountPoint(aAutoMountPoint)
+ { }
+
+ /** Copy constructor. */
+ SharedFolderData(const SharedFolderData& aThat)
+ : m_strHostPath(aThat.m_strHostPath)
+ , m_fWritable(aThat.m_fWritable)
+ , m_fAutoMount(aThat.m_fAutoMount)
+ , m_strAutoMountPoint(aThat.m_strAutoMountPoint)
+ { }
+
+ /** Copy assignment operator. */
+ SharedFolderData &operator=(SharedFolderData const &a_rThat) RT_NOEXCEPT
+ {
+ m_strHostPath = a_rThat.m_strHostPath;
+ m_fWritable = a_rThat.m_fWritable;
+ m_fAutoMount = a_rThat.m_fAutoMount;
+ m_strAutoMountPoint = a_rThat.m_strAutoMountPoint;
+
+ return *this;
+ }
+
+ Utf8Str m_strHostPath;
+ bool m_fWritable;
+ bool m_fAutoMount;
+ Utf8Str m_strAutoMountPoint;
+ };
+
+ /**
+ * Class for managing emulated USB MSDs.
+ */
+ class USBStorageDevice
+ {
+ public:
+ USBStorageDevice()
+ { }
+ /** The UUID associated with the USB device. */
+ RTUUID mUuid;
+ /** Port of the storage device. */
+ LONG iPort;
+ };
+
+ typedef std::map<Utf8Str, ComObjPtr<ConsoleSharedFolder> > SharedFolderMap;
+ typedef std::map<Utf8Str, SharedFolderData> SharedFolderDataMap;
+ typedef std::map<Utf8Str, ComPtr<IMediumAttachment> > MediumAttachmentMap;
+ typedef std::list<USBStorageDevice> USBStorageDeviceList;
+
+ static void i_powerUpThreadTask(VMPowerUpTask *pTask);
+ static void i_powerDownThreadTask(VMPowerDownTask *pTask);
+
+private:
+
+ typedef std::list <ComObjPtr<OUSBDevice> > USBDeviceList;
+ typedef std::list <ComObjPtr<RemoteUSBDevice> > RemoteUSBDeviceList;
+
+ HRESULT i_loadVMM(void) RT_NOEXCEPT;
+ HRESULT i_addVMCaller(bool aQuiet = false, bool aAllowNullVM = false);
+ void i_releaseVMCaller();
+ HRESULT i_safeVMPtrRetainer(PUVM *a_ppUVM, PCVMMR3VTABLE *a_ppVMM, bool aQuiet) RT_NOEXCEPT;
+ void i_safeVMPtrReleaser(PUVM *a_ppUVM);
+
+ HRESULT i_consoleInitReleaseLog(const ComPtr<IMachine> aMachine);
+
+ HRESULT i_powerUp(IProgress **aProgress, bool aPaused);
+ HRESULT i_powerDown(IProgress *aProgress = NULL);
+
+/* Note: FreeBSD needs this whether netflt is used or not. */
+#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
+ HRESULT i_attachToTapInterface(INetworkAdapter *networkAdapter);
+ HRESULT i_detachFromTapInterface(INetworkAdapter *networkAdapter);
+#endif
+ HRESULT i_powerDownHostInterfaces();
+
+ HRESULT i_setMachineState(MachineState_T aMachineState, bool aUpdateServer = true);
+ HRESULT i_setMachineStateLocally(MachineState_T aMachineState)
+ {
+ return i_setMachineState(aMachineState, false /* aUpdateServer */);
+ }
+
+ HRESULT i_findSharedFolder(const Utf8Str &strName,
+ ComObjPtr<ConsoleSharedFolder> &aSharedFolder,
+ bool aSetError = false);
+
+ HRESULT i_fetchSharedFolders(BOOL aGlobal);
+ bool i_findOtherSharedFolder(const Utf8Str &straName,
+ SharedFolderDataMap::const_iterator &aIt);
+
+ HRESULT i_createSharedFolder(const Utf8Str &strName, const SharedFolderData &aData);
+ HRESULT i_removeSharedFolder(const Utf8Str &strName);
+
+ HRESULT i_suspendBeforeConfigChange(PUVM pUVM, PCVMMR3VTABLE pVMM, AutoWriteLock *pAlock, bool *pfResume);
+ void i_resumeAfterConfigChange(PUVM pUVM, PCVMMR3VTABLE pVMM);
+
+ static DECLCALLBACK(int) i_configConstructor(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, void *pvConsole);
+ void InsertConfigString(PCFGMNODE pNode, const char *pcszName, const char *pcszValue);
+ void InsertConfigString(PCFGMNODE pNode, const char *pcszName, const Utf8Str &rStrValue);
+ void InsertConfigString(PCFGMNODE pNode, const char *pcszName, const Bstr &rBstrValue);
+ void InsertConfigStringF(PCFGMNODE pNode, const char *pcszName, const char *pszFormat, ...);
+ void InsertConfigPassword(PCFGMNODE pNode, const char *pcszName, const Utf8Str &rStrValue);
+ void InsertConfigBytes(PCFGMNODE pNode, const char *pcszName, const void *pvBytes, size_t cbBytes);
+ void InsertConfigInteger(PCFGMNODE pNode, const char *pcszName, uint64_t u64Integer);
+ void InsertConfigNode(PCFGMNODE pNode, const char *pcszName, PCFGMNODE *ppChild);
+ void InsertConfigNodeF(PCFGMNODE pNode, PCFGMNODE *ppChild, const char *pszNameFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+ void RemoveConfigValue(PCFGMNODE pNode, const char *pcszName);
+ int SetBiosDiskInfo(ComPtr<IMachine> pMachine, PCFGMNODE pCfg, PCFGMNODE pBiosCfg,
+ Bstr controllerName, const char * const s_apszBiosConfig[4]);
+ void i_configAudioDriver(IVirtualBox *pVirtualBox, IMachine *pMachine, PCFGMNODE pLUN, const char *pszDriverName,
+ bool fAudioEnabledIn, bool fAudioEnabledOut);
+ int i_configConstructorInner(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, AutoWriteLock *pAlock);
+ int i_configCfgmOverlay(PCFGMNODE pRoot, IVirtualBox *pVirtualBox, IMachine *pMachine);
+ int i_configDumpAPISettingsTweaks(IVirtualBox *pVirtualBox, IMachine *pMachine);
+
+ int i_configGraphicsController(PCFGMNODE pDevices,
+ const GraphicsControllerType_T graphicsController,
+ BusAssignmentManager *pBusMgr,
+ const ComPtr<IMachine> &ptrMachine,
+ const ComPtr<IGraphicsAdapter> &ptrGraphicsAdapter,
+ const ComPtr<IBIOSSettings> &ptrBiosSettings,
+ bool fHMEnabled);
+ int i_checkMediumLocation(IMedium *pMedium, bool *pfUseHostIOCache);
+ int i_unmountMediumFromGuest(PUVM pUVM, PCVMMR3VTABLE pVMM, StorageBus_T enmBus, DeviceType_T enmDevType,
+ const char *pcszDevice, unsigned uInstance, unsigned uLUN,
+ bool fForceUnmount) RT_NOEXCEPT;
+ int i_removeMediumDriverFromVm(PCFGMNODE pCtlInst,
+ const char *pcszDevice,
+ unsigned uInstance,
+ unsigned uLUN,
+ StorageBus_T enmBus,
+ bool fAttachDetach,
+ bool fHotplug,
+ bool fForceUnmount,
+ PUVM pUVM,
+ PCVMMR3VTABLE pVMM,
+ DeviceType_T enmDevType,
+ PCFGMNODE *ppLunL0);
+ int i_configMediumAttachment(const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ bool fUseHostIOCache,
+ bool fBuiltinIoCache,
+ bool fInsertDiskIntegrityDrv,
+ bool fSetupMerge,
+ unsigned uMergeSource,
+ unsigned uMergeTarget,
+ IMediumAttachment *pMediumAtt,
+ MachineState_T aMachineState,
+ HRESULT *phrc,
+ bool fAttachDetach,
+ bool fForceUnmount,
+ bool fHotplug,
+ PUVM pUVM,
+ PCVMMR3VTABLE pVMM,
+ DeviceType_T *paLedDevType,
+ PCFGMNODE *ppLunL0);
+ int i_configMedium(PCFGMNODE pLunL0,
+ bool fPassthrough,
+ DeviceType_T enmType,
+ bool fUseHostIOCache,
+ bool fBuiltinIoCache,
+ bool fInsertDiskIntegrityDrv,
+ bool fSetupMerge,
+ unsigned uMergeSource,
+ unsigned uMergeTarget,
+ const char *pcszBwGroup,
+ bool fDiscard,
+ bool fNonRotational,
+ ComPtr<IMedium> ptrMedium,
+ MachineState_T aMachineState,
+ HRESULT *phrc);
+ int i_configMediumProperties(PCFGMNODE pCur, IMedium *pMedium, bool *pfHostIP, bool *pfEncrypted);
+ static DECLCALLBACK(int) i_reconfigureMediumAttachment(Console *pThis,
+ PUVM pUVM,
+ PCVMMR3VTABLE pVMM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ bool fUseHostIOCache,
+ bool fBuiltinIoCache,
+ bool fInsertDiskIntegrityDrv,
+ bool fSetupMerge,
+ unsigned uMergeSource,
+ unsigned uMergeTarget,
+ IMediumAttachment *aMediumAtt,
+ MachineState_T aMachineState,
+ HRESULT *phrc);
+ static DECLCALLBACK(int) i_changeRemovableMedium(Console *pThis,
+ PUVM pUVM,
+ PCVMMR3VTABLE pVMM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ bool fUseHostIOCache,
+ IMediumAttachment *aMediumAtt,
+ bool fForce);
+
+ HRESULT i_attachRawPCIDevices(PUVM pUVM, BusAssignmentManager *BusMgr, PCFGMNODE pDevices);
+ struct LEDSET;
+ typedef struct LEDSET *PLEDSET;
+ PPDMLED volatile *i_getLedSet(uint32_t iLedSet);
+ void i_setLedType(DeviceType_T *penmSubTypeEntry, DeviceType_T enmNewType);
+ HRESULT i_refreshLedTypeArrays(AutoReadLock *pReadLock);
+ uint32_t i_allocateDriverLeds(uint32_t cLeds, uint32_t fTypes, DeviceType_T **ppSubTypes);
+ void i_attachStatusDriver(PCFGMNODE pCtlInst, DeviceType_T enmType, uint32_t cLeds = 1);
+ void i_attachStatusDriver(PCFGMNODE pCtlInst, uint32_t fTypes, uint32_t cLeds, DeviceType_T **ppaSubTypes,
+ Console::MediumAttachmentMap *pmapMediumAttachments,
+ const char *pcszDevice, unsigned uInstance);
+
+ int i_configNetwork(const char *pszDevice, unsigned uInstance, unsigned uLun, INetworkAdapter *aNetworkAdapter,
+ PCFGMNODE pCfg, PCFGMNODE pLunL0, PCFGMNODE pInst, bool fAttachDetach, bool fIgnoreConnectFailure,
+ PUVM pUVM, PCVMMR3VTABLE pVMM);
+ int i_configProxy(ComPtr<IVirtualBox> virtualBox, PCFGMNODE pCfg, const char *pcszPrefix, const com::Utf8Str &strIpAddr);
+
+ int i_configSerialPort(PCFGMNODE pInst, PortMode_T ePortMode, const char *pszPath, bool fServer);
+ static DECLCALLBACK(void) i_vmstateChangeCallback(PUVM pUVM, PCVMMR3VTABLE pVMM, VMSTATE enmState,
+ VMSTATE enmOldState, void *pvUser);
+ static DECLCALLBACK(int) i_unplugCpu(Console *pThis, PUVM pUVM, PCVMMR3VTABLE pVMM, VMCPUID idCpu);
+ static DECLCALLBACK(int) i_plugCpu(Console *pThis, PUVM pUVM, PCVMMR3VTABLE pVMM, VMCPUID idCpu);
+ HRESULT i_doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PUVM pUVM, PCVMMR3VTABLE pVMM);
+ HRESULT i_doCPURemove(ULONG aCpu, PUVM pUVM, PCVMMR3VTABLE pVMM);
+ HRESULT i_doCPUAdd(ULONG aCpu, PUVM pUVM, PCVMMR3VTABLE pVMM);
+
+ HRESULT i_doNetworkAdapterChange(PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice, unsigned uInstance,
+ unsigned uLun, INetworkAdapter *aNetworkAdapter);
+ static DECLCALLBACK(int) i_changeNetworkAttachment(Console *pThis, PUVM pUVM, PCVMMR3VTABLE pVMM, const char *pszDevice,
+ unsigned uInstance, unsigned uLun, INetworkAdapter *aNetworkAdapter);
+ static DECLCALLBACK(int) i_changeSerialPortAttachment(Console *pThis, PUVM pUVM, PCVMMR3VTABLE pVMM, ISerialPort *pSerialPort);
+
+ int i_changeClipboardMode(ClipboardMode_T aClipboardMode);
+ int i_changeClipboardFileTransferMode(bool aEnabled);
+ int i_changeDnDMode(DnDMode_T aDnDMode);
+
+#ifdef VBOX_WITH_USB
+ HRESULT i_attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs, const Utf8Str &aCaptureFilename);
+ HRESULT i_detachUSBDevice(const ComObjPtr<OUSBDevice> &aHostDevice);
+
+ static DECLCALLBACK(int) i_usbAttachCallback(Console *that, PUVM pUVM, PCVMMR3VTABLE pVMM, IUSBDevice *aHostDevice,
+ PCRTUUID aUuid, const char *aBackend, const char *aAddress,
+ PCFGMNODE pRemoteCfg, USBConnectionSpeed_T enmSpeed, ULONG aMaskedIfs,
+ const char *pszCaptureFilename);
+ static DECLCALLBACK(int) i_usbDetachCallback(Console *that, PUVM pUVM, PCVMMR3VTABLE pVMM, PCRTUUID aUuid);
+ static DECLCALLBACK(PREMOTEUSBCALLBACK) i_usbQueryRemoteUsbBackend(void *pvUser, PCRTUUID pUuid, uint32_t idClient);
+
+ /** Interface for the VRDP USB proxy backend to query for a device remote callback table. */
+ REMOTEUSBIF mRemoteUsbIf;
+#endif
+
+ static DECLCALLBACK(int) i_attachStorageDevice(Console *pThis,
+ PUVM pUVM,
+ PCVMMR3VTABLE pVMM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ bool fUseHostIOCache,
+ IMediumAttachment *aMediumAtt,
+ bool fSilent);
+ static DECLCALLBACK(int) i_detachStorageDevice(Console *pThis,
+ PUVM pUVM,
+ PCVMMR3VTABLE pVMM,
+ const char *pcszDevice,
+ unsigned uInstance,
+ StorageBus_T enmBus,
+ IMediumAttachment *aMediumAtt,
+ bool fSilent);
+ HRESULT i_doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUVM pUVM, PCVMMR3VTABLE pVMM, bool fSilent);
+ HRESULT i_doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUVM pUVM, PCVMMR3VTABLE pVMM, bool fSilent);
+
+ static DECLCALLBACK(int) i_stateProgressCallback(PUVM pUVM, unsigned uPercent, void *pvUser);
+
+ static DECLCALLBACK(void) i_genericVMSetErrorCallback(PUVM pUVM, void *pvUser, int vrc, RT_SRC_POS_DECL,
+ const char *pszErrorFmt, va_list va);
+
+ void i_atVMRuntimeErrorCallbackF(uint32_t fFatal, const char *pszErrorId, const char *pszFormat, ...);
+ static DECLCALLBACK(void) i_atVMRuntimeErrorCallback(PUVM pUVM, void *pvUser, uint32_t fFatal,
+ const char *pszErrorId, const char *pszFormat, va_list va);
+
+ HRESULT i_captureUSBDevices(PUVM pUVM);
+ void i_detachAllUSBDevices(bool aDone);
+
+
+ static DECLCALLBACK(int) i_vmm2User_SaveState(PCVMM2USERMETHODS pThis, PUVM pUVM);
+ static DECLCALLBACK(void) i_vmm2User_NotifyEmtInit(PCVMM2USERMETHODS pThis, PUVM pUVM, PUVMCPU pUVCpu);
+ static DECLCALLBACK(void) i_vmm2User_NotifyEmtTerm(PCVMM2USERMETHODS pThis, PUVM pUVM, PUVMCPU pUVCpu);
+ static DECLCALLBACK(void) i_vmm2User_NotifyPdmtInit(PCVMM2USERMETHODS pThis, PUVM pUVM);
+ static DECLCALLBACK(void) i_vmm2User_NotifyPdmtTerm(PCVMM2USERMETHODS pThis, PUVM pUVM);
+ static DECLCALLBACK(void) i_vmm2User_NotifyResetTurnedIntoPowerOff(PCVMM2USERMETHODS pThis, PUVM pUVM);
+ static DECLCALLBACK(void *) i_vmm2User_QueryGenericObject(PCVMM2USERMETHODS pThis, PUVM pUVM, PCRTUUID pUuid);
+
+ static DECLCALLBACK(void *) i_drvStatus_QueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(void) i_drvStatus_UnitChanged(PPDMILEDCONNECTORS pInterface, unsigned iLUN);
+ static DECLCALLBACK(int) i_drvStatus_MediumEjected(PPDMIMEDIANOTIFY pInterface, unsigned iLUN);
+ static DECLCALLBACK(void) i_drvStatus_Destruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(int) i_drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+
+ static DECLCALLBACK(int) i_pdmIfSecKey_KeyRetain(PPDMISECKEY pInterface, const char *pszId, const uint8_t **ppbKey,
+ size_t *pcbKey);
+ static DECLCALLBACK(int) i_pdmIfSecKey_KeyRelease(PPDMISECKEY pInterface, const char *pszId);
+ static DECLCALLBACK(int) i_pdmIfSecKey_PasswordRetain(PPDMISECKEY pInterface, const char *pszId, const char **ppszPassword);
+ static DECLCALLBACK(int) i_pdmIfSecKey_PasswordRelease(PPDMISECKEY pInterface, const char *pszId);
+
+ static DECLCALLBACK(int) i_pdmIfSecKeyHlp_KeyMissingNotify(PPDMISECKEYHLP pInterface);
+
+ int mcAudioRefs;
+ volatile uint32_t mcVRDPClients;
+ uint32_t mu32SingleRDPClientId; /* The id of a connected client in the single connection mode. */
+ volatile bool mcGuestCredentialsProvided;
+
+ static const char *sSSMConsoleUnit;
+
+ HRESULT i_loadDataFromSavedState();
+ int i_loadStateFileExecInternal(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, uint32_t u32Version);
+
+ static DECLCALLBACK(int) i_saveStateFileExec(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, void *pvUser);
+ static DECLCALLBACK(int) i_loadStateFileExec(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, void *pvUser,
+ uint32_t uVersion, uint32_t uPass);
+
+#ifdef VBOX_WITH_GUEST_PROPS
+ HRESULT i_doEnumerateGuestProperties(const Utf8Str &aPatterns,
+ std::vector<Utf8Str> &aNames,
+ std::vector<Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<Utf8Str> &aFlags);
+
+ void i_guestPropertiesHandleVMReset(void);
+ bool i_guestPropertiesVRDPEnabled(void);
+ void i_guestPropertiesVRDPUpdateLogon(uint32_t u32ClientId, const char *pszUser, const char *pszDomain);
+ void i_guestPropertiesVRDPUpdateActiveClient(uint32_t u32ClientId);
+ void i_guestPropertiesVRDPUpdateClientAttach(uint32_t u32ClientId, bool fAttached);
+ void i_guestPropertiesVRDPUpdateNameChange(uint32_t u32ClientId, const char *pszName);
+ void i_guestPropertiesVRDPUpdateIPAddrChange(uint32_t u32ClientId, const char *pszIPAddr);
+ void i_guestPropertiesVRDPUpdateLocationChange(uint32_t u32ClientId, const char *pszLocation);
+ void i_guestPropertiesVRDPUpdateOtherInfoChange(uint32_t u32ClientId, const char *pszOtherInfo);
+ void i_guestPropertiesVRDPUpdateDisconnect(uint32_t u32ClientId);
+#endif
+
+ /** @name Disk encryption support
+ * @{ */
+ HRESULT i_consoleParseDiskEncryption(const char *psz, const char **ppszEnd);
+ HRESULT i_configureEncryptionForDisk(const Utf8Str &strId, unsigned *pcDisksConfigured);
+ HRESULT i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(const Utf8Str &strId);
+ HRESULT i_initSecretKeyIfOnAllAttachments(void);
+ int i_consoleParseKeyValue(const char *psz, const char **ppszEnd,
+ char **ppszKey, char **ppszVal);
+ void i_removeSecretKeysOnSuspend();
+ /** @} */
+
+ /** @name Teleporter support
+ * @{ */
+ static DECLCALLBACK(int) i_teleporterSrcThreadWrapper(RTTHREAD hThreadSelf, void *pvUser);
+ HRESULT i_teleporterSrc(TeleporterStateSrc *pState);
+ HRESULT i_teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL);
+ HRESULT i_teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck = true);
+ HRESULT i_teleporterTrg(PUVM pUVM, PCVMMR3VTABLE pVMM, IMachine *pMachine, Utf8Str *pErrorMsg,
+ bool fStartPaused, Progress *pProgress, bool *pfPowerOffOnFailure);
+ static DECLCALLBACK(int) i_teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser);
+ /** @} */
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ /** @name Encrypted log interface
+ * @{ */
+ static DECLCALLBACK(int) i_logEncryptedOpen(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename, uint32_t fFlags);
+ static DECLCALLBACK(int) i_logEncryptedClose(PCRTLOGOUTPUTIF pIf, void *pvUser);
+ static DECLCALLBACK(int) i_logEncryptedDelete(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilename);
+ static DECLCALLBACK(int) i_logEncryptedRename(PCRTLOGOUTPUTIF pIf, void *pvUser, const char *pszFilenameOld,
+ const char *pszFilenameNew, uint32_t fFlags);
+ static DECLCALLBACK(int) i_logEncryptedQuerySize(PCRTLOGOUTPUTIF pIf, void *pvUser, uint64_t *pcbSize);
+ static DECLCALLBACK(int) i_logEncryptedWrite(PCRTLOGOUTPUTIF pIf, void *pvUser, const void *pvBuf,
+ size_t cbWrite, size_t *pcbWritten);
+ static DECLCALLBACK(int) i_logEncryptedFlush(PCRTLOGOUTPUTIF pIf, void *pvUser);
+ /** @} */
+#endif
+
+ bool mSavedStateDataLoaded : 1;
+
+ const ComPtr<IMachine> mMachine;
+ const ComPtr<IInternalMachineControl> mControl;
+
+ const ComPtr<IVRDEServer> mVRDEServer;
+
+ ConsoleVRDPServer * const mConsoleVRDPServer;
+ bool mfVRDEChangeInProcess;
+ bool mfVRDEChangePending;
+ const ComObjPtr<Guest> mGuest;
+ const ComObjPtr<Keyboard> mKeyboard;
+ const ComObjPtr<Mouse> mMouse;
+ const ComObjPtr<Display> mDisplay;
+ const ComObjPtr<MachineDebugger> mDebugger;
+ const ComObjPtr<VRDEServerInfo> mVRDEServerInfo;
+ /** This can safely be used without holding any locks.
+ * An AutoCaller suffices to prevent it being destroy while in use and
+ * internally there is a lock providing the necessary serialization. */
+ const ComObjPtr<EventSource> mEventSource;
+#ifdef VBOX_WITH_EXTPACK
+ const ComObjPtr<ExtPackManager> mptrExtPackManager;
+#endif
+ const ComObjPtr<EmulatedUSB> mEmulatedUSB;
+ const ComObjPtr<NvramStore> mptrNvramStore;
+
+ USBDeviceList mUSBDevices;
+ RemoteUSBDeviceList mRemoteUSBDevices;
+
+ SharedFolderDataMap m_mapGlobalSharedFolders;
+ SharedFolderDataMap m_mapMachineSharedFolders;
+ SharedFolderMap m_mapSharedFolders; // the console instances
+
+ /** VMM loader handle. */
+ RTLDRMOD mhModVMM;
+ /** The VMM vtable. */
+ PCVMMR3VTABLE mpVMM;
+ /** The user mode VM handle. */
+ PUVM mpUVM;
+ /** Holds the number of "readonly" mpUVM callers (users). */
+ uint32_t mVMCallers;
+ /** Semaphore posted when the number of mpUVM callers drops to zero. */
+ RTSEMEVENT mVMZeroCallersSem;
+ /** true when Console has entered the mpUVM destruction phase. */
+ bool mVMDestroying : 1;
+ /** true when power down is initiated by vmstateChangeCallback (EMT). */
+ bool mVMPoweredOff : 1;
+ /** true when vmstateChangeCallback shouldn't initiate a power down. */
+ bool mVMIsAlreadyPoweringOff : 1;
+ /** true if we already showed the snapshot folder size warning. */
+ bool mfSnapshotFolderSizeWarningShown : 1;
+ /** true if we already showed the snapshot folder ext4/xfs bug warning. */
+ bool mfSnapshotFolderExt4WarningShown : 1;
+ /** true if we already listed the disk type of the snapshot folder. */
+ bool mfSnapshotFolderDiskTypeShown : 1;
+ /** true if a USB controller is available (i.e. USB devices can be attached). */
+ bool mfVMHasUsbController : 1;
+ /** Shadow of the VBoxInternal2/TurnResetIntoPowerOff extra data setting.
+ * This is initialized by Console::i_configConstructorInner(). */
+ bool mfTurnResetIntoPowerOff : 1;
+ /** true if the VM power off was caused by reset. */
+ bool mfPowerOffCausedByReset : 1;
+
+ /** Pointer to the VMM -> User (that's us) callbacks. */
+ struct MYVMM2USERMETHODS : public VMM2USERMETHODS
+ {
+ Console *pConsole;
+ /** The in-progress snapshot. */
+ ISnapshot *pISnapshot;
+ } *mpVmm2UserMethods;
+
+ /** The current network attachment type in the VM.
+ * This doesn't have to match the network attachment type maintained in the
+ * NetworkAdapter. This is needed to change the network attachment
+ * dynamically.
+ */
+ typedef std::vector<NetworkAttachmentType_T> NetworkAttachmentTypeVector;
+ NetworkAttachmentTypeVector meAttachmentType;
+
+ VMMDev * m_pVMMDev;
+ AudioVRDE * const mAudioVRDE;
+#ifdef VBOX_WITH_USB_CARDREADER
+ UsbCardReader * const mUsbCardReader;
+#endif
+ BusAssignmentManager* mBusMgr;
+
+ /** @name LEDs and their management
+ * @{ */
+ /** Read/write lock separating LED allocations and per-type data construction
+ * (write) from queries (read). */
+ RWLockHandle mLedLock;
+ /** LED configuration generation. This is increased whenever a new set is
+ * allocated or a sub-device type changes. */
+ uint32_t muLedGen;
+ /** The LED configuration generation which maLedTypes was constructed for. */
+ uint32_t muLedTypeGen;
+ /** Number of LED sets in use in maLedSets. */
+ uint32_t mcLedSets;
+ /** LED sets. */
+ struct LEDSET
+ {
+ /** Bitmask of possible DeviceType_T values (e.g. RT_BIT_32(DeviceType_Network)). */
+ uint32_t fTypes;
+ /** Number of LEDs. */
+ uint32_t cLeds;
+ /** Array of PDMLED pointers. The pointers in the array can be changed at any
+ * time by Console::i_drvStatus_UnitChanged(). */
+ PPDMLED volatile *papLeds;
+ /** Optionally, device types for each individual LED. Runs parallel to papLeds. */
+ DeviceType_T *paSubTypes;
+ } maLedSets[32];
+ /** LEDs data organized by DeviceType_T.
+ * This is reconstructed by Console::i_refreshLedTypeArrays() when
+ * Console::getDeviceActivity is called and mLedTypeGen doesn't match
+ * muLedGen. */
+ struct
+ {
+ /** Number of possibly valid entries in pappLeds. */
+ uint32_t cLeds;
+ /** Number of allocated entries. */
+ uint32_t cAllocated;
+ /** Array of pointer to LEDSET::papLed entries.
+ * The indirection is due to Console::i_drvStatus_UnitChanged() only knowing
+ * about the LEDSET::papLeds. */
+ PPDMLED volatile **pappLeds;
+ } maLedTypes[DeviceType_End];
+ /** @} */
+
+ MediumAttachmentMap mapMediumAttachments;
+
+ /** List of attached USB storage devices. */
+ USBStorageDeviceList mUSBStorageDevices;
+
+ /** Store for secret keys. */
+ SecretKeyStore * const m_pKeyStore;
+ /** Number of disks configured for encryption. */
+ unsigned m_cDisksEncrypted;
+ /** Number of disks which have the key in the map. */
+ unsigned m_cDisksPwProvided;
+
+ /** Current active port modes of the supported serial ports. */
+ PortMode_T m_aeSerialPortMode[4];
+
+ /** Pointer to the key consumer -> provider (that's us) callbacks. */
+ struct MYPDMISECKEY : public PDMISECKEY
+ {
+ Console *pConsole;
+ } *mpIfSecKey;
+
+ /** Pointer to the key helpers -> provider (that's us) callbacks. */
+ struct MYPDMISECKEYHLP : public PDMISECKEYHLP
+ {
+ Console *pConsole;
+ } *mpIfSecKeyHlp;
+
+/* Note: FreeBSD needs this whether netflt is used or not. */
+#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
+ Utf8Str maTAPDeviceName[8];
+ RTFILE maTapFD[8];
+#endif
+
+ bool mVMStateChangeCallbackDisabled;
+
+ bool mfUseHostClipboard;
+
+ /** Local machine state value. */
+ MachineState_T mMachineState;
+
+ /** Machine uuid string. */
+ Bstr mstrUuid;
+
+ /** @name Members related to the cryptographic support interface.
+ * @{ */
+ /** The loaded module handle if loaded. */
+ RTLDRMOD mhLdrModCrypto;
+ /** Reference counter tracking how many users of the cryptographic support
+ * are there currently. */
+ volatile uint32_t mcRefsCrypto;
+ /** Pointer to the cryptographic support interface. */
+ PCVBOXCRYPTOIF mpCryptoIf;
+ /** @} */
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ /** Flag whether the log is encrypted. */
+ bool m_fEncryptedLog;
+ /** The file handle of the encrypted log. */
+ RTVFSFILE m_hVfsFileLog;
+ /** The logging output interface for encrypted logs. */
+ RTLOGOUTPUTIF m_LogOutputIf;
+ /** The log file key ID. */
+ Utf8Str m_strLogKeyId;
+ /** The log file key store. */
+ Utf8Str m_strLogKeyStore;
+#endif
+
+#ifdef VBOX_WITH_DRAG_AND_DROP
+ HGCMSVCEXTHANDLE m_hHgcmSvcExtDragAndDrop;
+#endif
+
+ /** Pointer to the progress object of a live cancelable task.
+ *
+ * This is currently only used by Console::Teleport(), but is intended to later
+ * be used by the live snapshot code path as well. Actions like
+ * Console::PowerDown, which automatically cancels out the running snapshot /
+ * teleportation operation, will cancel the teleportation / live snapshot
+ * operation before starting. */
+ ComPtr<IProgress> mptrCancelableProgress;
+
+ ComPtr<IEventListener> mVmListener;
+
+#ifdef VBOX_WITH_RECORDING
+ struct Recording
+ {
+ Recording()
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ : mAudioRec(NULL)
+# endif
+ { }
+
+ /** The recording context. */
+ RecordingContext mCtx;
+# ifdef VBOX_WITH_AUDIO_RECORDING
+ /** Pointer to capturing audio backend. */
+ AudioVideoRec * const mAudioRec;
+# endif
+ } mRecording;
+#endif /* VBOX_WITH_RECORDING */
+
+#ifdef VBOX_WITH_CLOUD_NET
+ GatewayInfo mGateway;
+#endif /* VBOX_WITH_CLOUD_NET */
+
+ friend class VMTask;
+ friend class ConsoleVRDPServer;
+};
+
+#endif /* !MAIN_INCLUDED_ConsoleImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ConsoleSharedFolderImpl.h b/src/VBox/Main/include/ConsoleSharedFolderImpl.h
new file mode 100644
index 00000000..1ad45a38
--- /dev/null
+++ b/src/VBox/Main/include/ConsoleSharedFolderImpl.h
@@ -0,0 +1,124 @@
+/* $Id: ConsoleSharedFolderImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ConsoleSharedFolderImpl_h
+#define MAIN_INCLUDED_ConsoleSharedFolderImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SharedFolderWrap.h"
+#include <VBox/shflsvc.h>
+
+class Console;
+
+class ATL_NO_VTABLE ConsoleSharedFolder :
+ public SharedFolderWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS (ConsoleSharedFolder)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+// HRESULT init(Machine *aMachine, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
+// bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
+// HRESULT initCopy(Machine *aMachine, SharedFolder *aThat);
+ HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
+ bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
+// HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
+// bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
+ void uninit();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+
+ /**
+ * Public internal method. Returns the shared folder's name. Needs caller! Locking not necessary.
+ * @return
+ */
+ const Utf8Str &i_getName() const;
+
+ /**
+ * Public internal method. Returns the shared folder's host path. Needs caller! Locking not necessary.
+ * @return
+ */
+ const Utf8Str &i_getHostPath() const;
+
+ /**
+ * Public internal method. Returns true if the shared folder is writable. Needs caller and locking!
+ * @return
+ */
+ bool i_isWritable() const;
+
+ /**
+ * Public internal method. Returns true if the shared folder is auto-mounted. Needs caller and locking!
+ * @return
+ */
+ bool i_isAutoMounted() const;
+
+ /**
+ * Public internal method for getting the auto mount point.
+ */
+ const Utf8Str &i_getAutoMountPoint() const;
+
+protected:
+
+ HRESULT i_protectedInit(VirtualBoxBase *aParent,
+ const Utf8Str &aName,
+ const Utf8Str &aHostPath,
+ bool aWritable,
+ bool aAutoMount,
+ const com::Utf8Str &aAutoMountPoint,
+ bool fFailOnError);
+private:
+
+ // wrapped ISharedFolder properies.
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getHostPath(com::Utf8Str &aHostPath);
+ HRESULT getAccessible(BOOL *aAccessible);
+ HRESULT getWritable(BOOL *aWritable);
+ HRESULT setWritable(BOOL aWritable);
+ HRESULT getAutoMount(BOOL *aAutoMount);
+ HRESULT setAutoMount(BOOL aAutoMount);
+ HRESULT getAutoMountPoint(com::Utf8Str &aAutoMountPoint);
+ HRESULT setAutoMountPoint(com::Utf8Str const &aAutoMountPoint);
+ HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
+
+ VirtualBoxBase * const mParent;
+
+ /* weak parents (only one of them is not null) */
+ Console * const mConsole;
+
+ struct Data; // opaque data struct, defined in ConsoleSharedFolderImpl.cpp
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_ConsoleSharedFolderImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ConsoleVRDPServer.h b/src/VBox/Main/include/ConsoleVRDPServer.h
new file mode 100644
index 00000000..dc08c270
--- /dev/null
+++ b/src/VBox/Main/include/ConsoleVRDPServer.h
@@ -0,0 +1,428 @@
+/* $Id: ConsoleVRDPServer.h $ */
+/** @file
+ * VBox Console VRDE Server Helper class and implementation of IVRDEServerInfo
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ConsoleVRDPServer_h
+#define MAIN_INCLUDED_ConsoleVRDPServer_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VRDEServerInfoWrap.h"
+#include "RemoteUSBBackend.h"
+#include "HGCM.h"
+
+#include "AuthLibrary.h"
+
+#include <VBox/RemoteDesktop/VRDEImage.h>
+#include <VBox/RemoteDesktop/VRDEMousePtr.h>
+#include <VBox/RemoteDesktop/VRDESCard.h>
+#include <VBox/RemoteDesktop/VRDETSMF.h>
+#define VRDE_VIDEOIN_WITH_VRDEINTERFACE /* Get the VRDE interface definitions. */
+#include <VBox/RemoteDesktop/VRDEVideoIn.h>
+#include <VBox/RemoteDesktop/VRDEInput.h>
+
+#include <VBox/HostServices/VBoxClipboardExt.h>
+#include <VBox/HostServices/VBoxHostChannel.h>
+
+#include "SchemaDefs.h"
+
+// ConsoleVRDPServer
+///////////////////////////////////////////////////////////////////////////////
+
+class EmWebcam;
+
+typedef struct _VRDPInputSynch
+{
+ int cGuestNumLockAdaptions;
+ int cGuestCapsLockAdaptions;
+
+ bool fGuestNumLock;
+ bool fGuestCapsLock;
+ bool fGuestScrollLock;
+
+ bool fClientNumLock;
+ bool fClientCapsLock;
+ bool fClientScrollLock;
+} VRDPInputSynch;
+
+/* Member of Console. Helper class for VRDP server management. Not a COM class. */
+class ConsoleVRDPServer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(ConsoleVRDPServer)
+
+ ConsoleVRDPServer (Console *console);
+ ~ConsoleVRDPServer ();
+
+ int Launch (void);
+
+ void NotifyAbsoluteMouse (bool fGuestWantsAbsolute)
+ {
+ m_fGuestWantsAbsolute = fGuestWantsAbsolute;
+ }
+
+ void NotifyKeyboardLedsChange (BOOL fNumLock, BOOL fCapsLock, BOOL fScrollLock)
+ {
+ bool fGuestNumLock = (fNumLock != FALSE);
+ bool fGuestCapsLock = (fCapsLock != FALSE);
+ bool fGuestScrollLock = (fScrollLock != FALSE);
+
+ /* Might need to resync in case the guest itself changed the LED status. */
+ if (m_InputSynch.fClientNumLock != fGuestNumLock)
+ {
+ m_InputSynch.cGuestNumLockAdaptions = 2;
+ }
+
+ if (m_InputSynch.fClientCapsLock != fGuestCapsLock)
+ {
+ m_InputSynch.cGuestCapsLockAdaptions = 2;
+ }
+
+ m_InputSynch.fGuestNumLock = fGuestNumLock;
+ m_InputSynch.fGuestCapsLock = fGuestCapsLock;
+ m_InputSynch.fGuestScrollLock = fGuestScrollLock;
+ }
+
+ void EnableConnections (void);
+ void DisconnectClient (uint32_t u32ClientId, bool fReconnect);
+ int MousePointer(BOOL alpha, ULONG xHot, ULONG yHot, ULONG width, ULONG height, const uint8_t *pu8Shape);
+ void MousePointerUpdate (const VRDECOLORPOINTER *pPointer);
+ void MousePointerHide (void);
+
+ void Stop (void);
+
+ AuthResult Authenticate (const Guid &uuid, AuthGuestJudgement guestJudgement,
+ const char *pszUser, const char *pszPassword, const char *pszDomain,
+ uint32_t u32ClientId);
+
+ void AuthDisconnect (const Guid &uuid, uint32_t u32ClientId);
+
+ void USBBackendCreate (uint32_t u32ClientId, void **ppvIntercept);
+ void USBBackendDelete (uint32_t u32ClientId);
+
+ void *USBBackendRequestPointer (uint32_t u32ClientId, const Guid *pGuid);
+ void USBBackendReleasePointer (const Guid *pGuid);
+
+ /* Private interface for the RemoteUSBBackend destructor. */
+ void usbBackendRemoveFromList (RemoteUSBBackend *pRemoteUSBBackend);
+
+ /* Private methods for the Remote USB thread. */
+ RemoteUSBBackend *usbBackendGetNext (RemoteUSBBackend *pRemoteUSBBackend);
+
+ void notifyRemoteUSBThreadRunning (RTTHREAD thread);
+ bool isRemoteUSBThreadRunning (void);
+ void waitRemoteUSBThreadEvent (RTMSINTERVAL cMillies);
+
+ void ClipboardCreate (uint32_t u32ClientId);
+ void ClipboardDelete (uint32_t u32ClientId);
+
+ /*
+ * Forwarders to VRDP server library.
+ */
+ void SendUpdate (unsigned uScreenId, void *pvUpdate, uint32_t cbUpdate) const;
+ void SendResize (void);
+ void SendUpdateBitmap (unsigned uScreenId, uint32_t x, uint32_t y, uint32_t w, uint32_t h) const;
+
+ void SendAudioSamples (void const *pvSamples, uint32_t cSamples, VRDEAUDIOFORMAT format) const;
+ void SendAudioVolume (uint16_t left, uint16_t right) const;
+ void SendUSBRequest (uint32_t u32ClientId, void *pvParms, uint32_t cbParms) const;
+
+ void QueryInfo (uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const;
+
+ int SendAudioInputBegin(void **ppvUserCtx,
+ void *pvContext,
+ uint32_t cSamples,
+ uint32_t iSampleHz,
+ uint32_t cChannels,
+ uint32_t cBits);
+
+ void SendAudioInputEnd(void *pvUserCtx);
+
+ int SCardRequest(void *pvUser, uint32_t u32Function, const void *pvData, uint32_t cbData);
+
+ int VideoInDeviceAttach(const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, void *pvDeviceCtx);
+ int VideoInDeviceDetach(const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle);
+ int VideoInGetDeviceDesc(void *pvUser, const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle);
+ int VideoInControl(void *pvUser, const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle,
+ const VRDEVIDEOINCTRLHDR *pReq, uint32_t cbReq);
+
+ Console *getConsole(void) { return mConsole; }
+
+ void onMousePointerShapeChange(BOOL visible, BOOL alpha, ULONG xHot, ULONG yHot,
+ ULONG width, ULONG height, ComSafeArrayIn(BYTE,shape));
+
+private:
+ /* Note: This is not a ComObjPtr here, because the ConsoleVRDPServer object
+ * is actually just a part of the Console.
+ */
+ Console *mConsole;
+
+ HVRDESERVER mhServer;
+ int mServerInterfaceVersion;
+
+ int32_t volatile mcInResize; /* Do not Stop the server if this is not 0. */
+
+ static int loadVRDPLibrary (const char *pszLibraryName);
+
+ /** Static because will never load this more than once! */
+ static RTLDRMOD mVRDPLibrary;
+
+ static PFNVRDECREATESERVER mpfnVRDECreateServer;
+
+ static VRDEENTRYPOINTS_4 mEntryPoints;
+ static VRDEENTRYPOINTS_4 *mpEntryPoints;
+ static VRDECALLBACKS_4 mCallbacks;
+
+ static DECLCALLBACK(int) VRDPCallbackQueryProperty (void *pvCallback, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut);
+ static DECLCALLBACK(int) VRDPCallbackClientLogon (void *pvCallback, uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain);
+ static DECLCALLBACK(void) VRDPCallbackClientConnect (void *pvCallback, uint32_t u32ClientId);
+ static DECLCALLBACK(void) VRDPCallbackClientDisconnect (void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercepted);
+ static DECLCALLBACK(int) VRDPCallbackIntercept (void *pvCallback, uint32_t u32ClientId, uint32_t fu32Intercept, void **ppvIntercept);
+ static DECLCALLBACK(int) VRDPCallbackUSB (void *pvCallback, void *pvIntercept, uint32_t u32ClientId, uint8_t u8Code, const void *pvRet, uint32_t cbRet);
+ static DECLCALLBACK(int) VRDPCallbackClipboard (void *pvCallback, void *pvIntercept, uint32_t u32ClientId, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData);
+ static DECLCALLBACK(bool) VRDPCallbackFramebufferQuery (void *pvCallback, unsigned uScreenId, VRDEFRAMEBUFFERINFO *pInfo);
+ static DECLCALLBACK(void) VRDPCallbackFramebufferLock (void *pvCallback, unsigned uScreenId);
+ static DECLCALLBACK(void) VRDPCallbackFramebufferUnlock (void *pvCallback, unsigned uScreenId);
+ static DECLCALLBACK(void) VRDPCallbackInput (void *pvCallback, int type, const void *pvInput, unsigned cbInput);
+ static DECLCALLBACK(void) VRDPCallbackVideoModeHint (void *pvCallback, unsigned cWidth, unsigned cHeight, unsigned cBitsPerPixel, unsigned uScreenId);
+ static DECLCALLBACK(void) VRDECallbackAudioIn (void *pvCallback, void *pvCtx, uint32_t u32ClientId, uint32_t u32Event, const void *pvData, uint32_t cbData);
+
+ void fetchCurrentState(void);
+
+ bool m_fGuestWantsAbsolute;
+ int m_mousex;
+ int m_mousey;
+
+ ComPtr<IDisplaySourceBitmap> maSourceBitmaps[SchemaDefs::MaxGuestMonitors];
+
+ ComPtr<IEventListener> mConsoleListener;
+
+ VRDPInputSynch m_InputSynch;
+
+ int32_t mVRDPBindPort;
+
+ RTCRITSECT mCritSect;
+
+ int lockConsoleVRDPServer (void);
+ void unlockConsoleVRDPServer (void);
+
+ int mcClipboardRefs;
+ HGCMSVCEXTHANDLE mhClipboard;
+ PFNVRDPCLIPBOARDEXTCALLBACK mpfnClipboardCallback;
+
+ static DECLCALLBACK(int) ClipboardCallback (void *pvCallback, uint32_t u32ClientId, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData);
+ static DECLCALLBACK(int) ClipboardServiceExtension(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms);
+
+#ifdef VBOX_WITH_USB
+ RemoteUSBBackend *usbBackendFindByUUID (const Guid *pGuid);
+ RemoteUSBBackend *usbBackendFind (uint32_t u32ClientId);
+
+ typedef struct _USBBackends
+ {
+ RemoteUSBBackend *pHead;
+ RemoteUSBBackend *pTail;
+
+ RTTHREAD thread;
+
+ bool fThreadRunning;
+
+ RTSEMEVENT event;
+ } USBBackends;
+
+ USBBackends mUSBBackends;
+
+ void remoteUSBThreadStart (void);
+ void remoteUSBThreadStop (void);
+#endif /* VBOX_WITH_USB */
+
+#ifndef VBOX_WITH_VRDEAUTH_IN_VBOXSVC
+ /* External authentication library context. The library is loaded in the
+ * Authenticate method and unloaded at the object destructor.
+ */
+ AUTHLIBRARYCONTEXT mAuthLibCtx;
+#endif
+
+ uint32_t volatile mu32AudioInputClientId;
+
+ int32_t volatile mcClients;
+
+#if 0 /** @todo Chromium got removed (see @bugref{9529}) and this is not available for VMSVGA yet. */
+ static DECLCALLBACK(void) H3DORBegin(const void *pvContext, void **ppvInstance,
+ const char *pszFormat);
+ static DECLCALLBACK(void) H3DORGeometry(void *pvInstance,
+ int32_t x, int32_t y, uint32_t w, uint32_t h);
+ static DECLCALLBACK(void) H3DORVisibleRegion(void *pvInstance,
+ uint32_t cRects, const RTRECT *paRects);
+ static DECLCALLBACK(void) H3DORFrame(void *pvInstance,
+ void *pvData, uint32_t cbData);
+ static DECLCALLBACK(void) H3DOREnd(void *pvInstance);
+ static DECLCALLBACK(int) H3DORContextProperty(const void *pvContext, uint32_t index,
+ void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut);
+#endif
+
+ void remote3DRedirect(bool fEnable);
+
+ /*
+ * VRDE server optional interfaces.
+ */
+
+ /* Image update interface. */
+ bool m_fInterfaceImage;
+ VRDEIMAGECALLBACKS m_interfaceCallbacksImage;
+ VRDEIMAGEINTERFACE m_interfaceImage;
+ static DECLCALLBACK(int) VRDEImageCbNotify (void *pvContext,
+ void *pvUser,
+ HVRDEIMAGE hVideo,
+ uint32_t u32Id,
+ void *pvData,
+ uint32_t cbData);
+ /* Mouse pointer interface. */
+ VRDEMOUSEPTRINTERFACE m_interfaceMousePtr;
+
+ /* Smartcard interface. */
+ VRDESCARDINTERFACE m_interfaceSCard;
+ VRDESCARDCALLBACKS m_interfaceCallbacksSCard;
+ static DECLCALLBACK(int) VRDESCardCbNotify(void *pvContext,
+ uint32_t u32Id,
+ void *pvData,
+ uint32_t cbData);
+ static DECLCALLBACK(int) VRDESCardCbResponse(void *pvContext,
+ int vrcRequest,
+ void *pvUser,
+ uint32_t u32Function,
+ void *pvData,
+ uint32_t cbData);
+
+ /* TSMF interface. */
+ VRDETSMFINTERFACE m_interfaceTSMF;
+ VRDETSMFCALLBACKS m_interfaceCallbacksTSMF;
+ static DECLCALLBACK(void) VRDETSMFCbNotify(void *pvContext,
+ uint32_t u32Notification,
+ void *pvChannel,
+ const void *pvParm,
+ uint32_t cbParm);
+ void setupTSMF(void);
+
+ static DECLCALLBACK(int) tsmfHostChannelAttach(void *pvProvider, void **ppvInstance, uint32_t u32Flags,
+ VBOXHOSTCHANNELCALLBACKS *pCallbacks, void *pvCallbacks);
+ static DECLCALLBACK(void) tsmfHostChannelDetach(void *pvInstance);
+ static DECLCALLBACK(int) tsmfHostChannelSend(void *pvInstance, const void *pvData, uint32_t cbData);
+ static DECLCALLBACK(int) tsmfHostChannelRecv(void *pvInstance, void *pvData, uint32_t cbData,
+ uint32_t *pcbReturned, uint32_t *pcbRemaining);
+ static DECLCALLBACK(int) tsmfHostChannelControl(void *pvInstance, uint32_t u32Code,
+ const void *pvParm, uint32_t cbParm,
+ const void *pvData, uint32_t cbData, uint32_t *pcbDataReturned);
+ int tsmfLock(void);
+ void tsmfUnlock(void);
+ RTCRITSECT mTSMFLock;
+
+ /* Video input interface. */
+ VRDEVIDEOININTERFACE m_interfaceVideoIn;
+ VRDEVIDEOINCALLBACKS m_interfaceCallbacksVideoIn;
+ static DECLCALLBACK(void) VRDECallbackVideoInNotify(void *pvCallback,
+ uint32_t u32Id,
+ const void *pvData,
+ uint32_t cbData);
+ static DECLCALLBACK(void) VRDECallbackVideoInDeviceDesc(void *pvCallback,
+ int vrcRequest,
+ void *pDeviceCtx,
+ void *pvUser,
+ const VRDEVIDEOINDEVICEDESC *pDeviceDesc,
+ uint32_t cbDevice);
+ static DECLCALLBACK(void) VRDECallbackVideoInControl(void *pvCallback,
+ int vrcRequest,
+ void *pDeviceCtx,
+ void *pvUser,
+ const VRDEVIDEOINCTRLHDR *pControl,
+ uint32_t cbControl);
+ static DECLCALLBACK(void) VRDECallbackVideoInFrame(void *pvCallback,
+ int vrcRequest,
+ void *pDeviceCtx,
+ const VRDEVIDEOINPAYLOADHDR *pFrame,
+ uint32_t cbFrame);
+ EmWebcam *mEmWebcam;
+
+ /* Input interface. */
+ VRDEINPUTINTERFACE m_interfaceInput;
+ VRDEINPUTCALLBACKS m_interfaceCallbacksInput;
+ static DECLCALLBACK(void) VRDECallbackInputSetup(void *pvCallback,
+ int vrcRequest,
+ uint32_t u32Method,
+ const void *pvResult,
+ uint32_t cbResult);
+ static DECLCALLBACK(void) VRDECallbackInputEvent(void *pvCallback,
+ uint32_t u32Method,
+ const void *pvEvent,
+ uint32_t cbEvent);
+ uint64_t mu64TouchInputTimestampMCS;
+};
+
+
+class Console;
+
+class ATL_NO_VTABLE VRDEServerInfo :
+ public VRDEServerInfoWrap
+{
+public:
+ DECLARE_NOT_AGGREGATABLE(VRDEServerInfo)
+
+ DECLARE_COMMON_CLASS_METHODS(VRDEServerInfo)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /* Public initializer/uninitializer for internal purposes only. */
+ HRESULT init(Console *aParent);
+ void uninit();
+
+private:
+ // wrapped IVRDEServerInfo properties
+#define DECL_GETTER(_aType, _aName) virtual HRESULT get##_aName(_aType *a##_aName)
+#define DECL_GETTER_REF(_aType, _aName) virtual HRESULT get##_aName(_aType &a##_aName)
+ DECL_GETTER(BOOL, Active);
+ DECL_GETTER(LONG, Port);
+ DECL_GETTER(ULONG, NumberOfClients);
+ DECL_GETTER(LONG64, BeginTime);
+ DECL_GETTER(LONG64, EndTime);
+ DECL_GETTER(LONG64, BytesSent);
+ DECL_GETTER(LONG64, BytesSentTotal);
+ DECL_GETTER(LONG64, BytesReceived);
+ DECL_GETTER(LONG64, BytesReceivedTotal);
+ DECL_GETTER_REF(com::Utf8Str, User);
+ DECL_GETTER_REF(com::Utf8Str, Domain);
+ DECL_GETTER_REF(com::Utf8Str, ClientName);
+ DECL_GETTER_REF(com::Utf8Str, ClientIP);
+ DECL_GETTER(ULONG, ClientVersion);
+ DECL_GETTER(ULONG, EncryptionStyle);
+#undef DECL_GETTER_REF
+#undef DECL_GETTER
+
+ Console * const mParent;
+};
+
+#endif /* !MAIN_INCLUDED_ConsoleVRDPServer_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/CryptoUtils.h b/src/VBox/Main/include/CryptoUtils.h
new file mode 100644
index 00000000..3a14029b
--- /dev/null
+++ b/src/VBox/Main/include/CryptoUtils.h
@@ -0,0 +1,141 @@
+/* $Id: CryptoUtils.h $ */
+/** @file
+ * Main - Cryptographic utility functions used by both VBoxSVC and VBoxC.
+ */
+
+/*
+ * Copyright (C) 2022-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_CryptoUtils_h
+#define MAIN_INCLUDED_CryptoUtils_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/vfs.h>
+
+#include <VBox/VBoxCryptoIf.h>
+#include <VBox/com/string.h>
+
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/vmmr3vtable.h>
+#include <VBox/vmm/vmapi.h>
+
+#include "SecretKeyStore.h"
+#ifdef VBOX_COM_INPROC
+# include "ConsoleImpl.h"
+#else
+# include "MachineImpl.h"
+# include "VirtualBoxImpl.h"
+#endif
+
+
+/**
+ * Class handling encrypted and non encrypted SSM files.
+ */
+class SsmStream
+{
+ public:
+#ifdef VBOX_COM_INPROC
+ SsmStream(Console *pParent, PCVMMR3VTABLE pVMM, SecretKeyStore *pKeyStore, const Utf8Str &strKeyId, const Utf8Str &strKeyStore);
+#else
+ SsmStream(VirtualBox *pParent, SecretKeyStore *pKeyStore, const Utf8Str &strKeyId, const Utf8Str &strKeyStore);
+#endif
+ ~SsmStream();
+
+ /**
+ * Actually opens the stream for either reading or writing.
+ *
+ * @returns VBox status code.
+ * @param strFilename The filename of the saved state to open or create.
+ * @param fWrite Flag whether the stream should be opened for writing (true) or readonly (false).
+ * @param ppSsmHandle Where to store the SSM handle on success, don't call SSMR3Close() but the provided close() method.
+ */
+ int open(const Utf8Str &strFilename, bool fWrite, PSSMHANDLE *ppSsmHandle);
+
+ /**
+ * Opens the saved state file for reading, doesn't call SSMR3Open().
+ *
+ * @returns VBox status code.
+ * @param strFilename The filename of the saved state to open.
+ */
+ int open(const Utf8Str &strFilename);
+
+ /**
+ * Creates a new saved state file under the given path.
+ *
+ * @returns VBox status code.
+ * @param strFilename The filename of the saved state to create.
+ */
+ int create(const Utf8Str &strFilename);
+
+ /**
+ * Returns the pointer to the stream operations table after a succesful opening/creation.
+ *
+ * @return VBox status code.
+ * @param ppStrmOps Where to store the pointer to the stream operations table on success.
+ * @param ppvStrmOpsUser Where to store the pointer to the opaque user data on success.
+ */
+ int querySsmStrmOps(PCSSMSTRMOPS *ppStrmOps, void **ppvStrmOpsUser);
+
+ /**
+ * Closes an previously opened stream.
+ *
+ * @returns VBox status code.
+ */
+ int close(void);
+
+ private:
+
+ static DECLCALLBACK(int) i_ssmCryptoWrite(void *pvUser, uint64_t offStream, const void *pvBuf, size_t cbToWrite);
+ static DECLCALLBACK(int) i_ssmCryptoRead(void *pvUser, uint64_t offStream, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+ static DECLCALLBACK(int) i_ssmCryptoSeek(void *pvUser, int64_t offSeek, unsigned uMethod, uint64_t *poffActual);
+ static DECLCALLBACK(uint64_t) i_ssmCryptoTell(void *pvUser);
+ static DECLCALLBACK(int) i_ssmCryptoSize(void *pvUser, uint64_t *pcb);
+ static DECLCALLBACK(int) i_ssmCryptoIsOk(void *pvUser);
+ static DECLCALLBACK(int) i_ssmCryptoClose(void *pvUser, bool fCancelled);
+
+#ifdef VBOX_COM_INPROC
+ Console *m_pParent;
+ PCVMMR3VTABLE m_pVMM;
+#else
+ VirtualBox *m_pParent;
+#endif
+ /** The key store for getting at passwords. */
+ SecretKeyStore *m_pKeyStore;
+ /** The key ID holding the password, empty if the saved state is not encrypted. */
+ Utf8Str m_strKeyId;
+ /** The keystore holding the encrypted DEK. */
+ Utf8Str m_strKeyStore;
+ /** The VFS file handle. */
+ RTVFSFILE m_hVfsFile;
+ /** The SSM handle when opened. */
+ PSSMHANDLE m_pSsm;
+ /** The SSM stream callbacks table. */
+ SSMSTRMOPS m_StrmOps;
+ /** The cryptographic interfacer. */
+ PCVBOXCRYPTOIF m_pCryptoIf;
+};
+
+#endif /* !MAIN_INCLUDED_CryptoUtils_h */
diff --git a/src/VBox/Main/include/DHCPConfigImpl.h b/src/VBox/Main/include/DHCPConfigImpl.h
new file mode 100644
index 00000000..eb83641d
--- /dev/null
+++ b/src/VBox/Main/include/DHCPConfigImpl.h
@@ -0,0 +1,529 @@
+/* $Id: DHCPConfigImpl.h $ */
+/** @file
+ * VirtualBox Main - IDHCPConfig, IDHCPConfigGlobal, IDHCPConfigGroup, IDHCPConfigIndividual header.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DHCPConfigImpl_h
+#define MAIN_INCLUDED_DHCPConfigImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "DHCPGlobalConfigWrap.h"
+#include "DHCPGroupConditionWrap.h"
+#include "DHCPGroupConfigWrap.h"
+#include "DHCPIndividualConfigWrap.h"
+#include <VBox/settings.h>
+
+
+class DHCPServer;
+class DHCPGroupConfig;
+
+
+/**
+ * Base class for the a DHCP configration layer.
+ *
+ * This does not inherit from DHCPConfigWrap because its children need to
+ * inherit from children of DHCPConfigWrap, which smells like trouble and thus
+ * wasn't even attempted. Instead, we have a hack for passing a pointer that we
+ * can call setError and such on.
+ */
+class DHCPConfig
+{
+protected:
+ /** Config scope (global, group, vm+nic, mac). */
+ DHCPConfigScope_T const m_enmScope;
+ /** Minimum lease time. */
+ ULONG m_secMinLeaseTime;
+ /** Default lease time. */
+ ULONG m_secDefaultLeaseTime;
+ /** Maximum lease time. */
+ ULONG m_secMaxLeaseTime;
+ /** List of options which are forced upon the client when available, whether
+ * requested by it or not. */
+ std::vector<DHCPOption_T> m_vecForcedOptions;
+ /** List of options which should be suppressed and not returned the the client
+ * when available and requested. */
+ std::vector<DHCPOption_T> m_vecSuppressedOptions;
+ /** DHCP option map. */
+ settings::DhcpOptionMap m_OptionMap;
+ /** The DHCP server parent (weak). */
+ DHCPServer * const m_pParent;
+ /** The DHCP server parent (weak). */
+ VirtualBox * const m_pVirtualBox;
+private:
+ /** For setError and such. */
+ VirtualBoxBase * const m_pHack;
+
+protected:
+ /** @name Constructors and destructors.
+ * @{ */
+ DHCPConfig(DHCPConfigScope_T a_enmScope, VirtualBoxBase *a_pHack)
+ : m_enmScope(a_enmScope), m_secMinLeaseTime(0), m_secDefaultLeaseTime(0), m_secMaxLeaseTime(0), m_OptionMap()
+ , m_pParent(NULL), m_pVirtualBox(NULL), m_pHack(a_pHack)
+ {}
+ DHCPConfig();
+ virtual ~DHCPConfig()
+ {}
+ HRESULT i_initWithDefaults(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent);
+ HRESULT i_initWithSettings(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent, const settings::DHCPConfig &rConfig);
+ /** @} */
+
+ /** @name IDHCPConfig properties
+ * @{ */
+ HRESULT i_getScope(DHCPConfigScope_T *aScope);
+ HRESULT i_getMinLeaseTime(ULONG *aMinLeaseTime);
+ HRESULT i_setMinLeaseTime(ULONG aMinLeaseTime);
+ HRESULT i_getDefaultLeaseTime(ULONG *aDefaultLeaseTime);
+ HRESULT i_setDefaultLeaseTime(ULONG aDefaultLeaseTime);
+ HRESULT i_getMaxLeaseTime(ULONG *aMaxLeaseTime);
+ HRESULT i_setMaxLeaseTime(ULONG aMaxLeaseTime);
+ HRESULT i_getForcedOptions(std::vector<DHCPOption_T> &aOptions);
+ HRESULT i_setForcedOptions(const std::vector<DHCPOption_T> &aOptions);
+ HRESULT i_getSuppressedOptions(std::vector<DHCPOption_T> &aOptions);
+ HRESULT i_setSuppressedOptions(const std::vector<DHCPOption_T> &aOptions);
+ /** @} */
+
+public:
+ DECLARE_TRANSLATE_METHODS(DHCPConfig)
+
+ /** @name IDHCPConfig methods
+ * @note public because the DHCPServer needs them for 6.0 interfaces.
+ * @todo Make protected again when IDHCPServer is cleaned up.
+ * @{ */
+ virtual HRESULT i_setOption(DHCPOption_T aOption, DHCPOptionEncoding_T aEncoding, const com::Utf8Str &aValue);
+
+ virtual HRESULT i_removeOption(DHCPOption_T aOption);
+ virtual HRESULT i_removeAllOptions();
+ HRESULT i_getOption(DHCPOption_T aOption, DHCPOptionEncoding_T *aEncoding, com::Utf8Str &aValue);
+ HRESULT i_getAllOptions(std::vector<DHCPOption_T> &aOptions, std::vector<DHCPOptionEncoding_T> &aEncodings,
+ std::vector<com::Utf8Str> &aValues);
+ virtual HRESULT i_remove();
+ /** @} */
+
+
+public:
+ HRESULT i_doWriteConfig();
+ HRESULT i_saveSettings(settings::DHCPConfig &a_rDst);
+ DHCPConfigScope_T i_getScope() const RT_NOEXCEPT { return m_enmScope; }
+ virtual void i_writeDhcpdConfig(xml::ElementNode *pElm);
+};
+
+
+/**
+ * Global DHCP configuration.
+ */
+class DHCPGlobalConfig : public DHCPGlobalConfigWrap, public DHCPConfig
+{
+public:
+ DECLARE_TRANSLATE_METHODS(DHCPGlobalConfig)
+
+ /** @name Constructors and destructors.
+ * @{ */
+ DHCPGlobalConfig()
+ : DHCPConfig(DHCPConfigScope_Global, this)
+ { }
+ HRESULT FinalConstruct()
+ {
+ return BaseFinalConstruct();
+ }
+ void FinalRelease()
+ {
+ uninit();
+ BaseFinalRelease();
+ }
+ HRESULT initWithDefaults(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent);
+ HRESULT initWithSettings(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent, const settings::DHCPConfig &rConfig);
+ void uninit();
+ /** @} */
+
+ HRESULT i_saveSettings(settings::DHCPConfig &a_rDst);
+ HRESULT i_getNetworkMask(com::Utf8Str &a_rDst);
+ HRESULT i_setNetworkMask(const com::Utf8Str &a_rSrc);
+
+protected:
+ /** @name wrapped IDHCPConfig properties
+ * @{ */
+ HRESULT getScope(DHCPConfigScope_T *aScope) RT_OVERRIDE { return i_getScope(aScope); }
+ HRESULT getMinLeaseTime(ULONG *aMinLeaseTime) RT_OVERRIDE { return i_getMinLeaseTime(aMinLeaseTime); }
+ HRESULT setMinLeaseTime(ULONG aMinLeaseTime) RT_OVERRIDE { return i_setMinLeaseTime(aMinLeaseTime); }
+ HRESULT getDefaultLeaseTime(ULONG *aDefaultLeaseTime) RT_OVERRIDE { return i_getDefaultLeaseTime(aDefaultLeaseTime); }
+ HRESULT setDefaultLeaseTime(ULONG aDefaultLeaseTime) RT_OVERRIDE { return i_setDefaultLeaseTime(aDefaultLeaseTime); }
+ HRESULT getMaxLeaseTime(ULONG *aMaxLeaseTime) RT_OVERRIDE { return i_getMaxLeaseTime(aMaxLeaseTime); }
+ HRESULT setMaxLeaseTime(ULONG aMaxLeaseTime) RT_OVERRIDE { return i_setMaxLeaseTime(aMaxLeaseTime); }
+ HRESULT getForcedOptions(std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_getForcedOptions(aOptions); }
+ HRESULT setForcedOptions(const std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_setForcedOptions(aOptions); }
+ HRESULT getSuppressedOptions(std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_getSuppressedOptions(aOptions); }
+ HRESULT setSuppressedOptions(const std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_setSuppressedOptions(aOptions); }
+ /** @} */
+
+ /** @name wrapped IDHCPConfig methods
+ * @{ */
+ HRESULT setOption(DHCPOption_T aOption, DHCPOptionEncoding_T aEncoding, const com::Utf8Str &aValue) RT_OVERRIDE
+ {
+ return i_setOption(aOption, aEncoding, aValue);
+ }
+
+ HRESULT removeOption(DHCPOption_T aOption) RT_OVERRIDE
+ {
+ return i_removeOption(aOption);
+ }
+
+ HRESULT removeAllOptions() RT_OVERRIDE
+ {
+ return i_removeAllOptions();
+ }
+
+ HRESULT getOption(DHCPOption_T aOption, DHCPOptionEncoding_T *aEncoding, com::Utf8Str &aValue) RT_OVERRIDE
+ {
+ return i_getOption(aOption, aEncoding, aValue);
+ }
+
+ HRESULT getAllOptions(std::vector<DHCPOption_T> &aOptions, std::vector<DHCPOptionEncoding_T> &aEncodings,
+ std::vector<com::Utf8Str> &aValues) RT_OVERRIDE
+ {
+ return i_getAllOptions(aOptions, aEncodings, aValues);
+ }
+
+ HRESULT remove() RT_OVERRIDE
+ {
+ return i_remove();
+ }
+ /** @} */
+
+public:
+ HRESULT i_setOption(DHCPOption_T aOption, DHCPOptionEncoding_T aEncoding, const com::Utf8Str &aValue) RT_OVERRIDE;
+ HRESULT i_removeOption(DHCPOption_T aOption) RT_OVERRIDE;
+ HRESULT i_removeAllOptions() RT_OVERRIDE;
+ HRESULT i_remove() RT_OVERRIDE;
+};
+
+
+/**
+ * DHCP Group inclusion/exclusion condition.
+ */
+class DHCPGroupCondition : public DHCPGroupConditionWrap
+{
+private:
+ /** Inclusive or exclusive condition. */
+ bool m_fInclusive;
+ /** The condition type (or how m_strValue should be interpreted). */
+ DHCPGroupConditionType_T m_enmType;
+ /** The value. Interpreted according to m_enmType. */
+ com::Utf8Str m_strValue;
+ /** Pointer to the parent (weak). */
+ DHCPGroupConfig *m_pParent;
+
+public:
+ DECLARE_TRANSLATE_METHODS(DHCPGroupCondition)
+
+ /** @name Constructors and destructors.
+ * @{ */
+ DHCPGroupCondition()
+ : m_enmType(DHCPGroupConditionType_MAC)
+ , m_pParent(NULL)
+ {}
+ HRESULT FinalConstruct()
+ {
+ return BaseFinalConstruct();
+ }
+ void FinalRelease()
+ {
+ uninit();
+ BaseFinalRelease();
+ }
+ HRESULT initWithDefaults(DHCPGroupConfig *a_pParent, bool a_fInclusive, DHCPGroupConditionType_T a_enmType,
+ const com::Utf8Str a_strValue);
+ HRESULT initWithSettings(DHCPGroupConfig *a_pParent, const settings::DHCPGroupCondition &a_rSrc);
+ void uninit();
+ /** @} */
+
+ HRESULT i_saveSettings(settings::DHCPGroupCondition &a_rDst);
+ static HRESULT i_validateTypeAndValue(DHCPGroupConditionType_T enmType, com::Utf8Str const &strValue,
+ VirtualBoxBase *pErrorDst);
+
+ /** @name Internal accessors
+ * @{ */
+ bool i_getInclusive() const RT_NOEXCEPT { return m_fInclusive; }
+ DHCPGroupConditionType_T i_getType() const RT_NOEXCEPT { return m_enmType; }
+ com::Utf8Str const &i_getValue() const RT_NOEXCEPT { return m_strValue; }
+ /** @} */
+
+protected:
+ /** @name Wrapped IDHCPGroupCondition properties
+ * @{ */
+ HRESULT getInclusive(BOOL *aInclusive) RT_OVERRIDE;
+ HRESULT setInclusive(BOOL aInclusive) RT_OVERRIDE;
+ HRESULT getType(DHCPGroupConditionType_T *aType) RT_OVERRIDE;
+ HRESULT setType(DHCPGroupConditionType_T aType) RT_OVERRIDE;
+ HRESULT getValue(com::Utf8Str &aValue) RT_OVERRIDE;
+ HRESULT setValue(const com::Utf8Str &aValue) RT_OVERRIDE;
+ /** @} */
+
+ /** @name Wrapped IDHCPGroupCondition methods
+ * @{ */
+ HRESULT remove() RT_OVERRIDE;
+ /** @} */
+};
+
+
+/**
+ * Group configuration.
+ */
+class DHCPGroupConfig : public DHCPGroupConfigWrap, public DHCPConfig
+{
+private:
+ /** Group name. */
+ com::Utf8Str m_strName;
+ /** Group membership conditions. */
+ std::vector<ComObjPtr<DHCPGroupCondition> > m_Conditions;
+ /** Iterator for m_Conditions. */
+ typedef std::vector<ComObjPtr<DHCPGroupCondition> >::iterator ConditionsIterator;
+
+public:
+ DECLARE_TRANSLATE_METHODS(DHCPGroupConfig)
+
+ /** @name Constructors and destructors.
+ * @{ */
+ DHCPGroupConfig()
+ : DHCPConfig(DHCPConfigScope_Group, this)
+ { }
+ HRESULT FinalConstruct()
+ {
+ return BaseFinalConstruct();
+ }
+ void FinalRelease()
+ {
+ uninit();
+ BaseFinalRelease();
+ }
+ HRESULT initWithDefaults(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent, const com::Utf8Str &a_rName);
+ HRESULT initWithSettings(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent, const settings::DHCPGroupConfig &a_rSrc);
+ void uninit();
+ /** @} */
+
+ HRESULT i_saveSettings(settings::DHCPGroupConfig &a_rDst);
+ HRESULT i_removeCondition(DHCPGroupCondition *a_pCondition);
+ void i_writeDhcpdConfig(xml::ElementNode *a_pElmGroup) RT_OVERRIDE;
+
+protected:
+ /** @name Wrapped IDHCPConfig properties
+ * @{ */
+ HRESULT getScope(DHCPConfigScope_T *aScope) RT_OVERRIDE { return i_getScope(aScope); }
+ HRESULT getMinLeaseTime(ULONG *aMinLeaseTime) RT_OVERRIDE { return i_getMinLeaseTime(aMinLeaseTime); }
+ HRESULT setMinLeaseTime(ULONG aMinLeaseTime) RT_OVERRIDE { return i_setMinLeaseTime(aMinLeaseTime); }
+ HRESULT getDefaultLeaseTime(ULONG *aDefaultLeaseTime) RT_OVERRIDE { return i_getDefaultLeaseTime(aDefaultLeaseTime); }
+ HRESULT setDefaultLeaseTime(ULONG aDefaultLeaseTime) RT_OVERRIDE { return i_setDefaultLeaseTime(aDefaultLeaseTime); }
+ HRESULT getMaxLeaseTime(ULONG *aMaxLeaseTime) RT_OVERRIDE { return i_getMaxLeaseTime(aMaxLeaseTime); }
+ HRESULT setMaxLeaseTime(ULONG aMaxLeaseTime) RT_OVERRIDE { return i_setMaxLeaseTime(aMaxLeaseTime); }
+ HRESULT getForcedOptions(std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_getForcedOptions(aOptions); }
+ HRESULT setForcedOptions(const std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_setForcedOptions(aOptions); }
+ HRESULT getSuppressedOptions(std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_getSuppressedOptions(aOptions); }
+ HRESULT setSuppressedOptions(const std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_setSuppressedOptions(aOptions); }
+ /** @} */
+
+ /** @name Wrapped IDHCPGroupConfig properties
+ * @{ */
+ HRESULT getName(com::Utf8Str &aName) RT_OVERRIDE;
+ HRESULT setName(const com::Utf8Str &aName) RT_OVERRIDE;
+ HRESULT getConditions(std::vector<ComPtr<IDHCPGroupCondition> > &aConditions) RT_OVERRIDE;
+ /** @} */
+
+ /** @name Wrapped IDHCPConfig methods
+ * @{ */
+ HRESULT setOption(DHCPOption_T aOption, DHCPOptionEncoding_T aEncoding, const com::Utf8Str &aValue) RT_OVERRIDE
+ {
+ return i_setOption(aOption, aEncoding, aValue);
+ }
+
+ HRESULT removeOption(DHCPOption_T aOption) RT_OVERRIDE
+ {
+ return i_removeOption(aOption);
+ }
+
+ HRESULT removeAllOptions() RT_OVERRIDE
+ {
+ return i_removeAllOptions();
+ }
+
+ HRESULT getOption(DHCPOption_T aOption, DHCPOptionEncoding_T *aEncoding, com::Utf8Str &aValue) RT_OVERRIDE
+ {
+ return i_getOption(aOption, aEncoding, aValue);
+ }
+
+ HRESULT getAllOptions(std::vector<DHCPOption_T> &aOptions, std::vector<DHCPOptionEncoding_T> &aEncodings,
+ std::vector<com::Utf8Str> &aValues) RT_OVERRIDE
+ {
+ return i_getAllOptions(aOptions, aEncodings, aValues);
+ }
+
+ HRESULT remove() RT_OVERRIDE
+ {
+ return i_remove();
+ }
+ /** @} */
+
+ /** @name Wrapped IDHCPGroupConfig methods
+ * @{ */
+ HRESULT addCondition(BOOL aInclusive, DHCPGroupConditionType_T aType, const com::Utf8Str &aValue,
+ ComPtr<IDHCPGroupCondition> &aCondition) RT_OVERRIDE;
+ HRESULT removeAllConditions() RT_OVERRIDE;
+ /** @} */
+};
+
+
+/**
+ * Individual DHCP configuration.
+ */
+class DHCPIndividualConfig : public DHCPIndividualConfigWrap, public DHCPConfig
+{
+private:
+ /** The MAC address or all zeros. */
+ RTMAC m_MACAddress;
+ /** The VM ID or all zeros. */
+ com::Guid const m_idMachine;
+ /** The VM NIC slot number, or ~(ULONG)0. */
+ ULONG const m_uSlot;
+ /** This is part of a hack to resolve the MAC address for
+ * DHCPConfigScope_MachineNIC instances. If non-zero, we m_MACAddress is valid.
+ * To deal with the impossibly theoretical scenario that the DHCP server is
+ * being started by more than one thread, this is a version number and not just
+ * a boolean indicator. */
+ uint32_t volatile m_uMACAddressResolvedVersion;
+
+ /** The fixed IPv4 address, empty if dynamic. */
+ com::Utf8Str m_strFixedAddress;
+
+public:
+ DECLARE_TRANSLATE_METHODS(DHCPIndividualConfig)
+
+ /** @name Constructors and destructors.
+ * @{ */
+ DHCPIndividualConfig()
+ : DHCPConfig(DHCPConfigScope_MAC, this)
+ , m_uSlot(~(ULONG)0)
+ , m_uMACAddressResolvedVersion(0)
+ {
+ RT_ZERO(m_MACAddress);
+ }
+ HRESULT FinalConstruct()
+ {
+ return BaseFinalConstruct();
+ }
+ void FinalRelease()
+ {
+ uninit();
+ BaseFinalRelease();
+ }
+ HRESULT initWithMachineIdAndSlot(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent, com::Guid const &a_idMachine,
+ ULONG a_uSlot, uint32_t a_uMACAddressVersion);
+ HRESULT initWithMACAddress(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent, PCRTMAC a_pMACAddress);
+ HRESULT initWithSettingsAndMachineIdAndSlot(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent,
+ const settings::DHCPIndividualConfig &rData, com::Guid const &a_idMachine,
+ ULONG a_uSlot, uint32_t a_uMACAddressVersion);
+ HRESULT initWithSettingsAndMACAddress(VirtualBox *a_pVirtualBox, DHCPServer *a_pParent,
+ const settings::DHCPIndividualConfig &rData, PCRTMAC a_pMACAddress);
+ void uninit();
+ /** @} */
+
+ /** @name Internal methods that are public for various reasons
+ * @{ */
+ HRESULT i_saveSettings(settings::DHCPIndividualConfig &a_rDst);
+ RTMAC const &i_getMACAddress() const RT_NOEXCEPT { return m_MACAddress; }
+ com::Guid const &i_getMachineId() const RT_NOEXCEPT { return m_idMachine; }
+ ULONG i_getSlot() const RT_NOEXCEPT { return m_uSlot; }
+ HRESULT i_getMachineMAC(PRTMAC pMACAddress);
+
+ HRESULT i_resolveMACAddress(uint32_t uVersion);
+ /** This is used to avoid producing bogus Dhcpd configuration elements. */
+ bool i_isMACAddressResolved(uint32_t uVersion) const
+ {
+ return m_enmScope != DHCPConfigScope_MachineNIC || (int32_t)(m_uMACAddressResolvedVersion - uVersion) >= 0;
+ }
+ void i_writeDhcpdConfig(xml::ElementNode *pElm) RT_OVERRIDE;
+ /** @} */
+
+protected:
+ /** @name wrapped IDHCPConfig properties
+ * @{ */
+ HRESULT getScope(DHCPConfigScope_T *aScope) RT_OVERRIDE { return i_getScope(aScope); }
+ HRESULT getMinLeaseTime(ULONG *aMinLeaseTime) RT_OVERRIDE { return i_getMinLeaseTime(aMinLeaseTime); }
+ HRESULT setMinLeaseTime(ULONG aMinLeaseTime) RT_OVERRIDE { return i_setMinLeaseTime(aMinLeaseTime); }
+ HRESULT getDefaultLeaseTime(ULONG *aDefaultLeaseTime) RT_OVERRIDE { return i_getDefaultLeaseTime(aDefaultLeaseTime); }
+ HRESULT setDefaultLeaseTime(ULONG aDefaultLeaseTime) RT_OVERRIDE { return i_setDefaultLeaseTime(aDefaultLeaseTime); }
+ HRESULT getMaxLeaseTime(ULONG *aMaxLeaseTime) RT_OVERRIDE { return i_getMaxLeaseTime(aMaxLeaseTime); }
+ HRESULT setMaxLeaseTime(ULONG aMaxLeaseTime) RT_OVERRIDE { return i_setMaxLeaseTime(aMaxLeaseTime); }
+ HRESULT getForcedOptions(std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_getForcedOptions(aOptions); }
+ HRESULT setForcedOptions(const std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_setForcedOptions(aOptions); }
+ HRESULT getSuppressedOptions(std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_getSuppressedOptions(aOptions); }
+ HRESULT setSuppressedOptions(const std::vector<DHCPOption_T> &aOptions) RT_OVERRIDE { return i_setSuppressedOptions(aOptions); }
+ /** @} */
+
+ /** @name wrapped IDHCPConfig methods
+ * @{ */
+ HRESULT setOption(DHCPOption_T aOption, DHCPOptionEncoding_T aEncoding, const com::Utf8Str &aValue) RT_OVERRIDE
+ {
+ return i_setOption(aOption, aEncoding, aValue);
+ }
+
+ HRESULT removeOption(DHCPOption_T aOption) RT_OVERRIDE
+ {
+ return i_removeOption(aOption);
+ }
+
+ HRESULT removeAllOptions() RT_OVERRIDE
+ {
+ return i_removeAllOptions();
+ }
+
+ HRESULT getOption(DHCPOption_T aOption, DHCPOptionEncoding_T *aEncoding, com::Utf8Str &aValue) RT_OVERRIDE
+ {
+ return i_getOption(aOption, aEncoding, aValue);
+ }
+
+ HRESULT getAllOptions(std::vector<DHCPOption_T> &aOptions, std::vector<DHCPOptionEncoding_T> &aEncodings,
+ std::vector<com::Utf8Str> &aValues) RT_OVERRIDE
+ {
+ return i_getAllOptions(aOptions, aEncodings, aValues);
+ }
+
+ HRESULT remove() RT_OVERRIDE
+ {
+ return i_remove();
+ }
+ /** @} */
+
+ /** @name IDHCPIndividualConfig properties
+ * @{ */
+ HRESULT getMACAddress(com::Utf8Str &aMacAddress) RT_OVERRIDE;
+ HRESULT getMachineId(com::Guid &aId) RT_OVERRIDE;
+ HRESULT getSlot(ULONG *aSlot) RT_OVERRIDE;
+ HRESULT getFixedAddress(com::Utf8Str &aFixedAddress) RT_OVERRIDE;
+ HRESULT setFixedAddress(const com::Utf8Str &aFixedAddress) RT_OVERRIDE;
+ /** @} */
+};
+
+#endif /* !MAIN_INCLUDED_DHCPConfigImpl_h */
+
diff --git a/src/VBox/Main/include/DHCPServerImpl.h b/src/VBox/Main/include/DHCPServerImpl.h
new file mode 100644
index 00000000..92c925f8
--- /dev/null
+++ b/src/VBox/Main/include/DHCPServerImpl.h
@@ -0,0 +1,130 @@
+/* $Id: DHCPServerImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DHCPServerImpl_h
+#define MAIN_INCLUDED_DHCPServerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "DHCPServerWrap.h"
+#include <map>
+
+namespace settings
+{
+ struct DHCPServer;
+ struct DhcpOptValue;
+ typedef std::map<DHCPOption_T, DhcpOptValue> DhcpOptionMap;
+}
+
+class DHCPConfig;
+class DHCPIndividualConfig;
+
+/**
+ * A DHCP server for internal host-only & NAT networks.
+ *
+ * Old notes:
+ *
+ * for server configuration needs, it's perhaps better to use (VM,slot) pair
+ * (vm-name, slot) <----> (MAC)
+ *
+ * but for client configuration, when server will have MACs at hand, it'd be
+ * easier to requiest options by MAC.
+ * (MAC) <----> (option-list)
+ *
+ * Doubts: What should be done if MAC changed for (vm-name, slot), when syncing should?
+ * XML: serialization of dependecy (DHCP options) - (VM,slot) shouldn't be done via MAC in
+ * the middle.
+ */
+class ATL_NO_VTABLE DHCPServer
+ : public DHCPServerWrap
+{
+public:
+ /** @name Constructors and destructors
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(DHCPServer)
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(VirtualBox *aVirtualBox, const com::Utf8Str &aName);
+ HRESULT init(VirtualBox *aVirtualBox, const settings::DHCPServer &data);
+ void uninit();
+ /** @} */
+
+ /** @name Public internal methods.
+ * @{ */
+ HRESULT i_saveSettings(settings::DHCPServer &data);
+ HRESULT i_removeConfig(DHCPConfig *pConfig, DHCPConfigScope_T enmScope);
+ /** @} */
+
+private:
+ /** @name IDHCPServer Properties
+ * @{ */
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource) RT_OVERRIDE;
+ HRESULT getEnabled(BOOL *aEnabled) RT_OVERRIDE;
+ HRESULT setEnabled(BOOL aEnabled) RT_OVERRIDE;
+ HRESULT getIPAddress(com::Utf8Str &aIPAddress) RT_OVERRIDE;
+ HRESULT getNetworkMask(com::Utf8Str &aNetworkMask) RT_OVERRIDE;
+ HRESULT getNetworkName(com::Utf8Str &aName) RT_OVERRIDE;
+ HRESULT getLowerIP(com::Utf8Str &aIPAddress) RT_OVERRIDE;
+ HRESULT getUpperIP(com::Utf8Str &aIPAddress) RT_OVERRIDE;
+ HRESULT setConfiguration(const com::Utf8Str &aIPAddress, const com::Utf8Str &aNetworkMask,
+ const com::Utf8Str &aFromIPAddress, const com::Utf8Str &aToIPAddress) RT_OVERRIDE;
+ HRESULT getGlobalConfig(ComPtr<IDHCPGlobalConfig> &aGlobalConfig) RT_OVERRIDE;
+ HRESULT getGroupConfigs(std::vector<ComPtr<IDHCPGroupConfig> > &aGroupConfigs) RT_OVERRIDE;
+ HRESULT getIndividualConfigs(std::vector<ComPtr<IDHCPIndividualConfig> > &aIndividualConfigs) ;
+ /** @} */
+
+ /** @name IDHCPServer Methods
+ * @{ */
+ HRESULT start(const com::Utf8Str &aTrunkName, const com::Utf8Str &aTrunkType) RT_OVERRIDE;
+ HRESULT stop() RT_OVERRIDE;
+ HRESULT restart() RT_OVERRIDE;
+ HRESULT findLeaseByMAC(const com::Utf8Str &aMac, LONG aType, com::Utf8Str &aAddress, com::Utf8Str &aState,
+ LONG64 *aIssued, LONG64 *aExpire) RT_OVERRIDE;
+ HRESULT getConfig(DHCPConfigScope_T aScope, const com::Utf8Str &aName, ULONG aSlot, BOOL aMayAdd,
+ ComPtr<IDHCPConfig> &aConfig) RT_OVERRIDE;
+ /** @} */
+
+ /** @name Helpers
+ * @{ */
+ HRESULT i_doSaveSettings();
+ HRESULT i_calcLeasesConfigAndLogFilenames(const com::Utf8Str &aNetwork) RT_NOEXCEPT;
+ HRESULT i_writeDhcpdConfig(const char *pszFilename, uint32_t uMACAddressVersion) RT_NOEXCEPT;
+
+ HRESULT i_vmNameToIdAndValidateSlot(const com::Utf8Str &aVmName, ULONG a_uSlot, com::Guid &idMachine);
+ HRESULT i_vmNameAndSlotToConfig(const com::Utf8Str &a_strVmName, ULONG a_uSlot, bool a_fCreateIfNeeded,
+ ComObjPtr<DHCPIndividualConfig> &a_rPtrConfig);
+ /** @} */
+
+ /** Private data */
+ struct Data;
+ /** Private data. */
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_DHCPServerImpl_h */
diff --git a/src/VBox/Main/include/DataStreamImpl.h b/src/VBox/Main/include/DataStreamImpl.h
new file mode 100644
index 00000000..1dad9b22
--- /dev/null
+++ b/src/VBox/Main/include/DataStreamImpl.h
@@ -0,0 +1,78 @@
+/* $Id: DataStreamImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DataStreamImpl_h
+#define MAIN_INCLUDED_DataStreamImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "DataStreamWrap.h"
+
+#include <iprt/circbuf.h>
+#include <iprt/semaphore.h>
+
+class ATL_NO_VTABLE DataStream
+ : public DataStreamWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(DataStream)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(unsigned long aBufferSize);
+ void uninit();
+
+ /// Feed data into the stream, used by the stream source.
+ /// Blocks if the internal buffer cannot take anything, otherwise
+ /// as much as the internal buffer can hold is taken (if smaller
+ /// than @a cbWrite). Modeled after RTStrmWriteEx.
+ int i_write(const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
+
+ /// Marks the end of the stream.
+ int i_close();
+
+private:
+ // wrapped IDataStream attributes and methods
+ HRESULT getReadSize(ULONG *aReadSize);
+ HRESULT read(ULONG aSize, ULONG aTimeoutMS, std::vector<BYTE> &aData);
+
+private:
+ /** The temporary buffer the conversion process writes into and the user reads from. */
+ PRTCIRCBUF m_pBuffer;
+ /** Event semaphore for waiting until data is available. */
+ RTSEMEVENT m_hSemEvtDataAvail;
+ /** Event semaphore for waiting until there is room in the buffer for writing. */
+ RTSEMEVENT m_hSemEvtBufSpcAvail;
+ /** Flag whether the end of stream flag is set. */
+ bool m_fEos;
+};
+
+#endif /* !MAIN_INCLUDED_DataStreamImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/DisplayImpl.h b/src/VBox/Main/include/DisplayImpl.h
new file mode 100644
index 00000000..052bf2f4
--- /dev/null
+++ b/src/VBox/Main/include/DisplayImpl.h
@@ -0,0 +1,562 @@
+/* $Id: DisplayImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DisplayImpl_h
+#define MAIN_INCLUDED_DisplayImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SchemaDefs.h"
+
+#include <iprt/semaphore.h>
+#include <VBox/vmm/pdmdrv.h>
+#include <VBoxVideo.h>
+#include <VBox/vmm/pdmifs.h>
+#include <VBox/VMMDev.h> /* For struct VMMDevDisplayDef - why is it in that file? */
+#include "DisplayWrap.h"
+
+#include "DisplaySourceBitmapWrap.h"
+#include "GuestScreenInfoWrap.h"
+
+
+class Console;
+
+typedef struct _DISPLAYFBINFO
+{
+ /* The following 3 fields (u32Offset, u32MaxFramebufferSize and u32InformationSize)
+ * are not used by the current HGSMI. They are needed for backward compatibility with
+ * pre-HGSMI additions.
+ */
+ uint32_t u32Offset;
+ uint32_t u32MaxFramebufferSize;
+ uint32_t u32InformationSize;
+
+ ComPtr<IFramebuffer> pFramebuffer;
+ com::Guid framebufferId;
+ ComPtr<IDisplaySourceBitmap> pSourceBitmap;
+ bool fDisabled;
+
+ uint32_t u32Caps;
+
+ struct
+ {
+ ComPtr<IDisplaySourceBitmap> pSourceBitmap;
+ uint8_t *pu8Address;
+ uint32_t cbLine;
+ } updateImage;
+
+ LONG xOrigin;
+ LONG yOrigin;
+
+ ULONG w;
+ ULONG h;
+
+ uint16_t u16BitsPerPixel;
+ uint8_t *pu8FramebufferVRAM;
+ uint32_t u32LineSize;
+
+ uint16_t flags;
+
+ VBOXVIDEOINFOHOSTEVENTS *pHostEvents;
+
+ /** The framebuffer has default format and must be updates immediately. */
+ bool fDefaultFormat;
+
+#ifdef VBOX_WITH_HGSMI
+ bool fVBVAEnabled;
+ bool fVBVAForceResize;
+ VBVAHOSTFLAGS RT_UNTRUSTED_VOLATILE_GUEST *pVBVAHostFlags;
+#endif /* VBOX_WITH_HGSMI */
+
+#ifdef VBOX_WITH_RECORDING
+ struct
+ {
+ ComPtr<IDisplaySourceBitmap> pSourceBitmap;
+ } Recording;
+#endif /* VBOX_WITH_RECORDING */
+
+ /** Description of the currently plugged monitor with preferred mode,
+ * a.k.a the last mode hint sent. */
+ struct VMMDevDisplayDef monitorDesc;
+} DISPLAYFBINFO;
+
+/* The legacy VBVA (VideoAccel) data.
+ *
+ * Backward compatibility with the Guest Additions 3.x or older.
+ */
+typedef struct VIDEOACCEL
+{
+ VBVAMEMORY *pVbvaMemory;
+ bool fVideoAccelEnabled;
+
+ uint8_t *pu8VbvaPartial;
+ uint32_t cbVbvaPartial;
+
+ /* Old Guest Additions (3.x and older) use both VMMDev and DevVGA refresh timer
+ * to process the VBVABUFFER memory. Therefore the legacy VBVA (VideoAccel) host
+ * code can be executed concurrently by VGA refresh timer and the guest VMMDev
+ * request in SMP VMs. The semaphore serialized this.
+ */
+ RTSEMXROADS hXRoadsVideoAccel;
+
+} VIDEOACCEL;
+
+class DisplayMouseInterface
+{
+public:
+ virtual ~DisplayMouseInterface() { }
+ virtual HRESULT i_getScreenResolution(ULONG cScreen, ULONG *pcx,
+ ULONG *pcy, ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin) = 0;
+ virtual void i_getFramebufferDimensions(int32_t *px1, int32_t *py1,
+ int32_t *px2, int32_t *py2) = 0;
+ virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved) = 0;
+ virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y, bool fOutOfRange) = 0;
+ virtual bool i_isInputMappingSet(void) = 0;
+};
+
+class VMMDev;
+
+class ATL_NO_VTABLE Display :
+ public DisplayWrap,
+ public DisplayMouseInterface
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(Display)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Console *aParent);
+ void uninit();
+ int i_registerSSM(PUVM pUVM);
+
+ // public methods only for internal purposes
+ unsigned i_getMonitorCount() { return mcMonitors; }
+ int i_handleDisplayResize(unsigned uScreenId, uint32_t bpp, void *pvVRAM,
+ uint32_t cbLine, uint32_t w, uint32_t h, uint16_t flags,
+ int32_t xOrigin, int32_t yOrigin, bool fVGAResize);
+ void i_handleDisplayUpdate(unsigned uScreenId, int x, int y, int w, int h);
+ void i_handleUpdateVMMDevSupportsGraphics(bool fSupportsGraphics);
+ void i_handleUpdateGuestVBVACapabilities(uint32_t fNewCapabilities);
+ void i_handleUpdateVBVAInputMapping(int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy);
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ int i_handleVHWACommandProcess(int enmCmd, bool fGuestCmd, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_GUEST *pCommand);
+#endif
+ int i_handle3DNotifyProcess(VBOX3DNOTIFY *p3DNotify);
+
+ int i_saveVisibleRegion(uint32_t cRect, PRTRECT pRect);
+ int i_handleSetVisibleRegion(uint32_t cRect, PRTRECT pRect);
+ int i_handleUpdateMonitorPositions(uint32_t cPositions, PCRTPOINT paPositions);
+ int i_handleQueryVisibleRegion(uint32_t *pcRects, PRTRECT paRects);
+
+ void i_VRDPConnectionEvent(bool fConnect);
+ void i_VideoAccelVRDP(bool fEnable, int c);
+
+ /* Legacy video acceleration requests coming from the VGA refresh timer. */
+ int VideoAccelEnableVGA(bool fEnable, VBVAMEMORY *pVbvaMemory);
+
+ /* Legacy video acceleration requests coming from VMMDev. */
+ int VideoAccelEnableVMMDev(bool fEnable, VBVAMEMORY *pVbvaMemory);
+ void VideoAccelFlushVMMDev(void);
+
+ void i_UpdateDeviceCursorCapabilities(void);
+
+#ifdef VBOX_WITH_RECORDING
+ int i_recordingInvalidate(void);
+ void i_recordingScreenChanged(unsigned uScreenId);
+#endif
+
+ void i_notifyPowerDown(void);
+
+ // DisplayMouseInterface methods
+ virtual HRESULT i_getScreenResolution(ULONG cScreen, ULONG *pcx,
+ ULONG *pcy, ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin)
+ {
+ return getScreenResolution(cScreen, pcx, pcy, pcBPP, pXOrigin, pYOrigin, NULL);
+ }
+ virtual void i_getFramebufferDimensions(int32_t *px1, int32_t *py1,
+ int32_t *px2, int32_t *py2);
+ virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved);
+ virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y, bool fOutOfRange);
+ virtual bool i_isInputMappingSet(void)
+ {
+ return cxInputMapping != 0 && cyInputMapping != 0;
+ }
+
+ static const PDMDRVREG DrvReg;
+
+private:
+ // Wrapped IDisplay properties
+ virtual HRESULT getGuestScreenLayout(std::vector<ComPtr<IGuestScreenInfo> > &aGuestScreenLayout);
+
+ // Wrapped IDisplay methods
+ virtual HRESULT getScreenResolution(ULONG aScreenId,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ ULONG *aBitsPerPixel,
+ LONG *aXOrigin,
+ LONG *aYOrigin,
+ GuestMonitorStatus_T *aGuestMonitorStatus);
+ virtual HRESULT attachFramebuffer(ULONG aScreenId,
+ const ComPtr<IFramebuffer> &aFramebuffer,
+ com::Guid &aId);
+ virtual HRESULT detachFramebuffer(ULONG aScreenId,
+ const com::Guid &aId);
+ virtual HRESULT queryFramebuffer(ULONG aScreenId,
+ ComPtr<IFramebuffer> &aFramebuffer);
+ virtual HRESULT setVideoModeHint(ULONG aDisplay,
+ BOOL aEnabled,
+ BOOL aChangeOrigin,
+ LONG aOriginX,
+ LONG aOriginY,
+ ULONG aWidth,
+ ULONG aHeight,
+ ULONG aBitsPerPixel,
+ BOOL aNotify);
+ virtual HRESULT getVideoModeHint(ULONG aDisplay,
+ BOOL *aEnabled,
+ BOOL *aChangeOrigin,
+ LONG *aOriginX,
+ LONG *aOriginY,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ ULONG *aBitsPerPixel);
+ virtual HRESULT setSeamlessMode(BOOL aEnabled);
+ virtual HRESULT takeScreenShot(ULONG aScreenId,
+ BYTE *aAddress,
+ ULONG aWidth,
+ ULONG aHeight,
+ BitmapFormat_T aBitmapFormat);
+ virtual HRESULT takeScreenShotToArray(ULONG aScreenId,
+ ULONG aWidth,
+ ULONG aHeight,
+ BitmapFormat_T aBitmapFormat,
+ std::vector<BYTE> &aScreenData);
+ virtual HRESULT drawToScreen(ULONG aScreenId,
+ BYTE *aAddress,
+ ULONG aX,
+ ULONG aY,
+ ULONG aWidth,
+ ULONG aHeight);
+ virtual HRESULT invalidateAndUpdate();
+ virtual HRESULT invalidateAndUpdateScreen(ULONG aScreenId);
+ virtual HRESULT completeVHWACommand(BYTE *aCommand);
+ virtual HRESULT viewportChanged(ULONG aScreenId,
+ ULONG aX,
+ ULONG aY,
+ ULONG aWidth,
+ ULONG aHeight);
+ virtual HRESULT querySourceBitmap(ULONG aScreenId,
+ ComPtr<IDisplaySourceBitmap> &aDisplaySourceBitmap);
+ virtual HRESULT notifyScaleFactorChange(ULONG aScreenId,
+ ULONG aScaleFactorWMultiplied,
+ ULONG aScaleFactorHMultiplied);
+ virtual HRESULT notifyHiDPIOutputPolicyChange(BOOL fUnscaledHiDPI);
+ virtual HRESULT setScreenLayout(ScreenLayoutMode_T aScreenLayoutMode,
+ const std::vector<ComPtr<IGuestScreenInfo> > &aGuestScreenInfo);
+ virtual HRESULT detachScreens(const std::vector<LONG> &aScreenIds);
+ virtual HRESULT createGuestScreenInfo(ULONG aDisplay,
+ GuestMonitorStatus_T aStatus,
+ BOOL aPrimary,
+ BOOL aChangeOrigin,
+ LONG aOriginX,
+ LONG aOriginY,
+ ULONG aWidth,
+ ULONG aHeight,
+ ULONG aBitsPerPixel,
+ ComPtr<IGuestScreenInfo> &aGuestScreenInfo);
+
+ // Wrapped IEventListener properties
+
+ // Wrapped IEventListener methods
+ virtual HRESULT handleEvent(const ComPtr<IEvent> &aEvent);
+
+ // other internal methods
+ HRESULT takeScreenShotWorker(ULONG aScreenId,
+ BYTE *aAddress,
+ ULONG aWidth,
+ ULONG aHeight,
+ BitmapFormat_T aBitmapFormat,
+ ULONG *pcbOut);
+ int processVBVAResize(PCVBVAINFOVIEW pView, PCVBVAINFOSCREEN pScreen, void *pvVRAM, bool fResetInputMapping);
+
+ static DECLCALLBACK(void*) i_drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) i_drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) i_drvDestruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) i_drvPowerOff(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(int) i_displayResizeCallback(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM,
+ uint32_t cbLine, uint32_t cx, uint32_t cy);
+ static DECLCALLBACK(void) i_displayUpdateCallback(PPDMIDISPLAYCONNECTOR pInterface,
+ uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
+ static DECLCALLBACK(void) i_displayRefreshCallback(PPDMIDISPLAYCONNECTOR pInterface);
+ static DECLCALLBACK(void) i_displayResetCallback(PPDMIDISPLAYCONNECTOR pInterface);
+ static DECLCALLBACK(void) i_displayLFBModeChangeCallback(PPDMIDISPLAYCONNECTOR pInterface, bool fEnabled);
+ static DECLCALLBACK(void) i_displayProcessAdapterDataCallback(PPDMIDISPLAYCONNECTOR pInterface,
+ void *pvVRAM, uint32_t u32VRAMSize);
+ static DECLCALLBACK(void) i_displayProcessDisplayDataCallback(PPDMIDISPLAYCONNECTOR pInterface,
+ void *pvVRAM, unsigned uScreenId);
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+ static DECLCALLBACK(int) i_displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, int enmCmd, bool fGuestCmd,
+ VBOXVHWACMD RT_UNTRUSTED_VOLATILE_GUEST *pCommand);
+#endif
+ static DECLCALLBACK(int) i_display3DNotifyProcess(PPDMIDISPLAYCONNECTOR pInterface,
+ VBOX3DNOTIFY *p3DNotify);
+
+#ifdef VBOX_WITH_HGSMI
+ static DECLCALLBACK(int) i_displayVBVAEnable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
+ VBVAHOSTFLAGS RT_UNTRUSTED_VOLATILE_GUEST *pHostFlags);
+ static DECLCALLBACK(void) i_displayVBVADisable(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId);
+ static DECLCALLBACK(void) i_displayVBVAUpdateBegin(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId);
+ static DECLCALLBACK(void) i_displayVBVAUpdateProcess(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId,
+ struct VBVACMDHDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd, size_t cbCmd);
+ static DECLCALLBACK(void) i_displayVBVAUpdateEnd(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, int32_t x, int32_t y,
+ uint32_t cx, uint32_t cy);
+ static DECLCALLBACK(int) i_displayVBVAResize(PPDMIDISPLAYCONNECTOR pInterface, PCVBVAINFOVIEW pView,
+ PCVBVAINFOSCREEN pScreen, void *pvVRAM,
+ bool fResetInputMapping);
+ static DECLCALLBACK(int) i_displayVBVAMousePointerShape(PPDMIDISPLAYCONNECTOR pInterface, bool fVisible, bool fAlpha,
+ uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy,
+ const void *pvShape);
+ static DECLCALLBACK(void) i_displayVBVAGuestCapabilityUpdate(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities);
+
+ static DECLCALLBACK(void) i_displayVBVAInputMappingUpdate(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin,
+ uint32_t cx, uint32_t cy);
+ static DECLCALLBACK(void) i_displayVBVAReportCursorPosition(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fFlags, uint32_t uScreen, uint32_t x, uint32_t y);
+#endif
+
+ static DECLCALLBACK(int) i_displaySSMSaveScreenshot(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, void *pvUser);
+ static DECLCALLBACK(int) i_displaySSMLoadScreenshot(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, void *pvUser,
+ uint32_t uVersion, uint32_t uPass);
+ static DECLCALLBACK(int) i_displaySSMSave(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, void *pvUser);
+ static DECLCALLBACK(int) i_displaySSMLoad(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, void *pvUser,
+ uint32_t uVersion, uint32_t uPass);
+
+ Console * const mParent;
+ /** Pointer to the associated display driver. */
+ struct DRVMAINDISPLAY *mpDrv;
+
+ unsigned mcMonitors;
+ /** Input mapping rectangle top left X relative to the first screen. */
+ int32_t xInputMappingOrigin;
+ /** Input mapping rectangle top left Y relative to the first screen. */
+ int32_t yInputMappingOrigin;
+ uint32_t cxInputMapping; /**< Input mapping rectangle width. */
+ uint32_t cyInputMapping; /**< Input mapping rectangle height. */
+ DISPLAYFBINFO maFramebuffers[SchemaDefs::MaxGuestMonitors];
+ /** Does the VMM device have the "supports graphics" capability set?
+ * Does not go into the saved state as it is refreshed on restore. */
+ bool mfVMMDevSupportsGraphics;
+ /** Mirror of the current guest VBVA capabilities. */
+ uint32_t mfGuestVBVACapabilities;
+ /** Mirror of the current host cursor capabilities. */
+ uint32_t mfHostCursorCapabilities;
+
+ bool mfSourceBitmapEnabled;
+ bool volatile fVGAResizing;
+
+ /** Are we in seamless mode? Not saved, as we exit seamless on saving. */
+ bool mfSeamlessEnabled;
+ /** Last set seamless visible region, number of rectangles. */
+ uint32_t mcRectVisibleRegion;
+ /** Last set seamless visible region, data. Freed on final clean-up. */
+ PRTRECT mpRectVisibleRegion;
+
+ bool mfVideoAccelVRDP;
+ uint32_t mfu32SupportedOrders;
+ /** Number of currently connected VRDP clients. */
+ int32_t volatile mcVRDPRefs;
+
+ /* The legacy VBVA data and methods. */
+ VIDEOACCEL mVideoAccelLegacy;
+
+ int i_VideoAccelEnable(bool fEnable, VBVAMEMORY *pVbvaMemory, PPDMIDISPLAYPORT pUpPort);
+ void i_VideoAccelFlush(PPDMIDISPLAYPORT pUpPort);
+ bool i_VideoAccelAllowed(void);
+
+ int i_videoAccelRefreshProcess(PPDMIDISPLAYPORT pUpPort);
+ int i_videoAccelEnable(bool fEnable, VBVAMEMORY *pVbvaMemory, PPDMIDISPLAYPORT pUpPort);
+ int i_videoAccelFlush(PPDMIDISPLAYPORT pUpPort);
+
+ /* Legacy pre-HGSMI handlers. */
+ void processAdapterData(void *pvVRAM, uint32_t u32VRAMSize);
+ void processDisplayData(void *pvVRAM, unsigned uScreenId);
+
+ /** Serializes access to mVideoAccelLegacy and mfVideoAccelVRDP, etc between VRDP and Display. */
+ RTCRITSECT mVideoAccelLock;
+
+#ifdef VBOX_WITH_RECORDING
+ /* Serializes access to video recording source bitmaps. */
+ RTCRITSECT mVideoRecLock;
+ /** Array which defines which screens are being enabled for recording. */
+ bool maRecordingEnabled[SchemaDefs::MaxGuestMonitors];
+#endif
+
+public:
+
+ static DECLCALLBACK(int) i_displayTakeScreenshotEMT(Display *pDisplay, ULONG aScreenId, uint8_t **ppbData, size_t *pcbData,
+ uint32_t *pcx, uint32_t *pcy, bool *pfMemFree);
+
+private:
+ static DECLCALLBACK(int) i_InvalidateAndUpdateEMT(Display *pDisplay, unsigned uId, bool fUpdateAll);
+ static DECLCALLBACK(int) i_drawToScreenEMT(Display *pDisplay, ULONG aScreenId, BYTE *address, ULONG x, ULONG y,
+ ULONG width, ULONG height);
+
+ void i_updateGuestGraphicsFacility(void);
+
+#ifdef VBOX_WITH_HGSMI
+ volatile uint32_t mu32UpdateVBVAFlags;
+#endif
+
+private:
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(Display); /* Shuts up MSC warning C4625. */
+};
+
+/* The legacy VBVA helpers. */
+int videoAccelConstruct(VIDEOACCEL *pVideoAccel);
+void videoAccelDestroy(VIDEOACCEL *pVideoAccel);
+void i_vbvaSetMemoryFlags(VBVAMEMORY *pVbvaMemory,
+ bool fVideoAccelEnabled,
+ bool fVideoAccelVRDP,
+ uint32_t fu32SupportedOrders,
+ DISPLAYFBINFO *paFBInfos,
+ unsigned cFBInfos);
+int videoAccelEnterVGA(VIDEOACCEL *pVideoAccel);
+void videoAccelLeaveVGA(VIDEOACCEL *pVideoAccel);
+int videoAccelEnterVMMDev(VIDEOACCEL *pVideoAccel);
+void videoAccelLeaveVMMDev(VIDEOACCEL *pVideoAccel);
+
+
+/* helper function, code in DisplayResampleImage.cpp */
+void BitmapScale32(uint8_t *dst, int dstW, int dstH,
+ const uint8_t *src, int iDeltaLine, int srcW, int srcH);
+
+/* helper function, code in DisplayPNGUtul.cpp */
+int DisplayMakePNG(uint8_t *pbData, uint32_t cx, uint32_t cy,
+ uint8_t **ppu8PNG, uint32_t *pcbPNG, uint32_t *pcxPNG, uint32_t *pcyPNG,
+ uint8_t fLimitSize);
+
+class ATL_NO_VTABLE DisplaySourceBitmap:
+ public DisplaySourceBitmapWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(DisplaySourceBitmap)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /* Public initializer/uninitializer for internal purposes only. */
+ HRESULT init(ComObjPtr<Display> pDisplay, unsigned uScreenId, DISPLAYFBINFO *pFBInfo);
+ void uninit();
+
+ bool i_usesVRAM(void) { return m.pu8Allocated == NULL; }
+
+private:
+ // wrapped IDisplaySourceBitmap properties
+ virtual HRESULT getScreenId(ULONG *aScreenId);
+
+ // wrapped IDisplaySourceBitmap methods
+ virtual HRESULT queryBitmapInfo(BYTE **aAddress,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ ULONG *aBitsPerPixel,
+ ULONG *aBytesPerLine,
+ BitmapFormat_T *aBitmapFormat);
+
+ int initSourceBitmap(unsigned aScreenId, DISPLAYFBINFO *pFBInfo);
+
+ struct Data
+ {
+ ComObjPtr<Display> pDisplay;
+ unsigned uScreenId;
+ DISPLAYFBINFO *pFBInfo;
+
+ uint8_t *pu8Allocated;
+
+ uint8_t *pu8Address;
+ ULONG ulWidth;
+ ULONG ulHeight;
+ ULONG ulBitsPerPixel;
+ ULONG ulBytesPerLine;
+ BitmapFormat_T bitmapFormat;
+ };
+
+ Data m;
+};
+
+class ATL_NO_VTABLE GuestScreenInfo:
+ public GuestScreenInfoWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(GuestScreenInfo)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /* Public initializer/uninitializer for internal purposes only. */
+ HRESULT init(ULONG aDisplay,
+ GuestMonitorStatus_T aGuestMonitorStatus,
+ BOOL aPrimary,
+ BOOL aChangeOrigin,
+ LONG aOriginX,
+ LONG aOriginY,
+ ULONG aWidth,
+ ULONG aHeight,
+ ULONG aBitsPerPixel);
+ void uninit();
+
+private:
+ // wrapped IGuestScreenInfo properties
+ virtual HRESULT getScreenId(ULONG *aScreenId);
+ virtual HRESULT getGuestMonitorStatus(GuestMonitorStatus_T *aGuestMonitorStatus);
+ virtual HRESULT getPrimary(BOOL *aPrimary);
+ virtual HRESULT getOrigin(BOOL *aOrigin);
+ virtual HRESULT getOriginX(LONG *aOriginX);
+ virtual HRESULT getOriginY(LONG *aOriginY);
+ virtual HRESULT getWidth(ULONG *aWidth);
+ virtual HRESULT getHeight(ULONG *aHeight);
+ virtual HRESULT getBitsPerPixel(ULONG *aBitsPerPixel);
+ virtual HRESULT getExtendedInfo(com::Utf8Str &aExtendedInfo);
+
+ ULONG mScreenId;
+ GuestMonitorStatus_T mGuestMonitorStatus;
+ BOOL mPrimary;
+ BOOL mOrigin;
+ LONG mOriginX;
+ LONG mOriginY;
+ ULONG mWidth;
+ ULONG mHeight;
+ ULONG mBitsPerPixel;
+};
+
+#endif /* !MAIN_INCLUDED_DisplayImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/DisplayUtils.h b/src/VBox/Main/include/DisplayUtils.h
new file mode 100644
index 00000000..90a6f1e8
--- /dev/null
+++ b/src/VBox/Main/include/DisplayUtils.h
@@ -0,0 +1,57 @@
+/* $Id: DisplayUtils.h $ */
+/** @file
+ * Display helper declarations
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DisplayUtils_h
+#define MAIN_INCLUDED_DisplayUtils_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VBox/com/string.h"
+
+#include "CryptoUtils.h"
+
+using namespace com;
+
+#define sSSMDisplayScreenshotVer 0x00010001
+#define sSSMDisplayVer 0x00010001
+#define sSSMDisplayVer2 0x00010002
+#define sSSMDisplayVer3 0x00010003
+#define sSSMDisplayVer4 0x00010004
+#define sSSMDisplayVer5 0x00010005
+
+int readSavedGuestScreenInfo(SsmStream &ssmStream, const Utf8Str &strStateFilePath,
+ uint32_t u32ScreenId, uint32_t *pu32OriginX, uint32_t *pu32OriginY,
+ uint32_t *pu32Width, uint32_t *pu32Height, uint16_t *pu16Flags);
+
+int readSavedDisplayScreenshot(SsmStream &ssmStream, const Utf8Str &strStateFilePath,
+ uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData,
+ uint32_t *pu32Width, uint32_t *pu32Height);
+void freeSavedDisplayScreenshot(uint8_t *pu8Data);
+
+#endif /* !MAIN_INCLUDED_DisplayUtils_h */
+
diff --git a/src/VBox/Main/include/DrvAudioRec.h b/src/VBox/Main/include/DrvAudioRec.h
new file mode 100644
index 00000000..a5d5c5fd
--- /dev/null
+++ b/src/VBox/Main/include/DrvAudioRec.h
@@ -0,0 +1,79 @@
+/* $Id: DrvAudioRec.h $ */
+/** @file
+ * VirtualBox driver interface video recording audio backend.
+ */
+
+/*
+ * Copyright (C) 2017-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DrvAudioRec_h
+#define MAIN_INCLUDED_DrvAudioRec_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/ptr.h>
+#include <VBox/settings.h>
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/vmm/pdmifs.h>
+
+#include "AudioDriver.h"
+#include "Recording.h"
+
+using namespace com;
+
+class Console;
+
+class AudioVideoRec : public AudioDriver
+{
+
+public:
+
+ AudioVideoRec(Console *pConsole);
+ virtual ~AudioVideoRec(void);
+
+public:
+
+ static const PDMDRVREG DrvReg;
+
+public:
+
+ int applyConfiguration(const settings::RecordingSettings &Settings);
+
+public:
+
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvPowerOff(PPDMDRVINS pDrvIns);
+
+private:
+
+ virtual int configureDriver(PCFGMNODE pLunCfg, PCVMMR3VTABLE pVMM) RT_OVERRIDE;
+
+ /** Pointer to the associated video recording audio driver. */
+ struct DRVAUDIORECORDING *mpDrv;
+ /** Recording settings used for configuring the driver. */
+ struct settings::RecordingSettings mSettings;
+};
+
+#endif /* !MAIN_INCLUDED_DrvAudioRec_h */
+
diff --git a/src/VBox/Main/include/DrvAudioVRDE.h b/src/VBox/Main/include/DrvAudioVRDE.h
new file mode 100644
index 00000000..c070c7cf
--- /dev/null
+++ b/src/VBox/Main/include/DrvAudioVRDE.h
@@ -0,0 +1,87 @@
+/* $Id: DrvAudioVRDE.h $ */
+/** @file
+ * VirtualBox driver interface to VRDE backend.
+ */
+
+/*
+ * Copyright (C) 2014-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_DrvAudioVRDE_h
+#define MAIN_INCLUDED_DrvAudioVRDE_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/ptr.h>
+#include <VBox/com/string.h>
+
+#include <VBox/RemoteDesktop/VRDE.h>
+
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/vmm/pdmifs.h>
+
+#include "AudioDriver.h"
+
+using namespace com;
+
+class Console;
+
+class AudioVRDE : public AudioDriver
+{
+
+public:
+
+ AudioVRDE(Console *pConsole);
+ virtual ~AudioVRDE(void);
+
+public:
+
+ static const PDMDRVREG DrvReg;
+
+public:
+
+ void onVRDEClientConnect(uint32_t uClientID);
+ void onVRDEClientDisconnect(uint32_t uClientID);
+ int onVRDEControl(bool fEnable, uint32_t uFlags);
+ int onVRDEInputBegin(void *pvContext, PVRDEAUDIOINBEGIN pVRDEAudioBegin);
+ int onVRDEInputData(void *pvContext, const void *pvData, uint32_t cbData);
+ int onVRDEInputEnd(void *pvContext);
+ int onVRDEInputIntercept(bool fIntercept);
+
+public:
+
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvPowerOff(PPDMDRVINS pDrvIns);
+
+private:
+
+ virtual int configureDriver(PCFGMNODE pLunCfg, PCVMMR3VTABLE pVMM) RT_OVERRIDE;
+
+ /** Pointer to the associated VRDE audio driver. */
+ struct DRVAUDIOVRDE *mpDrv;
+ /** Protects accesses to mpDrv from racing driver destruction. */
+ RTCRITSECT mCritSect;
+};
+
+#endif /* !MAIN_INCLUDED_DrvAudioVRDE_h */
+
diff --git a/src/VBox/Main/include/EBMLWriter.h b/src/VBox/Main/include/EBMLWriter.h
new file mode 100644
index 00000000..eda3f4b1
--- /dev/null
+++ b/src/VBox/Main/include/EBMLWriter.h
@@ -0,0 +1,135 @@
+/* $Id: EBMLWriter.h $ */
+/** @file
+ * EBMLWriter.h - EBML writer.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_EBMLWriter_h
+#define MAIN_INCLUDED_EBMLWriter_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <stack>
+
+#include <iprt/critsect.h>
+#include <iprt/file.h>
+
+#include <VBox/com/string.h>
+
+
+/** No flags set. */
+#define VBOX_EBMLWRITER_FLAG_NONE 0
+/** The file handle was inherited. */
+#define VBOX_EBMLWRITER_FLAG_HANDLE_INHERITED RT_BIT(0)
+
+class EBMLWriter
+{
+public:
+ typedef uint32_t EbmlClassId;
+
+private:
+
+ struct EbmlSubElement
+ {
+ uint64_t offset;
+ EbmlClassId classId;
+ EbmlSubElement(uint64_t offs, EbmlClassId cid) : offset(offs), classId(cid) {}
+ };
+
+ /** Stack of EBML sub elements. */
+ std::stack<EbmlSubElement> m_Elements;
+ /** The file's handle. */
+ RTFILE m_hFile;
+ /** The file's name (path). */
+ com::Utf8Str m_strFile;
+ /** Flags. */
+ uint32_t m_fFlags;
+
+public:
+
+ EBMLWriter(void)
+ : m_hFile(NIL_RTFILE)
+ , m_fFlags(VBOX_EBMLWRITER_FLAG_NONE) { }
+
+ virtual ~EBMLWriter(void) { close(); }
+
+public:
+
+ int createEx(const char *a_pszFile, PRTFILE phFile);
+
+ int create(const char *a_pszFile, uint64_t fOpen);
+
+ void close(void);
+
+ /** Returns the file name. */
+ const com::Utf8Str& getFileName(void) { return m_strFile; }
+
+ /** Returns file size. */
+ uint64_t getFileSize(void) { return RTFileTell(m_hFile); }
+
+ /** Get reference to file descriptor */
+ inline const RTFILE &getFile(void) { return m_hFile; }
+
+ /** Returns available space on storage. */
+ uint64_t getAvailableSpace(void);
+
+ /**
+ * Returns whether the file is open or not.
+ *
+ * @returns True if open, false if not.
+ */
+ bool isOpen(void) { return RTFileIsValid(m_hFile); }
+
+public:
+
+ EBMLWriter &subStart(EbmlClassId classId);
+
+ EBMLWriter &subEnd(EbmlClassId classId);
+
+ EBMLWriter &serializeString(EbmlClassId classId, const char *str);
+
+ EBMLWriter &serializeUnsignedInteger(EbmlClassId classId, uint64_t parm, size_t size = 0);
+
+ EBMLWriter &serializeFloat(EbmlClassId classId, float value);
+
+ EBMLWriter &serializeData(EbmlClassId classId, const void *pvData, size_t cbData);
+
+ int write(const void *data, size_t size);
+
+ void writeUnsignedInteger(uint64_t value, size_t size = sizeof(uint64_t));
+
+ void writeClassId(EbmlClassId parm);
+
+ void writeSize(uint64_t parm);
+
+ static inline size_t getSizeOfUInt(uint64_t arg);
+
+private:
+
+ void operator=(const EBMLWriter &);
+};
+
+#endif /* !MAIN_INCLUDED_EBMLWriter_h */
+
diff --git a/src/VBox/Main/include/EBML_MKV.h b/src/VBox/Main/include/EBML_MKV.h
new file mode 100644
index 00000000..75d87c0d
--- /dev/null
+++ b/src/VBox/Main/include/EBML_MKV.h
@@ -0,0 +1,106 @@
+/* $Id: EBML_MKV.h $ */
+/** @file
+ * EbmlMkvIDs.h - Matroska EBML Class IDs.
+ */
+
+/*
+ * Copyright (C) 2017-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_EBML_MKV_h
+#define MAIN_INCLUDED_EBML_MKV_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+/** Matroska EBML Class IDs supported by WebM.
+ *
+ * Keep the structure clean and group elements where it makes sense
+ * for easier reading / lookup. */
+enum MkvElem
+{
+ MkvElem_EBML = 0x1A45DFA3,
+ MkvElem_EBMLVersion = 0x4286,
+ MkvElem_EBMLReadVersion = 0x42F7,
+ MkvElem_EBMLMaxIDLength = 0x42F2,
+ MkvElem_EBMLMaxSizeLength = 0x42F3,
+
+ MkvElem_DocType = 0x4282,
+ MkvElem_DocTypeVersion = 0x4287,
+ MkvElem_DocTypeReadVersion = 0x4285,
+
+ MkvElem_Segment = 0x18538067,
+ MkvElem_Segment_Duration = 0x4489,
+
+ MkvElem_SeekHead = 0x114D9B74,
+ MkvElem_Seek = 0x4DBB,
+ MkvElem_SeekID = 0x53AB,
+ MkvElem_SeekPosition = 0x53AC,
+
+ MkvElem_Info = 0x1549A966,
+ MkvElem_TimecodeScale = 0x2AD7B1,
+ MkvElem_MuxingApp = 0x4D80,
+ MkvElem_WritingApp = 0x5741,
+
+ MkvElem_Tracks = 0x1654AE6B,
+ MkvElem_TrackEntry = 0xAE,
+ MkvElem_TrackNumber = 0xD7,
+ MkvElem_TrackUID = 0x73C5,
+ MkvElem_TrackType = 0x83,
+
+ MkvElem_Language = 0x22B59C,
+
+ MkvElem_FlagLacing = 0x9C,
+
+ MkvElem_Cluster = 0x1F43B675,
+ MkvElem_Timecode = 0xE7,
+
+ MkvElem_SimpleBlock = 0xA3,
+
+ MkvElem_SeekPreRoll = 0x56BB,
+
+ MkvElem_CodecID = 0x86,
+ MkvElem_CodecDelay = 0x56AA,
+ MkvElem_CodecPrivate = 0x63A2,
+ MkvElem_CodecName = 0x258688,
+
+ MkvElem_Video = 0xE0,
+ MkvElem_PixelWidth = 0xB0,
+ MkvElem_PixelHeight = 0xBA,
+ MkvElem_FrameRate = 0x2383E3,
+
+ MkvElem_Audio = 0xE1,
+ MkvElem_SamplingFrequency = 0xB5,
+ MkvElem_OutputSamplingFrequency = 0x78B5,
+ MkvElem_Channels = 0x9F,
+ MkvElem_BitDepth = 0x6264,
+
+ MkvElem_Cues = 0x1C53BB6B,
+ MkvElem_CuePoint = 0xBB,
+ MkvElem_CueTime = 0xB3,
+ MkvElem_CueTrackPositions = 0xB7,
+ MkvElem_CueTrack = 0xF7,
+ MkvElem_CueClusterPosition = 0xF1
+};
+
+#endif /* !MAIN_INCLUDED_EBML_MKV_h */
+
diff --git a/src/VBox/Main/include/EmulatedUSBImpl.h b/src/VBox/Main/include/EmulatedUSBImpl.h
new file mode 100644
index 00000000..7e1ae3e7
--- /dev/null
+++ b/src/VBox/Main/include/EmulatedUSBImpl.h
@@ -0,0 +1,103 @@
+/* $Id: EmulatedUSBImpl.h $ */
+/** @file
+ * Emulated USB devices manager.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_EmulatedUSBImpl_h
+#define MAIN_INCLUDED_EmulatedUSBImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "EmulatedUSBWrap.h"
+
+#include <VBox/vrdpusb.h>
+
+class Console;
+class EUSBWEBCAM;
+
+typedef std::map<Utf8Str, EUSBWEBCAM *> WebcamsMap;
+
+class ATL_NO_VTABLE EmulatedUSB :
+ public EmulatedUSBWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(EmulatedUSB)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /* Public initializer/uninitializer for internal purposes only. */
+ HRESULT init(ComObjPtr<Console> pConsole);
+ void uninit();
+
+ /* Public method for internal use. */
+ static DECLCALLBACK(int) i_eusbCallback(void *pv, const char *pszId, uint32_t iEvent,
+ const void *pvData, uint32_t cbData);
+
+ PEMULATEDUSBIF i_getEmulatedUsbIf();
+
+ HRESULT i_webcamAttachInternal(const com::Utf8Str &aPath,
+ const com::Utf8Str &aSettings,
+ const char *pszDriver,
+ void *pvObject);
+ HRESULT i_webcamDetachInternal(const com::Utf8Str &aPath);
+
+private:
+
+ static DECLCALLBACK(int) eusbCallbackEMT(EmulatedUSB *pThis, char *pszId, uint32_t iEvent,
+ void *pvData, uint32_t cbData);
+
+ static DECLCALLBACK(int) i_QueryEmulatedUsbDataById(void *pvUser, const char *pszId, void **ppvEmUsbCb, void **ppvEmUsbCbData, void **ppvObject);
+
+ HRESULT webcamPathFromId(com::Utf8Str *pPath, const char *pszId);
+
+ // wrapped IEmulatedUSB properties
+ virtual HRESULT getWebcams(std::vector<com::Utf8Str> &aWebcams);
+
+ // wrapped IEmulatedUSB methods
+ virtual HRESULT webcamAttach(const com::Utf8Str &aPath,
+ const com::Utf8Str &aSettings);
+ virtual HRESULT webcamDetach(const com::Utf8Str &aPath);
+
+ /* Data. */
+ struct Data
+ {
+ Data()
+ {
+ }
+
+ ComObjPtr<Console> pConsole;
+ WebcamsMap webcams;
+ };
+
+ Data m;
+ EMULATEDUSBIF mEmUsbIf;
+};
+
+#endif /* !MAIN_INCLUDED_EmulatedUSBImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/EventImpl.h b/src/VBox/Main/include/EventImpl.h
new file mode 100644
index 00000000..ee196402
--- /dev/null
+++ b/src/VBox/Main/include/EventImpl.h
@@ -0,0 +1,188 @@
+/* $Id: EventImpl.h $ */
+/** @file
+ * VirtualBox COM IEvent implementation
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_EventImpl_h
+#define MAIN_INCLUDED_EventImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "EventWrap.h"
+#include "EventSourceWrap.h"
+#include "VetoEventWrap.h"
+
+
+class ATL_NO_VTABLE VBoxEvent
+ : public EventWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(VBoxEvent)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(IEventSource *aSource, VBoxEventType_T aType, BOOL aWaitable);
+ void uninit();
+
+private:
+ // wrapped IEvent properties
+ HRESULT getType(VBoxEventType_T *aType);
+ HRESULT getSource(ComPtr<IEventSource> &aSource);
+ HRESULT getWaitable(BOOL *aWaitable);
+
+ // wrapped IEvent methods
+ HRESULT setProcessed();
+ HRESULT waitProcessed(LONG aTimeout, BOOL *aResult);
+
+ struct Data;
+ Data* m;
+};
+
+
+class ATL_NO_VTABLE VBoxVetoEvent
+ : public VetoEventWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(VBoxVetoEvent)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(IEventSource *aSource, VBoxEventType_T aType);
+ void uninit();
+
+private:
+ // wrapped IEvent properties
+ HRESULT getType(VBoxEventType_T *aType);
+ HRESULT getSource(ComPtr<IEventSource> &aSource);
+ HRESULT getWaitable(BOOL *aWaitable);
+
+ // wrapped IEvent methods
+ HRESULT setProcessed();
+ HRESULT waitProcessed(LONG aTimeout, BOOL *aResult);
+
+ // wrapped IVetoEvent methods
+ HRESULT addVeto(const com::Utf8Str &aReason);
+ HRESULT isVetoed(BOOL *aResult);
+ HRESULT getVetos(std::vector<com::Utf8Str> &aResult);
+ HRESULT addApproval(const com::Utf8Str &aReason);
+ HRESULT isApproved(BOOL *aResult);
+ HRESULT getApprovals(std::vector<com::Utf8Str> &aResult);
+
+ struct Data;
+ Data* m;
+};
+
+class ATL_NO_VTABLE EventSource :
+ public EventSourceWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(EventSource)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init();
+ void uninit();
+
+private:
+ // wrapped IEventSource methods
+ HRESULT createListener(ComPtr<IEventListener> &aListener);
+ HRESULT createAggregator(const std::vector<ComPtr<IEventSource> > &aSubordinates,
+ ComPtr<IEventSource> &aResult);
+ HRESULT registerListener(const ComPtr<IEventListener> &aListener,
+ const std::vector<VBoxEventType_T> &aInteresting,
+ BOOL aActive);
+ HRESULT unregisterListener(const ComPtr<IEventListener> &aListener);
+ HRESULT fireEvent(const ComPtr<IEvent> &aEvent,
+ LONG aTimeout,
+ BOOL *aResult);
+ HRESULT getEvent(const ComPtr<IEventListener> &aListener,
+ LONG aTimeout,
+ ComPtr<IEvent> &aEvent);
+ HRESULT eventProcessed(const ComPtr<IEventListener> &aListener,
+ const ComPtr<IEvent> &aEvent);
+
+
+ struct Data;
+ Data *m;
+
+ friend class ListenerRecord;
+};
+
+class VBoxEventDesc
+{
+public:
+ VBoxEventDesc() : mEvent(0), mEventSource(0)
+ {}
+
+ VBoxEventDesc(IEvent *aEvent, IEventSource *aSource)
+ : mEvent(aEvent), mEventSource(aSource)
+ {}
+
+ ~VBoxEventDesc()
+ {}
+
+ void init(IEvent *aEvent, IEventSource *aSource)
+ {
+ mEvent = aEvent;
+ mEventSource = aSource;
+ }
+
+ void uninit()
+ {
+ mEvent.setNull();
+ mEventSource.setNull();
+ }
+
+ void getEvent(IEvent **aEvent)
+ {
+ mEvent.queryInterfaceTo(aEvent);
+ }
+
+ BOOL fire(LONG aTimeout)
+ {
+ if (mEventSource && mEvent)
+ {
+ BOOL fDelivered = FALSE;
+ HRESULT hrc = mEventSource->FireEvent(mEvent, aTimeout, &fDelivered);
+ AssertComRCReturn(hrc, FALSE);
+ return fDelivered;
+ }
+ return FALSE;
+ }
+
+private:
+ ComPtr<IEvent> mEvent;
+ ComPtr<IEventSource> mEventSource;
+};
+
+
+#endif /* !MAIN_INCLUDED_EventImpl_h */
diff --git a/src/VBox/Main/include/ExtPackManagerImpl.h b/src/VBox/Main/include/ExtPackManagerImpl.h
new file mode 100644
index 00000000..9fde4043
--- /dev/null
+++ b/src/VBox/Main/include/ExtPackManagerImpl.h
@@ -0,0 +1,322 @@
+/* $Id: ExtPackManagerImpl.h $ */
+/** @file
+ * VirtualBox Main - interface for Extension Packs, VBoxSVC & VBoxC.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ExtPackManagerImpl_h
+#define MAIN_INCLUDED_ExtPackManagerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include <VBox/ExtPack/ExtPack.h>
+#include "ExtPackWrap.h"
+#include "ExtPackFileWrap.h"
+#include "ExtPackManagerWrap.h"
+#include <iprt/fs.h>
+
+
+/** The name of the oracle extension back. */
+#define ORACLE_PUEL_EXTPACK_NAME "Oracle VM VirtualBox Extension Pack"
+
+
+#ifndef VBOX_COM_INPROC
+/**
+ * An extension pack file.
+ */
+class ATL_NO_VTABLE ExtPackFile :
+ public ExtPackFileWrap
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(ExtPackFile)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ HRESULT initWithFile(const char *a_pszFile, const char *a_pszDigest, class ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox);
+ void uninit();
+ /** @} */
+
+private:
+ /** @name Misc init helpers
+ * @{ */
+ HRESULT initFailed(const char *a_pszWhyFmt, ...);
+ /** @} */
+
+private:
+
+ // wrapped IExtPackFile properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT getVersion(com::Utf8Str &aVersion);
+ HRESULT getRevision(ULONG *aRevision);
+ HRESULT getEdition(com::Utf8Str &aEdition);
+ HRESULT getVRDEModule(com::Utf8Str &aVRDEModule);
+ HRESULT getCryptoModule(com::Utf8Str &aCryptoModule);
+ HRESULT getPlugIns(std::vector<ComPtr<IExtPackPlugIn> > &aPlugIns);
+ HRESULT getUsable(BOOL *aUsable);
+ HRESULT getWhyUnusable(com::Utf8Str &aWhyUnusable);
+ HRESULT getShowLicense(BOOL *aShowLicense);
+ HRESULT getLicense(com::Utf8Str &aLicense);
+ HRESULT getFilePath(com::Utf8Str &aFilePath);
+
+ // wrapped IExtPackFile methods
+ HRESULT queryLicense(const com::Utf8Str &aPreferredLocale,
+ const com::Utf8Str &aPreferredLanguage,
+ const com::Utf8Str &aFormat,
+ com::Utf8Str &aLicenseText);
+ HRESULT install(BOOL aReplace,
+ const com::Utf8Str &aDisplayInfo,
+ ComPtr<IProgress> &aProgess);
+
+ struct Data;
+ /** Pointer to the private instance. */
+ Data *m;
+
+ friend class ExtPackManager;
+ friend class ExtPackInstallTask;
+};
+#endif /* !VBOX_COM_INPROC */
+
+
+/**
+ * An installed extension pack.
+ */
+class ATL_NO_VTABLE ExtPack :
+ public ExtPackWrap
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(ExtPack)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ HRESULT initWithDir(VirtualBox *a_pVirtualBox, VBOXEXTPACKCTX a_enmContext, const char *a_pszName, const char *a_pszDir);
+ void uninit();
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+ /** @} */
+
+ /** @name Internal interfaces used by ExtPackManager.
+ * @{ */
+#ifndef VBOX_COM_INPROC
+ bool i_callInstalledHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock, PRTERRINFO pErrInfo);
+ HRESULT i_callUninstallHookAndClose(IVirtualBox *a_pVirtualBox, bool a_fForcedRemoval);
+ bool i_callVirtualBoxReadyHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock);
+#endif
+#ifdef VBOX_COM_INPROC
+ bool i_callConsoleReadyHook(IConsole *a_pConsole, AutoWriteLock *a_pLock);
+#endif
+#ifndef VBOX_COM_INPROC
+ bool i_callVmCreatedHook(IVirtualBox *a_pVirtualBox, IMachine *a_pMachine, AutoWriteLock *a_pLock);
+#endif
+#ifdef VBOX_COM_INPROC
+ bool i_callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM, PCVMMR3VTABLE a_pVMM,
+ AutoWriteLock *a_pLock, int *a_pvrc);
+ bool i_callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM, PCVMMR3VTABLE a_pVMM, AutoWriteLock *a_pLock, int *a_pvrc);
+ bool i_callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM, PCVMMR3VTABLE a_pVMM, AutoWriteLock *a_pLock);
+#endif
+ HRESULT i_checkVrde(void);
+ HRESULT i_checkCrypto(void);
+ HRESULT i_getVrdpLibraryName(Utf8Str *a_pstrVrdeLibrary);
+ HRESULT i_getCryptoLibraryName(Utf8Str *a_pstrCryptoLibrary);
+ HRESULT i_getLibraryName(const char *a_pszModuleName, Utf8Str *a_pstrLibrary);
+ bool i_wantsToBeDefaultVrde(void) const;
+ bool i_wantsToBeDefaultCrypto(void) const;
+ HRESULT i_refresh(bool *pfCanDelete);
+#ifndef VBOX_COM_INPROC
+ bool i_areThereCloudProviderUninstallVetos();
+ void i_notifyCloudProviderManager();
+#endif
+ /** @} */
+
+protected:
+ /** @name Internal helper methods.
+ * @{ */
+ void i_probeAndLoad(void);
+ bool i_findModule(const char *a_pszName, const char *a_pszExt, VBOXEXTPACKMODKIND a_enmKind,
+ Utf8Str *a_ppStrFound, bool *a_pfNative, PRTFSOBJINFO a_pObjInfo) const;
+ static bool i_objinfoIsEqual(PCRTFSOBJINFO pObjInfo1, PCRTFSOBJINFO pObjInfo2);
+ /** @} */
+
+ /** @name Extension Pack Helpers
+ * @{ */
+ static DECLCALLBACK(int) i_hlpFindModule(PCVBOXEXTPACKHLP pHlp, const char *pszName, const char *pszExt,
+ VBOXEXTPACKMODKIND enmKind, char *pszFound, size_t cbFound, bool *pfNative);
+ static DECLCALLBACK(int) i_hlpGetFilePath(PCVBOXEXTPACKHLP pHlp, const char *pszFilename, char *pszPath, size_t cbPath);
+ static DECLCALLBACK(VBOXEXTPACKCTX) i_hlpGetContext(PCVBOXEXTPACKHLP pHlp);
+ static DECLCALLBACK(int) i_hlpLoadHGCMService(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IConsole) *pConsole, const char *pszServiceLibrary, const char *pszServiceName);
+ static DECLCALLBACK(int) i_hlpLoadVDPlugin(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox, const char *pszPluginLibrary);
+ static DECLCALLBACK(int) i_hlpUnloadVDPlugin(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox, const char *pszPluginLibrary);
+ static DECLCALLBACK(uint32_t) i_hlpCreateProgress(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IUnknown) *pInitiator,
+ const char *pcszDescription, uint32_t cOperations,
+ uint32_t uTotalOperationsWeight, const char *pcszFirstOperationDescription,
+ uint32_t uFirstOperationWeight, VBOXEXTPACK_IF_CS(IProgress) **ppProgressOut);
+ static DECLCALLBACK(uint32_t) i_hlpGetCanceledProgress(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IProgress) *pProgress,
+ bool *pfCanceled);
+ static DECLCALLBACK(uint32_t) i_hlpUpdateProgress(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IProgress) *pProgress,
+ uint32_t uPercent);
+ static DECLCALLBACK(uint32_t) i_hlpNextOperationProgress(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IProgress) *pProgress,
+ const char *pcszNextOperationDescription,
+ uint32_t uNextOperationWeight);
+ static DECLCALLBACK(uint32_t) i_hlpWaitOtherProgress(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IProgress) *pProgress,
+ VBOXEXTPACK_IF_CS(IProgress) *pProgressOther,
+ uint32_t cTimeoutMS);
+ static DECLCALLBACK(uint32_t) i_hlpCompleteProgress(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IProgress) *pProgress,
+ uint32_t uResultCode);
+ static DECLCALLBACK(uint32_t) i_hlpCreateEvent(PCVBOXEXTPACKHLP pHlp,
+ VBOXEXTPACK_IF_CS(IEventSource) *aSource,
+ /* VBoxEventType_T */ uint32_t aType, bool aWaitable,
+ VBOXEXTPACK_IF_CS(IEvent) **ppEventOut);
+ static DECLCALLBACK(uint32_t) i_hlpCreateVetoEvent(PCVBOXEXTPACKHLP pHlp,
+ VBOXEXTPACK_IF_CS(IEventSource) *aSource,
+ /* VBoxEventType_T */ uint32_t aType,
+ VBOXEXTPACK_IF_CS(IVetoEvent) **ppEventOut);
+ static DECLCALLBACK(const char *) i_hlpTranslate(PCVBOXEXTPACKHLP pHlp,
+ const char *pszComponent,
+ const char *pszSourceText,
+ const char *pszComment = NULL,
+ const size_t aNum = ~(size_t)0);
+ static DECLCALLBACK(int) i_hlpReservedN(PCVBOXEXTPACKHLP pHlp);
+ /** @} */
+
+private:
+
+ // wrapped IExtPack properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT getVersion(com::Utf8Str &aVersion);
+ HRESULT getRevision(ULONG *aRevision);
+ HRESULT getEdition(com::Utf8Str &aEdition);
+ HRESULT getVRDEModule(com::Utf8Str &aVRDEModule);
+ HRESULT getCryptoModule(com::Utf8Str &aCryptoModule);
+ HRESULT getPlugIns(std::vector<ComPtr<IExtPackPlugIn> > &aPlugIns);
+ HRESULT getUsable(BOOL *aUsable);
+ HRESULT getWhyUnusable(com::Utf8Str &aWhyUnusable);
+ HRESULT getShowLicense(BOOL *aShowLicense);
+ HRESULT getLicense(com::Utf8Str &aLicense);
+
+ // wrapped IExtPack methods
+ HRESULT queryLicense(const com::Utf8Str &aPreferredLocale,
+ const com::Utf8Str &aPreferredLanguage,
+ const com::Utf8Str &aFormat,
+ com::Utf8Str &aLicenseText);
+ HRESULT queryObject(const com::Utf8Str &aObjUuid,
+ ComPtr<IUnknown> &aReturnInterface);
+
+
+ struct Data;
+ /** Pointer to the private instance. */
+ Data *m;
+
+ friend class ExtPackManager;
+};
+
+
+/**
+ * Extension pack manager.
+ */
+class ATL_NO_VTABLE ExtPackManager :
+ public ExtPackManagerWrap
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(ExtPackManager)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ HRESULT initExtPackManager(VirtualBox *a_pVirtualBox, VBOXEXTPACKCTX a_enmContext);
+ void uninit();
+ /** @} */
+
+ /** @name Internal interfaces used by other Main classes.
+ * @{ */
+#ifndef VBOX_COM_INPROC
+ HRESULT i_doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo);
+ HRESULT i_doUninstall(const Utf8Str *a_pstrName, bool a_fForcedRemoval, const Utf8Str *a_pstrDisplayInfo);
+ void i_callAllVirtualBoxReadyHooks(void);
+ HRESULT i_queryObjects(const com::Utf8Str &aObjUuid, std::vector<ComPtr<IUnknown> > &aObjects, std::vector<com::Utf8Str> *a_pstrExtPackNames);
+#endif
+#ifdef VBOX_COM_INPROC
+ void i_callAllConsoleReadyHooks(IConsole *a_pConsole);
+#endif
+#ifndef VBOX_COM_INPROC
+ void i_callAllVmCreatedHooks(IMachine *a_pMachine);
+#endif
+#ifdef VBOX_COM_INPROC
+ int i_callAllVmConfigureVmmHooks(IConsole *a_pConsole, PVM a_pVM, PCVMMR3VTABLE a_pVMM);
+ int i_callAllVmPowerOnHooks(IConsole *a_pConsole, PVM a_pVM, PCVMMR3VTABLE a_pVMM);
+ void i_callAllVmPowerOffHooks(IConsole *a_pConsole, PVM a_pVM, PCVMMR3VTABLE a_pVMM);
+#endif
+ HRESULT i_checkVrdeExtPack(Utf8Str const *a_pstrExtPack);
+ int i_getVrdeLibraryPathForExtPack(Utf8Str const *a_pstrExtPack, Utf8Str *a_pstrVrdeLibrary);
+ HRESULT i_checkCryptoExtPack(Utf8Str const *a_pstrExtPack);
+ int i_getCryptoLibraryPathForExtPack(Utf8Str const *a_pstrExtPack, Utf8Str *a_pstrVrdeLibrary);
+ HRESULT i_getLibraryPathForExtPack(const char *a_pszModuleName, const char *a_pszExtPack, Utf8Str *a_pstrLibrary);
+ HRESULT i_getDefaultVrdeExtPack(Utf8Str *a_pstrExtPack);
+ HRESULT i_getDefaultCryptoExtPack(Utf8Str *a_pstrExtPack);
+ bool i_isExtPackUsable(const char *a_pszExtPack);
+ void i_dumpAllToReleaseLog(void);
+ uint64_t i_getUpdateCounter(void);
+ /** @} */
+
+private:
+ // wrapped IExtPackManager properties
+ HRESULT getInstalledExtPacks(std::vector<ComPtr<IExtPack> > &aInstalledExtPacks);
+
+ // wrapped IExtPackManager methods
+ HRESULT find(const com::Utf8Str &aName,
+ ComPtr<IExtPack> &aReturnData);
+ HRESULT openExtPackFile(const com::Utf8Str &aPath,
+ ComPtr<IExtPackFile> &aFile);
+ HRESULT uninstall(const com::Utf8Str &aName,
+ BOOL aForcedRemoval,
+ const com::Utf8Str &aDisplayInfo,
+ ComPtr<IProgress> &aProgess);
+ HRESULT cleanup();
+ HRESULT queryAllPlugInsForFrontend(const com::Utf8Str &aFrontendName,
+ std::vector<com::Utf8Str> &aPlugInModules);
+ HRESULT isExtPackUsable(const com::Utf8Str &aName,
+ BOOL *aUsable);
+
+ bool i_areThereAnyRunningVMs(void) const;
+ HRESULT i_runSetUidToRootHelper(Utf8Str const *a_pstrDisplayInfo, const char *a_pszCommand, ...);
+ ExtPack *i_findExtPack(const char *a_pszName);
+ void i_removeExtPack(const char *a_pszName);
+ HRESULT i_refreshExtPack(const char *a_pszName, bool a_fUnsuableIsError, ExtPack **a_ppExtPack);
+
+private:
+ struct Data;
+ /** Pointer to the private instance. */
+ Data *m;
+
+ friend class ExtPackUninstallTask;
+};
+
+#endif /* !MAIN_INCLUDED_ExtPackManagerImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ExtPackUtil.h b/src/VBox/Main/include/ExtPackUtil.h
new file mode 100644
index 00000000..82c0ef0c
--- /dev/null
+++ b/src/VBox/Main/include/ExtPackUtil.h
@@ -0,0 +1,158 @@
+/* $Id: ExtPackUtil.h $ */
+/** @file
+ * VirtualBox Main - Extension Pack Utilities and definitions, VBoxC, VBoxSVC, ++.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ExtPackUtil_h
+#define MAIN_INCLUDED_ExtPackUtil_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef __cplusplus
+# include <iprt/cpp/ministring.h>
+#endif
+#include <iprt/fs.h>
+#include <iprt/vfs.h>
+
+
+/** @name VBOX_EXTPACK_DESCRIPTION_NAME
+ * The name of the description file in an extension pack. */
+#define VBOX_EXTPACK_DESCRIPTION_NAME "ExtPack.xml"
+/** @name VBOX_EXTPACK_DESCRIPTION_NAME
+ * The name of the manifest file in an extension pack. */
+#define VBOX_EXTPACK_MANIFEST_NAME "ExtPack.manifest"
+/** @name VBOX_EXTPACK_SIGNATURE_NAME
+ * The name of the signature file in an extension pack. */
+#define VBOX_EXTPACK_SIGNATURE_NAME "ExtPack.signature"
+/** @name VBOX_EXTPACK_LICENSE_NAME_PREFIX
+ * The name prefix of a license file in an extension pack. There can be
+ * several license files in a pack, the variations being on locale, language
+ * and format (HTML, RTF, plain text). All extension packages shall include
+ * a */
+#define VBOX_EXTPACK_LICENSE_NAME_PREFIX "ExtPack-license"
+/** @name VBOX_EXTPACK_SUFFIX
+ * The suffix of a extension pack tarball. */
+#define VBOX_EXTPACK_SUFFIX ".vbox-extpack"
+
+/** The minimum length (strlen) of a extension pack name. */
+#define VBOX_EXTPACK_NAME_MIN_LEN 3
+/** The max length (strlen) of a extension pack name. */
+#define VBOX_EXTPACK_NAME_MAX_LEN 64
+
+/** The architecture-dependent application data subdirectory where the
+ * extension packs are installed. Relative to RTPathAppPrivateArch. */
+#define VBOX_EXTPACK_INSTALL_DIR "ExtensionPacks"
+/** The architecture-independent application data subdirectory where the
+ * certificates are installed. Relative to RTPathAppPrivateNoArch. */
+#define VBOX_EXTPACK_CERT_DIR "ExtPackCertificates"
+
+/** The maximum entry name length.
+ * Play short and safe. */
+#define VBOX_EXTPACK_MAX_MEMBER_NAME_LENGTH 128
+
+
+#ifdef __cplusplus
+
+/**
+ * Plug-in descriptor.
+ */
+typedef struct VBOXEXTPACKPLUGINDESC
+{
+ /** The name. */
+ RTCString strName;
+ /** The module name. */
+ RTCString strModule;
+ /** The description. */
+ RTCString strDescription;
+ /** The frontend or component which it plugs into. */
+ RTCString strFrontend;
+} VBOXEXTPACKPLUGINDESC;
+/** Pointer to a plug-in descriptor. */
+typedef VBOXEXTPACKPLUGINDESC *PVBOXEXTPACKPLUGINDESC;
+
+/**
+ * Extension pack descriptor
+ *
+ * This is the internal representation of the ExtPack.xml.
+ */
+typedef struct VBOXEXTPACKDESC
+{
+ /** The name. */
+ RTCString strName;
+ /** The description. */
+ RTCString strDescription;
+ /** The version string. */
+ RTCString strVersion;
+ /** The edition string. */
+ RTCString strEdition;
+ /** The internal revision number. */
+ uint32_t uRevision;
+ /** The name of the main module. */
+ RTCString strMainModule;
+ /** The name of the main VM module, empty if none. */
+ RTCString strMainVMModule;
+ /** The name of the VRDE module, empty if none. */
+ RTCString strVrdeModule;
+ /** The name of the cryptographic module, empty if none. */
+ RTCString strCryptoModule;
+ /** The number of plug-in descriptors. */
+ uint32_t cPlugIns;
+ /** Pointer to an array of plug-in descriptors. */
+ PVBOXEXTPACKPLUGINDESC paPlugIns;
+ /** Whether to show the license prior to installation. */
+ bool fShowLicense;
+} VBOXEXTPACKDESC;
+
+/** Pointer to a extension pack descriptor. */
+typedef VBOXEXTPACKDESC *PVBOXEXTPACKDESC;
+/** Pointer to a const extension pack descriptor. */
+typedef VBOXEXTPACKDESC const *PCVBOXEXTPACKDESC;
+
+
+void VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
+RTCString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
+RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
+RTCString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball);
+void VBoxExtPackFreeDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
+bool VBoxExtPackIsValidName(const char *pszName);
+bool VBoxExtPackIsValidMangledName(const char *pszMangledName, size_t cchMax = RTSTR_MAX);
+RTCString *VBoxExtPackMangleName(const char *pszName);
+RTCString *VBoxExtPackUnmangleName(const char *pszMangledName, size_t cbMax);
+int VBoxExtPackCalcDir(char *pszExtPackDir, size_t cbExtPackDir, const char *pszParentDir, const char *pszName);
+bool VBoxExtPackIsValidVersionString(const char *pszVersion);
+bool VBoxExtPackIsValidEditionString(const char *pszEdition);
+bool VBoxExtPackIsValidModuleString(const char *pszModule);
+
+int VBoxExtPackValidateMember(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOBJ hVfsObj, char *pszError, size_t cbError);
+int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss, PRTMANIFEST phFileManifest);
+int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
+ const char *pszTarball, const char *pszTarballDigest,
+ char *pszError, size_t cbError,
+ PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile, RTCString *pStrDigest);
+#endif /* __cplusplus */
+
+#endif /* !MAIN_INCLUDED_ExtPackUtil_h */
+
diff --git a/src/VBox/Main/include/Global.h b/src/VBox/Main/include/Global.h
new file mode 100644
index 00000000..f8b752f7
--- /dev/null
+++ b/src/VBox/Main/include/Global.h
@@ -0,0 +1,255 @@
+/* $Id: Global.h $ */
+/** @file
+ * VirtualBox COM API - Global Declarations and Definitions.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_Global_h
+#define MAIN_INCLUDED_Global_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/* interface definitions */
+#include "VBox/com/VirtualBox.h"
+
+#include <VBox/ostypes.h>
+
+#include <iprt/types.h>
+
+#define VBOXOSHINT_NONE 0
+#define VBOXOSHINT_64BIT RT_BIT(0)
+#define VBOXOSHINT_HWVIRTEX RT_BIT(1)
+#define VBOXOSHINT_IOAPIC RT_BIT(2)
+#define VBOXOSHINT_EFI RT_BIT(3)
+#define VBOXOSHINT_PAE RT_BIT(4)
+#define VBOXOSHINT_USBHID RT_BIT(5)
+#define VBOXOSHINT_HPET RT_BIT(6)
+#define VBOXOSHINT_USBTABLET RT_BIT(7)
+#define VBOXOSHINT_RTCUTC RT_BIT(8)
+#define VBOXOSHINT_ACCEL2D RT_BIT(9)
+#define VBOXOSHINT_ACCEL3D RT_BIT(10)
+#define VBOXOSHINT_FLOPPY RT_BIT(11)
+#define VBOXOSHINT_NOUSB RT_BIT(12)
+#define VBOXOSHINT_TFRESET RT_BIT(13)
+#define VBOXOSHINT_USB3 RT_BIT(14)
+#define VBOXOSHINT_X2APIC RT_BIT(15)
+#define VBOXOSHINT_EFI_SECUREBOOT RT_BIT(16)
+#define VBOXOSHINT_TPM RT_BIT(17)
+#define VBOXOSHINT_TPM2 RT_BIT(18)
+#define VBOXOSHINT_WDDM_GRAPHICS RT_BIT(19)
+
+/** The VBoxVRDP kludge extension pack name.
+ *
+ * This is not a valid extension pack name (dashes are not allowed), and
+ * hence will not conflict with real extension packs.
+ */
+#define VBOXVRDP_KLUDGE_EXTPACK_NAME "Built-in-VBoxVRDP"
+
+/** The VBoxPuelCrypto kludge extension pack name.
+ *
+ * This is not a valid extension pack name (dashes are not allowed), and
+ * hence will not conflict with real extension packs.
+ */
+#define VBOXPUELCRYPTO_KLUDGE_EXTPACK_NAME "Built-in-VBoxPuelCrypto"
+
+/**
+ * Contains global static definitions that can be referenced by all COM classes
+ * regardless of the apartment.
+ */
+class Global
+{
+public:
+
+ /** Represents OS Type <-> string mappings. */
+ struct OSType
+ {
+ const char *familyId; /* utf-8 */
+ const char *familyDescription; /* utf-8 */
+ const char *id; /* utf-8, VM config file value */
+ const char *description; /* utf-8 */
+ const VBOXOSTYPE osType;
+ const uint32_t osHint;
+ const uint32_t recommendedCPUCount;
+ const uint32_t recommendedRAM;
+ const uint32_t recommendedVRAM;
+ const uint64_t recommendedHDD;
+ const GraphicsControllerType_T graphicsControllerType;
+ const NetworkAdapterType_T networkAdapterType;
+ const uint32_t numSerialEnabled;
+ const StorageControllerType_T dvdStorageControllerType;
+ const StorageBus_T dvdStorageBusType;
+ const StorageControllerType_T hdStorageControllerType;
+ const StorageBus_T hdStorageBusType;
+ const ChipsetType_T chipsetType;
+ const IommuType_T iommuType;
+ const AudioControllerType_T audioControllerType;
+ const AudioCodecType_T audioCodecType;
+ };
+
+ static const OSType sOSTypes[];
+ static size_t cOSTypes;
+
+ /**
+ * Maps VBOXOSTYPE to the OS type which is used in VM configs.
+ */
+ static const char *OSTypeId(VBOXOSTYPE aOSType);
+
+ /**
+ * Maps an OS type ID string to index into sOSTypes.
+ * @returns index on success, UINT32_MAX if not found.
+ */
+ static uint32_t getOSTypeIndexFromId(const char *pszId);
+
+ /**
+ * Get the network adapter limit for each chipset type.
+ */
+ static uint32_t getMaxNetworkAdapters(ChipsetType_T aChipsetType);
+
+ /**
+ * Returns @c true if the given machine state is an online state. This is a
+ * recommended way to detect if the VM is online (being executed in a
+ * dedicated process) or not. Note that some online states are also
+ * transitional states (see #IsTransient()).
+ */
+ static bool IsOnline(MachineState_T aState)
+ {
+ return aState >= MachineState_FirstOnline &&
+ aState <= MachineState_LastOnline;
+ }
+
+ /**
+ * Returns @c true if the given machine state is a transient state. This is
+ * a recommended way to detect if the VM is performing some potentially
+ * lengthy operation (such as starting, stopping, saving, deleting
+ * snapshot, etc.). Note some (but not all) transitional states are also
+ * online states (see #IsOnline()).
+ */
+ static bool IsTransient(MachineState_T aState)
+ {
+ return aState >= MachineState_FirstTransient &&
+ aState <= MachineState_LastTransient;
+ }
+
+ /**
+ * Shortcut to <tt>IsOnline(aState) || IsTransient(aState)</tt>. When it returns
+ * @c false, the VM is turned off (no VM process) and not busy with
+ * another exclusive operation.
+ */
+ static bool IsOnlineOrTransient(MachineState_T aState)
+ {
+ return IsOnline(aState) || IsTransient(aState);
+ }
+
+ /**
+ * Stringify a machine state - translated.
+ *
+ * Drop the Global:: prefix and include StringifyEnums.h for an untranslated
+ * version of this method.
+ *
+ * @returns Pointer to a read only string.
+ * @param aState Valid machine state.
+ */
+ static const char *stringifyMachineState(MachineState_T aState);
+
+ /**
+ * Stringify a session state - translated.
+ *
+ * Drop the Global:: prefix and include StringifyEnums.h for an untranslated
+ * version of this method.
+ *
+ * @returns Pointer to a read only string.
+ * @param aState Valid session state.
+ */
+ static const char *stringifySessionState(SessionState_T aState);
+
+ /**
+ * Stringify a device type.
+ *
+ * Drop the Global:: prefix and include StringifyEnums.h for an untranslated
+ * version of this method.
+ *
+ * @returns Pointer to a read only string.
+ * @param aType The device type.
+ */
+ static const char *stringifyDeviceType(DeviceType_T aType);
+
+ /**
+ * Stringify a storage controller type.
+ *
+ * Drop the Global:: prefix and include StringifyEnums.h for an untranslated
+ * version of this method.
+ *
+ * @returns Pointer to a read only string.
+ * @param aType The storage controller type.
+ */
+ static const char *stringifyStorageControllerType(StorageControllerType_T aType);
+
+#if 0 /* unused */
+ /**
+ * Stringify a storage bus type.
+ *
+ * Drop the Global:: prefix and include StringifyEnums.h for an untranslated
+ * version of this method.
+ *
+ * @returns Pointer to a read only string.
+ * @param aBus The storage bus type.
+ */
+ static const char *stringifyStorageBus(StorageBus_T aBus);
+
+ /**
+ * Stringify a reason.
+ *
+ * Drop the Global:: prefix and include StringifyEnums.h for an untranslated
+ * version of this method.
+ *
+ * @returns Pointer to a read only string.
+ * @param aReason The reason code.
+ */
+ static const char *stringifyReason(Reason_T aReason);
+#endif
+
+ /**
+ * Try convert a COM status code to a VirtualBox status code (VBox/err.h).
+ *
+ * @returns VBox status code.
+ * @param aComStatus COM status code.
+ */
+ static int vboxStatusCodeFromCOM(HRESULT aComStatus);
+
+ /**
+ * Try convert a VirtualBox status code (VBox/err.h) to a COM status code.
+ *
+ * This is mainly intended for dealing with vboxStatusCodeFromCOM() return
+ * values. If used on anything else, it won't be able to cope with most of the
+ * input!
+ *
+ * @returns COM status code.
+ * @param aVBoxStatus VBox status code.
+ */
+ static HRESULT vboxStatusCodeToCOM(int aVBoxStatus);
+};
+
+#endif /* !MAIN_INCLUDED_Global_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/GraphicsAdapterImpl.h b/src/VBox/Main/include/GraphicsAdapterImpl.h
new file mode 100644
index 00000000..762037dd
--- /dev/null
+++ b/src/VBox/Main/include/GraphicsAdapterImpl.h
@@ -0,0 +1,88 @@
+/* $Id: GraphicsAdapterImpl.h $ */
+/** @file
+ * Implementation of IGraphicsAdapter in VBoxSVC - Header.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GraphicsAdapterImpl_h
+#define MAIN_INCLUDED_GraphicsAdapterImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GraphicsAdapterWrap.h"
+
+
+namespace settings
+{
+ struct GraphicsAdapter;
+};
+
+
+class ATL_NO_VTABLE GraphicsAdapter :
+ public GraphicsAdapterWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(GraphicsAdapter)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent);
+ HRESULT init(Machine *aParent, GraphicsAdapter *aThat);
+ HRESULT initCopy(Machine *aParent, GraphicsAdapter *aThat);
+ void uninit();
+
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::GraphicsAdapter &data);
+ HRESULT i_saveSettings(settings::GraphicsAdapter &data);
+
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(GraphicsAdapter *aThat);
+
+private:
+
+ // wrapped IGraphicsAdapter properties
+ HRESULT getGraphicsControllerType(GraphicsControllerType_T *aGraphicsControllerType);
+ HRESULT setGraphicsControllerType(GraphicsControllerType_T aGraphicsControllerType);
+ HRESULT getVRAMSize(ULONG *aVRAMSize);
+ HRESULT setVRAMSize(ULONG aVRAMSize);
+ HRESULT getAccelerate3DEnabled(BOOL *aAccelerate3DEnabled);
+ HRESULT setAccelerate3DEnabled(BOOL aAccelerate3DEnabled);
+ HRESULT getAccelerate2DVideoEnabled(BOOL *aAccelerate2DVideoEnabled);
+ HRESULT setAccelerate2DVideoEnabled(BOOL aAccelerate2DVideoEnabled);
+ HRESULT getMonitorCount(ULONG *aMonitorCount);
+ HRESULT setMonitorCount(ULONG aMonitorCount);
+
+ Machine * const mParent;
+ const ComObjPtr<GraphicsAdapter> mPeer;
+ Backupable<settings::GraphicsAdapter> mData;
+};
+
+#endif /* !MAIN_INCLUDED_GraphicsAdapterImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/GuestCtrlImplPrivate.h b/src/VBox/Main/include/GuestCtrlImplPrivate.h
new file mode 100644
index 00000000..6287dfd7
--- /dev/null
+++ b/src/VBox/Main/include/GuestCtrlImplPrivate.h
@@ -0,0 +1,1459 @@
+/* $Id: GuestCtrlImplPrivate.h $ */
+/** @file
+ * Internal helpers/structures for guest control functionality.
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestCtrlImplPrivate_h
+#define MAIN_INCLUDED_GuestCtrlImplPrivate_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "ConsoleImpl.h"
+#include "Global.h"
+
+#include <iprt/asm.h>
+#include <iprt/env.h>
+#include <iprt/semaphore.h>
+#include <iprt/cpp/utils.h>
+
+#include <VBox/com/com.h>
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/string.h>
+#include <VBox/com/VirtualBox.h>
+#include <VBox/err.h> /* VERR_GSTCTL_GUEST_ERROR */
+
+#include <map>
+#include <vector>
+
+using namespace com;
+
+#ifdef VBOX_WITH_GUEST_CONTROL
+# include <VBox/GuestHost/GuestControl.h>
+# include <VBox/HostServices/GuestControlSvc.h>
+using namespace guestControl;
+#endif
+
+/** Vector holding a process' CPU affinity. */
+typedef std::vector <LONG> ProcessAffinity;
+/** Vector holding process startup arguments. */
+typedef std::vector <Utf8Str> ProcessArguments;
+
+class GuestProcessStreamBlock;
+class GuestSession;
+
+
+/**
+ * Simple structure mantaining guest credentials.
+ */
+struct GuestCredentials
+{
+ Utf8Str mUser;
+ Utf8Str mPassword;
+ Utf8Str mDomain;
+};
+
+
+/**
+ * Wrapper around the RTEnv API, unusable base class.
+ *
+ * @remarks Feel free to elevate this class to iprt/cpp/env.h as RTCEnv.
+ */
+class GuestEnvironmentBase
+{
+public:
+ /**
+ * Default constructor.
+ *
+ * The user must invoke one of the init methods before using the object.
+ */
+ GuestEnvironmentBase(void)
+ : m_hEnv(NIL_RTENV)
+ , m_cRefs(1)
+ , m_fFlags(0)
+ { }
+
+ /**
+ * Destructor.
+ */
+ virtual ~GuestEnvironmentBase(void)
+ {
+ Assert(m_cRefs <= 1);
+ int vrc = RTEnvDestroy(m_hEnv); AssertRC(vrc);
+ m_hEnv = NIL_RTENV;
+ }
+
+ /**
+ * Retains a reference to this object.
+ * @returns New reference count.
+ * @remarks Sharing an object is currently only safe if no changes are made to
+ * it because RTENV does not yet implement any locking. For the only
+ * purpose we need this, implementing IGuestProcess::environment by
+ * using IGuestSession::environmentBase, that's fine as the session
+ * base environment is immutable.
+ */
+ uint32_t retain(void)
+ {
+ uint32_t cRefs = ASMAtomicIncU32(&m_cRefs);
+ Assert(cRefs > 1); Assert(cRefs < _1M);
+ return cRefs;
+
+ }
+ /** Useful shortcut. */
+ uint32_t retainConst(void) const { return unconst(this)->retain(); }
+
+ /**
+ * Releases a reference to this object, deleting the object when reaching zero.
+ * @returns New reference count.
+ */
+ uint32_t release(void)
+ {
+ uint32_t cRefs = ASMAtomicDecU32(&m_cRefs);
+ Assert(cRefs < _1M);
+ if (cRefs == 0)
+ delete this;
+ return cRefs;
+ }
+
+ /** Useful shortcut. */
+ uint32_t releaseConst(void) const { return unconst(this)->retain(); }
+
+ /**
+ * Checks if the environment has been successfully initialized or not.
+ *
+ * @returns @c true if initialized, @c false if not.
+ */
+ bool isInitialized(void) const
+ {
+ return m_hEnv != NIL_RTENV;
+ }
+
+ /**
+ * Returns the variable count.
+ * @return Number of variables.
+ * @sa RTEnvCountEx
+ */
+ uint32_t count(void) const
+ {
+ return RTEnvCountEx(m_hEnv);
+ }
+
+ /**
+ * Deletes the environment change record entirely.
+ *
+ * The count() method will return zero after this call.
+ *
+ * @sa RTEnvReset
+ */
+ void reset(void)
+ {
+ int vrc = RTEnvReset(m_hEnv);
+ AssertRC(vrc);
+ }
+
+ /**
+ * Exports the environment change block as an array of putenv style strings.
+ *
+ *
+ * @returns VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param pArray The output array.
+ */
+ int queryPutEnvArray(std::vector<com::Utf8Str> *pArray) const
+ {
+ uint32_t cVars = RTEnvCountEx(m_hEnv);
+ try
+ {
+ pArray->resize(cVars);
+ for (uint32_t iVar = 0; iVar < cVars; iVar++)
+ {
+ const char *psz = RTEnvGetByIndexRawEx(m_hEnv, iVar);
+ AssertReturn(psz, VERR_INTERNAL_ERROR_3); /* someone is racing us! */
+ (*pArray)[iVar] = psz;
+ }
+ return VINF_SUCCESS;
+ }
+ catch (std::bad_alloc &)
+ {
+ return VERR_NO_MEMORY;
+ }
+ }
+
+ /**
+ * Applies an array of putenv style strings.
+ *
+ * @returns IPRT status code.
+ * @param rArray The array with the putenv style strings.
+ * @param pidxError Where to return the index causing trouble on
+ * failure. Optional.
+ * @sa RTEnvPutEx
+ */
+ int applyPutEnvArray(const std::vector<com::Utf8Str> &rArray, size_t *pidxError = NULL)
+ {
+ size_t const cArray = rArray.size();
+ for (size_t i = 0; i < cArray; i++)
+ {
+ int vrc = RTEnvPutEx(m_hEnv, rArray[i].c_str());
+ if (RT_FAILURE(vrc))
+ {
+ if (pidxError)
+ *pidxError = i;
+ return vrc;
+ }
+ }
+ return VINF_SUCCESS;
+ }
+
+ /**
+ * Applies the changes from another environment to this.
+ *
+ * @returns IPRT status code.
+ * @param rChanges Reference to an environment which variables will be
+ * imported and, if it's a change record, schedule
+ * variable unsets will be applied.
+ * @sa RTEnvApplyChanges
+ */
+ int applyChanges(const GuestEnvironmentBase &rChanges)
+ {
+ return RTEnvApplyChanges(m_hEnv, rChanges.m_hEnv);
+ }
+
+ /**
+ * See RTEnvQueryUtf8Block for details.
+ * @returns IPRT status code.
+ * @param ppszzBlock Where to return the block pointer.
+ * @param pcbBlock Where to optionally return the block size.
+ * @sa RTEnvQueryUtf8Block
+ */
+ int queryUtf8Block(char **ppszzBlock, size_t *pcbBlock)
+ {
+ return RTEnvQueryUtf8Block(m_hEnv, true /*fSorted*/, ppszzBlock, pcbBlock);
+ }
+
+ /**
+ * Frees what queryUtf8Block returned, NULL ignored.
+ * @sa RTEnvFreeUtf8Block
+ */
+ static void freeUtf8Block(char *pszzBlock)
+ {
+ return RTEnvFreeUtf8Block(pszzBlock);
+ }
+
+ /**
+ * Applies a block on the format returned by queryUtf8Block.
+ *
+ * @returns IPRT status code.
+ * @param pszzBlock Pointer to the block.
+ * @param cbBlock The size of the block.
+ * @param fNoEqualMeansUnset Whether the lack of a '=' (equal) sign in a
+ * string means it should be unset (@c true), or if
+ * it means the variable should be defined with an
+ * empty value (@c false, the default).
+ * @todo move this to RTEnv!
+ */
+ int copyUtf8Block(const char *pszzBlock, size_t cbBlock, bool fNoEqualMeansUnset = false)
+ {
+ int vrc = VINF_SUCCESS;
+ while (cbBlock > 0 && *pszzBlock != '\0')
+ {
+ const char *pszEnd = (const char *)memchr(pszzBlock, '\0', cbBlock);
+ if (!pszEnd)
+ return VERR_BUFFER_UNDERFLOW;
+ int vrc2;
+ if (fNoEqualMeansUnset || strchr(pszzBlock, '='))
+ vrc2 = RTEnvPutEx(m_hEnv, pszzBlock);
+ else
+ vrc2 = RTEnvSetEx(m_hEnv, pszzBlock, "");
+ if (RT_FAILURE(vrc2) && RT_SUCCESS(vrc))
+ vrc = vrc2;
+
+ /* Advance. */
+ cbBlock -= pszEnd - pszzBlock;
+ if (cbBlock < 2)
+ return VERR_BUFFER_UNDERFLOW;
+ cbBlock--;
+ pszzBlock = pszEnd + 1;
+ }
+
+ /* The remainder must be zero padded. */
+ if (RT_SUCCESS(vrc))
+ {
+ if (ASMMemIsZero(pszzBlock, cbBlock))
+ return VINF_SUCCESS;
+ return VERR_TOO_MUCH_DATA;
+ }
+ return vrc;
+ }
+
+ /**
+ * Get an environment variable.
+ *
+ * @returns IPRT status code.
+ * @param rName The variable name.
+ * @param pValue Where to return the value.
+ * @sa RTEnvGetEx
+ */
+ int getVariable(const com::Utf8Str &rName, com::Utf8Str *pValue) const
+ {
+ size_t cchNeeded;
+ int vrc = RTEnvGetEx(m_hEnv, rName.c_str(), NULL, 0, &cchNeeded);
+ if ( RT_SUCCESS(vrc)
+ || vrc == VERR_BUFFER_OVERFLOW)
+ {
+ try
+ {
+ pValue->reserve(cchNeeded + 1);
+ vrc = RTEnvGetEx(m_hEnv, rName.c_str(), pValue->mutableRaw(), pValue->capacity(), NULL);
+ pValue->jolt();
+ }
+ catch (std::bad_alloc &)
+ {
+ vrc = VERR_NO_STR_MEMORY;
+ }
+ }
+ return vrc;
+ }
+
+ /**
+ * Checks if the given variable exists.
+ *
+ * @returns @c true if it exists, @c false if not or if it's an scheduled unset
+ * in a environment change record.
+ * @param rName The variable name.
+ * @sa RTEnvExistEx
+ */
+ bool doesVariableExist(const com::Utf8Str &rName) const
+ {
+ return RTEnvExistEx(m_hEnv, rName.c_str());
+ }
+
+ /**
+ * Set an environment variable.
+ *
+ * @returns IPRT status code.
+ * @param rName The variable name.
+ * @param rValue The value of the variable.
+ * @sa RTEnvSetEx
+ */
+ int setVariable(const com::Utf8Str &rName, const com::Utf8Str &rValue)
+ {
+ return RTEnvSetEx(m_hEnv, rName.c_str(), rValue.c_str());
+ }
+
+ /**
+ * Unset an environment variable.
+ *
+ * @returns IPRT status code.
+ * @param rName The variable name.
+ * @sa RTEnvUnsetEx
+ */
+ int unsetVariable(const com::Utf8Str &rName)
+ {
+ return RTEnvUnsetEx(m_hEnv, rName.c_str());
+ }
+
+protected:
+ /**
+ * Copy constructor.
+ * @throws HRESULT
+ */
+ GuestEnvironmentBase(const GuestEnvironmentBase &rThat, bool fChangeRecord, uint32_t fFlags = 0)
+ : m_hEnv(NIL_RTENV)
+ , m_cRefs(1)
+ , m_fFlags(fFlags)
+ {
+ int vrc = cloneCommon(rThat, fChangeRecord);
+ if (RT_FAILURE(vrc))
+ throw Global::vboxStatusCodeToCOM(vrc);
+ }
+
+ /**
+ * Common clone/copy method with type conversion abilities.
+ *
+ * @returns IPRT status code.
+ * @param rThat The object to clone.
+ * @param fChangeRecord Whether the this instance is a change record (true)
+ * or normal (false) environment.
+ */
+ int cloneCommon(const GuestEnvironmentBase &rThat, bool fChangeRecord)
+ {
+ int vrc = VINF_SUCCESS;
+ RTENV hNewEnv = NIL_RTENV;
+ if (rThat.m_hEnv != NIL_RTENV)
+ {
+ /*
+ * Clone it.
+ */
+ if (RTEnvIsChangeRecord(rThat.m_hEnv) == fChangeRecord)
+ vrc = RTEnvClone(&hNewEnv, rThat.m_hEnv);
+ else
+ {
+ /* Need to type convert it. */
+ if (fChangeRecord)
+ vrc = RTEnvCreateChangeRecordEx(&hNewEnv, rThat.m_fFlags);
+ else
+ vrc = RTEnvCreateEx(&hNewEnv, rThat.m_fFlags);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = RTEnvApplyChanges(hNewEnv, rThat.m_hEnv);
+ if (RT_FAILURE(vrc))
+ RTEnvDestroy(hNewEnv);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Create an empty one so the object works smoothly.
+ * (Relevant for GuestProcessStartupInfo and internal commands.)
+ */
+ if (fChangeRecord)
+ vrc = RTEnvCreateChangeRecordEx(&hNewEnv, rThat.m_fFlags);
+ else
+ vrc = RTEnvCreateEx(&hNewEnv, rThat.m_fFlags);
+ }
+ if (RT_SUCCESS(vrc))
+ {
+ RTEnvDestroy(m_hEnv);
+ m_hEnv = hNewEnv;
+ m_fFlags = rThat.m_fFlags;
+ }
+ return vrc;
+ }
+
+
+ /** The environment change record. */
+ RTENV m_hEnv;
+ /** Reference counter. */
+ uint32_t volatile m_cRefs;
+ /** RTENV_CREATE_F_XXX. */
+ uint32_t m_fFlags;
+};
+
+class GuestEnvironmentChanges;
+
+
+/**
+ * Wrapper around the RTEnv API for a normal environment.
+ */
+class GuestEnvironment : public GuestEnvironmentBase
+{
+public:
+ /**
+ * Default constructor.
+ *
+ * The user must invoke one of the init methods before using the object.
+ */
+ GuestEnvironment(void)
+ : GuestEnvironmentBase()
+ { }
+
+ /**
+ * Copy operator.
+ * @param rThat The object to copy.
+ * @throws HRESULT
+ */
+ GuestEnvironment(const GuestEnvironment &rThat)
+ : GuestEnvironmentBase(rThat, false /*fChangeRecord*/)
+ { }
+
+ /**
+ * Copy operator.
+ * @param rThat The object to copy.
+ * @throws HRESULT
+ */
+ GuestEnvironment(const GuestEnvironmentBase &rThat)
+ : GuestEnvironmentBase(rThat, false /*fChangeRecord*/)
+ { }
+
+ /**
+ * Initialize this as a normal environment block.
+ * @returns IPRT status code.
+ * @param fFlags RTENV_CREATE_F_XXX
+ */
+ int initNormal(uint32_t fFlags)
+ {
+ AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
+ m_fFlags = fFlags;
+ return RTEnvCreateEx(&m_hEnv, fFlags);
+ }
+
+ /**
+ * Replaces this environemnt with that in @a rThat.
+ *
+ * @returns IPRT status code
+ * @param rThat The environment to copy. If it's a different type
+ * we'll convert the data to a normal environment block.
+ */
+ int copy(const GuestEnvironmentBase &rThat)
+ {
+ return cloneCommon(rThat, false /*fChangeRecord*/);
+ }
+
+ /**
+ * @copydoc GuestEnvironment::copy()
+ */
+ GuestEnvironment &operator=(const GuestEnvironmentBase &rThat)
+ {
+ int vrc = copy(rThat);
+ if (RT_FAILURE(vrc))
+ throw Global::vboxStatusCodeToCOM(vrc);
+ return *this;
+ }
+
+ /** @copydoc GuestEnvironment::copy() */
+ GuestEnvironment &operator=(const GuestEnvironment &rThat)
+ { return operator=((const GuestEnvironmentBase &)rThat); }
+
+ /** @copydoc GuestEnvironment::copy() */
+ GuestEnvironment &operator=(const GuestEnvironmentChanges &rThat)
+ { return operator=((const GuestEnvironmentBase &)rThat); }
+
+};
+
+
+/**
+ * Wrapper around the RTEnv API for a environment change record.
+ *
+ * This class is used as a record of changes to be applied to a different
+ * environment block (in VBoxService before launching a new process).
+ */
+class GuestEnvironmentChanges : public GuestEnvironmentBase
+{
+public:
+ /**
+ * Default constructor.
+ *
+ * The user must invoke one of the init methods before using the object.
+ */
+ GuestEnvironmentChanges(void)
+ : GuestEnvironmentBase()
+ { }
+
+ /**
+ * Copy operator.
+ * @param rThat The object to copy.
+ * @throws HRESULT
+ */
+ GuestEnvironmentChanges(const GuestEnvironmentChanges &rThat)
+ : GuestEnvironmentBase(rThat, true /*fChangeRecord*/)
+ { }
+
+ /**
+ * Copy operator.
+ * @param rThat The object to copy.
+ * @throws HRESULT
+ */
+ GuestEnvironmentChanges(const GuestEnvironmentBase &rThat)
+ : GuestEnvironmentBase(rThat, true /*fChangeRecord*/)
+ { }
+
+ /**
+ * Initialize this as a environment change record.
+ * @returns IPRT status code.
+ * @param fFlags RTENV_CREATE_F_XXX
+ */
+ int initChangeRecord(uint32_t fFlags)
+ {
+ AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
+ m_fFlags = fFlags;
+ return RTEnvCreateChangeRecordEx(&m_hEnv, fFlags);
+ }
+
+ /**
+ * Replaces this environemnt with that in @a rThat.
+ *
+ * @returns IPRT status code
+ * @param rThat The environment to copy. If it's a different type
+ * we'll convert the data to a set of changes.
+ */
+ int copy(const GuestEnvironmentBase &rThat)
+ {
+ return cloneCommon(rThat, true /*fChangeRecord*/);
+ }
+
+ /**
+ * @copydoc GuestEnvironmentChanges::copy()
+ * @throws HRESULT
+ */
+ GuestEnvironmentChanges &operator=(const GuestEnvironmentBase &rThat)
+ {
+ int vrc = copy(rThat);
+ if (RT_FAILURE(vrc))
+ throw Global::vboxStatusCodeToCOM(vrc);
+ return *this;
+ }
+
+ /** @copydoc GuestEnvironmentChanges::copy()
+ * @throws HRESULT */
+ GuestEnvironmentChanges &operator=(const GuestEnvironmentChanges &rThat)
+ { return operator=((const GuestEnvironmentBase &)rThat); }
+
+ /** @copydoc GuestEnvironmentChanges::copy()
+ * @throws HRESULT */
+ GuestEnvironmentChanges &operator=(const GuestEnvironment &rThat)
+ { return operator=((const GuestEnvironmentBase &)rThat); }
+};
+
+/**
+ * Class for keeping guest error information.
+ */
+class GuestErrorInfo
+{
+public:
+
+ /**
+ * Enumeration for specifying the guest error type.
+ */
+ enum Type
+ {
+ /** Guest error is anonymous. Avoid this. */
+ Type_Anonymous = 0,
+ /** Guest error is from a guest session. */
+ Type_Session,
+ /** Guest error is from a guest process. */
+ Type_Process,
+ /** Guest error is from a guest file object. */
+ Type_File,
+ /** Guest error is from a guest directory object. */
+ Type_Directory,
+ /** Guest error is from a the built-in toolbox "vbox_cat" command. */
+ Type_ToolCat,
+ /** Guest error is from a the built-in toolbox "vbox_ls" command. */
+ Type_ToolLs,
+ /** Guest error is from a the built-in toolbox "vbox_rm" command. */
+ Type_ToolRm,
+ /** Guest error is from a the built-in toolbox "vbox_mkdir" command. */
+ Type_ToolMkDir,
+ /** Guest error is from a the built-in toolbox "vbox_mktemp" command. */
+ Type_ToolMkTemp,
+ /** Guest error is from a the built-in toolbox "vbox_stat" command. */
+ Type_ToolStat,
+ /** The usual 32-bit hack. */
+ Type_32BIT_HACK = 0x7fffffff
+ };
+
+ /**
+ * Initialization constructor.
+ *
+ * @param eType Error type to use.
+ * @param vrc VBox status code to use.
+ * @param pcszWhat Subject to use.
+ */
+ GuestErrorInfo(GuestErrorInfo::Type eType, int vrc, const char *pcszWhat)
+ {
+ int vrc2 = setV(eType, vrc, pcszWhat);
+ if (RT_FAILURE(vrc2))
+ throw vrc2;
+ }
+
+ /**
+ * Returns the VBox status code for this error.
+ *
+ * @returns VBox status code.
+ */
+ int getVrc(void) const { return mVrc; }
+
+ /**
+ * Returns the type of this error.
+ *
+ * @returns Error type.
+ */
+ Type getType(void) const { return mType; }
+
+ /**
+ * Returns the subject of this error.
+ *
+ * @returns Subject as a string.
+ */
+ Utf8Str getWhat(void) const { return mWhat; }
+
+ /**
+ * Sets the error information using a variable arguments list (va_list).
+ *
+ * @returns VBox status code.
+ * @param eType Error type to use.
+ * @param vrc VBox status code to use.
+ * @param pcszWhat Subject to use.
+ */
+ int setV(GuestErrorInfo::Type eType, int vrc, const char *pcszWhat)
+ {
+ mType = eType;
+ mVrc = vrc;
+ mWhat = pcszWhat;
+
+ return VINF_SUCCESS;
+ }
+
+protected:
+
+ /** Error type. */
+ Type mType;
+ /** VBox status (error) code. */
+ int mVrc;
+ /** Subject string related to this error. */
+ Utf8Str mWhat;
+};
+
+/**
+ * Structure for keeping all the relevant guest directory
+ * information around.
+ */
+struct GuestDirectoryOpenInfo
+{
+ GuestDirectoryOpenInfo(void)
+ : mFlags(0) { }
+
+ /** The directory path. */
+ Utf8Str mPath;
+ /** Then open filter. */
+ Utf8Str mFilter;
+ /** Opening flags. */
+ uint32_t mFlags;
+};
+
+
+/**
+ * Structure for keeping all the relevant guest file
+ * information around.
+ */
+struct GuestFileOpenInfo
+{
+ GuestFileOpenInfo(void)
+ : mAccessMode((FileAccessMode_T)0)
+ , mOpenAction((FileOpenAction_T)0)
+ , mSharingMode((FileSharingMode_T)0)
+ , mCreationMode(0)
+ , mfOpenEx(0) { }
+
+ /**
+ * Validates a file open info.
+ *
+ * @returns \c true if valid, \c false if not.
+ */
+ bool IsValid(void) const
+ {
+ if (mfOpenEx) /** @todo Open flags not implemented yet. */
+ return false;
+
+ switch (mOpenAction)
+ {
+ case FileOpenAction_OpenExisting:
+ break;
+ case FileOpenAction_OpenOrCreate:
+ break;
+ case FileOpenAction_CreateNew:
+ break;
+ case FileOpenAction_CreateOrReplace:
+ break;
+ case FileOpenAction_OpenExistingTruncated:
+ {
+ if ( mAccessMode == FileAccessMode_ReadOnly
+ || mAccessMode == FileAccessMode_AppendOnly
+ || mAccessMode == FileAccessMode_AppendRead)
+ return false;
+ break;
+ }
+ case FileOpenAction_AppendOrCreate: /* Deprecated, do not use. */
+ break;
+ default:
+ AssertFailedReturn(false);
+ break;
+ }
+
+ return true; /** @todo Do we need more checks here? */
+ }
+
+ /** The filename. */
+ Utf8Str mFilename;
+ /** The file access mode. */
+ FileAccessMode_T mAccessMode;
+ /** The file open action. */
+ FileOpenAction_T mOpenAction;
+ /** The file sharing mode. */
+ FileSharingMode_T mSharingMode;
+ /** Octal creation mode. */
+ uint32_t mCreationMode;
+ /** Extended open flags (currently none defined). */
+ uint32_t mfOpenEx;
+};
+
+
+/**
+ * Structure representing information of a
+ * file system object.
+ */
+struct GuestFsObjData
+{
+ GuestFsObjData(void)
+ : mType(FsObjType_Unknown)
+ , mObjectSize(0)
+ , mAllocatedSize(0)
+ , mAccessTime(0)
+ , mBirthTime(0)
+ , mChangeTime(0)
+ , mModificationTime(0)
+ , mUID(0)
+ , mGID(0)
+ , mNodeID(0)
+ , mNodeIDDevice(0)
+ , mNumHardLinks(0)
+ , mDeviceNumber(0)
+ , mGenerationID(0)
+ , mUserFlags(0) { }
+
+ /** @name Helper functions to extract the data from a certin VBoxService tool's guest stream block.
+ * @{ */
+ int FromLs(const GuestProcessStreamBlock &strmBlk, bool fLong);
+ int FromRm(const GuestProcessStreamBlock &strmBlk);
+ int FromStat(const GuestProcessStreamBlock &strmBlk);
+ int FromMkTemp(const GuestProcessStreamBlock &strmBlk);
+ /** @} */
+
+ /** @name Static helper functions to work with time from stream block keys.
+ * @{ */
+ static PRTTIMESPEC TimeSpecFromKey(const GuestProcessStreamBlock &strmBlk, const Utf8Str &strKey, PRTTIMESPEC pTimeSpec);
+ static int64_t UnixEpochNsFromKey(const GuestProcessStreamBlock &strmBlk, const Utf8Str &strKey);
+ /** @} */
+
+ /** @name helper functions to work with IPRT stuff.
+ * @{ */
+ RTFMODE GetFileMode(void) const;
+ /** @} */
+
+ Utf8Str mName;
+ FsObjType_T mType;
+ Utf8Str mFileAttrs;
+ int64_t mObjectSize;
+ int64_t mAllocatedSize;
+ int64_t mAccessTime;
+ int64_t mBirthTime;
+ int64_t mChangeTime;
+ int64_t mModificationTime;
+ Utf8Str mUserName;
+ int32_t mUID;
+ int32_t mGID;
+ Utf8Str mGroupName;
+ Utf8Str mACL;
+ int64_t mNodeID;
+ uint32_t mNodeIDDevice;
+ uint32_t mNumHardLinks;
+ uint32_t mDeviceNumber;
+ uint32_t mGenerationID;
+ uint32_t mUserFlags;
+};
+
+
+/**
+ * Structure for keeping all the relevant guest session
+ * startup parameters around.
+ */
+class GuestSessionStartupInfo
+{
+public:
+
+ GuestSessionStartupInfo(void)
+ : mID(UINT32_MAX)
+ , mIsInternal(false /* Non-internal session */)
+ , mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */)
+ , mOpenFlags(0 /* No opening flags set */) { }
+
+ /** The session's friendly name. Optional. */
+ Utf8Str mName;
+ /** The session's unique ID. Used to encode a context ID.
+ * UINT32_MAX if not initialized. */
+ uint32_t mID;
+ /** Flag indicating if this is an internal session
+ * or not. Internal session are not accessible by
+ * public API clients. */
+ bool mIsInternal;
+ /** Timeout (in ms) used for opening the session. */
+ uint32_t mOpenTimeoutMS;
+ /** Session opening flags. */
+ uint32_t mOpenFlags;
+};
+
+
+/**
+ * Structure for keeping all the relevant guest process
+ * startup parameters around.
+ */
+class GuestProcessStartupInfo
+{
+public:
+
+ GuestProcessStartupInfo(void)
+ : mFlags(ProcessCreateFlag_None)
+ , mTimeoutMS(UINT32_MAX /* No timeout by default */)
+ , mPriority(ProcessPriority_Default)
+ , mAffinity(0) { }
+
+ /** The process' friendly name. */
+ Utf8Str mName;
+ /** The executable. */
+ Utf8Str mExecutable;
+ /** Arguments vector (starting with argument \#0). */
+ ProcessArguments mArguments;
+ /** The process environment change record. */
+ GuestEnvironmentChanges mEnvironmentChanges;
+ /** Process creation flags. */
+ uint32_t mFlags;
+ /** Timeout (in ms) the process is allowed to run.
+ * Specify UINT32_MAX if no timeout (unlimited run time) is given. */
+ ULONG mTimeoutMS;
+ /** Process priority. */
+ ProcessPriority_T mPriority;
+ /** Process affinity. At the moment we
+ * only support 64 VCPUs. API and
+ * guest can do more already! */
+ uint64_t mAffinity;
+};
+
+
+/**
+ * Class representing the "value" side of a "key=value" pair.
+ */
+class GuestProcessStreamValue
+{
+public:
+
+ GuestProcessStreamValue(void) { }
+ GuestProcessStreamValue(const char *pszValue, size_t cwcValue = RTSTR_MAX)
+ : mValue(pszValue, cwcValue) {}
+
+ GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
+ : mValue(aThat.mValue) { }
+
+ /** Copy assignment operator. */
+ GuestProcessStreamValue &operator=(GuestProcessStreamValue const &a_rThat) RT_NOEXCEPT
+ {
+ mValue = a_rThat.mValue;
+
+ return *this;
+ }
+
+ Utf8Str mValue;
+};
+
+/** Map containing "key=value" pairs of a guest process stream. */
+typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
+typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
+typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
+typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
+
+class GuestProcessStream;
+
+/**
+ * Class representing a block of stream pairs (key=value). Each block in a raw guest
+ * output stream is separated by "\0\0", each pair is separated by "\0". The overall
+ * end of a guest stream is marked by "\0\0\0\0".
+ *
+ * An empty stream block will be treated as being incomplete.
+ *
+ * Only used for the busybox-like toolbox commands within VBoxService.
+ * Deprecated, do not use anymore.
+ */
+class GuestProcessStreamBlock
+{
+ friend GuestProcessStream;
+
+public:
+
+ GuestProcessStreamBlock(void);
+
+ virtual ~GuestProcessStreamBlock(void);
+
+public:
+
+ void Clear(void);
+
+#ifdef DEBUG
+ void DumpToLog(void) const;
+#endif
+
+ const char *GetString(const char *pszKey) const;
+ size_t GetCount(void) const;
+ int GetVrc(bool fSucceedIfNotFound = false) const;
+ int GetInt64Ex(const char *pszKey, int64_t *piVal) const;
+ int64_t GetInt64(const char *pszKey) const;
+ int GetUInt32Ex(const char *pszKey, uint32_t *puVal) const;
+ uint32_t GetUInt32(const char *pszKey, uint32_t uDefault = 0) const;
+ int32_t GetInt32(const char *pszKey, int32_t iDefault = 0) const;
+
+ bool IsComplete(void) const { return !m_mapPairs.empty() && m_fComplete; }
+ bool IsEmpty(void) const { return m_mapPairs.empty(); }
+
+ int SetValueEx(const char *pszKey, size_t cwcKey, const char *pszValue, size_t cwcValue, bool fOverwrite = false);
+ int SetValue(const char *pszKey, const char *pszValue);
+
+protected:
+
+ /** Wheter the stream block is marked as complete.
+ * An empty stream block is considered as incomplete. */
+ bool m_fComplete;
+ /** Map of stream pairs this block contains.*/
+ GuestCtrlStreamPairMap m_mapPairs;
+};
+
+/** Vector containing multiple allocated stream pair objects. */
+typedef std::vector< GuestProcessStreamBlock > GuestCtrlStreamObjects;
+typedef std::vector< GuestProcessStreamBlock >::iterator GuestCtrlStreamObjectsIter;
+typedef std::vector< GuestProcessStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
+
+/** Defines a single terminator as a single char. */
+#define GUESTTOOLBOX_STRM_TERM '\0'
+/** Defines a single terminator as a string. */
+#define GUESTTOOLBOX_STRM_TERM_STR "\0"
+/** Defines the termination sequence for a single key/value pair. */
+#define GUESTTOOLBOX_STRM_TERM_PAIR_STR GUESTTOOLBOX_STRM_TERM_STR
+/** Defines the termination sequence for a single stream block. */
+#define GUESTTOOLBOX_STRM_TERM_BLOCK_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR
+/** Defines the termination sequence for the stream. */
+#define GUESTTOOLBOX_STRM_TERM_STREAM_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR
+/** Defines how many consequtive terminators a key/value pair has. */
+#define GUESTTOOLBOX_STRM_PAIR_TERM_CNT 1
+/** Defines how many consequtive terminators a stream block has. */
+#define GUESTTOOLBOX_STRM_BLK_TERM_CNT 2
+/** Defines how many consequtive terminators a stream has. */
+#define GUESTTOOLBOX_STRM_TERM_CNT 4
+
+/**
+ * Class for parsing machine-readable guest process output by VBoxService'
+ * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
+ */
+class GuestProcessStream
+{
+
+public:
+
+ GuestProcessStream();
+
+ virtual ~GuestProcessStream();
+
+public:
+
+ int AddData(const BYTE *pbData, size_t cbData);
+
+ void Destroy();
+
+#ifdef DEBUG
+ void Dump(const char *pszFile);
+#endif
+
+ size_t GetOffset(void) const { return m_offBuf; }
+
+ size_t GetSize(void) const { return m_cbUsed; }
+
+ size_t GetBlocks(void) const { return m_cBlocks; }
+
+ int ParseBlock(GuestProcessStreamBlock &streamBlock);
+
+protected:
+
+ /** Maximum allowed size the stream buffer can grow to.
+ * Defaults to 32 MB. */
+ size_t m_cbMax;
+ /** Currently allocated size of internal stream buffer. */
+ size_t m_cbAllocated;
+ /** Currently used size at m_offBuffer. */
+ size_t m_cbUsed;
+ /** Current byte offset within the internal stream buffer. */
+ size_t m_offBuf;
+ /** Internal stream buffer. */
+ BYTE *m_pbBuffer;
+ /** How many completed stream blocks already were processed. */
+ size_t m_cBlocks;
+};
+
+class Guest;
+class Progress;
+
+class GuestWaitEventPayload
+{
+
+public:
+
+ GuestWaitEventPayload(void)
+ : uType(0)
+ , cbData(0)
+ , pvData(NULL)
+ { }
+
+ /**
+ * Initialization constructor.
+ *
+ * @throws VBox status code (vrc).
+ *
+ * @param uTypePayload Payload type to set.
+ * @param pvPayload Pointer to payload data to set (deep copy).
+ * @param cbPayload Size (in bytes) of payload data to set.
+ */
+ GuestWaitEventPayload(uint32_t uTypePayload, const void *pvPayload, uint32_t cbPayload)
+ : uType(0)
+ , cbData(0)
+ , pvData(NULL)
+ {
+ int vrc = copyFrom(uTypePayload, pvPayload, cbPayload);
+ if (RT_FAILURE(vrc))
+ throw vrc;
+ }
+
+ virtual ~GuestWaitEventPayload(void)
+ {
+ Clear();
+ }
+
+ GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that)
+ {
+ CopyFromDeep(that);
+ return *this;
+ }
+
+public:
+
+ void Clear(void)
+ {
+ if (pvData)
+ {
+ Assert(cbData);
+ RTMemFree(pvData);
+ cbData = 0;
+ pvData = NULL;
+ }
+ uType = 0;
+ }
+
+ int CopyFromDeep(const GuestWaitEventPayload &payload)
+ {
+ return copyFrom(payload.uType, payload.pvData, payload.cbData);
+ }
+
+ const void* Raw(void) const { return pvData; }
+
+ size_t Size(void) const { return cbData; }
+
+ uint32_t Type(void) const { return uType; }
+
+ void* MutableRaw(void) { return pvData; }
+
+ Utf8Str ToString(void)
+ {
+ const char *pszStr = (const char *)pvData;
+ size_t cbStr = cbData;
+
+ if (RT_FAILURE(RTStrValidateEncodingEx(pszStr, cbStr,
+ RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED | RTSTR_VALIDATE_ENCODING_EXACT_LENGTH)))
+ {
+ AssertFailed();
+ return "";
+ }
+
+ return Utf8Str(pszStr, cbStr);
+ }
+
+protected:
+
+ int copyFrom(uint32_t uTypePayload, const void *pvPayload, uint32_t cbPayload)
+ {
+ if (cbPayload > _64K) /* Paranoia. */
+ return VERR_TOO_MUCH_DATA;
+
+ Clear();
+
+ int vrc = VINF_SUCCESS;
+ if (cbPayload)
+ {
+ pvData = RTMemAlloc(cbPayload);
+ if (pvData)
+ {
+ uType = uTypePayload;
+
+ memcpy(pvData, pvPayload, cbPayload);
+ cbData = cbPayload;
+ }
+ else
+ vrc = VERR_NO_MEMORY;
+ }
+ else
+ {
+ uType = uTypePayload;
+
+ pvData = NULL;
+ cbData = 0;
+ }
+
+ return vrc;
+ }
+
+protected:
+
+ /** Type of payload. */
+ uint32_t uType;
+ /** Size (in bytes) of payload. */
+ uint32_t cbData;
+ /** Pointer to actual payload data. */
+ void *pvData;
+};
+
+class GuestWaitEventBase
+{
+
+protected:
+
+ GuestWaitEventBase(void);
+ virtual ~GuestWaitEventBase(void);
+
+public:
+
+ uint32_t ContextID(void) { return mCID; };
+ int GuestResult(void) { return mGuestRc; }
+ int Result(void) { return mVrc; }
+ GuestWaitEventPayload &Payload(void) { return mPayload; }
+ int SignalInternal(int vrc, int vrcGuest, const GuestWaitEventPayload *pPayload);
+ int Wait(RTMSINTERVAL uTimeoutMS);
+
+protected:
+
+ int Init(uint32_t uCID);
+
+protected:
+
+ /** Shutdown indicator. */
+ bool mfAborted;
+ /** Associated context ID (CID). */
+ uint32_t mCID;
+ /** The event semaphore for triggering the actual event. */
+ RTSEMEVENT mEventSem;
+ /** The event's overall result.
+ * If set to VERR_GSTCTL_GUEST_ERROR, mGuestRc will contain the actual
+ * error code from the guest side. */
+ int mVrc;
+ /** The event'S overall result from the guest side.
+ * If used, mVrc must be set to VERR_GSTCTL_GUEST_ERROR. */
+ int mGuestRc;
+ /** The event's payload data. Optional. */
+ GuestWaitEventPayload mPayload;
+};
+
+/** List of public guest event types. */
+typedef std::list < VBoxEventType_T > GuestEventTypes;
+
+class GuestWaitEvent : public GuestWaitEventBase
+{
+
+public:
+
+ GuestWaitEvent(void);
+ virtual ~GuestWaitEvent(void);
+
+public:
+
+ int Init(uint32_t uCID);
+ int Init(uint32_t uCID, const GuestEventTypes &lstEvents);
+ int Cancel(void);
+ const ComPtr<IEvent> Event(void) { return mEvent; }
+ bool HasGuestError(void) const { return mVrc == VERR_GSTCTL_GUEST_ERROR; }
+ int GetGuestError(void) const { return mGuestRc; }
+ int SignalExternal(IEvent *pEvent);
+ const GuestEventTypes &Types(void) { return mEventTypes; }
+ size_t TypeCount(void) { return mEventTypes.size(); }
+
+protected:
+
+ /** List of public event types this event should
+ * be signalled on. Optional. */
+ GuestEventTypes mEventTypes;
+ /** Pointer to the actual public event, if any. */
+ ComPtr<IEvent> mEvent;
+};
+/** Map of pointers to guest events. The primary key
+ * contains the context ID. */
+typedef std::map < uint32_t, GuestWaitEvent* > GuestWaitEvents;
+/** Map of wait events per public guest event. Nice for
+ * faster lookups when signalling a whole event group. */
+typedef std::map < VBoxEventType_T, GuestWaitEvents > GuestEventGroup;
+
+class GuestBase
+{
+
+public:
+
+ GuestBase(void);
+ virtual ~GuestBase(void);
+
+public:
+
+ /** Signals a wait event using a public guest event; also used for
+ * for external event listeners. */
+ int signalWaitEvent(VBoxEventType_T aType, IEvent *aEvent);
+ /** Signals a wait event using a guest vrc. */
+ int signalWaitEventInternal(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int vrcGuest, const GuestWaitEventPayload *pPayload);
+ /** Signals a wait event without letting public guest events know,
+ * extended director's cut version. */
+ int signalWaitEventInternalEx(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int vrc, int vrcGuest, const GuestWaitEventPayload *pPayload);
+
+public:
+
+ int baseInit(void);
+ void baseUninit(void);
+ int cancelWaitEvents(void);
+ int dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID);
+ int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent);
+ int registerWaitEventEx(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
+ int unregisterWaitEvent(GuestWaitEvent *pEvent);
+ int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent);
+
+public:
+
+ static FsObjType_T fileModeToFsObjType(RTFMODE fMode);
+ static const char *fsObjTypeToStr(FsObjType_T enmType);
+ static const char *pathStyleToStr(PathStyle_T enmPathStyle);
+ static Utf8Str getErrorAsString(const Utf8Str &strAction, const GuestErrorInfo& guestErrorInfo);
+ static Utf8Str getErrorAsString(const GuestErrorInfo &guestErrorInfo);
+
+protected:
+
+ /** Pointer to the console object. Needed
+ * for HGCM (VMMDev) communication. */
+ Console *mConsole;
+ /** The next context ID counter component for this object. */
+ uint32_t mNextContextID;
+ /** Local listener for handling the waiting events
+ * internally. */
+ ComPtr<IEventListener> mLocalListener;
+ /** Critical section for wait events access. */
+ RTCRITSECT mWaitEventCritSect;
+ /** Map of registered wait events per event group. */
+ GuestEventGroup mWaitEventGroups;
+ /** Map of registered wait events. */
+ GuestWaitEvents mWaitEvents;
+};
+
+/**
+ * Virtual class (interface) for guest objects (processes, files, ...) --
+ * contains all per-object callback management.
+ */
+class GuestObject : public GuestBase
+{
+ friend class GuestSession;
+
+public:
+
+ GuestObject(void);
+ virtual ~GuestObject(void);
+
+public:
+
+ ULONG getObjectID(void) { return mObjectID; }
+
+protected:
+
+ /**
+ * Called by IGuestSession when the session status has been changed.
+ *
+ * @returns VBox status code.
+ * @param enmSessionStatus New session status.
+ */
+ virtual int i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus) = 0;
+
+ /**
+ * Called by IGuestSession right before this object gets
+ * unregistered (removed) from the public object list.
+ */
+ virtual int i_onUnregister(void) = 0;
+
+ /** Callback dispatcher -- must be implemented by the actual object. */
+ virtual int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) = 0;
+
+protected:
+
+ int bindToSession(Console *pConsole, GuestSession *pSession, uint32_t uObjectID);
+ int registerWaitEvent(const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
+ int sendMessage(uint32_t uFunction, uint32_t cParms, PVBOXHGCMSVCPARM paParms);
+
+protected:
+
+ /** @name Common parameters for all derived objects. They have their own
+ * mData structure to keep their specific data around.
+ * @{ */
+ /** Pointer to parent session. Per definition
+ * this objects *always* lives shorter than the
+ * parent.
+ * @todo r=bird: When wanting to use mSession in the
+ * IGuestProcess::getEnvironment() implementation I wanted to access
+ * GuestSession::mData::mpBaseEnvironment. Seeing the comment in
+ * GuestProcess::terminate() saying:
+ * "Now only API clients still can hold references to it."
+ * and recalling seeing similar things in VirtualBox.xidl or some such place,
+ * I'm wondering how this "per definition" behavior is enforced. Is there any
+ * GuestProcess:uninit() call or similar magic that invalidates objects that
+ * GuestSession loses track of in place like GuestProcess::terminate() that I've
+ * failed to spot?
+ *
+ * Please enlighten me.
+ */
+ GuestSession *mSession;
+ /** The object ID -- must be unique for each guest
+ * object and is encoded into the context ID. Must
+ * be set manually when initializing the object.
+ *
+ * For guest processes this is the internal PID,
+ * for guest files this is the internal file ID. */
+ uint32_t mObjectID;
+ /** @} */
+};
+
+/** Returns the path separator based on \a a_enmPathStyle as a C-string. */
+#define PATH_STYLE_SEP_STR(a_enmPathStyle) a_enmPathStyle == PathStyle_DOS ? "\\" : "/"
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+# define PATH_STYLE_NATIVE PathStyle_DOS
+#else
+# define PATH_STYLE_NATIVE PathStyle_UNIX
+#endif
+
+/**
+ * Class for handling guest / host path functions.
+ */
+class GuestPath
+{
+private:
+
+ /**
+ * Default constructor.
+ *
+ * Not directly instantiable (yet).
+ */
+ GuestPath(void) { }
+
+public:
+
+ /** @name Static helper functions.
+ * @{ */
+ static int BuildDestinationPath(const Utf8Str &strSrcPath, PathStyle_T enmSrcPathStyle, Utf8Str &strDstPath, PathStyle_T enmDstPathStyle);
+ static int Translate(Utf8Str &strPath, PathStyle_T enmSrcPathStyle, PathStyle_T enmDstPathStyle, bool fForce = false);
+ /** @} */
+};
+#endif /* !MAIN_INCLUDED_GuestCtrlImplPrivate_h */
+
diff --git a/src/VBox/Main/include/GuestDebugControlImpl.h b/src/VBox/Main/include/GuestDebugControlImpl.h
new file mode 100644
index 00000000..76263a13
--- /dev/null
+++ b/src/VBox/Main/include/GuestDebugControlImpl.h
@@ -0,0 +1,82 @@
+/* $Id: GuestDebugControlImpl.h $ */
+/** @file
+ *
+ * VirtualBox/GuestDebugControl COM class implementation
+ */
+
+/*
+ * Copyright (C) 2022-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestDebugControlImpl_h
+#define MAIN_INCLUDED_GuestDebugControlImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestDebugControlWrap.h"
+
+namespace settings
+{
+ struct Debugging;
+}
+
+class ATL_NO_VTABLE GuestDebugControl :
+ public GuestDebugControlWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(GuestDebugControl)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent);
+ HRESULT init(Machine *aParent, GuestDebugControl *aThat);
+ HRESULT initCopy(Machine *aParent, GuestDebugControl *aThat);
+ void uninit();
+
+ // public internal methods
+ HRESULT i_loadSettings(const settings::Debugging &data);
+ HRESULT i_saveSettings(settings::Debugging &data);
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(GuestDebugControl *aThat);
+ Machine *i_getMachine() const;
+
+private:
+
+ // wrapped IGuestDebugControl properties
+ HRESULT getDebugProvider(GuestDebugProvider_T *aDebugProvider);
+ HRESULT setDebugProvider(GuestDebugProvider_T aDebugProvider);
+ HRESULT getDebugIoProvider(GuestDebugIoProvider_T *aDebugIoProvider);
+ HRESULT setDebugIoProvider(GuestDebugIoProvider_T aDebugIoProvider);
+ HRESULT getDebugAddress(com::Utf8Str &aAddress);
+ HRESULT setDebugAddress(const com::Utf8Str &aAddress);
+ HRESULT getDebugPort(ULONG *aPort);
+ HRESULT setDebugPort(ULONG aPort);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_GuestDebugControlImpl_h */
diff --git a/src/VBox/Main/include/GuestDirectoryImpl.h b/src/VBox/Main/include/GuestDirectoryImpl.h
new file mode 100644
index 00000000..9dc2223b
--- /dev/null
+++ b/src/VBox/Main/include/GuestDirectoryImpl.h
@@ -0,0 +1,108 @@
+/* $Id: GuestDirectoryImpl.h $ */
+/** @file
+ * VirtualBox Main - Guest directory handling implementation.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestDirectoryImpl_h
+#define MAIN_INCLUDED_GuestDirectoryImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestDirectoryWrap.h"
+#include "GuestFsObjInfoImpl.h"
+#include "GuestProcessImpl.h"
+
+class GuestSession;
+
+/**
+ * TODO
+ */
+class ATL_NO_VTABLE GuestDirectory :
+ public GuestDirectoryWrap,
+ public GuestObject
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(GuestDirectory)
+
+ int init(Console *pConsole, GuestSession *pSession, ULONG aObjectID, const GuestDirectoryOpenInfo &openInfo);
+ void uninit(void);
+
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+public:
+ /** @name Implemented virtual methods from GuestObject.
+ * @{ */
+ int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ int i_onUnregister(void);
+ int i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus);
+ /** @} */
+
+public:
+ /** @name Public internal methods.
+ * @{ */
+ int i_closeInternal(int *pvrcGuest);
+ int i_read(ComObjPtr<GuestFsObjInfo> &fsObjInfo, int *pvrcGuest);
+ int i_readInternal(GuestFsObjData &objData, int *prcGuest);
+ /** @} */
+
+public:
+ /** @name Public static internal methods.
+ * @{ */
+ static Utf8Str i_guestErrorToString(int vrcGuest, const char *pcszWhat);
+ /** @} */
+
+private:
+
+ /** Wrapped @name IGuestDirectory properties
+ * @{ */
+ HRESULT getDirectoryName(com::Utf8Str &aDirectoryName);
+ HRESULT getFilter(com::Utf8Str &aFilter);
+ /** @} */
+
+ /** Wrapped @name IGuestDirectory methods.
+ * @{ */
+ HRESULT close();
+ HRESULT read(ComPtr<IFsObjInfo> &aObjInfo);
+ /** @} */
+
+ struct Data
+ {
+ /** The directory's open info. */
+ GuestDirectoryOpenInfo mOpenInfo;
+ /** The process tool instance to use. */
+ GuestProcessTool mProcessTool;
+ /** Object data cache.
+ * Its mName attribute acts as a beacon if the cache is valid or not. */
+ GuestFsObjData mObjData;
+ } mData;
+};
+
+#endif /* !MAIN_INCLUDED_GuestDirectoryImpl_h */
+
diff --git a/src/VBox/Main/include/GuestDnDPrivate.h b/src/VBox/Main/include/GuestDnDPrivate.h
new file mode 100644
index 00000000..ca5d3a96
--- /dev/null
+++ b/src/VBox/Main/include/GuestDnDPrivate.h
@@ -0,0 +1,1108 @@
+/* $Id: GuestDnDPrivate.h $ */
+/** @file
+ * Private guest drag and drop code, used by GuestDnDTarget +
+ * GuestDnDSource.
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestDnDPrivate_h
+#define MAIN_INCLUDED_GuestDnDPrivate_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/dir.h>
+#include <iprt/file.h>
+#include <iprt/path.h>
+
+#include <VBox/hgcmsvc.h> /* For PVBOXHGCMSVCPARM. */
+#include <VBox/GuestHost/DragAndDrop.h>
+#include <VBox/GuestHost/DragAndDropDefs.h>
+#include <VBox/HostServices/DragAndDropSvc.h>
+
+/**
+ * Forward prototype declarations.
+ */
+class Guest;
+class GuestDnDBase;
+class GuestDnDState;
+class GuestDnDSource;
+class GuestDnDTarget;
+class Progress;
+
+/**
+ * Type definitions.
+ */
+
+/** List (vector) of MIME types. */
+typedef std::vector<com::Utf8Str> GuestDnDMIMEList;
+
+/**
+ * Class to handle a guest DnD callback event.
+ */
+class GuestDnDCallbackEvent
+{
+public:
+
+ GuestDnDCallbackEvent(void)
+ : m_SemEvent(NIL_RTSEMEVENT)
+ , m_vrc(VINF_SUCCESS) { }
+
+ virtual ~GuestDnDCallbackEvent(void);
+
+public:
+
+ int Reset(void);
+
+ int Notify(int vrc = VINF_SUCCESS);
+
+ int Result(void) const { return m_vrc; }
+
+ int Wait(RTMSINTERVAL msTimeout);
+
+protected:
+
+ /** Event semaphore to notify on error/completion. */
+ RTSEMEVENT m_SemEvent;
+ /** Callback result. */
+ int m_vrc;
+};
+
+/**
+ * Struct for handling the (raw) meta data.
+ */
+struct GuestDnDMetaData
+{
+ GuestDnDMetaData(void)
+ : pvData(NULL)
+ , cbData(0)
+ , cbAllocated(0)
+ , cbAnnounced(0) { }
+
+ virtual ~GuestDnDMetaData(void)
+ {
+ reset();
+ }
+
+ /**
+ * Adds new meta data.
+ *
+ * @returns New (total) meta data size in bytes.
+ * @param pvDataAdd Pointer of data to add.
+ * @param cbDataAdd Size (in bytes) of data to add.
+ */
+ size_t add(const void *pvDataAdd, size_t cbDataAdd)
+ {
+ LogFlowThisFunc(("cbAllocated=%zu, cbAnnounced=%zu, pvDataAdd=%p, cbDataAdd=%zu\n",
+ cbAllocated, cbAnnounced, pvDataAdd, cbDataAdd));
+ if (!cbDataAdd)
+ return 0;
+ AssertPtrReturn(pvDataAdd, 0);
+
+ const size_t cbAllocatedTmp = cbData + cbDataAdd;
+ if (cbAllocatedTmp > cbAllocated)
+ {
+ int vrc = resize(cbAllocatedTmp);
+ if (RT_FAILURE(vrc))
+ return 0;
+ }
+
+ Assert(cbAllocated >= cbData + cbDataAdd);
+ memcpy((uint8_t *)pvData + cbData, pvDataAdd, cbDataAdd);
+
+ cbData += cbDataAdd;
+ cbAnnounced = cbData;
+
+ return cbData;
+ }
+
+ /**
+ * Adds new meta data.
+ *
+ * @returns New (total) meta data size in bytes.
+ * @param vecAdd Meta data to add.
+ */
+ size_t add(const std::vector<BYTE> &vecAdd)
+ {
+ if (!vecAdd.size())
+ return 0;
+
+ if (vecAdd.size() > UINT32_MAX) /* Paranoia. */
+ return 0;
+
+ return add(&vecAdd.front(), (uint32_t)vecAdd.size());
+ }
+
+ /**
+ * Resets (clears) all data.
+ */
+ void reset(void)
+ {
+ strFmt = "";
+
+ if (pvData)
+ {
+ Assert(cbAllocated);
+ RTMemFree(pvData);
+ pvData = NULL;
+ }
+
+ cbData = 0;
+ cbAllocated = 0;
+ cbAnnounced = 0;
+ }
+
+ /**
+ * Resizes the allocation size.
+ *
+ * @returns VBox status code.
+ * @param cbSize New allocation size (in bytes).
+ */
+ int resize(size_t cbSize)
+ {
+ if (!cbSize)
+ {
+ reset();
+ return VINF_SUCCESS;
+ }
+
+ if (cbSize == cbAllocated)
+ return VINF_SUCCESS;
+
+ cbSize = RT_ALIGN_Z(cbSize, PAGE_SIZE);
+
+ if (cbSize > _32M) /* Meta data can be up to 32MB. */
+ return VERR_BUFFER_OVERFLOW;
+
+ void *pvTmp = NULL;
+ if (!cbAllocated)
+ {
+ Assert(cbData == 0);
+ pvTmp = RTMemAllocZ(cbSize);
+ }
+ else
+ {
+ AssertPtr(pvData);
+ pvTmp = RTMemRealloc(pvData, cbSize);
+ }
+
+ if (pvTmp)
+ {
+ pvData = pvTmp;
+ cbAllocated = cbSize;
+ return VINF_SUCCESS;
+ }
+
+ return VERR_NO_MEMORY;
+ }
+
+ /** Format string of this meta data. */
+ com::Utf8Str strFmt;
+ /** Pointer to allocated meta data. */
+ void *pvData;
+ /** Used bytes of meta data. Must not exceed cbAllocated. */
+ size_t cbData;
+ /** Size (in bytes) of allocated meta data. */
+ size_t cbAllocated;
+ /** Size (in bytes) of announced meta data. */
+ size_t cbAnnounced;
+};
+
+/**
+ * Struct for accounting shared DnD data to be sent/received.
+ */
+struct GuestDnDData
+{
+ GuestDnDData(void)
+ : cbExtra(0)
+ , cbProcessed(0) { }
+
+ virtual ~GuestDnDData(void)
+ {
+ reset();
+ }
+
+ /**
+ * Adds processed data to the internal accounting.
+ *
+ * @returns New processed data size.
+ * @param cbDataAdd Bytes to add as done processing.
+ */
+ size_t addProcessed(size_t cbDataAdd)
+ {
+ const size_t cbTotal = getTotalAnnounced(); RT_NOREF(cbTotal);
+ AssertReturn(cbProcessed + cbDataAdd <= cbTotal, 0);
+ cbProcessed += cbDataAdd;
+ return cbProcessed;
+ }
+
+ /**
+ * Returns whether all data has been processed or not.
+ *
+ * @returns \c true if all data has been processed, \c false if not.
+ */
+ bool isComplete(void) const
+ {
+ const size_t cbTotal = getTotalAnnounced();
+ LogFlowFunc(("cbProcessed=%zu, cbTotal=%zu\n", cbProcessed, cbTotal));
+ AssertReturn(cbProcessed <= cbTotal, true);
+ return (cbProcessed == cbTotal);
+ }
+
+ /**
+ * Returns the percentage (0-100) of the already processed data.
+ *
+ * @returns Percentage (0-100) of the already processed data.
+ */
+ uint8_t getPercentComplete(void) const
+ {
+ const size_t cbTotal = getTotalAnnounced();
+ return (uint8_t)(cbProcessed * 100 / RT_MAX(cbTotal, 1));
+ }
+
+ /**
+ * Returns the remaining (outstanding) data left for processing.
+ *
+ * @returns Remaining (outstanding) data (in bytes) left for processing.
+ */
+ size_t getRemaining(void) const
+ {
+ const size_t cbTotal = getTotalAnnounced();
+ AssertReturn(cbProcessed <= cbTotal, 0);
+ return cbTotal - cbProcessed;
+ }
+
+ /**
+ * Returns the total data size (in bytes) announced.
+ *
+ * @returns Total data size (in bytes) announced.
+ */
+ size_t getTotalAnnounced(void) const
+ {
+ return Meta.cbAnnounced + cbExtra;
+ }
+
+ /**
+ * Returns the total data size (in bytes) available.
+ * For receiving data, this represents the already received data.
+ * For sending data, this represents the data left to send.
+ *
+ * @returns Total data size (in bytes) available.
+ */
+ size_t getTotalAvailable(void) const
+ {
+ return Meta.cbData + cbExtra;
+ }
+
+ /**
+ * Resets all data.
+ */
+ void reset(void)
+ {
+ Meta.reset();
+
+ cbExtra = 0;
+ cbProcessed = 0;
+ }
+
+ /** For storing the actual meta data.
+ * This might be an URI list or just plain raw data,
+ * according to the format being sent. */
+ GuestDnDMetaData Meta;
+ /** Extra data to send/receive (in bytes). Can be 0 for raw data.
+ * For (file) transfers this is the total size for all files. */
+ size_t cbExtra;
+ /** Overall size (in bytes) of processed data. */
+ size_t cbProcessed;
+};
+
+/** Initial object context state / no state set. */
+#define DND_OBJ_STATE_NONE 0
+/** The header was received / sent. */
+#define DND_OBJ_STATE_HAS_HDR RT_BIT(0)
+/** Validation mask for object context state. */
+#define DND_OBJ_STATE_VALID_MASK UINT32_C(0x00000001)
+
+/**
+ * Base class for keeping around DnD (file) transfer data.
+ * Used for sending / receiving transfer data.
+ */
+struct GuestDnDTransferData
+{
+
+public:
+
+ GuestDnDTransferData(void)
+ : cObjToProcess(0)
+ , cObjProcessed(0)
+ , pvScratchBuf(NULL)
+ , cbScratchBuf(0) { }
+
+ virtual ~GuestDnDTransferData(void)
+ {
+ destroy();
+ }
+
+ /**
+ * Initializes a transfer data object.
+ *
+ * @param cbBuf Scratch buffer size (in bytes) to use.
+ * If not specified, DND_DEFAULT_CHUNK_SIZE will be used.
+ */
+ int init(size_t cbBuf = DND_DEFAULT_CHUNK_SIZE)
+ {
+ reset();
+
+ pvScratchBuf = RTMemAlloc(cbBuf);
+ if (!pvScratchBuf)
+ return VERR_NO_MEMORY;
+
+ cbScratchBuf = cbBuf;
+ return VINF_SUCCESS;
+ }
+
+ /**
+ * Destroys a transfer data object.
+ */
+ void destroy(void)
+ {
+ reset();
+
+ if (pvScratchBuf)
+ {
+ Assert(cbScratchBuf);
+ RTMemFree(pvScratchBuf);
+ pvScratchBuf = NULL;
+ }
+ cbScratchBuf = 0;
+ }
+
+ /**
+ * Resets a transfer data object.
+ */
+ void reset(void)
+ {
+ LogFlowFuncEnter();
+
+ cObjToProcess = 0;
+ cObjProcessed = 0;
+ }
+
+ /**
+ * Returns whether this transfer object is complete or not.
+ *
+ * @returns \c true if complete, \c false if not.
+ */
+ bool isComplete(void) const
+ {
+ return (cObjProcessed == cObjToProcess);
+ }
+
+ /** Number of objects to process. */
+ uint64_t cObjToProcess;
+ /** Number of objects already processed. */
+ uint64_t cObjProcessed;
+ /** Pointer to an optional scratch buffer to use for
+ * doing the actual chunk transfers. */
+ void *pvScratchBuf;
+ /** Size (in bytes) of scratch buffer. */
+ size_t cbScratchBuf;
+};
+
+/**
+ * Class for keeping around DnD transfer send data (Host -> Guest).
+ */
+struct GuestDnDTransferSendData : public GuestDnDTransferData
+{
+ GuestDnDTransferSendData()
+ : fObjState(0)
+ {
+ RT_ZERO(List);
+ int vrc2 = DnDTransferListInit(&List);
+ AssertRC(vrc2);
+ }
+
+ virtual ~GuestDnDTransferSendData()
+ {
+ destroy();
+ }
+
+ /**
+ * Destroys the object.
+ */
+ void destroy(void)
+ {
+ DnDTransferListDestroy(&List);
+ }
+
+ /**
+ * Resets the object.
+ */
+ void reset(void)
+ {
+ DnDTransferListReset(&List);
+ fObjState = 0;
+
+ GuestDnDTransferData::reset();
+ }
+
+ /** Transfer List to handle. */
+ DNDTRANSFERLIST List;
+ /** Current state of object in transfer.
+ * This is needed for keeping compatibility to old(er) DnD HGCM protocols.
+ *
+ * At the moment we only support transferring one object at a time. */
+ uint32_t fObjState;
+};
+
+/**
+ * Context structure for sending data to the guest.
+ */
+struct GuestDnDSendCtx : public GuestDnDData
+{
+ GuestDnDSendCtx(void);
+
+ /**
+ * Resets the object.
+ */
+ void reset(void);
+
+ /** Pointer to guest target class this context belongs to. */
+ GuestDnDTarget *pTarget;
+ /** Pointer to guest state this context belongs to. */
+ GuestDnDState *pState;
+ /** Target (VM) screen ID. */
+ uint32_t uScreenID;
+ /** Transfer data structure. */
+ GuestDnDTransferSendData Transfer;
+ /** Callback event to use. */
+ GuestDnDCallbackEvent EventCallback;
+};
+
+struct GuestDnDTransferRecvData : public GuestDnDTransferData
+{
+ GuestDnDTransferRecvData()
+ {
+ RT_ZERO(DroppedFiles);
+ int vrc2 = DnDDroppedFilesInit(&DroppedFiles);
+ AssertRC(vrc2);
+
+ RT_ZERO(List);
+ vrc2 = DnDTransferListInit(&List);
+ AssertRC(vrc2);
+
+ RT_ZERO(ObjCur);
+ vrc2 = DnDTransferObjectInit(&ObjCur);
+ AssertRC(vrc2);
+ }
+
+ virtual ~GuestDnDTransferRecvData()
+ {
+ destroy();
+ }
+
+ /**
+ * Destroys the object.
+ */
+ void destroy(void)
+ {
+ DnDTransferListDestroy(&List);
+ }
+
+ /**
+ * Resets the object.
+ */
+ void reset(void)
+ {
+ DnDDroppedFilesClose(&DroppedFiles);
+ DnDTransferListReset(&List);
+ DnDTransferObjectReset(&ObjCur);
+
+ GuestDnDTransferData::reset();
+ }
+
+ /** The "VirtualBox Dropped Files" directory on the host we're going
+ * to utilize for transferring files from guest to the host. */
+ DNDDROPPEDFILES DroppedFiles;
+ /** Transfer List to handle.
+ * Currently we only support one transfer list at a time. */
+ DNDTRANSFERLIST List;
+ /** Current transfer object being handled.
+ * Currently we only support one transfer object at a time. */
+ DNDTRANSFEROBJECT ObjCur;
+};
+
+/**
+ * Context structure for receiving data from the guest.
+ */
+struct GuestDnDRecvCtx : public GuestDnDData
+{
+ GuestDnDRecvCtx(void);
+
+ /**
+ * Resets the object.
+ */
+ void reset(void);
+
+ /** Pointer to guest source class this context belongs to. */
+ GuestDnDSource *pSource;
+ /** Pointer to guest state this context belongs to. */
+ GuestDnDState *pState;
+ /** Formats offered by the guest (and supported by the host). */
+ GuestDnDMIMEList lstFmtOffered;
+ /** Original drop format requested to receive from the guest. */
+ com::Utf8Str strFmtReq;
+ /** Intermediate drop format to be received from the guest.
+ * Some original drop formats require a different intermediate
+ * drop format:
+ *
+ * Receiving a file link as "text/plain" requires still to
+ * receive the file from the guest as "text/uri-list" first,
+ * then pointing to the file path on the host with the data
+ * in "text/plain" format returned. */
+ com::Utf8Str strFmtRecv;
+ /** Desired drop action to perform on the host.
+ * Needed to tell the guest if data has to be
+ * deleted e.g. when moving instead of copying. */
+ VBOXDNDACTION enmAction;
+ /** Transfer data structure. */
+ GuestDnDTransferRecvData Transfer;
+ /** Callback event to use. */
+ GuestDnDCallbackEvent EventCallback;
+};
+
+/**
+ * Class for maintainig a (buffered) guest DnD message.
+ */
+class GuestDnDMsg
+{
+public:
+
+ GuestDnDMsg(void)
+ : uMsg(0)
+ , cParms(0)
+ , cParmsAlloc(0)
+ , paParms(NULL) { }
+
+ virtual ~GuestDnDMsg(void)
+ {
+ reset();
+ }
+
+public:
+
+ /**
+ * Appends a new HGCM parameter to the message and returns the pointer to it.
+ */
+ PVBOXHGCMSVCPARM getNextParam(void)
+ {
+ if (cParms >= cParmsAlloc)
+ {
+ if (!paParms)
+ paParms = (PVBOXHGCMSVCPARM)RTMemAlloc(4 * sizeof(VBOXHGCMSVCPARM));
+ else
+ paParms = (PVBOXHGCMSVCPARM)RTMemRealloc(paParms, (cParmsAlloc + 4) * sizeof(VBOXHGCMSVCPARM));
+ if (!paParms)
+ throw VERR_NO_MEMORY;
+ RT_BZERO(&paParms[cParmsAlloc], 4 * sizeof(VBOXHGCMSVCPARM));
+ cParmsAlloc += 4;
+ }
+
+ return &paParms[cParms++];
+ }
+
+ /**
+ * Returns the current parameter count.
+ *
+ * @returns Current parameter count.
+ */
+ uint32_t getCount(void) const { return cParms; }
+
+ /**
+ * Returns the pointer to the beginning of the HGCM parameters array. Use with care.
+ *
+ * @returns Pointer to the beginning of the HGCM parameters array.
+ */
+ PVBOXHGCMSVCPARM getParms(void) const { return paParms; }
+
+ /**
+ * Returns the message type.
+ *
+ * @returns Message type.
+ */
+ uint32_t getType(void) const { return uMsg; }
+
+ /**
+ * Resets the object.
+ */
+ void reset(void)
+ {
+ if (paParms)
+ {
+ /* Remove deep copies. */
+ for (uint32_t i = 0; i < cParms; i++)
+ {
+ if ( paParms[i].type == VBOX_HGCM_SVC_PARM_PTR
+ && paParms[i].u.pointer.size)
+ {
+ AssertPtr(paParms[i].u.pointer.addr);
+ RTMemFree(paParms[i].u.pointer.addr);
+ }
+ }
+
+ RTMemFree(paParms);
+ paParms = NULL;
+ }
+
+ uMsg = cParms = cParmsAlloc = 0;
+ }
+
+ /**
+ * Appends a new message parameter of type pointer.
+ *
+ * @returns VBox status code.
+ * @param pvBuf Pointer to data to use.
+ * @param cbBuf Size (in bytes) of data to use.
+ */
+ int appendPointer(void *pvBuf, uint32_t cbBuf)
+ {
+ PVBOXHGCMSVCPARM pParm = getNextParam();
+ if (!pParm)
+ return VERR_NO_MEMORY;
+
+ void *pvTmp = NULL;
+ if (cbBuf)
+ {
+ AssertPtr(pvBuf);
+ pvTmp = RTMemDup(pvBuf, cbBuf);
+ if (!pvTmp)
+ return VERR_NO_MEMORY;
+ }
+
+ HGCMSvcSetPv(pParm, pvTmp, cbBuf);
+ return VINF_SUCCESS;
+ }
+
+ /**
+ * Appends a new message parameter of type string.
+ *
+ * @returns VBox status code.
+ * @param pszString Pointer to string data to use.
+ */
+ int appendString(const char *pszString)
+ {
+ PVBOXHGCMSVCPARM pParm = getNextParam();
+ if (!pParm)
+ return VERR_NO_MEMORY;
+
+ char *pszTemp = RTStrDup(pszString);
+ if (!pszTemp)
+ return VERR_NO_MEMORY;
+
+ HGCMSvcSetStr(pParm, pszTemp);
+ return VINF_SUCCESS;
+ }
+
+ /**
+ * Appends a new message parameter of type uint32_t.
+ *
+ * @returns VBox status code.
+ * @param u32Val uint32_t value to use.
+ */
+ int appendUInt32(uint32_t u32Val)
+ {
+ PVBOXHGCMSVCPARM pParm = getNextParam();
+ if (!pParm)
+ return VERR_NO_MEMORY;
+
+ HGCMSvcSetU32(pParm, u32Val);
+ return VINF_SUCCESS;
+ }
+
+ /**
+ * Appends a new message parameter of type uint64_t.
+ *
+ * @returns VBox status code.
+ * @param u64Val uint64_t value to use.
+ */
+ int appendUInt64(uint64_t u64Val)
+ {
+ PVBOXHGCMSVCPARM pParm = getNextParam();
+ if (!pParm)
+ return VERR_NO_MEMORY;
+
+ HGCMSvcSetU64(pParm, u64Val);
+ return VINF_SUCCESS;
+ }
+
+ /**
+ * Sets the HGCM message type (function number).
+ *
+ * @param uMsgType Message type to set.
+ */
+ void setType(uint32_t uMsgType) { uMsg = uMsgType; }
+
+protected:
+
+ /** Message type. */
+ uint32_t uMsg;
+ /** Message parameters. */
+ uint32_t cParms;
+ /** Size of array. */
+ uint32_t cParmsAlloc;
+ /** Array of HGCM parameters */
+ PVBOXHGCMSVCPARM paParms;
+};
+
+/** Guest DnD callback function definition. */
+typedef DECLCALLBACKPTR(int, PFNGUESTDNDCALLBACK,(uint32_t uMsg, void *pvParms, size_t cbParms, void *pvUser));
+
+/**
+ * Structure for keeping a guest DnD callback.
+ * Each callback can handle one HGCM message, however, multiple HGCM messages can be registered
+ * to the same callback (function).
+ */
+typedef struct GuestDnDCallback
+{
+ GuestDnDCallback(void)
+ : uMessgage(0)
+ , pfnCallback(NULL)
+ , pvUser(NULL) { }
+
+ GuestDnDCallback(PFNGUESTDNDCALLBACK pvCB, uint32_t uMsg, void *pvUsr = NULL)
+ : uMessgage(uMsg)
+ , pfnCallback(pvCB)
+ , pvUser(pvUsr) { }
+
+ /** The HGCM message ID to handle. */
+ uint32_t uMessgage;
+ /** Pointer to callback function. */
+ PFNGUESTDNDCALLBACK pfnCallback;
+ /** Pointer to user-supplied data. */
+ void *pvUser;
+} GuestDnDCallback;
+
+/** Contains registered callback pointers for specific HGCM message types. */
+typedef std::map<uint32_t, GuestDnDCallback> GuestDnDCallbackMap;
+
+/**
+ * Class for keeping a DnD guest state around.
+ */
+class GuestDnDState
+{
+
+public:
+ DECLARE_TRANSLATE_METHODS(GuestDnDState)
+
+ GuestDnDState(const ComObjPtr<Guest>& pGuest);
+ virtual ~GuestDnDState(void);
+
+public:
+
+ VBOXDNDSTATE get(void) const { return m_enmState; }
+ int set(VBOXDNDSTATE enmState) { LogRel3(("DnD: State %s -> %s\n", DnDStateToStr(m_enmState), DnDStateToStr(enmState))); m_enmState = enmState; return 0; }
+ void lock() { RTCritSectEnter(&m_CritSect); };
+ void unlock() { RTCritSectLeave(&m_CritSect); };
+
+ /** @name Guest response handling.
+ * @{ */
+ int notifyAboutGuestResponse(int vrcGuest = VINF_SUCCESS);
+ int waitForGuestResponseEx(RTMSINTERVAL msTimeout = 3000, int *pvrcGuest = NULL);
+ int waitForGuestResponse(int *pvrcGuest = NULL);
+ /** @} */
+
+ void setActionsAllowed(VBOXDNDACTIONLIST a) { m_dndLstActionsAllowed = a; }
+ VBOXDNDACTIONLIST getActionsAllowed(void) const { return m_dndLstActionsAllowed; }
+
+ void setActionDefault(VBOXDNDACTION a) { m_dndActionDefault = a; }
+ VBOXDNDACTION getActionDefault(void) const { return m_dndActionDefault; }
+
+ void setFormats(const GuestDnDMIMEList &lstFormats) { m_lstFormats = lstFormats; }
+ GuestDnDMIMEList formats(void) const { return m_lstFormats; }
+
+ void reset(void);
+
+ /** @name Callback handling.
+ * @{ */
+ static DECLCALLBACK(int) i_defaultCallback(uint32_t uMsg, void *pvParms, size_t cbParms, void *pvUser);
+ int setCallback(uint32_t uMsg, PFNGUESTDNDCALLBACK pfnCallback, void *pvUser = NULL);
+ /** @} */
+
+ /** @name Progress handling.
+ * @{ */
+ bool isProgressCanceled(void) const;
+ bool isProgressRunning(void) const;
+ int setProgress(unsigned uPercentage, uint32_t uStatus, int vrcOp = VINF_SUCCESS, const Utf8Str &strMsg = Utf8Str::Empty);
+ HRESULT resetProgress(const ComObjPtr<Guest>& pParent, const Utf8Str &strDesc);
+ HRESULT queryProgressTo(IProgress **ppProgress);
+ /** @} */
+
+public:
+
+ /** @name HGCM callback handling.
+ @{ */
+ int onDispatch(uint32_t u32Function, void *pvParms, uint32_t cbParms);
+ /** @} */
+
+public:
+
+ /** Pointer to context this class is tied to. */
+ void *m_pvCtx;
+ RTCRITSECT m_CritSect;
+ /** The current state we're in. */
+ VBOXDNDSTATE m_enmState;
+ /** The DnD protocol version to use, depending on the
+ * installed Guest Additions. See DragAndDropSvc.h for
+ * a protocol changelog. */
+ uint32_t m_uProtocolVersion;
+ /** The guest feature flags reported to the host (VBOX_DND_GF_XXX). */
+ uint64_t m_fGuestFeatures0;
+ /** Event for waiting for response. */
+ RTSEMEVENT m_EventSem;
+ /** Last error reported from guest.
+ * Set to VERR_IPE_UNINITIALIZED_STATUS if not set yet. */
+ int m_vrcGuest;
+ /** Default action to perform in case of a
+ * successful drop. */
+ VBOXDNDACTION m_dndActionDefault;
+ /** Actions supported by the guest in case of a successful drop. */
+ VBOXDNDACTIONLIST m_dndLstActionsAllowed;
+ /** Format(s) requested/supported from the guest. */
+ GuestDnDMIMEList m_lstFormats;
+ /** Pointer to IGuest parent object. */
+ ComObjPtr<Guest> m_pParent;
+ /** Pointer to associated progress object. Optional. */
+ ComObjPtr<Progress> m_pProgress;
+ /** Callback map. */
+ GuestDnDCallbackMap m_mapCallbacks;
+};
+
+/**
+ * Private singleton class for the guest's DnD implementation.
+ *
+ * Can't be instanciated directly, only via the factory pattern.
+ * Keeps track of all ongoing DnD transfers.
+ */
+class GuestDnD
+{
+public:
+
+ /**
+ * Creates the Singleton GuestDnD object.
+ *
+ * @returns Newly created Singleton object, or NULL on failure.
+ */
+ static GuestDnD *createInstance(const ComObjPtr<Guest>& pGuest)
+ {
+ Assert(NULL == GuestDnD::s_pInstance);
+ GuestDnD::s_pInstance = new GuestDnD(pGuest);
+ return GuestDnD::s_pInstance;
+ }
+
+ /**
+ * Destroys the Singleton GuestDnD object.
+ */
+ static void destroyInstance(void)
+ {
+ if (GuestDnD::s_pInstance)
+ {
+ delete GuestDnD::s_pInstance;
+ GuestDnD::s_pInstance = NULL;
+ }
+ }
+
+ /**
+ * Returns the Singleton GuestDnD object.
+ *
+ * @returns Pointer to Singleton GuestDnD object, or NULL if not created yet.
+ */
+ static inline GuestDnD *getInstance(void)
+ {
+ AssertPtr(GuestDnD::s_pInstance);
+ return GuestDnD::s_pInstance;
+ }
+
+protected:
+
+ /** List of registered DnD sources. */
+ typedef std::list< ComObjPtr<GuestDnDSource> > GuestDnDSrcList;
+ /** List of registered DnD targets. */
+ typedef std::list< ComObjPtr<GuestDnDTarget> > GuestDnDTgtList;
+
+ /** Constructor; will throw vrc on failure. */
+ GuestDnD(const ComObjPtr<Guest>& pGuest);
+ virtual ~GuestDnD(void);
+
+public:
+
+ /** @name Public helper functions.
+ * @{ */
+ HRESULT adjustScreenCoordinates(ULONG uScreenId, ULONG *puX, ULONG *puY) const;
+ GuestDnDState *getState(uint32_t = 0) const;
+ int hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
+ GuestDnDMIMEList defaultFormats(void) const { return m_strDefaultFormats; }
+ /** @} */
+
+ /** @name Source / target management.
+ * @{ */
+ int registerSource(const ComObjPtr<GuestDnDSource> &Source);
+ int unregisterSource(const ComObjPtr<GuestDnDSource> &Source);
+ size_t getSourceCount(void);
+
+ int registerTarget(const ComObjPtr<GuestDnDTarget> &Target);
+ int unregisterTarget(const ComObjPtr<GuestDnDTarget> &Target);
+ size_t getTargetCount(void);
+ /** @} */
+
+public:
+
+ /** @name Static low-level HGCM callback handler.
+ * @{ */
+ static DECLCALLBACK(int) notifyDnDDispatcher(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms);
+ /** @} */
+
+ /** @name Static helper methods.
+ * @{ */
+ static bool isFormatInFormatList(const com::Utf8Str &strFormat, const GuestDnDMIMEList &lstFormats);
+ static GuestDnDMIMEList toFormatList(const com::Utf8Str &strFormats, const com::Utf8Str &strSep = DND_FORMATS_SEPARATOR_STR);
+ static com::Utf8Str toFormatString(const GuestDnDMIMEList &lstFormats, const com::Utf8Str &strSep = DND_FORMATS_SEPARATOR_STR);
+ static GuestDnDMIMEList toFilteredFormatList(const GuestDnDMIMEList &lstFormatsSupported, const GuestDnDMIMEList &lstFormatsWanted);
+ static GuestDnDMIMEList toFilteredFormatList(const GuestDnDMIMEList &lstFormatsSupported, const com::Utf8Str &strFormatsWanted);
+ static DnDAction_T toMainAction(VBOXDNDACTION dndAction);
+ static std::vector<DnDAction_T> toMainActions(VBOXDNDACTIONLIST dndActionList);
+ static VBOXDNDACTION toHGCMAction(DnDAction_T enmAction);
+ static void toHGCMActions(DnDAction_T enmDefAction, VBOXDNDACTION *pDefAction, const std::vector<DnDAction_T> vecAllowedActions, VBOXDNDACTIONLIST *pLstAllowedActions);
+ /** @} */
+
+protected:
+
+ /** @name Singleton properties.
+ * @{ */
+ /** List of supported default MIME/Content-type formats. */
+ GuestDnDMIMEList m_strDefaultFormats;
+ /** Pointer to guest implementation. */
+ const ComObjPtr<Guest> m_pGuest;
+ /** The current state from the guest. At the
+ * moment we only support only state a time (ARQ-style). */
+ GuestDnDState *m_pState;
+ /** Critical section to serialize access. */
+ RTCRITSECT m_CritSect;
+ /** Number of active transfers (guest->host or host->guest). */
+ uint32_t m_cTransfersPending;
+ GuestDnDSrcList m_lstSrc;
+ GuestDnDTgtList m_lstTgt;
+ /** @} */
+
+private:
+
+ /** Static pointer to singleton instance. */
+ static GuestDnD *s_pInstance;
+};
+
+/** Access to the GuestDnD's singleton instance. */
+#define GuestDnDInst() GuestDnD::getInstance()
+
+/** List of pointers to guest DnD Messages. */
+typedef std::list<GuestDnDMsg *> GuestDnDMsgList;
+
+/**
+ * IDnDBase class implementation for sharing code between
+ * IGuestDnDSource and IGuestDnDTarget implementation.
+ */
+class GuestDnDBase
+{
+protected:
+
+ GuestDnDBase(VirtualBoxBase *pBase);
+
+ virtual ~GuestDnDBase(void);
+
+protected:
+
+ /** Shared (internal) IDnDBase method implementations.
+ * @{ */
+ bool i_isFormatSupported(const com::Utf8Str &aFormat) const;
+ const GuestDnDMIMEList &i_getFormats(void) const;
+ HRESULT i_addFormats(const GuestDnDMIMEList &aFormats);
+ HRESULT i_removeFormats(const GuestDnDMIMEList &aFormats);
+ /** @} */
+
+ /** @name Error handling.
+ * @{ */
+ HRESULT i_setErrorV(int vrc, const char *pcszMsgFmt, va_list va);
+ HRESULT i_setError(int vrc, const char *pcszMsgFmt, ...);
+ HRESULT i_setErrorAndReset(const char *pcszMsgFmt, ...);
+ HRESULT i_setErrorAndReset(int vrc, const char *pcszMsgFmt, ...);
+ /** @} */
+
+protected:
+
+ /** @name Pure virtual functions needed to be implemented by the actual (derived) implementation.
+ * @{ */
+ virtual void i_reset(void) = 0;
+ /** @} */
+
+protected:
+
+ /** @name Functions for handling a simple host HGCM message queue.
+ * @{ */
+ int msgQueueAdd(GuestDnDMsg *pMsg);
+ GuestDnDMsg *msgQueueGetNext(void);
+ void msgQueueRemoveNext(void);
+ void msgQueueClear(void);
+ /** @} */
+
+ int sendCancel(void);
+ int updateProgress(GuestDnDData *pData, GuestDnDState *pState, size_t cbDataAdd = 0);
+ int waitForEvent(GuestDnDCallbackEvent *pEvent, GuestDnDState *pState, RTMSINTERVAL msTimeout);
+
+protected:
+
+ /** Pointer to base class to use for stuff like error handlng. */
+ VirtualBoxBase *m_pBase;
+ /** @name Public attributes (through getters/setters).
+ * @{ */
+ /** Pointer to guest implementation. */
+ const ComObjPtr<Guest> m_pGuest;
+ /** List of supported MIME types by the source. */
+ GuestDnDMIMEList m_lstFmtSupported;
+ /** List of offered MIME types to the counterpart. */
+ GuestDnDMIMEList m_lstFmtOffered;
+ /** Whether the object still is in pending state. */
+ bool m_fIsPending;
+ /** Pointer to state bound to this object. */
+ GuestDnDState *m_pState;
+ /** @} */
+
+ /**
+ * Internal stuff.
+ */
+ struct
+ {
+ /** Outgoing message queue (FIFO). */
+ GuestDnDMsgList lstMsgOut;
+ } m_DataBase;
+};
+#endif /* !MAIN_INCLUDED_GuestDnDPrivate_h */
+
diff --git a/src/VBox/Main/include/GuestDnDSourceImpl.h b/src/VBox/Main/include/GuestDnDSourceImpl.h
new file mode 100644
index 00000000..42373620
--- /dev/null
+++ b/src/VBox/Main/include/GuestDnDSourceImpl.h
@@ -0,0 +1,131 @@
+/* $Id: GuestDnDSourceImpl.h $ */
+/** @file
+ * VBox Console COM Class implementation - Guest drag'n drop source.
+ */
+
+/*
+ * Copyright (C) 2014-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestDnDSourceImpl_h
+#define MAIN_INCLUDED_GuestDnDSourceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/GuestHost/DragAndDrop.h>
+#include <VBox/HostServices/DragAndDropSvc.h>
+
+using namespace DragAndDropSvc;
+
+#include "GuestDnDSourceWrap.h"
+#include "GuestDnDPrivate.h"
+
+class GuestDnDRecvDataTask;
+struct GuestDnDRecvCtx;
+
+class ATL_NO_VTABLE GuestDnDSource :
+ public GuestDnDSourceWrap,
+ public GuestDnDBase
+{
+public:
+ GuestDnDSource(void);
+ virtual ~GuestDnDSource(void);
+
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_TRANSLATE_METHODS(GuestDnDSource);
+
+ HRESULT init(const ComObjPtr<Guest>& pGuest);
+ void uninit(void);
+
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+private:
+
+ /** Private wrapped @name IDnDBase methods.
+ * @{ */
+ HRESULT isFormatSupported(const com::Utf8Str &aFormat, BOOL *aSupported);
+ HRESULT getFormats(GuestDnDMIMEList &aFormats);
+ HRESULT addFormats(const GuestDnDMIMEList &aFormats);
+ HRESULT removeFormats(const GuestDnDMIMEList &aFormats);
+ /** @} */
+
+ /** Private wrapped @name IDnDSource methods.
+ * @{ */
+ HRESULT dragIsPending(ULONG uScreenId, GuestDnDMIMEList &aFormats, std::vector<DnDAction_T> &aAllowedActions, DnDAction_T *aDefaultAction);
+ HRESULT drop(const com::Utf8Str &aFormat, DnDAction_T aAction, ComPtr<IProgress> &aProgress);
+ HRESULT receiveData(std::vector<BYTE> &aData);
+ /** @} */
+
+protected:
+
+ /** @name Implemented virtual functions.
+ * @{ */
+ void i_reset(void);
+ /** @} */
+
+#ifdef VBOX_WITH_DRAG_AND_DROP_GH
+ /** @name Dispatch handlers for the HGCM callbacks.
+ * @{ */
+ int i_onReceiveDataHdr(GuestDnDRecvCtx *pCtx, PVBOXDNDSNDDATAHDR pDataHdr);
+ int i_onReceiveData(GuestDnDRecvCtx *pCtx, PVBOXDNDSNDDATA pSndData);
+ int i_onReceiveDir(GuestDnDRecvCtx *pCtx, const char *pszPath, uint32_t cbPath, uint32_t fMode);
+ int i_onReceiveFileHdr(GuestDnDRecvCtx *pCtx, const char *pszPath, uint32_t cbPath, uint64_t cbSize, uint32_t fMode, uint32_t fFlags);
+ int i_onReceiveFileData(GuestDnDRecvCtx *pCtx,const void *pvData, uint32_t cbData);
+ /** @} */
+#endif
+
+protected:
+
+ static Utf8Str i_guestErrorToString(int guestRc);
+ static Utf8Str i_hostErrorToString(int hostRc);
+
+ /** @name Callbacks for dispatch handler.
+ * @{ */
+ static DECLCALLBACK(int) i_receiveRawDataCallback(uint32_t uMsg, void *pvParms, size_t cbParms, void *pvUser);
+ static DECLCALLBACK(int) i_receiveTransferDataCallback(uint32_t uMsg, void *pvParms, size_t cbParms, void *pvUser);
+ /** @} */
+
+protected:
+
+ int i_receiveData(GuestDnDRecvCtx *pCtx, RTMSINTERVAL msTimeout);
+ int i_receiveRawData(GuestDnDRecvCtx *pCtx, RTMSINTERVAL msTimeout);
+ int i_receiveTransferData(GuestDnDRecvCtx *pCtx, RTMSINTERVAL msTimeout);
+
+protected:
+
+ struct
+ {
+ /** Maximum data block size (in bytes) the source can handle. */
+ uint32_t mcbBlockSize;
+ /** The context for receiving data from the guest.
+ * At the moment only one transfer at a time is supported. */
+ GuestDnDRecvCtx mRecvCtx;
+ } mData;
+
+ friend class GuestDnDRecvDataTask;
+};
+
+#endif /* !MAIN_INCLUDED_GuestDnDSourceImpl_h */
+
diff --git a/src/VBox/Main/include/GuestDnDTargetImpl.h b/src/VBox/Main/include/GuestDnDTargetImpl.h
new file mode 100644
index 00000000..0b7fc268
--- /dev/null
+++ b/src/VBox/Main/include/GuestDnDTargetImpl.h
@@ -0,0 +1,128 @@
+/* $Id: GuestDnDTargetImpl.h $ */
+/** @file
+ * VBox Console COM Class implementation - Guest drag'n drop target.
+ */
+
+/*
+ * Copyright (C) 2014-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestDnDTargetImpl_h
+#define MAIN_INCLUDED_GuestDnDTargetImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestDnDTargetWrap.h"
+#include "GuestDnDPrivate.h"
+
+#include <VBox/GuestHost/DragAndDrop.h>
+#include <VBox/HostServices/DragAndDropSvc.h>
+
+struct GuestDnDSendCtx;
+class GuestDnDSendDataTask;
+
+class ATL_NO_VTABLE GuestDnDTarget :
+ public GuestDnDTargetWrap,
+ public GuestDnDBase
+{
+public:
+ GuestDnDTarget(void);
+ virtual ~GuestDnDTarget(void);
+
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_TRANSLATE_METHODS(GuestDnDTarget);
+
+ HRESULT init(const ComObjPtr<Guest>& pGuest);
+ void uninit(void);
+
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+private:
+
+ /** Private wrapped @name IDnDBase methods.
+ * @{ */
+ HRESULT isFormatSupported(const com::Utf8Str &aFormat, BOOL *aSupported);
+ HRESULT getFormats(GuestDnDMIMEList &aFormats);
+ HRESULT addFormats(const GuestDnDMIMEList &aFormats);
+ HRESULT removeFormats(const GuestDnDMIMEList &aFormats);
+ /** @} */
+
+ /** Private wrapped @name IDnDTarget methods.
+ * @{ */
+ HRESULT enter(ULONG aScreenId, ULONG ax, ULONG aY, DnDAction_T aDefaultAction, const std::vector<DnDAction_T> &aAllowedActions, const GuestDnDMIMEList &aFormats, DnDAction_T *aResultAction);
+ HRESULT move(ULONG aScreenId, ULONG aX, ULONG aY, DnDAction_T aDefaultAction, const std::vector<DnDAction_T> &aAllowedActions, const GuestDnDMIMEList &aFormats, DnDAction_T *aResultAction);
+ HRESULT leave(ULONG aScreenId);
+ HRESULT drop(ULONG aScreenId, ULONG aX, ULONG aY, DnDAction_T aDefaultAction, const std::vector<DnDAction_T> &aAllowedActions, const GuestDnDMIMEList &aFormats, com::Utf8Str &aFormat, DnDAction_T *aResultAction);
+ HRESULT sendData(ULONG aScreenId, const com::Utf8Str &aFormat, const std::vector<BYTE> &aData, ComPtr<IProgress> &aProgress);
+ HRESULT cancel(BOOL *aVeto);
+ /** @} */
+
+protected:
+
+ static Utf8Str i_guestErrorToString(int guestRc);
+ static Utf8Str i_hostErrorToString(int hostRc);
+
+ /** @name Callbacks for dispatch handler.
+ * @{ */
+ static DECLCALLBACK(int) i_sendTransferDataCallback(uint32_t uMsg, void *pvParms, size_t cbParms, void *pvUser);
+ /** @} */
+
+protected:
+
+ /** @name Implemented virtual functions.
+ * @{ */
+ void i_reset(void);
+ /** @} */
+
+ int i_sendData(GuestDnDSendCtx *pCtx, RTMSINTERVAL msTimeout);
+
+ int i_sendMetaDataBody(GuestDnDSendCtx *pCtx);
+ int i_sendMetaDataHeader(GuestDnDSendCtx *pCtx);
+
+ int i_sendTransferData(GuestDnDSendCtx *pCtx, RTMSINTERVAL msTimeout);
+ int i_sendTransferListObject(GuestDnDSendCtx *pCtx, PDNDTRANSFERLIST pList, GuestDnDMsg *pMsg);
+
+ int i_sendDirectory(GuestDnDSendCtx *pCtx, PDNDTRANSFEROBJECT pObj, GuestDnDMsg *pMsg);
+ int i_sendFile(GuestDnDSendCtx *pCtx, PDNDTRANSFEROBJECT pObj, GuestDnDMsg *pMsg);
+ int i_sendFileData(GuestDnDSendCtx *pCtx, PDNDTRANSFEROBJECT pObj, GuestDnDMsg *pMsg);
+
+ int i_sendRawData(GuestDnDSendCtx *pCtx, RTMSINTERVAL msTimeout);
+
+protected:
+
+ struct
+ {
+ /** Maximum data block size (in bytes) the target can handle. */
+ uint32_t mcbBlockSize;
+ /** The context for sending data to the guest.
+ * At the moment only one transfer at a time is supported. */
+ GuestDnDSendCtx mSendCtx;
+ } mData;
+
+ friend class GuestDnDSendDataTask;
+};
+
+#endif /* !MAIN_INCLUDED_GuestDnDTargetImpl_h */
+
diff --git a/src/VBox/Main/include/GuestFileImpl.h b/src/VBox/Main/include/GuestFileImpl.h
new file mode 100644
index 00000000..b6feda07
--- /dev/null
+++ b/src/VBox/Main/include/GuestFileImpl.h
@@ -0,0 +1,161 @@
+/* $Id: GuestFileImpl.h $ */
+/** @file
+ * VirtualBox Main - Guest file handling implementation.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestFileImpl_h
+#define MAIN_INCLUDED_GuestFileImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include "EventImpl.h"
+
+#include "GuestCtrlImplPrivate.h"
+#include "GuestFileWrap.h"
+
+class Console;
+class GuestSession;
+class GuestProcess;
+
+class ATL_NO_VTABLE GuestFile :
+ public GuestFileWrap,
+ public GuestObject
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(GuestFile)
+
+ int init(Console *pConsole, GuestSession *pSession, ULONG uFileID, const GuestFileOpenInfo &openInfo);
+ void uninit(void);
+
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+public:
+ /** @name Implemented virtual methods from GuestObject.
+ * @{ */
+ int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ int i_onUnregister(void);
+ int i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus);
+ /** @} */
+
+public:
+ /** @name Public internal methods.
+ * @{ */
+ int i_closeFile(int *pGuestRc);
+ EventSource *i_getEventSource(void) { return mEventSource; }
+ int i_onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_openFile(uint32_t uTimeoutMS, int *pGuestRc);
+ int i_queryInfo(GuestFsObjData &objData, int *prcGuest);
+ int i_readData(uint32_t uSize, uint32_t uTimeoutMS, void* pvData, uint32_t cbData, uint32_t* pcbRead);
+ int i_readDataAt(uint64_t uOffset, uint32_t uSize, uint32_t uTimeoutMS,
+ void* pvData, size_t cbData, size_t* pcbRead);
+ int i_seekAt(int64_t iOffset, GUEST_FILE_SEEKTYPE eSeekType, uint32_t uTimeoutMS, uint64_t *puOffset);
+ int i_setFileStatus(FileStatus_T fileStatus, int vrcFile);
+ int i_waitForOffsetChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, uint64_t *puOffset);
+ int i_waitForRead(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, void *pvData, size_t cbData, uint32_t *pcbRead);
+ int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, FileStatus_T *pFileStatus, int *pGuestRc);
+ int i_waitForWrite(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, uint32_t *pcbWritten);
+ int i_writeData(uint32_t uTimeoutMS, const void *pvData, uint32_t cbData, uint32_t *pcbWritten);
+ int i_writeDataAt(uint64_t uOffset, uint32_t uTimeoutMS, const void *pvData, uint32_t cbData, uint32_t *pcbWritten);
+ /** @} */
+
+ /** @name Static helper methods.
+ * @{ */
+ static Utf8Str i_guestErrorToString(int guestRc, const char *pcszWhat);
+ /** @} */
+
+public:
+
+ /** @name Wrapped IGuestFile properties.
+ * @{ */
+ HRESULT getCreationMode(ULONG *aCreationMode);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getId(ULONG *aId);
+ HRESULT getInitialSize(LONG64 *aInitialSize);
+ HRESULT getOffset(LONG64 *aOffset);
+ HRESULT getStatus(FileStatus_T *aStatus);
+ HRESULT getFilename(com::Utf8Str &aFilename);
+ HRESULT getAccessMode(FileAccessMode_T *aAccessMode);
+ HRESULT getOpenAction(FileOpenAction_T *aOpenAction);
+ /** @} */
+
+ /** @name Wrapped IGuestFile methods.
+ * @{ */
+ HRESULT close();
+ HRESULT queryInfo(ComPtr<IFsObjInfo> &aObjInfo);
+ HRESULT querySize(LONG64 *aSize);
+ HRESULT read(ULONG aToRead,
+ ULONG aTimeoutMS,
+ std::vector<BYTE> &aData);
+ HRESULT readAt(LONG64 aOffset,
+ ULONG aToRead,
+ ULONG aTimeoutMS,
+ std::vector<BYTE> &aData);
+ HRESULT seek(LONG64 aOffset,
+ FileSeekOrigin_T aWhence,
+ LONG64 *aNewOffset);
+ HRESULT setACL(const com::Utf8Str &aAcl,
+ ULONG aMode);
+ HRESULT setSize(LONG64 aSize);
+ HRESULT write(const std::vector<BYTE> &aData,
+ ULONG aTimeoutMS,
+ ULONG *aWritten);
+ HRESULT writeAt(LONG64 aOffset,
+ const std::vector<BYTE> &aData,
+ ULONG aTimeoutMS,
+ ULONG *aWritten);
+ /** @} */
+
+private:
+
+ /** This can safely be used without holding any locks.
+ * An AutoCaller suffices to prevent it being destroy while in use and
+ * internally there is a lock providing the necessary serialization. */
+ const ComObjPtr<EventSource> mEventSource;
+
+ struct Data
+ {
+ /** The file's open info. */
+ GuestFileOpenInfo mOpenInfo;
+ /** The file's initial size on open. */
+ uint64_t mInitialSize;
+ /** The current file status. */
+ FileStatus_T mStatus;
+ /** The last returned process status
+ * returned from the guest side. */
+ int mLastError;
+ /** The file's current offset. */
+ uint64_t mOffCurrent;
+ } mData;
+};
+
+#endif /* !MAIN_INCLUDED_GuestFileImpl_h */
+
diff --git a/src/VBox/Main/include/GuestFsObjInfoImpl.h b/src/VBox/Main/include/GuestFsObjInfoImpl.h
new file mode 100644
index 00000000..8e8e4789
--- /dev/null
+++ b/src/VBox/Main/include/GuestFsObjInfoImpl.h
@@ -0,0 +1,86 @@
+/* $Id: GuestFsObjInfoImpl.h $ */
+/** @file
+ * VirtualBox Main - Guest file system object information implementation.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestFsObjInfoImpl_h
+#define MAIN_INCLUDED_GuestFsObjInfoImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestFsObjInfoWrap.h"
+#include "GuestCtrlImplPrivate.h"
+
+class ATL_NO_VTABLE GuestFsObjInfo
+ : public GuestFsObjInfoWrap
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(GuestFsObjInfo)
+
+ int init(const GuestFsObjData &objData);
+ void uninit(void);
+
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+ /** @name Internal access helpers.
+ * @{ */
+ const GuestFsObjData &i_getData() const { return mData; }
+ /** @} */
+
+private:
+
+ /** Wrapped @name IGuestFsObjInfo properties.
+ * @{ */
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getType(FsObjType_T *aType);
+ HRESULT getFileAttributes(com::Utf8Str &aFileAttributes);
+ HRESULT getObjectSize(LONG64 *aObjectSize);
+ HRESULT getAllocatedSize(LONG64 *aAllocatedSize);
+ HRESULT getAccessTime(LONG64 *aAccessTime);
+ HRESULT getBirthTime(LONG64 *aBirthTime);
+ HRESULT getChangeTime(LONG64 *aChangeTime);
+ HRESULT getModificationTime(LONG64 *aModificationTime);
+ HRESULT getUID(LONG *aUID);
+ HRESULT getUserName(com::Utf8Str &aUserName);
+ HRESULT getGID(LONG *aGID);
+ HRESULT getGroupName(com::Utf8Str &aGroupName);
+ HRESULT getNodeId(LONG64 *aNodeId);
+ HRESULT getNodeIdDevice(ULONG *aNodeIdDevice);
+ HRESULT getHardLinks(ULONG *aHardLinks);
+ HRESULT getDeviceNumber(ULONG *aDeviceNumber);
+ HRESULT getGenerationId(ULONG *aGenerationId);
+ HRESULT getUserFlags(ULONG *aUserFlags);
+ /** @} */
+
+ GuestFsObjData mData;
+};
+
+#endif /* !MAIN_INCLUDED_GuestFsObjInfoImpl_h */
+
diff --git a/src/VBox/Main/include/GuestImpl.h b/src/VBox/Main/include/GuestImpl.h
new file mode 100644
index 00000000..622c87b3
--- /dev/null
+++ b/src/VBox/Main/include/GuestImpl.h
@@ -0,0 +1,282 @@
+/* $Id: GuestImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestImpl_h
+#define MAIN_INCLUDED_GuestImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestWrap.h"
+#include "VirtualBoxBase.h"
+#include <iprt/list.h>
+#include <iprt/time.h>
+#include <VBox/ostypes.h>
+#include <VBox/param.h>
+#include <VBox/vmm/stam.h>
+
+#include "AdditionsFacilityImpl.h"
+#ifdef VBOX_WITH_GUEST_CONTROL
+# include "GuestCtrlImplPrivate.h"
+# include "GuestSessionImpl.h"
+#endif
+#ifdef VBOX_WITH_DRAG_AND_DROP
+# include "GuestDnDSourceImpl.h"
+# include "GuestDnDTargetImpl.h"
+#endif
+#include "EventImpl.h"
+#include "HGCM.h"
+
+typedef enum
+{
+ GUESTSTATTYPE_CPUUSER = 0,
+ GUESTSTATTYPE_CPUKERNEL = 1,
+ GUESTSTATTYPE_CPUIDLE = 2,
+ GUESTSTATTYPE_MEMTOTAL = 3,
+ GUESTSTATTYPE_MEMFREE = 4,
+ GUESTSTATTYPE_MEMBALLOON = 5,
+ GUESTSTATTYPE_MEMCACHE = 6,
+ GUESTSTATTYPE_PAGETOTAL = 7,
+ GUESTSTATTYPE_PAGEFREE = 8,
+ GUESTSTATTYPE_MAX = 9
+} GUESTSTATTYPE;
+
+class Console;
+
+class ATL_NO_VTABLE Guest :
+ public GuestWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS (Guest)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // Public initializer/uninitializer for internal purposes only.
+ HRESULT init(Console *aParent);
+ void uninit();
+
+
+public:
+ /** @name Static internal methods.
+ * @{ */
+#ifdef VBOX_WITH_GUEST_CONTROL
+ /** Static callback for handling guest control notifications. */
+ static DECLCALLBACK(int) i_notifyCtrlDispatcher(void *pvExtension, uint32_t u32Function, void *pvData, uint32_t cbData);
+#endif
+ static DECLCALLBACK(void) i_staticUpdateStats(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
+ /** @} */
+
+public:
+ /** @name Public internal methods.
+ * @{ */
+ void i_enableVMMStatistics(BOOL aEnable) { mCollectVMMStats = aEnable; };
+ void i_setAdditionsInfo(const com::Utf8Str &aInterfaceVersion, VBOXOSTYPE aOsType);
+ void i_setAdditionsInfo2(uint32_t a_uFullVersion, const char *a_pszName, uint32_t a_uRevision, uint32_t a_fFeatures);
+ bool i_facilityIsActive(VBoxGuestFacilityType enmFacility);
+ bool i_facilityUpdate(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
+ ComObjPtr<Console> i_getConsole(void) { return mParent; }
+ void i_setAdditionsStatus(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
+ void i_onUserStateChanged(const Utf8Str &aUser, const Utf8Str &aDomain, VBoxGuestUserState enmState,
+ const uint8_t *puDetails, uint32_t cbDetails);
+ void i_setSupportedFeatures(uint32_t aCaps);
+ HRESULT i_setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal);
+ BOOL i_isPageFusionEnabled();
+ void i_setCpuCount(uint32_t aCpus) { mCpus = aCpus; }
+ static HRESULT i_setErrorStatic(HRESULT aResultCode, const char *aText, ...)
+ {
+ va_list va;
+ va_start(va, aText);
+ HRESULT hrc = setErrorInternalV(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, va, false, true);
+ va_end(va);
+ return hrc;
+ }
+ uint32_t i_getAdditionsRevision(void) { return mData.mAdditionsRevision; }
+ uint32_t i_getAdditionsVersion(void) { return mData.mAdditionsVersionFull; }
+ VBOXOSTYPE i_getGuestOSType(void) const { return mData.mOSType; }
+ /** Checks if the guest OS type is part of the windows NT family. */
+ bool i_isGuestInWindowsNtFamily(void) const
+ {
+ return mData.mOSType < VBOXOSTYPE_OS2 && mData.mOSType >= VBOXOSTYPE_WinNT;
+ }
+#ifdef VBOX_WITH_GUEST_CONTROL
+ int i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ int i_sessionCreate(const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds,
+ ComObjPtr<GuestSession> &pGuestSession);
+ int i_sessionDestroy(uint32_t uSessionID);
+ inline bool i_sessionExists(uint32_t uSessionID);
+ /** Returns the VBOX_GUESTCTRL_GF_0_XXX mask reported by the guest. */
+ uint64_t i_getGuestControlFeatures0() const { return mData.mfGuestFeatures0; }
+ /** Returns the VBOX_GUESTCTRL_GF_1_XXX mask reported by the guest. */
+ uint64_t i_getGuestControlFeatures1() const { return mData.mfGuestFeatures1; }
+#endif
+ /** @} */
+
+private:
+
+ // wrapped IGuest properties
+ HRESULT getOSTypeId(com::Utf8Str &aOSTypeId);
+ HRESULT getAdditionsRunLevel(AdditionsRunLevelType_T *aAdditionsRunLevel);
+ HRESULT getAdditionsVersion(com::Utf8Str &aAdditionsVersion);
+ HRESULT getAdditionsRevision(ULONG *aAdditionsRevision);
+ HRESULT getDnDSource(ComPtr<IGuestDnDSource> &aDnDSource);
+ HRESULT getDnDTarget(ComPtr<IGuestDnDTarget> &aDnDTarget);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getFacilities(std::vector<ComPtr<IAdditionsFacility> > &aFacilities);
+ HRESULT getSessions(std::vector<ComPtr<IGuestSession> > &aSessions);
+ HRESULT getMemoryBalloonSize(ULONG *aMemoryBalloonSize);
+ HRESULT setMemoryBalloonSize(ULONG aMemoryBalloonSize);
+ HRESULT getStatisticsUpdateInterval(ULONG *aStatisticsUpdateInterval);
+ HRESULT setStatisticsUpdateInterval(ULONG aStatisticsUpdateInterval);
+ HRESULT internalGetStatistics(ULONG *aCpuUser,
+ ULONG *aCpuKernel,
+ ULONG *aCpuIdle,
+ ULONG *aMemTotal,
+ ULONG *aMemFree,
+ ULONG *aMemBalloon,
+ ULONG *aMemShared,
+ ULONG *aMemCache,
+ ULONG *aPagedTotal,
+ ULONG *aMemAllocTotal,
+ ULONG *aMemFreeTotal,
+ ULONG *aMemBalloonTotal,
+ ULONG *aMemSharedTotal);
+ HRESULT getFacilityStatus(AdditionsFacilityType_T aFacility,
+ LONG64 *aTimestamp,
+ AdditionsFacilityStatus_T *aStatus);
+ HRESULT getAdditionsStatus(AdditionsRunLevelType_T aLevel,
+ BOOL *aActive);
+ HRESULT setCredentials(const com::Utf8Str &aUserName,
+ const com::Utf8Str &aPassword,
+ const com::Utf8Str &aDomain,
+ BOOL aAllowInteractiveLogon);
+
+ // wrapped IGuest methods
+ HRESULT createSession(const com::Utf8Str &aUser,
+ const com::Utf8Str &aPassword,
+ const com::Utf8Str &aDomain,
+ const com::Utf8Str &aSessionName,
+ ComPtr<IGuestSession> &aGuestSession);
+
+ HRESULT findSession(const com::Utf8Str &aSessionName,
+ std::vector<ComPtr<IGuestSession> > &aSessions);
+ HRESULT shutdown(const std::vector<GuestShutdownFlag_T> &aFlags);
+ HRESULT updateGuestAdditions(const com::Utf8Str &aSource,
+ const std::vector<com::Utf8Str> &aArguments,
+ const std::vector<AdditionsUpdateFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+
+
+ /** @name Private internal methods.
+ * @{ */
+ void i_updateStats(uint64_t iTick);
+ static DECLCALLBACK(int) i_staticEnumStatsCallback(const char *pszName, STAMTYPE enmType, void *pvSample,
+ STAMUNIT enmUnit, const char *pszUnit, STAMVISIBILITY enmVisiblity,
+ const char *pszDesc, void *pvUser);
+
+ /** @} */
+
+ typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> > FacilityMap;
+ typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> >::iterator FacilityMapIter;
+ typedef std::map< AdditionsFacilityType_T, ComObjPtr<AdditionsFacility> >::const_iterator FacilityMapIterConst;
+
+#ifdef VBOX_WITH_GUEST_CONTROL
+ /** Map for keeping the guest sessions. The primary key marks the guest session ID. */
+ typedef std::map <uint32_t, ComObjPtr<GuestSession> > GuestSessions;
+#endif
+
+ struct Data
+ {
+ Data() : mOSType(VBOXOSTYPE_Unknown), mAdditionsRunLevel(AdditionsRunLevelType_None)
+ , mAdditionsVersionFull(0), mAdditionsRevision(0), mAdditionsFeatures(0)
+#ifdef VBOX_WITH_GUEST_CONTROL
+ , mfGuestFeatures0(0), mfGuestFeatures1(0)
+#endif
+ { }
+
+ VBOXOSTYPE mOSType; /**@< For internal used. VBOXOSTYPE_Unknown if not reported. */
+ Utf8Str mOSTypeId;
+ FacilityMap mFacilityMap;
+ AdditionsRunLevelType_T mAdditionsRunLevel;
+ uint32_t mAdditionsVersionFull;
+ Utf8Str mAdditionsVersionNew;
+ uint32_t mAdditionsRevision;
+ uint32_t mAdditionsFeatures;
+ Utf8Str mInterfaceVersion;
+#ifdef VBOX_WITH_GUEST_CONTROL
+ GuestSessions mGuestSessions;
+ /** Guest control features (reported by the guest), VBOX_GUESTCTRL_GF_0_XXX. */
+ uint64_t mfGuestFeatures0;
+ /** Guest control features (reported by the guest), VBOX_GUESTCTRL_GF_1_XXX. */
+ uint64_t mfGuestFeatures1;
+#endif
+ } mData;
+
+ ULONG mMemoryBalloonSize;
+ ULONG mStatUpdateInterval; /**< In seconds. */
+ uint64_t mNetStatRx;
+ uint64_t mNetStatTx;
+ uint64_t mNetStatLastTs;
+ ULONG mCurrentGuestStat[GUESTSTATTYPE_MAX];
+ ULONG mCurrentGuestCpuUserStat[VMM_MAX_CPU_COUNT];
+ ULONG mCurrentGuestCpuKernelStat[VMM_MAX_CPU_COUNT];
+ ULONG mCurrentGuestCpuIdleStat[VMM_MAX_CPU_COUNT];
+ ULONG mVmValidStats;
+ BOOL mCollectVMMStats;
+ BOOL mfPageFusionEnabled;
+ uint32_t mCpus;
+
+ const ComObjPtr<Console> mParent;
+
+ /**
+ * This can safely be used without holding any locks.
+ * An AutoCaller suffices to prevent it being destroy while in use and
+ * internally there is a lock providing the necessary serialization.
+ */
+ const ComObjPtr<EventSource> mEventSource;
+#ifdef VBOX_WITH_GUEST_CONTROL
+ /** General extension callback for guest control. */
+ HGCMSVCEXTHANDLE mhExtCtrl;
+#endif
+
+#ifdef VBOX_WITH_DRAG_AND_DROP
+ /** The guest's DnD source. */
+ const ComObjPtr<GuestDnDSource> mDnDSource;
+ /** The guest's DnD target. */
+ const ComObjPtr<GuestDnDTarget> mDnDTarget;
+#endif
+
+ RTTIMERLR mStatTimer;
+ uint32_t mMagic; /** @todo r=andy Rename this to something more meaningful. */
+};
+#define GUEST_MAGIC 0xCEED2006u /** @todo r=andy Not very well defined!? */
+
+#endif /* !MAIN_INCLUDED_GuestImpl_h */
+
diff --git a/src/VBox/Main/include/GuestOSTypeImpl.h b/src/VBox/Main/include/GuestOSTypeImpl.h
new file mode 100644
index 00000000..354edfa3
--- /dev/null
+++ b/src/VBox/Main/include/GuestOSTypeImpl.h
@@ -0,0 +1,131 @@
+/* $Id: GuestOSTypeImpl.h $ */
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestOSTypeImpl_h
+#define MAIN_INCLUDED_GuestOSTypeImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "Global.h"
+#include "GuestOSTypeWrap.h"
+
+class ATL_NO_VTABLE GuestOSType :
+ public GuestOSTypeWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(GuestOSType)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(const Global::OSType &ostype);
+ void uninit();
+
+ // public methods only for internal purposes
+ const Utf8Str &i_id() const { return mID; }
+ const Utf8Str &i_familyId() const { return mFamilyID; }
+ bool i_is64Bit() const { return !!(mOSHint & VBOXOSHINT_64BIT); }
+ bool i_recommendedIOAPIC() const { return !!(mOSHint & VBOXOSHINT_IOAPIC); }
+ bool i_recommendedX2APIC() const { return !!(mOSHint & VBOXOSHINT_X2APIC); }
+ bool i_recommendedVirtEx() const { return !!(mOSHint & VBOXOSHINT_HWVIRTEX); }
+ bool i_recommendedEFI() const { return !!(mOSHint & VBOXOSHINT_EFI); }
+ bool i_recommendedEFISecureBoot() const { return !!(mOSHint & VBOXOSHINT_EFI_SECUREBOOT); }
+ bool i_recommendedTpm2() const { return !!(mOSHint & VBOXOSHINT_TPM2); }
+ NetworkAdapterType_T i_networkAdapterType() const { return mNetworkAdapterType; }
+ uint32_t i_numSerialEnabled() const { return mNumSerialEnabled; }
+
+private:
+
+ // Wrapped IGuestOSType properties
+ HRESULT getFamilyId(com::Utf8Str &aFamilyId);
+ HRESULT getFamilyDescription(com::Utf8Str &aFamilyDescription);
+ HRESULT getId(com::Utf8Str &aId);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT getIs64Bit(BOOL *aIs64Bit);
+ HRESULT getRecommendedIOAPIC(BOOL *aRecommendedIOAPIC);
+ HRESULT getRecommendedVirtEx(BOOL *aRecommendedVirtEx);
+ HRESULT getRecommendedRAM(ULONG *RAMSize);
+ HRESULT getRecommendedGraphicsController(GraphicsControllerType_T *aRecommendedGraphicsController);
+ HRESULT getRecommendedVRAM(ULONG *aVRAMSize);
+ HRESULT getRecommended2DVideoAcceleration(BOOL *aRecommended2DVideoAcceleration);
+ HRESULT getRecommended3DAcceleration(BOOL *aRecommended3DAcceleration);
+ HRESULT getRecommendedHDD(LONG64 *aHDDSize);
+ HRESULT getAdapterType(NetworkAdapterType_T *aNetworkAdapterType);
+ HRESULT getRecommendedPAE(BOOL *aRecommendedPAE);
+ HRESULT getRecommendedDVDStorageController(StorageControllerType_T *aStorageControllerType);
+ HRESULT getRecommendedFirmware(FirmwareType_T *aFirmwareType);
+ HRESULT getRecommendedDVDStorageBus(StorageBus_T *aStorageBusType);
+ HRESULT getRecommendedHDStorageController(StorageControllerType_T *aStorageControllerType);
+ HRESULT getRecommendedHDStorageBus(StorageBus_T *aStorageBusType);
+ HRESULT getRecommendedUSBHID(BOOL *aRecommendedUSBHID);
+ HRESULT getRecommendedHPET(BOOL *aRecommendedHPET);
+ HRESULT getRecommendedUSBTablet(BOOL *aRecommendedUSBTablet);
+ HRESULT getRecommendedRTCUseUTC(BOOL *aRecommendedRTCUseUTC);
+ HRESULT getRecommendedChipset(ChipsetType_T *aChipsetType);
+ HRESULT getRecommendedIommuType(IommuType_T *aIommuType);
+ HRESULT getRecommendedAudioController(AudioControllerType_T *aAudioController);
+ HRESULT getRecommendedAudioCodec(AudioCodecType_T *aAudioCodec);
+ HRESULT getRecommendedFloppy(BOOL *aRecommendedFloppy);
+ HRESULT getRecommendedUSB(BOOL *aRecommendedUSB);
+ HRESULT getRecommendedUSB3(BOOL *aRecommendedUSB3);
+ HRESULT getRecommendedTFReset(BOOL *aRecommendedTFReset);
+ HRESULT getRecommendedX2APIC(BOOL *aRecommendedX2APIC);
+ HRESULT getRecommendedCPUCount(ULONG *aRecommendedCPUCount);
+ HRESULT getRecommendedTpmType(TpmType_T *aRecommendedTpmType);
+ HRESULT getRecommendedSecureBoot(BOOL *aRecommendedSecureBoot);
+ HRESULT getRecommendedWDDMGraphics(BOOL *aRecommendedWDDMGraphics);
+
+
+ const Utf8Str mFamilyID;
+ const Utf8Str mFamilyDescription;
+ const Utf8Str mID;
+ const Utf8Str mDescription;
+ const VBOXOSTYPE mOSType;
+ const uint32_t mOSHint;
+ const uint32_t mRAMSize;
+ const uint32_t mCPUCount;
+ const GraphicsControllerType_T mGraphicsControllerType;
+ const uint32_t mVRAMSize;
+ const uint64_t mHDDSize;
+ const NetworkAdapterType_T mNetworkAdapterType;
+ const uint32_t mNumSerialEnabled;
+ const StorageControllerType_T mDVDStorageControllerType;
+ const StorageBus_T mDVDStorageBusType;
+ const StorageControllerType_T mHDStorageControllerType;
+ const StorageBus_T mHDStorageBusType;
+ const ChipsetType_T mChipsetType;
+ const IommuType_T mIommuType;
+ const AudioControllerType_T mAudioControllerType;
+ const AudioCodecType_T mAudioCodecType;
+};
+
+#endif /* !MAIN_INCLUDED_GuestOSTypeImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/GuestProcessImpl.h b/src/VBox/Main/include/GuestProcessImpl.h
new file mode 100644
index 00000000..793b6db6
--- /dev/null
+++ b/src/VBox/Main/include/GuestProcessImpl.h
@@ -0,0 +1,310 @@
+/* $Id: GuestProcessImpl.h $ */
+/** @file
+ * VirtualBox Main - Guest process handling implementation.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestProcessImpl_h
+#define MAIN_INCLUDED_GuestProcessImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestCtrlImplPrivate.h"
+#include "GuestProcessWrap.h"
+
+#include <iprt/cpp/utils.h>
+
+class Console;
+class GuestSession;
+class GuestProcessStartTask;
+
+/**
+ * Class for handling a guest process.
+ */
+class ATL_NO_VTABLE GuestProcess :
+ public GuestProcessWrap,
+ public GuestObject
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(GuestProcess)
+
+ int init(Console *aConsole, GuestSession *aSession, ULONG aObjectID,
+ const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv);
+ void uninit(void);
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+public:
+ /** @name Implemented virtual methods from GuestObject.
+ * @{ */
+ int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ int i_onUnregister(void);
+ int i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus);
+ /** @} */
+
+public:
+ /** @name Public internal methods.
+ * @{ */
+ inline int i_checkPID(uint32_t uPID);
+ ProcessStatus_T i_getStatus(void);
+ int i_readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, uint32_t *pcbRead, int *pvrcGuest);
+ int i_startProcess(uint32_t cMsTimeout, int *pvrcGuest);
+ int i_startProcessInner(uint32_t cMsTimeout, AutoWriteLock &rLock, GuestWaitEvent *pEvent, int *pvrcGuest);
+ int i_startProcessAsync(void);
+ int i_terminateProcess(uint32_t uTimeoutMS, int *pvrcGuest);
+ ProcessWaitResult_T i_waitFlagsToResult(uint32_t fWaitFlags);
+ int i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, ProcessWaitResult_T &waitResult, int *pvrcGuest);
+ int i_waitForInputNotify(GuestWaitEvent *pEvent, uint32_t uHandle, uint32_t uTimeoutMS, ProcessInputStatus_T *pInputStatus, uint32_t *pcbProcessed);
+ int i_waitForOutput(GuestWaitEvent *pEvent, uint32_t uHandle, uint32_t uTimeoutMS, void* pvData, size_t cbData, uint32_t *pcbRead);
+ int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, ProcessStatus_T *pProcessStatus, int *pvrcGuest);
+ int i_writeData(uint32_t uHandle, uint32_t uFlags, void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten, int *pvrcGuest);
+ /** @} */
+
+ /** @name Static internal methods.
+ * @{ */
+ static Utf8Str i_guestErrorToString(int vrcGuest, const char *pcszWhat);
+ static Utf8Str i_statusToString(ProcessStatus_T enmStatus);
+ static bool i_isGuestError(int guestRc);
+ static ProcessWaitResult_T i_waitFlagsToResultEx(uint32_t fWaitFlags, ProcessStatus_T oldStatus, ProcessStatus_T newStatus, uint32_t uProcFlags, uint32_t uProtocol);
+#if 0 /* unused */
+ static bool i_waitResultImpliesEx(ProcessWaitResult_T waitResult, ProcessStatus_T procStatus, uint32_t uProtocol);
+#endif
+ /** @} */
+
+protected:
+ /** @name Protected internal methods.
+ * @{ */
+ inline bool i_isAlive(void);
+ inline bool i_hasEnded(void);
+ int i_onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_onProcessInputStatus(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_onProcessNotifyIO(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_onProcessStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_onProcessOutput(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ int i_prepareExecuteEnv(const char *pszEnv, void **ppvList, ULONG *pcbList, ULONG *pcEnvVars);
+ int i_setProcessStatus(ProcessStatus_T procStatus, int vrcProc);
+ static int i_startProcessThreadTask(GuestProcessStartTask *pTask);
+ /** @} */
+
+private:
+ /** Wrapped @name IProcess properties.
+ * @{ */
+ HRESULT getArguments(std::vector<com::Utf8Str> &aArguments);
+ HRESULT getEnvironment(std::vector<com::Utf8Str> &aEnvironment);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getExecutablePath(com::Utf8Str &aExecutablePath);
+ HRESULT getExitCode(LONG *aExitCode);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getPID(ULONG *aPID);
+ HRESULT getStatus(ProcessStatus_T *aStatus);
+ /** @} */
+
+ /** Wrapped @name IProcess methods.
+ * @{ */
+ HRESULT waitFor(ULONG aWaitFor,
+ ULONG aTimeoutMS,
+ ProcessWaitResult_T *aReason);
+ HRESULT waitForArray(const std::vector<ProcessWaitForFlag_T> &aWaitFor,
+ ULONG aTimeoutMS,
+ ProcessWaitResult_T *aReason);
+ HRESULT read(ULONG aHandle,
+ ULONG aToRead,
+ ULONG aTimeoutMS,
+ std::vector<BYTE> &aData);
+ HRESULT write(ULONG aHandle,
+ ULONG aFlags,
+ const std::vector<BYTE> &aData,
+ ULONG aTimeoutMS,
+ ULONG *aWritten);
+ HRESULT writeArray(ULONG aHandle,
+ const std::vector<ProcessInputFlag_T> &aFlags,
+ const std::vector<BYTE> &aData,
+ ULONG aTimeoutMS,
+ ULONG *aWritten);
+ HRESULT terminate(void);
+ /** @} */
+
+ /**
+ * This can safely be used without holding any locks.
+ * An AutoCaller suffices to prevent it being destroy while in use and
+ * internally there is a lock providing the necessary serialization.
+ */
+ const ComObjPtr<EventSource> mEventSource;
+
+ struct Data
+ {
+ /** The process startup information. */
+ GuestProcessStartupInfo mProcess;
+ /** Reference to the immutable session base environment. NULL if the
+ * environment feature isn't supported.
+ * @remarks If there is proof that the uninit order of GuestSession and
+ * this class is what GuestObjectBase claims, then this isn't
+ * strictly necessary. */
+ GuestEnvironment const *mpSessionBaseEnv;
+ /** Exit code if process has been terminated. */
+ LONG mExitCode;
+ /** PID reported from the guest.
+ * Note: This is *not* the internal object ID! */
+ ULONG mPID;
+ /** The current process status. */
+ ProcessStatus_T mStatus;
+ /** The last returned process status
+ * returned from the guest side. */
+ int mLastError;
+
+ Data(void) : mpSessionBaseEnv(NULL)
+ { }
+ ~Data(void)
+ {
+ if (mpSessionBaseEnv)
+ {
+ mpSessionBaseEnv->releaseConst();
+ mpSessionBaseEnv = NULL;
+ }
+ }
+ } mData;
+
+ friend class GuestProcessStartTask;
+};
+
+/**
+ * Guest process tool wait flags.
+ */
+/** No wait flags specified; wait until process terminates.
+ * The maximum waiting time is set in the process' startup
+ * info. */
+#define GUESTPROCESSTOOL_WAIT_FLAG_NONE 0
+/** Wait until next stream block from stdout has been
+ * read in completely, then return.
+ */
+#define GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK RT_BIT(0)
+
+/**
+ * Structure for keeping a VBoxService toolbox tool's error info around.
+ */
+struct GuestProcessToolErrorInfo
+{
+ /** Return (VBox status) code from the guest side for executing the process tool. */
+ int vrcGuest;
+ /** The process tool's returned exit code. */
+ int32_t iExitCode;
+};
+
+/**
+ * Internal class for handling the BusyBox-like tools built into VBoxService
+ * on the guest side. It's also called the VBoxService Toolbox (tm).
+ *
+ * Those initially were necessary to guarantee execution of commands (like "ls", "cat")
+ * under the behalf of a certain guest user.
+ *
+ * This class essentially helps to wrap all the gory details like process creation,
+ * information extraction and maintaining the overall status.
+ *
+ * Note! When implementing new functionality / commands, do *not* use this approach anymore!
+ * This class has to be kept to guarantee backwards-compatibility.
+ */
+class GuestProcessTool
+{
+public:
+ DECLARE_TRANSLATE_METHODS(GuestProcessTool)
+
+ GuestProcessTool(void);
+
+ virtual ~GuestProcessTool(void);
+
+public:
+
+ int init(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, bool fAsync, int *pvrcGuest);
+
+ void uninit(void);
+
+ int getCurrentBlock(uint32_t uHandle, GuestProcessStreamBlock &strmBlock);
+
+ int getRc(void) const;
+
+ /** Returns the stdout output from the guest process tool. */
+ GuestProcessStream &getStdOut(void) { return mStdOut; }
+
+ /** Returns the stderr output from the guest process tool. */
+ GuestProcessStream &getStdErr(void) { return mStdErr; }
+
+ int wait(uint32_t fToolWaitFlags, int *pvrcGuest);
+
+ int waitEx(uint32_t fToolWaitFlags, GuestProcessStreamBlock *pStreamBlock, int *pvrcGuest);
+
+ bool isRunning(void);
+
+ bool isTerminatedOk(void);
+
+ int getTerminationStatus(int32_t *piExitCode = NULL);
+
+ int terminate(uint32_t uTimeoutMS, int *pvrcGuest);
+
+public:
+
+ /** Wrapped @name Static run methods.
+ * @{ */
+ static int run(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, int *pvrcGuest);
+
+ static int runErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, GuestProcessToolErrorInfo &errorInfo);
+
+ static int runEx(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
+ GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, int *pvrcGuest);
+
+ static int runExErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
+ GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, GuestProcessToolErrorInfo &errorInfo);
+ /** @} */
+
+ /** Wrapped @name Static exit code conversion methods.
+ * @{ */
+ static int exitCodeToRc(const GuestProcessStartupInfo &startupInfo, int32_t iExitCode);
+
+ static int exitCodeToRc(const char *pszTool, int32_t iExitCode);
+ /** @} */
+
+ /** Wrapped @name Static guest error conversion methods.
+ * @{ */
+ static Utf8Str guestErrorToString(const char *pszTool, const GuestErrorInfo& guestErrorInfo);
+ /** @} */
+
+protected:
+
+ /** Pointer to session this toolbox object is bound to. */
+ ComObjPtr<GuestSession> pSession;
+ /** Pointer to process object this toolbox object is bound to. */
+ ComObjPtr<GuestProcess> pProcess;
+ /** The toolbox' startup info. */
+ GuestProcessStartupInfo mStartupInfo;
+ /** Stream object for handling the toolbox' stdout data. */
+ GuestProcessStream mStdOut;
+ /** Stream object for handling the toolbox' stderr data. */
+ GuestProcessStream mStdErr;
+};
+
+#endif /* !MAIN_INCLUDED_GuestProcessImpl_h */
+
diff --git a/src/VBox/Main/include/GuestSessionImpl.h b/src/VBox/Main/include/GuestSessionImpl.h
new file mode 100644
index 00000000..a5dcb3be
--- /dev/null
+++ b/src/VBox/Main/include/GuestSessionImpl.h
@@ -0,0 +1,460 @@
+/* $Id: GuestSessionImpl.h $ */
+/** @file
+ * VirtualBox Main - Guest session handling.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestSessionImpl_h
+#define MAIN_INCLUDED_GuestSessionImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestSessionWrap.h"
+#include "EventImpl.h"
+
+#include "GuestCtrlImplPrivate.h"
+#include "GuestProcessImpl.h"
+#include "GuestDirectoryImpl.h"
+#include "GuestFileImpl.h"
+#include "GuestFsObjInfoImpl.h"
+#include "GuestSessionImplTasks.h"
+
+#include <iprt/asm.h> /** @todo r=bird: Needed for ASMBitSet() in GuestSession::Data constructor. Removed when
+ * that is moved into the class implementation file as it should be. */
+#include <deque>
+
+class GuestSessionTaskInternalStart; /* Needed for i_startSessionThreadTask(). */
+
+/**
+ * Guest session implementation.
+ */
+class ATL_NO_VTABLE GuestSession
+ : public GuestSessionWrap
+ , public GuestBase
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(GuestSession)
+
+ int init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds);
+ void uninit(void);
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+private:
+
+ /** Wrapped @name IGuestSession properties.
+ * @{ */
+ HRESULT getUser(com::Utf8Str &aUser);
+ HRESULT getDomain(com::Utf8Str &aDomain);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getId(ULONG *aId);
+ HRESULT getTimeout(ULONG *aTimeout);
+ HRESULT setTimeout(ULONG aTimeout);
+ HRESULT getProtocolVersion(ULONG *aProtocolVersion);
+ HRESULT getStatus(GuestSessionStatus_T *aStatus);
+ HRESULT getEnvironmentChanges(std::vector<com::Utf8Str> &aEnvironmentChanges);
+ HRESULT setEnvironmentChanges(const std::vector<com::Utf8Str> &aEnvironmentChanges);
+ HRESULT getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase);
+ HRESULT getProcesses(std::vector<ComPtr<IGuestProcess> > &aProcesses);
+ HRESULT getPathStyle(PathStyle_T *aPathStyle);
+ HRESULT getCurrentDirectory(com::Utf8Str &aCurrentDirectory);
+ HRESULT setCurrentDirectory(const com::Utf8Str &aCurrentDirectory);
+ HRESULT getUserDocuments(com::Utf8Str &aUserDocuments);
+ HRESULT getUserHome(com::Utf8Str &aUserHome);
+ HRESULT getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories);
+ HRESULT getFiles(std::vector<ComPtr<IGuestFile> > &aFiles);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ /** @} */
+
+ /** Wrapped @name IGuestSession methods.
+ * @{ */
+ HRESULT close();
+
+ HRESULT copyFromGuest(const std::vector<com::Utf8Str> &aSources,
+ const std::vector<com::Utf8Str> &aFilters,
+ const std::vector<com::Utf8Str> &aFlags,
+ const com::Utf8Str &aDestination,
+ ComPtr<IProgress> &aProgress);
+ HRESULT copyToGuest(const std::vector<com::Utf8Str> &aSources,
+ const std::vector<com::Utf8Str> &aFilters,
+ const std::vector<com::Utf8Str> &aFlags,
+ const com::Utf8Str &aDestination,
+ ComPtr<IProgress> &aProgress);
+
+ HRESULT directoryCopy(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<DirectoryCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT directoryCopyFromGuest(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<DirectoryCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT directoryCopyToGuest(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<DirectoryCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT directoryCreate(const com::Utf8Str &aPath,
+ ULONG aMode,
+ const std::vector<DirectoryCreateFlag_T> &aFlags);
+ HRESULT directoryCreateTemp(const com::Utf8Str &aTemplateName,
+ ULONG aMode,
+ const com::Utf8Str &aPath,
+ BOOL aSecure,
+ com::Utf8Str &aDirectory);
+ HRESULT directoryExists(const com::Utf8Str &aPath,
+ BOOL aFollowSymlinks,
+ BOOL *aExists);
+ HRESULT directoryOpen(const com::Utf8Str &aPath,
+ const com::Utf8Str &aFilter,
+ const std::vector<DirectoryOpenFlag_T> &aFlags,
+ ComPtr<IGuestDirectory> &aDirectory);
+ HRESULT directoryRemove(const com::Utf8Str &aPath);
+ HRESULT directoryRemoveRecursive(const com::Utf8Str &aPath,
+ const std::vector<DirectoryRemoveRecFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT environmentScheduleSet(const com::Utf8Str &aName,
+ const com::Utf8Str &aValue);
+ HRESULT environmentScheduleUnset(const com::Utf8Str &aName);
+ HRESULT environmentGetBaseVariable(const com::Utf8Str &aName,
+ com::Utf8Str &aValue);
+ HRESULT environmentDoesBaseVariableExist(const com::Utf8Str &aName,
+ BOOL *aExists);
+
+ HRESULT fileCopy(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<FileCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fileCopyToGuest(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<FileCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fileCopyFromGuest(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<FileCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fileCreateTemp(const com::Utf8Str &aTemplateName,
+ ULONG aMode,
+ const com::Utf8Str &aPath,
+ BOOL aSecure,
+ ComPtr<IGuestFile> &aFile);
+ HRESULT fileExists(const com::Utf8Str &aPath,
+ BOOL aFollowSymlinks,
+ BOOL *aExists);
+ HRESULT fileOpen(const com::Utf8Str &aPath,
+ FileAccessMode_T aAccessMode,
+ FileOpenAction_T aOpenAction,
+ ULONG aCreationMode,
+ ComPtr<IGuestFile> &aFile);
+ HRESULT fileOpenEx(const com::Utf8Str &aPath,
+ FileAccessMode_T aAccessMode,
+ FileOpenAction_T aOpenAction,
+ FileSharingMode_T aSharingMode,
+ ULONG aCreationMode,
+ const std::vector<FileOpenExFlag_T> &aFlags,
+ ComPtr<IGuestFile> &aFile);
+ HRESULT fileQuerySize(const com::Utf8Str &aPath,
+ BOOL aFollowSymlinks,
+ LONG64 *aSize);
+ HRESULT fsQueryFreeSpace(const com::Utf8Str &aPath, LONG64 *aFreeSpace);
+ HRESULT fsQueryInfo(const com::Utf8Str &aPath, ComPtr<IGuestFsInfo> &aInfo);
+ HRESULT fsObjExists(const com::Utf8Str &aPath,
+ BOOL aFollowSymlinks,
+ BOOL *pfExists);
+ HRESULT fsObjQueryInfo(const com::Utf8Str &aPath,
+ BOOL aFollowSymlinks,
+ ComPtr<IGuestFsObjInfo> &aInfo);
+ HRESULT fsObjRemove(const com::Utf8Str &aPath);
+ HRESULT fsObjRemoveArray(const std::vector<com::Utf8Str> &aPaths,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fsObjRename(const com::Utf8Str &aOldPath,
+ const com::Utf8Str &aNewPath,
+ const std::vector<FsObjRenameFlag_T> &aFlags);
+ HRESULT fsObjMove(const com::Utf8Str &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<FsObjMoveFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fsObjMoveArray(const std::vector<com::Utf8Str> &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<FsObjMoveFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fsObjCopyArray(const std::vector<com::Utf8Str> &aSource,
+ const com::Utf8Str &aDestination,
+ const std::vector<FileCopyFlag_T> &aFlags,
+ ComPtr<IProgress> &aProgress);
+ HRESULT fsObjSetACL(const com::Utf8Str &aPath,
+ BOOL aFollowSymlinks,
+ const com::Utf8Str &aAcl,
+ ULONG aMode);
+ HRESULT processCreate(const com::Utf8Str &aCommand,
+ const std::vector<com::Utf8Str> &aArguments,
+ const std::vector<com::Utf8Str> &aEnvironment,
+ const std::vector<ProcessCreateFlag_T> &aFlags,
+ ULONG aTimeoutMS,
+ ComPtr<IGuestProcess> &aGuestProcess);
+ HRESULT processCreateEx(const com::Utf8Str &aCommand,
+ const std::vector<com::Utf8Str> &aArguments,
+ const std::vector<com::Utf8Str> &aEnvironment,
+ const std::vector<ProcessCreateFlag_T> &aFlags,
+ ULONG aTimeoutMS,
+ ProcessPriority_T aPriority,
+ const std::vector<LONG> &aAffinity,
+ ComPtr<IGuestProcess> &aGuestProcess);
+ HRESULT processGet(ULONG aPid,
+ ComPtr<IGuestProcess> &aGuestProcess);
+ HRESULT symlinkCreate(const com::Utf8Str &aSource,
+ const com::Utf8Str &aTarget,
+ SymlinkType_T aType);
+ HRESULT symlinkExists(const com::Utf8Str &aSymlink,
+ BOOL *aExists);
+ HRESULT symlinkRead(const com::Utf8Str &aSymlink,
+ const std::vector<SymlinkReadFlag_T> &aFlags,
+ com::Utf8Str &aTarget);
+ HRESULT waitFor(ULONG aWaitFor,
+ ULONG aTimeoutMS,
+ GuestSessionWaitResult_T *aReason);
+ HRESULT waitForArray(const std::vector<GuestSessionWaitForFlag_T> &aWaitFor,
+ ULONG aTimeoutMS,
+ GuestSessionWaitResult_T *aReason);
+ /** @} */
+
+ /** Map of guest directories. The key specifies the internal directory ID. */
+ typedef std::map <uint32_t, ComObjPtr<GuestDirectory> > SessionDirectories;
+ /** Map of guest files. The key specifies the internal file ID. */
+ typedef std::map <uint32_t, ComObjPtr<GuestFile> > SessionFiles;
+ /** Map of guest processes. The key specifies the internal process number.
+ * To retrieve the process' guest PID use the Id() method of the IProcess interface. */
+ typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
+
+ /** Guest session object type enumeration. */
+ enum SESSIONOBJECTTYPE
+ {
+ /** Invalid session object type. */
+ SESSIONOBJECTTYPE_INVALID = 0,
+ /** Session object. */
+ SESSIONOBJECTTYPE_SESSION = 1,
+ /** Directory object. */
+ SESSIONOBJECTTYPE_DIRECTORY = 2,
+ /** File object. */
+ SESSIONOBJECTTYPE_FILE = 3,
+ /** Process object. */
+ SESSIONOBJECTTYPE_PROCESS = 4
+ };
+
+ struct SessionObject
+ {
+ /** Creation timestamp (in ms).
+ * @note not used by anyone at the moment. */
+ uint64_t msBirth;
+ /** The object type. */
+ SESSIONOBJECTTYPE enmType;
+ /** Weak pointer to the object itself.
+ * Is NULL for SESSIONOBJECTTYPE_SESSION because GuestSession doesn't
+ * inherit from GuestObject. */
+ GuestObject *pObject;
+ };
+
+ /** Map containing all objects bound to a guest session.
+ * The key specifies the (global) context ID. */
+ typedef std::map<uint32_t, SessionObject> SessionObjects;
+
+public:
+ /** @name Public internal methods.
+ * @todo r=bird: Most of these are public for no real reason...
+ * @{ */
+ HRESULT i_copyFromGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
+ ComPtr<IProgress> &pProgress);
+ HRESULT i_copyToGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
+ ComPtr<IProgress> &pProgress);
+ int i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pvrcGuest);
+ HRESULT i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, bool fStrict, DirectoryCopyFlag_T *pfFlags);
+ bool i_directoryExists(const Utf8Str &strPath);
+ inline bool i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
+ int i_directoryUnregister(GuestDirectory *pDirectory);
+ int i_directoryRemove(const Utf8Str &strPath, uint32_t fFlags, int *pvrcGuest);
+ int i_directoryCreate(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, int *pvrcGuest);
+ int i_directoryOpen(const GuestDirectoryOpenInfo &openInfo,
+ ComObjPtr<GuestDirectory> &pDirectory, int *pvrcGuest);
+ int i_directoryQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pvrcGuest);
+ int i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ int i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+ HRESULT i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, bool fStrict, FileCopyFlag_T *pfFlags);
+ inline bool i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
+ int i_fileUnregister(GuestFile *pFile);
+ int i_fileRemove(const Utf8Str &strPath, int *pvrcGuest);
+ int i_fileOpenEx(const com::Utf8Str &aPath, FileAccessMode_T aAccessMode, FileOpenAction_T aOpenAction,
+ FileSharingMode_T aSharingMode, ULONG aCreationMode,
+ const std::vector<FileOpenExFlag_T> &aFlags,
+ ComObjPtr<GuestFile> &pFile, int *pvrcGuest);
+ int i_fileOpen(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pvrcGuest);
+ int i_fileQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pvrcGuest);
+ int i_fileQuerySize(const Utf8Str &strPath, bool fFollowSymlinks, int64_t *pllSize, int *pvrcGuest);
+ int i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,
+ Utf8Str &strName, uint32_t fMode, bool fSecure, int *pvrcGuest);
+ int i_fsQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pvrcGuest);
+ const GuestCredentials &i_getCredentials(void);
+ EventSource *i_getEventSource(void) { return mEventSource; }
+ Utf8Str i_getName(void);
+ ULONG i_getId(void) { return mData.mSession.mID; }
+ bool i_isStarted(void) const;
+ HRESULT i_isStartedExternal(void);
+ bool i_isTerminated(void) const;
+ int i_onRemove(void);
+ int i_onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
+ PathStyle_T i_getGuestPathStyle(void);
+ static PathStyle_T i_getHostPathStyle(void);
+ int i_startSession(int *pvrcGuest);
+ int i_startSessionAsync(void);
+ Guest *i_getParent(void) { return mParent; }
+ uint32_t i_getProtocolVersion(void) { return mData.mProtocolVersion; }
+ int i_objectRegister(GuestObject *pObject, SESSIONOBJECTTYPE enmType, uint32_t *pidObject);
+ int i_objectUnregister(uint32_t uObjectID);
+ int i_objectsUnregister(void);
+ int i_objectsNotifyAboutStatusChange(GuestSessionStatus_T enmSessionStatus);
+ int i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *pvrcGuest);
+ int i_pathUserDocuments(Utf8Str &strPath, int *pvrcGuest);
+ int i_pathUserHome(Utf8Str &strPath, int *pvrcGuest);
+ int i_processUnregister(GuestProcess *pProcess);
+ int i_processCreateEx(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
+ inline bool i_processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess);
+ inline int i_processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
+ int i_sendMessage(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms,
+ uint64_t fDst = VBOX_GUESTCTRL_DST_SESSION);
+ int i_setSessionStatus(GuestSessionStatus_T sessionStatus, int vrcSession);
+ int i_signalWaiters(GuestSessionWaitResult_T enmWaitResult, int vrc /*= VINF_SUCCESS */);
+ int i_shutdown(uint32_t fFlags, int *pvrcGuest);
+ int i_determineProtocolVersion(void);
+ int i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestSessionWaitResult_T &waitResult, int *pvrcGuest);
+ int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_t uTimeoutMS,
+ GuestSessionStatus_T *pSessionStatus, int *pvrcGuest);
+ /** @} */
+
+public:
+
+ /** @name Static helper methods.
+ * @{ */
+ static Utf8Str i_guestErrorToString(int guestRc);
+ static bool i_isTerminated(GuestSessionStatus_T enmStatus);
+ static int i_startSessionThreadTask(GuestSessionTaskInternalStart *pTask);
+ /** @} */
+
+private:
+
+ /** Pointer to the parent (Guest). */
+ Guest *mParent;
+ /**
+ * The session's event source. This source is used for
+ * serving the internal listener as well as all other
+ * external listeners that may register to it.
+ *
+ * Note: This can safely be used without holding any locks.
+ * An AutoCaller suffices to prevent it being destroy while in use and
+ * internally there is a lock providing the necessary serialization.
+ */
+ const ComObjPtr<EventSource> mEventSource;
+
+ /** @todo r=bird: One of the core points of the DATA sub-structures in Main is
+ * hinding implementation details and stuff that requires including iprt/asm.h.
+ * The way it's used here totally defeats that purpose. You need to make it
+ * a pointer to a anynmous Data struct and define that structure in
+ * GuestSessionImpl.cpp and allocate it in the Init() function.
+ */
+ struct Data
+ {
+ /** The session credentials. */
+ GuestCredentials mCredentials;
+ /** The session's startup info. */
+ GuestSessionStartupInfo mSession;
+ /** The session's object ID.
+ * Needed for registering wait events which are bound directly to this session. */
+ uint32_t mObjectID;
+ /** The session's current status. */
+ GuestSessionStatus_T mStatus;
+ /** The set of environment changes for the session for use when
+ * creating new guest processes. */
+ GuestEnvironmentChanges mEnvironmentChanges;
+ /** Pointer to the immutable base environment for the session.
+ * @note This is not allocated until the guest reports it to the host. It is
+ * also shared with child processes.
+ * @todo This is actually not yet implemented, see
+ * GuestSession::i_onSessionStatusChange. */
+ GuestEnvironment const *mpBaseEnvironment;
+ /** Directory objects bound to this session. */
+ SessionDirectories mDirectories;
+ /** File objects bound to this session. */
+ SessionFiles mFiles;
+ /** Process objects bound to this session. */
+ SessionProcesses mProcesses;
+ /** Map of registered session objects (files, directories, ...). */
+ SessionObjects mObjects;
+ /** Guest control protocol version to be used.
+ * Guest Additions < VBox 4.3 have version 1,
+ * any newer version will have version 2. */
+ uint32_t mProtocolVersion;
+ /** Session timeout (in ms). */
+ uint32_t mTimeout;
+ /** The last returned session VBox status status returned from the guest side. */
+ int mVrc;
+ /** Object ID allocation bitmap; clear bits are free, set bits are busy. */
+ uint64_t bmObjectIds[VBOX_GUESTCTRL_MAX_OBJECTS / sizeof(uint64_t) / 8];
+
+ Data(void)
+ : mpBaseEnvironment(NULL)
+ {
+ RT_ZERO(bmObjectIds);
+ ASMBitSet(&bmObjectIds, VBOX_GUESTCTRL_MAX_OBJECTS - 1); /* Reserved for the session itself? */
+ ASMBitSet(&bmObjectIds, 0); /* Let's reserve this too. */
+ }
+ Data(const Data &rThat)
+ : mCredentials(rThat.mCredentials)
+ , mSession(rThat.mSession)
+ , mStatus(rThat.mStatus)
+ , mEnvironmentChanges(rThat.mEnvironmentChanges)
+ , mpBaseEnvironment(NULL)
+ , mDirectories(rThat.mDirectories)
+ , mFiles(rThat.mFiles)
+ , mProcesses(rThat.mProcesses)
+ , mObjects(rThat.mObjects)
+ , mProtocolVersion(rThat.mProtocolVersion)
+ , mTimeout(rThat.mTimeout)
+ , mVrc(rThat.mVrc)
+ {
+ memcpy(&bmObjectIds, &rThat.bmObjectIds, sizeof(bmObjectIds));
+ }
+ ~Data(void)
+ {
+ if (mpBaseEnvironment)
+ {
+ mpBaseEnvironment->releaseConst();
+ mpBaseEnvironment = NULL;
+ }
+ }
+ } mData;
+};
+
+#endif /* !MAIN_INCLUDED_GuestSessionImpl_h */
+
diff --git a/src/VBox/Main/include/GuestSessionImplTasks.h b/src/VBox/Main/include/GuestSessionImplTasks.h
new file mode 100644
index 00000000..d32cd8b3
--- /dev/null
+++ b/src/VBox/Main/include/GuestSessionImplTasks.h
@@ -0,0 +1,436 @@
+/* $Id: GuestSessionImplTasks.h $ */
+/** @file
+ * VirtualBox Main - Guest session tasks header.
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_GuestSessionImplTasks_h
+#define MAIN_INCLUDED_GuestSessionImplTasks_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "GuestSessionWrap.h"
+#include "EventImpl.h"
+#include "ProgressImpl.h"
+
+#include "GuestCtrlImplPrivate.h"
+#include "GuestSessionImpl.h"
+#include "ThreadTask.h"
+
+#include <iprt/vfs.h>
+
+#include <vector>
+
+class Guest;
+class GuestSessionTask;
+class GuestSessionTaskInternalStart;
+
+
+/**
+ * Structure for keeping a file system source specification,
+ * along with options.
+ */
+struct GuestSessionFsSourceSpec
+{
+ GuestSessionFsSourceSpec()
+ : enmType(FsObjType_Unknown)
+ , enmPathStyle(PathStyle_Unknown)
+ , fDryRun(false) { RT_ZERO(Type); }
+
+ /** The (absolute) path to the source to use. */
+ Utf8Str strSource;
+ /** Filter to use. Currently not implemented and thus ignored. */
+ Utf8Str strFilter;
+ /** The root object type of this source (directory, file). */
+ FsObjType_T enmType;
+ /** The path style to use. */
+ PathStyle_T enmPathStyle;
+ /** Whether to do a dry run (e.g. not really touching anything) or not. */
+ bool fDryRun;
+ /** Directory copy flags. */
+ DirectoryCopyFlag_T fDirCopyFlags;
+ /** File copy flags. */
+ FileCopyFlag_T fFileCopyFlags;
+ /** Union to keep type-specific data. Must be a POD type (zero'ing). */
+ union
+ {
+ /** File-specific data. */
+ struct
+ {
+ /** Source file offset to start copying from. */
+ size_t offStart;
+ /** Host file handle to use for reading from / writing to.
+ * Optional and can be NULL if not used. */
+ PRTFILE phFile;
+ /** Source size (in bytes) to copy. */
+ uint64_t cbSize;
+ } File;
+ } Type;
+};
+
+/** A set of GuestSessionFsSourceSpec sources. */
+typedef std::vector<GuestSessionFsSourceSpec> GuestSessionFsSourceSet;
+
+/**
+ * Structure for keeping a file system entry.
+ */
+struct FsEntry
+{
+ /** The entrie's file mode. */
+ RTFMODE fMode;
+ /** The entrie's path, relative to the list's root path. */
+ Utf8Str strPath;
+};
+
+/** A vector of FsEntry entries. */
+typedef std::vector<FsEntry *> FsEntries;
+
+/**
+ * Class for storing and handling file system entries, neeed for doing
+ * internal file / directory operations to / from the guest.
+ */
+class FsList
+{
+public:
+
+ FsList(const GuestSessionTask &Task);
+ virtual ~FsList();
+
+public:
+
+ int Init(const Utf8Str &strSrcRootAbs, const Utf8Str &strDstRootAbs, const GuestSessionFsSourceSpec &SourceSpec);
+ void Destroy(void);
+
+#ifdef DEBUG
+ void DumpToLog(void);
+#endif
+
+ int AddEntryFromGuest(const Utf8Str &strFile, const GuestFsObjData &fsObjData);
+ int AddDirFromGuest(const Utf8Str &strPath, const Utf8Str &strSubDir = "");
+
+ int AddEntryFromHost(const Utf8Str &strFile, PCRTFSOBJINFO pcObjInfo);
+ int AddDirFromHost(const Utf8Str &strPath, const Utf8Str &strSubDir, char *pszPathReal, size_t cbPathReal, PRTDIRENTRYEX pDirEntry);
+
+public:
+
+ /** The guest session task object this list is working on. */
+ const GuestSessionTask &mTask;
+ /** File system filter / options to use for this task. */
+ GuestSessionFsSourceSpec mSourceSpec;
+ /** The source' root path. Always in the source's path style!
+ *
+ * For a single file list this is the full (absolute) path to a file,
+ * for a directory list this is the source root directory. */
+ Utf8Str mSrcRootAbs;
+ /** The destinations's root path. Always in the destination's path style!
+ *
+ * For a single file list this is the full (absolute) path to a file,
+ * for a directory list this is the destination root directory. */
+ Utf8Str mDstRootAbs;
+ /** Total size (in bytes) of all list entries together. */
+ uint64_t mcbTotalSize;
+ /** List of file system entries this list contains. */
+ FsEntries mVecEntries;
+};
+
+/** A set of FsList lists. */
+typedef std::vector<FsList *> FsLists;
+
+/**
+ * Abstract base class for a lenghtly per-session operation which
+ * runs in a Main worker thread.
+ */
+class GuestSessionTask
+ : public ThreadTask
+{
+public:
+ DECLARE_TRANSLATE_METHODS(GuestSessionTask)
+
+ GuestSessionTask(GuestSession *pSession);
+
+ virtual ~GuestSessionTask(void);
+
+public:
+
+ /**
+ * Function which implements the actual task to perform.
+ *
+ * @returns VBox status code.
+ */
+ virtual int Run(void) = 0;
+
+ void handler()
+ {
+ int vrc = Run();
+ if (RT_FAILURE(vrc)) /* Could be VERR_INTERRUPTED if the user manually canceled the task. */
+ {
+ /* Make sure to let users know if there is a buggy task which failed but didn't set the progress object
+ * to a failed state, and if not canceled manually by the user. */
+ BOOL fCanceled;
+ if (SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))))
+ {
+ if (!fCanceled)
+ {
+ BOOL fCompleted;
+ if (SUCCEEDED(mProgress->COMGETTER(Completed(&fCompleted))))
+ {
+ if (!fCompleted)
+ setProgressErrorMsg(E_UNEXPECTED,
+ Utf8StrFmt(tr("Task '%s' failed with %Rrc, but progress is still pending. Please report this bug!\n"),
+ mDesc.c_str(), vrc));
+ }
+ else
+ AssertReleaseMsgFailed(("Guest Control: Unable to retrieve progress completion status for task '%s' (task result is %Rrc)\n",
+ mDesc.c_str(), vrc));
+ }
+ }
+ else
+ AssertReleaseMsgFailed(("Guest Control: Unable to retrieve progress cancellation status for task '%s' (task result is %Rrc)\n",
+ mDesc.c_str(), vrc));
+ }
+ }
+
+ // unused: int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
+
+ virtual HRESULT Init(const Utf8Str &strTaskDesc)
+ {
+ setTaskDesc(strTaskDesc);
+ int vrc = createAndSetProgressObject(); /* Single operation by default. */
+ if (RT_SUCCESS(vrc))
+ return S_OK;
+ return E_FAIL;
+ }
+
+ /** Returns the task's progress object. */
+ const ComObjPtr<Progress>& GetProgressObject(void) const { return mProgress; }
+
+ /** Returns the task's guest session object. */
+ const ComObjPtr<GuestSession>& GetSession(void) const { return mSession; }
+
+protected:
+
+ /** @name Directory handling primitives.
+ * @{ */
+ int directoryCreateOnGuest(const com::Utf8Str &strPath,
+ uint32_t fMode, DirectoryCreateFlag_T enmDirectoryCreateFlags,
+ bool fFollowSymlinks, bool fCanExist);
+ int directoryCreateOnHost(const com::Utf8Str &strPath, uint32_t fMode, uint32_t fCreate, bool fCanExist);
+ /** @} */
+
+ /** @name File handling primitives.
+ * @{ */
+ int fileClose(const ComObjPtr<GuestFile> &file);
+ int fileCopyFromGuestInner(const Utf8Str &strSrcFile, ComObjPtr<GuestFile> &srcFile,
+ const Utf8Str &strDstFile, PRTFILE phDstFile,
+ FileCopyFlag_T fFileCopyFlags, uint64_t offCopy, uint64_t cbSize);
+ int fileCopyFromGuest(const Utf8Str &strSource, const Utf8Str &strDest, FileCopyFlag_T fFileCopyFlags);
+ int fileCopyToGuestInner(const Utf8Str &strSrcFile, RTVFSFILE hSrcFile,
+ const Utf8Str &strDstFile, ComObjPtr<GuestFile> &dstFile,
+ FileCopyFlag_T fFileCopyFlags, uint64_t offCopy, uint64_t cbSize);
+
+ int fileCopyToGuest(const Utf8Str &strSource, const Utf8Str &strDest, FileCopyFlag_T fFileCopyFlags);
+ /** @} */
+
+ /** @name Guest property handling primitives.
+ * @{ */
+ int getGuestProperty(const ComObjPtr<Guest> &pGuest, const Utf8Str &strPath, Utf8Str &strValue);
+ /** @} */
+
+ int setProgress(ULONG uPercent);
+ int setProgressSuccess(void);
+ HRESULT setProgressErrorMsg(HRESULT hrc, const Utf8Str &strMsg);
+ HRESULT setProgressErrorMsg(HRESULT hrc, const Utf8Str &strMsg, const GuestErrorInfo &guestErrorInfo);
+
+ inline void setTaskDesc(const Utf8Str &strTaskDesc) throw()
+ {
+ mDesc = strTaskDesc;
+ }
+
+ int createAndSetProgressObject(ULONG cOperations = 1);
+
+protected:
+
+ Utf8Str mDesc;
+ /** The guest session object this task is working on. */
+ ComObjPtr<GuestSession> mSession;
+ /** Progress object for getting updated when running
+ * asynchronously. Optional. */
+ ComObjPtr<Progress> mProgress;
+ /** The guest's path style as char representation (depending on the guest OS type set). */
+ Utf8Str mstrGuestPathStyle;
+};
+
+/**
+ * Task for opening a guest session.
+ */
+class GuestSessionTaskOpen : public GuestSessionTask
+{
+public:
+
+ GuestSessionTaskOpen(GuestSession *pSession,
+ uint32_t uFlags,
+ uint32_t uTimeoutMS);
+ virtual ~GuestSessionTaskOpen(void);
+ int Run(void);
+
+protected:
+
+ /** Session creation flags. */
+ uint32_t mFlags;
+ /** Session creation timeout (in ms). */
+ uint32_t mTimeoutMS;
+};
+
+class GuestSessionCopyTask : public GuestSessionTask
+{
+public:
+ DECLARE_TRANSLATE_METHODS(GuestSessionCopyTask)
+
+ GuestSessionCopyTask(GuestSession *pSession);
+ virtual ~GuestSessionCopyTask();
+
+protected:
+
+ /** Source set. */
+ GuestSessionFsSourceSet mSources;
+ /** Destination to copy to. */
+ Utf8Str mDest;
+ /** Vector of file system lists to handle.
+ * This either can be from the guest or the host side. */
+ FsLists mVecLists;
+};
+
+/**
+ * Guest session task for copying files / directories from guest to the host.
+ */
+class GuestSessionTaskCopyFrom : public GuestSessionCopyTask
+{
+public:
+ DECLARE_TRANSLATE_METHODS(GuestSessionTaskCopyFrom)
+
+ GuestSessionTaskCopyFrom(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
+ virtual ~GuestSessionTaskCopyFrom(void);
+
+ HRESULT Init(const Utf8Str &strTaskDesc);
+ int Run(void);
+};
+
+/**
+ * Task for copying directories from host to the guest.
+ */
+class GuestSessionTaskCopyTo : public GuestSessionCopyTask
+{
+public:
+ DECLARE_TRANSLATE_METHODS(GuestSessionTaskCopyTo)
+
+ GuestSessionTaskCopyTo(GuestSession *pSession, GuestSessionFsSourceSet const &vecSrc, const Utf8Str &strDest);
+ virtual ~GuestSessionTaskCopyTo(void);
+
+ HRESULT Init(const Utf8Str &strTaskDesc);
+ int Run(void);
+};
+
+/**
+ * Guest session task for automatically updating the Guest Additions on the guest.
+ */
+class GuestSessionTaskUpdateAdditions : public GuestSessionTask
+{
+public:
+ DECLARE_TRANSLATE_METHODS(GuestSessionTaskUpdateAdditions)
+
+ GuestSessionTaskUpdateAdditions(GuestSession *pSession, const Utf8Str &strSource,
+ const ProcessArguments &aArguments, uint32_t fFlags);
+ virtual ~GuestSessionTaskUpdateAdditions(void);
+ int Run(void);
+
+protected:
+
+ /**
+ * Suported OS types for automatic updating.
+ */
+ enum eOSType
+ {
+ eOSType_Unknown = 0,
+ eOSType_Windows = 1,
+ eOSType_Linux = 2,
+ eOSType_Solaris = 3
+ };
+
+ /**
+ * Structure representing a file to
+ * get off the .ISO, copied to the guest.
+ */
+ struct ISOFile
+ {
+ ISOFile(const Utf8Str &aSource,
+ const Utf8Str &aDest,
+ uint32_t aFlags = 0)
+ : strSource(aSource),
+ strDest(aDest),
+ fFlags(aFlags) { }
+
+ ISOFile(const Utf8Str &aSource,
+ const Utf8Str &aDest,
+ uint32_t aFlags,
+ const GuestProcessStartupInfo &aStartupInfo)
+ : strSource(aSource),
+ strDest(aDest),
+ fFlags(aFlags),
+ mProcInfo(aStartupInfo)
+ {
+ mProcInfo.mExecutable = strDest;
+ if (mProcInfo.mName.isEmpty())
+ mProcInfo.mName = strDest;
+ }
+
+ /** Source file on .ISO. */
+ Utf8Str strSource;
+ /** Destination file on the guest. */
+ Utf8Str strDest;
+ /** ISO file flags (see ISOFILE_FLAG_ defines). */
+ uint32_t fFlags;
+ /** Optional arguments if this file needs to be
+ * executed. */
+ GuestProcessStartupInfo mProcInfo;
+ };
+
+ int addProcessArguments(ProcessArguments &aArgumentsDest, const ProcessArguments &aArgumentsSource);
+ int copyFileToGuest(GuestSession *pSession, RTVFS hVfsIso, Utf8Str const &strFileSource, const Utf8Str &strFileDest, bool fOptional);
+ int runFileOnGuest(GuestSession *pSession, GuestProcessStartupInfo &procInfo, bool fSilent = false);
+
+ int checkGuestAdditionsStatus(GuestSession *pSession, eOSType osType);
+ int waitForGuestSession(ComObjPtr<Guest> pGuest, eOSType osType);
+
+ /** Files to handle. */
+ std::vector<ISOFile> mFiles;
+ /** The (optionally) specified Guest Additions .ISO on the host
+ * which will be used for the updating process. */
+ Utf8Str mSource;
+ /** (Optional) installer command line arguments. */
+ ProcessArguments mArguments;
+ /** Update flags. */
+ uint32_t mFlags;
+};
+#endif /* !MAIN_INCLUDED_GuestSessionImplTasks_h */
diff --git a/src/VBox/Main/include/HGCM.h b/src/VBox/Main/include/HGCM.h
new file mode 100644
index 00000000..47b0ccf2
--- /dev/null
+++ b/src/VBox/Main/include/HGCM.h
@@ -0,0 +1,69 @@
+/* $Id: HGCM.h $ */
+/** @file
+ * HGCM - Host-Guest Communication Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HGCM_h
+#define MAIN_INCLUDED_HGCM_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/vmm/pdmifs.h>
+
+#include <VBox/hgcmsvc.h>
+
+/* Handle of a HGCM service extension. */
+struct _HGCMSVCEXTHANDLEDATA;
+typedef struct _HGCMSVCEXTHANDLEDATA *HGCMSVCEXTHANDLE;
+
+RT_C_DECLS_BEGIN
+int HGCMHostInit(void);
+int HGCMHostShutdown(bool fUvmIsInvalid = false);
+
+int HGCMHostReset(bool fForShutdown);
+
+int HGCMHostLoad(const char *pszServiceLibrary, const char *pszServiceName,
+ PUVM pUVM, PCVMMR3VTABLE pVMM, PPDMIHGCMPORT pHgcmPort);
+
+int HGCMHostRegisterServiceExtension(HGCMSVCEXTHANDLE *pHandle, const char *pszServiceName, PFNHGCMSVCEXT pfnExtension, void *pvExtension);
+void HGCMHostUnregisterServiceExtension(HGCMSVCEXTHANDLE handle);
+
+int HGCMGuestConnect(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmdPtr, const char *pszServiceName, uint32_t *pClientID);
+int HGCMGuestDisconnect(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmdPtr, uint32_t clientID);
+int HGCMGuestCall(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmdPtr, uint32_t clientID, uint32_t function, uint32_t cParms,
+ VBOXHGCMSVCPARM *paParms, uint64_t tsArrival);
+void HGCMGuestCancelled(PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmdPtr, uint32_t idClient);
+
+int HGCMHostCall(const char *pszServiceName, uint32_t function, uint32_t cParms, VBOXHGCMSVCPARM aParms[]);
+int HGCMBroadcastEvent(HGCMNOTIFYEVENT enmEvent);
+
+int HGCMHostSaveState(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM);
+int HGCMHostLoadState(PSSMHANDLE pSSM, PCVMMR3VTABLE pVMM, uint32_t uVersion);
+
+RT_C_DECLS_END
+
+#endif /* !MAIN_INCLUDED_HGCM_h */
+
diff --git a/src/VBox/Main/include/HGCMObjects.h b/src/VBox/Main/include/HGCMObjects.h
new file mode 100644
index 00000000..a651d3c3
--- /dev/null
+++ b/src/VBox/Main/include/HGCMObjects.h
@@ -0,0 +1,138 @@
+/* $Id: HGCMObjects.h $ */
+/** @file
+ * HGCMObjects - Host-Guest Communication Manager objects header.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HGCMObjects_h
+#define MAIN_INCLUDED_HGCMObjects_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/assert.h>
+#include <iprt/avl.h>
+#include <iprt/critsect.h>
+#include <iprt/asm.h>
+
+class HGCMObject;
+
+typedef struct ObjectAVLCore
+{
+ AVLU32NODECORE AvlCore;
+ HGCMObject *pSelf;
+} ObjectAVLCore;
+
+typedef enum
+{
+ HGCMOBJ_CLIENT,
+ HGCMOBJ_THREAD,
+ HGCMOBJ_MSG,
+ HGCMOBJ_SizeHack = 0x7fffffff
+} HGCMOBJ_TYPE;
+
+
+/**
+ * A referenced object.
+ */
+class HGCMReferencedObject
+{
+ private:
+ int32_t volatile m_cRefs;
+ HGCMOBJ_TYPE m_enmObjType;
+
+ protected:
+ virtual ~HGCMReferencedObject()
+ {}
+
+ public:
+ HGCMReferencedObject(HGCMOBJ_TYPE enmObjType)
+ : m_cRefs(0) /** @todo change to 1! */
+ , m_enmObjType(enmObjType)
+ {}
+
+ void Reference()
+ {
+ int32_t cRefs = ASMAtomicIncS32(&m_cRefs);
+ NOREF(cRefs);
+ Log(("Reference(%p/%d): cRefs = %d\n", this, m_enmObjType, cRefs));
+ }
+
+ void Dereference()
+ {
+ int32_t cRefs = ASMAtomicDecS32(&m_cRefs);
+ Log(("Dereference(%p/%d): cRefs = %d \n", this, m_enmObjType, cRefs));
+ AssertRelease(cRefs >= 0);
+
+ if (cRefs)
+ { /* likely */ }
+ else
+ delete this;
+ }
+
+ HGCMOBJ_TYPE Type()
+ {
+ return m_enmObjType;
+ }
+};
+
+
+class HGCMObject : public HGCMReferencedObject
+{
+ private:
+ friend uint32_t hgcmObjMake(HGCMObject *pObject, uint32_t u32HandleIn);
+
+ ObjectAVLCore m_core;
+
+ protected:
+ virtual ~HGCMObject()
+ {}
+
+ public:
+ HGCMObject(HGCMOBJ_TYPE enmObjType)
+ : HGCMReferencedObject(enmObjType)
+ {}
+
+ uint32_t Handle()
+ {
+ return (uint32_t)m_core.AvlCore.Key;
+ }
+};
+
+int hgcmObjInit();
+void hgcmObjUninit();
+
+uint32_t hgcmObjGenerateHandle(HGCMObject *pObject);
+uint32_t hgcmObjAssignHandle(HGCMObject *pObject, uint32_t u32Handle);
+
+void hgcmObjDeleteHandle(uint32_t handle);
+
+HGCMObject *hgcmObjReference(uint32_t handle, HGCMOBJ_TYPE enmObjType);
+void hgcmObjDereference(HGCMObject *pObject);
+
+uint32_t hgcmObjQueryHandleCount();
+void hgcmObjSetHandleCount(uint32_t u32HandleCount);
+
+
+#endif /* !MAIN_INCLUDED_HGCMObjects_h */
diff --git a/src/VBox/Main/include/HGCMThread.h b/src/VBox/Main/include/HGCMThread.h
new file mode 100644
index 00000000..cbb96538
--- /dev/null
+++ b/src/VBox/Main/include/HGCMThread.h
@@ -0,0 +1,238 @@
+/* $Id: HGCMThread.h $ */
+/** @file
+ * HGCMThread - Host-Guest Communication Manager worker threads header.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HGCMThread_h
+#define MAIN_INCLUDED_HGCMThread_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/types.h>
+
+#include "HGCMObjects.h"
+
+/* Forward declaration of the worker thread class. */
+class HGCMThread;
+
+/** A handle for HGCM message. */
+typedef uint32_t HGCMMSGHANDLE;
+
+/* Forward declaration of message core class. */
+class HGCMMsgCore;
+
+/** @todo comment */
+
+typedef HGCMMsgCore *FNHGCMNEWMSGALLOC(uint32_t u32MsgId);
+typedef FNHGCMNEWMSGALLOC *PFNHGCMNEWMSGALLOC;
+
+/** Function that is called after message processing by worker thread,
+ * or if an error occurred during message handling after successfully
+ * posting (hgcmMsgPost) the message to worker thread.
+ *
+ * @param result Return code either from the service which actually processed the message
+ * or from HGCM.
+ * @param pMsgCore Pointer to just processed message.
+ *
+ * @return Restricted set of VBox status codes when guest call message:
+ * @retval VINF_SUCCESS on success
+ * @retval VERR_CANCELLED if the request was cancelled.
+ * @retval VERR_ALREADY_RESET if the VM is resetting.
+ * @retval VERR_NOT_AVAILABLE if HGCM has been disconnected from the VMMDev
+ * (shouldn't happen).
+ */
+typedef DECLCALLBACKTYPE(int, FNHGCMMSGCALLBACK,(int32_t result, HGCMMsgCore *pMsgCore));
+/** Pointer to a message completeion callback function. */
+typedef FNHGCMMSGCALLBACK *PFNHGCMMSGCALLBACK;
+
+
+/** HGCM core message. */
+class HGCMMsgCore : public HGCMReferencedObject
+{
+ private:
+ friend class HGCMThread;
+
+ /** Version of message header. */
+ uint32_t m_u32Version;
+
+ /** Message number/identifier. */
+ uint32_t m_u32Msg;
+
+ /** Thread the message belongs to, referenced by the message. */
+ HGCMThread *m_pThread;
+
+ /** Callback function pointer. */
+ PFNHGCMMSGCALLBACK m_pfnCallback;
+
+ /** Next element in a message queue. */
+ HGCMMsgCore *m_pNext;
+ /** Previous element in a message queue.
+ * @todo seems not necessary. */
+ HGCMMsgCore *m_pPrev;
+
+ /** Various internal flags. */
+ uint32_t m_fu32Flags;
+
+ /** Result code for a Send */
+ int32_t m_vrcSend;
+
+ protected:
+ void InitializeCore(uint32_t u32MsgId, HGCMThread *pThread);
+
+ virtual ~HGCMMsgCore();
+
+ public:
+ HGCMMsgCore() : HGCMReferencedObject(HGCMOBJ_MSG) {};
+
+ uint32_t MsgId(void) { return m_u32Msg; };
+
+ HGCMThread *Thread(void) { return m_pThread; };
+
+ /** Initialize message after it was allocated. */
+ virtual void Initialize(void) {};
+
+ /** Uninitialize message. */
+ virtual void Uninitialize(void) {};
+};
+
+
+/** HGCM worker thread function.
+ *
+ * @param pThread The HGCM thread instance.
+ * @param pvUser User specified thread parameter.
+ */
+typedef DECLCALLBACKTYPE(void, FNHGCMTHREAD,(HGCMThread *pThread, void *pvUser));
+typedef FNHGCMTHREAD *PFNHGCMTHREAD;
+
+
+/**
+ * Thread API.
+ * Based on thread handles. Internals of a thread are not exposed to users.
+ */
+
+/** Initialize threads.
+ *
+ * @return VBox status code.
+ */
+int hgcmThreadInit(void);
+void hgcmThreadUninit(void);
+
+
+/** Create a HGCM worker thread.
+ *
+ * @param ppThread Where to return the pointer to the worker thread.
+ * @param pszThreadName Name of the thread, needed by runtime.
+ * @param pfnThread The worker thread function.
+ * @param pvUser A pointer passed to worker thread.
+ * @param pszStatsSubDir The "sub-directory" under "/HGCM/" where thread
+ * statistics should be registered. The caller,
+ * HGCMService, will deregister them. NULL if no stats.
+ * @param pUVM The user mode VM handle to register statistics with.
+ * NULL if no stats.
+ * @param pVMM The VMM vtable for statistics registration. NULL if
+ * no stats.
+ *
+ * @return VBox status code.
+ */
+int hgcmThreadCreate(HGCMThread **ppThread, const char *pszThreadName, PFNHGCMTHREAD pfnThread, void *pvUser,
+ const char *pszStatsSubDir, PUVM pUVM, PCVMMR3VTABLE pVMM);
+
+/** Wait for termination of a HGCM worker thread.
+ *
+ * @param pThread The HGCM thread. The passed in reference is always
+ * consumed.
+ *
+ * @return VBox status code.
+ */
+int hgcmThreadWait(HGCMThread *pThread);
+
+/** Allocate a message to be posted to HGCM worker thread.
+ *
+ * @param pThread The HGCM worker thread.
+ * @param ppHandle Where to store the pointer to the new message.
+ * @param u32MsgId Message identifier.
+ * @param pfnNewMessage New message allocation callback.
+ *
+ * @return VBox status code.
+ */
+int hgcmMsgAlloc(HGCMThread *pThread, HGCMMsgCore **ppHandle, uint32_t u32MsgId, PFNHGCMNEWMSGALLOC pfnNewMessage);
+
+/** Post a message to HGCM worker thread.
+ *
+ * @param pMsg The message. Reference will be consumed!
+ * @param pfnCallback Message completion callback.
+ *
+ * @return VBox status code.
+ * @retval VINF_HGCM_ASYNC_EXECUTE on success.
+ *
+ * @thread any
+ */
+int hgcmMsgPost(HGCMMsgCore *pMsg, PFNHGCMMSGCALLBACK pfnCallback);
+
+/** Send a message to HGCM worker thread.
+ *
+ * The function will return after message is processed by thread.
+ *
+ * @param pMsg The message. Reference will be consumed!
+ *
+ * @return VBox status code.
+ *
+ * @thread any
+ */
+int hgcmMsgSend(HGCMMsgCore *pMsg);
+
+
+/* Wait for and get a message.
+ *
+ * @param pThread The HGCM worker thread.
+ * @param ppMsg Where to store returned message pointer.
+ *
+ * @return VBox status code.
+ *
+ * @thread worker thread
+ */
+int hgcmMsgGet(HGCMThread *pThread, HGCMMsgCore **ppMsg);
+
+
+/** Worker thread has processed a message previously obtained with hgcmMsgGet.
+ *
+ * @param pMsg Processed message pointer.
+ * @param result Result code, VBox status code.
+ *
+ * @return Restricted set of VBox status codes when guest call message:
+ * @retval VINF_SUCCESS on success
+ * @retval VERR_CANCELLED if the request was cancelled.
+ * @retval VERR_ALREADY_RESET if the VM is resetting.
+ * @retval VERR_NOT_AVAILABLE if HGCM has been disconnected from the VMMDev
+ * (shouldn't happen).
+ *
+ * @thread worker thread
+ */
+int hgcmMsgComplete(HGCMMsgCore *pMsg, int32_t result);
+
+
+#endif /* !MAIN_INCLUDED_HGCMThread_h */
+
diff --git a/src/VBox/Main/include/HashedPw.h b/src/VBox/Main/include/HashedPw.h
new file mode 100644
index 00000000..19a82c22
--- /dev/null
+++ b/src/VBox/Main/include/HashedPw.h
@@ -0,0 +1,40 @@
+/* $Id: HashedPw.h $ */
+/** @file
+ * Main - Password Hashing
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HashedPw_h
+#define MAIN_INCLUDED_HashedPw_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cpp/ministring.h>
+
+bool VBoxIsPasswordHashed(RTCString const *a_pstrPassword);
+void VBoxHashPassword(RTCString *a_pstrPassword);
+
+#endif /* !MAIN_INCLUDED_HashedPw_h */
+
diff --git a/src/VBox/Main/include/HostAudioDeviceImpl.h b/src/VBox/Main/include/HostAudioDeviceImpl.h
new file mode 100644
index 00000000..c3a8895b
--- /dev/null
+++ b/src/VBox/Main/include/HostAudioDeviceImpl.h
@@ -0,0 +1,58 @@
+/* $Id: HostAudioDeviceImpl.h $ */
+
+/** @file
+ * VirtualBox COM class implementation - Host audio device implementation.
+ */
+
+/*
+ * Copyright (C) 2022-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostAudioDeviceImpl_h
+#define MAIN_INCLUDED_HostAudioDeviceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostAudioDeviceWrap.h"
+
+class ATL_NO_VTABLE HostAudioDevice :
+ public HostAudioDeviceWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(HostAudioDevice)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init();
+ void uninit();
+
+private:
+
+ // wrapped IHostAudioDevice properties
+
+};
+
+#endif /* !MAIN_INCLUDED_HostAudioDeviceImpl_h */
+
diff --git a/src/VBox/Main/include/HostDriveImpl.h b/src/VBox/Main/include/HostDriveImpl.h
new file mode 100644
index 00000000..37a55677
--- /dev/null
+++ b/src/VBox/Main/include/HostDriveImpl.h
@@ -0,0 +1,86 @@
+/* $Id: HostDriveImpl.h $ */
+/** @file
+ * VirtualBox Main - IHostDrive implementation, VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostDriveImpl_h
+#define MAIN_INCLUDED_HostDriveImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostDriveWrap.h"
+
+class ATL_NO_VTABLE HostDrive
+ : public HostDriveWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(HostDrive)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /** @name Public initializer/uninitializer for internal purposes only.
+ * @{ */
+ HRESULT initFromPathAndModel(const com::Utf8Str &drivePath, const com::Utf8Str &driveModel);
+ void uninit();
+ /** @} */
+
+ com::Utf8Str i_getDrivePath() { return m.drivePath; }
+
+private:
+ /** @name wrapped IHostDrive properties
+ * @{ */
+ virtual HRESULT getPartitioningType(PartitioningType_T *aPartitioningType) RT_OVERRIDE;
+ virtual HRESULT getDrivePath(com::Utf8Str &aDrivePath) RT_OVERRIDE;
+ virtual HRESULT getUuid(com::Guid &aUuid) RT_OVERRIDE;
+ virtual HRESULT getSectorSize(ULONG *aSectorSize) RT_OVERRIDE;
+ virtual HRESULT getSize(LONG64 *aSize) RT_OVERRIDE;
+ virtual HRESULT getModel(com::Utf8Str &aModel) RT_OVERRIDE;
+ virtual HRESULT getPartitions(std::vector<ComPtr<IHostDrivePartition> > &aPartitions) RT_OVERRIDE;
+ /** @} */
+
+ /** Data. */
+ struct Data
+ {
+ Data() : cbSector(0), cbDisk(0)
+ {
+ }
+
+ PartitioningType_T partitioningType;
+ com::Utf8Str drivePath;
+ com::Guid uuid;
+ uint32_t cbSector;
+ uint64_t cbDisk;
+ com::Utf8Str model;
+ std::vector<ComPtr<IHostDrivePartition> > partitions;
+ };
+
+ Data m;
+};
+
+#endif /* !MAIN_INCLUDED_HostDriveImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/HostDrivePartitionImpl.h b/src/VBox/Main/include/HostDrivePartitionImpl.h
new file mode 100644
index 00000000..6c33690f
--- /dev/null
+++ b/src/VBox/Main/include/HostDrivePartitionImpl.h
@@ -0,0 +1,126 @@
+/* $Id: HostDrivePartitionImpl.h $ */
+/** @file
+ * VirtualBox Main - IHostDrivePartition implementation, VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostDrivePartitionImpl_h
+#define MAIN_INCLUDED_HostDrivePartitionImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostDrivePartitionWrap.h"
+
+#include <iprt/dvm.h>
+
+class ATL_NO_VTABLE HostDrivePartition
+ : public HostDrivePartitionWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(HostDrivePartition)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /** @name Public initializer/uninitializer for internal purposes only.
+ * @{ */
+ HRESULT initFromDvmVol(RTDVMVOLUME hVol);
+ void uninit();
+ /** @} */
+
+private:
+ /** @name wrapped IHostDrivePartition properties
+ * @{ */
+ /* Common: */
+ virtual HRESULT getNumber(ULONG *aNumber) RT_OVERRIDE { *aNumber = m.number; return S_OK; }
+ virtual HRESULT getSize(LONG64 *aSize) RT_OVERRIDE { *aSize = m.cbVol; return S_OK; }
+ virtual HRESULT getStart(LONG64 *aStart) RT_OVERRIDE { *aStart = m.offStart; return S_OK; }
+ virtual HRESULT getType(PartitionType_T *aType) RT_OVERRIDE { *aType = m.enmType; return S_OK; }
+ virtual HRESULT getActive(BOOL *aActive) RT_OVERRIDE { *aActive = m.active; return S_OK; }
+ /* MBR: */
+ virtual HRESULT getTypeMBR(ULONG *aTypeMBR) RT_OVERRIDE { *aTypeMBR = m.bMBRType; return S_OK; }
+ virtual HRESULT getStartCylinder(ULONG *aStartCylinder) RT_OVERRIDE { *aStartCylinder = m.firstCylinder; return S_OK; }
+ virtual HRESULT getStartHead(ULONG *aStartHead) RT_OVERRIDE { *aStartHead = m.firstHead; return S_OK; }
+ virtual HRESULT getStartSector(ULONG *aStartSector) RT_OVERRIDE { *aStartSector = m.firstSector; return S_OK; }
+ virtual HRESULT getEndCylinder(ULONG *aEndCylinder) RT_OVERRIDE { *aEndCylinder = m.lastCylinder; return S_OK; }
+ virtual HRESULT getEndHead(ULONG *aEndHead) RT_OVERRIDE { *aEndHead = m.lastHead; return S_OK; }
+ virtual HRESULT getEndSector(ULONG *aEndSector) RT_OVERRIDE { *aEndSector = m.lastSector; return S_OK; }
+ /* GPT: */
+ virtual HRESULT getTypeUuid(com::Guid &aTypeUuid) RT_OVERRIDE { aTypeUuid = m.typeUuid; return S_OK; }
+ virtual HRESULT getUuid(com::Guid &aUuid) RT_OVERRIDE { aUuid = m.uuid; return S_OK; }
+ virtual HRESULT getName(com::Utf8Str &aName) RT_OVERRIDE { return aName.assignEx(m.name); };
+ /** @} */
+
+ /** Data. */
+ struct Data
+ {
+ Data()
+ : number(0)
+ , cbVol(0)
+ , offStart(0)
+ , enmType(PartitionType_Unknown)
+ , active(FALSE)
+ , bMBRType(0)
+ , firstCylinder(0)
+ , firstHead(0)
+ , firstSector(0)
+ , lastCylinder(0)
+ , lastHead(0)
+ , lastSector(0)
+ , typeUuid()
+ , uuid()
+ , name()
+ {
+ }
+
+ ULONG number;
+ LONG64 cbVol;
+ LONG64 offStart;
+ PartitionType_T enmType;
+ BOOL active;
+ /** @name MBR specifics
+ * @{ */
+ uint8_t bMBRType;
+ uint16_t firstCylinder;
+ uint8_t firstHead;
+ uint8_t firstSector;
+ uint16_t lastCylinder;
+ uint8_t lastHead;
+ uint8_t lastSector;
+ /** @} */
+ /** @name GPT specifics
+ * @{ */
+ com::Guid typeUuid;
+ com::Guid uuid;
+ com::Utf8Str name;
+ /** @} */
+ };
+
+ Data m;
+};
+
+#endif /* !MAIN_INCLUDED_HostDrivePartitionImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/HostHardwareLinux.h b/src/VBox/Main/include/HostHardwareLinux.h
new file mode 100644
index 00000000..b9206bc6
--- /dev/null
+++ b/src/VBox/Main/include/HostHardwareLinux.h
@@ -0,0 +1,209 @@
+/* $Id: HostHardwareLinux.h $ */
+/** @file
+ * VirtualBox Main - Classes for handling hardware detection under Linux.
+ *
+ * Please feel free to expand these to work for other systems (Solaris!) or to
+ * add new ones for other systems.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostHardwareLinux_h
+#define MAIN_INCLUDED_HostHardwareLinux_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/err.h>
+#include <iprt/cpp/ministring.h>
+#include <vector>
+#include <vector.h>
+
+/**
+ * Class for probing and returning information about host DVD and floppy
+ * drives. To use this class, create an instance, call one of the update
+ * methods to do the actual probing and use the iterator methods to get the
+ * result of the probe.
+ */
+class VBoxMainDriveInfo
+{
+public:
+ /** Structure describing a host drive */
+ struct DriveInfo
+ {
+ /** The device node of the drive. */
+ RTCString mDevice;
+ /** A unique identifier for the device, if available. This should be
+ * kept consistent across different probing methods of a given
+ * platform if at all possible. */
+ RTCString mUdi;
+ /** A textual description of the drive. */
+ RTCString mDescription;
+
+ /** Constructors */
+ DriveInfo(const RTCString &aDevice,
+ const RTCString &aUdi = "",
+ const RTCString &aDescription = "")
+ : mDevice(aDevice),
+ mUdi(aUdi),
+ mDescription(aDescription)
+ { }
+ };
+
+ /** List (resp vector) holding drive information */
+ typedef std::vector<DriveInfo> DriveInfoList;
+
+ /**
+ * Search for host floppy drives and rebuild the list, which remains empty
+ * until the first time this method is called.
+ * @returns iprt status code
+ */
+ int updateFloppies() RT_NOEXCEPT;
+
+ /**
+ * Search for host DVD drives and rebuild the list, which remains empty
+ * until the first time this method is called.
+ * @returns iprt status code
+ */
+ int updateDVDs() RT_NOEXCEPT;
+
+ /**
+ * Search for fixed disks (HDDs) and rebuild the list, which remains empty until
+ * the first time this method is called.
+ * @returns iprt status code
+ */
+ int updateFixedDrives() RT_NOEXCEPT;
+
+ /** Get the first element in the list of floppy drives. */
+ DriveInfoList::const_iterator FloppyBegin()
+ {
+ return mFloppyList.begin();
+ }
+
+ /** Get the last element in the list of floppy drives. */
+ DriveInfoList::const_iterator FloppyEnd()
+ {
+ return mFloppyList.end();
+ }
+
+ /** Get the first element in the list of DVD drives. */
+ DriveInfoList::const_iterator DVDBegin()
+ {
+ return mDVDList.begin();
+ }
+
+ /** Get the last element in the list of DVD drives. */
+ DriveInfoList::const_iterator DVDEnd()
+ {
+ return mDVDList.end();
+ }
+
+ /** Get the first element in the list of fixed drives. */
+ DriveInfoList::const_iterator FixedDriveBegin()
+ {
+ return mFixedDriveList.begin();
+ }
+
+ /** Get the last element in the list of fixed drives. */
+ DriveInfoList::const_iterator FixedDriveEnd()
+ {
+ return mFixedDriveList.end();
+ }
+private:
+ /** The list of currently available floppy drives */
+ DriveInfoList mFloppyList;
+ /** The list of currently available DVD drives */
+ DriveInfoList mDVDList;
+ /** The list of currently available fixed drives */
+ DriveInfoList mFixedDriveList;
+};
+
+/** Convenience typedef. */
+typedef VBoxMainDriveInfo::DriveInfoList DriveInfoList;
+/** Convenience typedef. */
+typedef VBoxMainDriveInfo::DriveInfo DriveInfo;
+
+/** Implementation of the hotplug waiter class below */
+class VBoxMainHotplugWaiterImpl
+{
+public:
+ VBoxMainHotplugWaiterImpl(void) {}
+ virtual ~VBoxMainHotplugWaiterImpl(void) {}
+ /** @copydoc VBoxMainHotplugWaiter::Wait */
+ virtual int Wait(RTMSINTERVAL cMillies) = 0;
+ /** @copydoc VBoxMainHotplugWaiter::Interrupt */
+ virtual void Interrupt(void) = 0;
+ /** @copydoc VBoxMainHotplugWaiter::getStatus */
+ virtual int getStatus(void) = 0;
+};
+
+/**
+ * Class for waiting for a hotplug event. To use this class, create an
+ * instance and call the @a Wait() method, which blocks until an event or a
+ * user-triggered interruption occurs. Call @a Interrupt() to interrupt the
+ * wait before an event occurs.
+ */
+class VBoxMainHotplugWaiter
+{
+ /** Class implementation. */
+ VBoxMainHotplugWaiterImpl *mImpl;
+public:
+ /** Constructor. Responsible for selecting the implementation. */
+ VBoxMainHotplugWaiter(const char *pcszDevicesRoot);
+ /** Destructor. */
+ ~VBoxMainHotplugWaiter (void)
+ {
+ delete mImpl;
+ }
+ /**
+ * Wait for a hotplug event.
+ *
+ * @returns VINF_SUCCESS if an event occurred or if Interrupt() was called.
+ * @returns VERR_TRY_AGAIN if the wait failed but this might (!) be a
+ * temporary failure.
+ * @returns VERR_NOT_SUPPORTED if the wait failed and will definitely not
+ * succeed if retried.
+ * @returns Possibly other iprt status codes otherwise.
+ * @param cMillies How long to wait for at most.
+ */
+ int Wait (RTMSINTERVAL cMillies)
+ {
+ return mImpl->Wait(cMillies);
+ }
+ /**
+ * Interrupts an active wait. In the current implementation, the wait
+ * may not return until up to two seconds after calling this method.
+ */
+ void Interrupt (void)
+ {
+ mImpl->Interrupt();
+ }
+
+ int getStatus(void)
+ {
+ return mImpl ? mImpl->getStatus() : VERR_NO_MEMORY;
+ }
+};
+
+#endif /* !MAIN_INCLUDED_HostHardwareLinux_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/HostImpl.h b/src/VBox/Main/include/HostImpl.h
new file mode 100644
index 00000000..a3fbbe8c
--- /dev/null
+++ b/src/VBox/Main/include/HostImpl.h
@@ -0,0 +1,227 @@
+/* $Id: HostImpl.h $ */
+/** @file
+ * Implementation of IHost.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostImpl_h
+#define MAIN_INCLUDED_HostImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostWrap.h"
+
+class HostUSBDeviceFilter;
+class USBProxyService;
+class SessionMachine;
+class Progress;
+class PerformanceCollector;
+class HostDrive;
+class HostDrivePartition;
+
+namespace settings
+{
+ struct Host;
+}
+
+#include <list>
+
+class ATL_NO_VTABLE Host :
+ public HostWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(Host)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(VirtualBox *aParent);
+ void uninit();
+
+ // public methods only for internal purposes
+
+ /**
+ * Override of the default locking class to be used for validating lock
+ * order with the standard member lock handle.
+ */
+ virtual VBoxLockingClass getLockingClass() const
+ {
+ return LOCKCLASS_HOSTOBJECT;
+ }
+
+ HRESULT i_loadSettings(const settings::Host &data);
+ HRESULT i_saveSettings(settings::Host &data);
+
+ void i_updateProcessorFeatures();
+
+ HRESULT i_getDrives(DeviceType_T mediumType, bool fRefresh, MediaList *&pll, AutoWriteLock &treeLock);
+ HRESULT i_findHostDriveById(DeviceType_T mediumType, const Guid &uuid, bool fRefresh, ComObjPtr<Medium> &pMedium);
+ HRESULT i_findHostDriveByName(DeviceType_T mediumType, const Utf8Str &strLocationFull, bool fRefresh, ComObjPtr<Medium> &pMedium);
+
+#ifdef VBOX_WITH_USB
+ typedef std::list< ComObjPtr<HostUSBDeviceFilter> > USBDeviceFilterList;
+
+ /** Must be called from under this object's lock. */
+ USBProxyService* i_usbProxyService();
+
+ HRESULT i_addChild(HostUSBDeviceFilter *pChild);
+ HRESULT i_removeChild(HostUSBDeviceFilter *pChild);
+ VirtualBox* i_parent();
+
+ HRESULT i_onUSBDeviceFilterChange(HostUSBDeviceFilter *aFilter, BOOL aActiveChanged = FALSE);
+ void i_getUSBFilters(USBDeviceFilterList *aGlobalFiltes);
+ HRESULT i_checkUSBProxyService();
+#endif /* !VBOX_WITH_USB */
+
+ static void i_generateMACAddress(Utf8Str &mac);
+
+#ifdef RT_OS_WINDOWS
+ HRESULT i_updatePersistentConfigForHostOnlyAdapters(void);
+ HRESULT i_removePersistentConfig(const Bstr &bstrGuid);
+#endif /* RT_OS_WINDOWS */
+
+
+private:
+
+ // wrapped IHost properties
+ HRESULT getDVDDrives(std::vector<ComPtr<IMedium> > &aDVDDrives);
+ HRESULT getFloppyDrives(std::vector<ComPtr<IMedium> > &aFloppyDrives);
+ HRESULT getAudioDevices(std::vector<ComPtr<IHostAudioDevice> > &aAudioDevices);
+ HRESULT getUSBDevices(std::vector<ComPtr<IHostUSBDevice> > &aUSBDevices);
+ HRESULT getUSBDeviceFilters(std::vector<ComPtr<IHostUSBDeviceFilter> > &aUSBDeviceFilters);
+ HRESULT getNetworkInterfaces(std::vector<ComPtr<IHostNetworkInterface> > &aNetworkInterfaces);
+ HRESULT getNameServers(std::vector<com::Utf8Str> &aNameServers);
+ HRESULT getDomainName(com::Utf8Str &aDomainName);
+ HRESULT getSearchStrings(std::vector<com::Utf8Str> &aSearchStrings);
+ HRESULT getProcessorCount(ULONG *aProcessorCount);
+ HRESULT getProcessorOnlineCount(ULONG *aProcessorOnlineCount);
+ HRESULT getProcessorCoreCount(ULONG *aProcessorCoreCount);
+ HRESULT getProcessorOnlineCoreCount(ULONG *aProcessorOnlineCoreCount);
+ HRESULT getHostDrives(std::vector<ComPtr<IHostDrive> > &aHostDrives);
+ HRESULT getMemorySize(ULONG *aMemorySize);
+ HRESULT getMemoryAvailable(ULONG *aMemoryAvailable);
+ HRESULT getOperatingSystem(com::Utf8Str &aOperatingSystem);
+ HRESULT getOSVersion(com::Utf8Str &aOSVersion);
+ HRESULT getUTCTime(LONG64 *aUTCTime);
+ HRESULT getAcceleration3DAvailable(BOOL *aAcceleration3DAvailable);
+ HRESULT getVideoInputDevices(std::vector<ComPtr<IHostVideoInputDevice> > &aVideoInputDevices);
+ HRESULT getUpdateHost(ComPtr<IUpdateAgent> &aUpdate);
+ HRESULT getUpdateExtPack(ComPtr<IUpdateAgent> &aUpdate);
+ HRESULT getUpdateGuestAdditions(ComPtr<IUpdateAgent> &aUpdate);
+ HRESULT getUpdateResponse(BOOL *aUpdateNeeded);
+ HRESULT getUpdateVersion(com::Utf8Str &aUpdateVersion);
+ HRESULT getUpdateURL(com::Utf8Str &aUpdateURL);
+ HRESULT getUpdateCheckNeeded(BOOL *aUpdateCheckNeeded);
+
+ // wrapped IHost methods
+ HRESULT getProcessorSpeed(ULONG aCpuId,
+ ULONG *aSpeed);
+ HRESULT getProcessorFeature(ProcessorFeature_T aFeature,
+ BOOL *aSupported);
+ HRESULT getProcessorDescription(ULONG aCpuId,
+ com::Utf8Str &aDescription);
+ HRESULT getProcessorCPUIDLeaf(ULONG aCpuId,
+ ULONG aLeaf,
+ ULONG aSubLeaf,
+ ULONG *aValEax,
+ ULONG *aValEbx,
+ ULONG *aValEcx,
+ ULONG *aValEdx);
+ HRESULT createHostOnlyNetworkInterface(ComPtr<IHostNetworkInterface> &aHostInterface,
+ ComPtr<IProgress> &aProgress);
+ HRESULT removeHostOnlyNetworkInterface(const com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT createUSBDeviceFilter(const com::Utf8Str &aName,
+ ComPtr<IHostUSBDeviceFilter> &aFilter);
+ HRESULT insertUSBDeviceFilter(ULONG aPosition,
+ const ComPtr<IHostUSBDeviceFilter> &aFilter);
+ HRESULT removeUSBDeviceFilter(ULONG aPosition);
+ HRESULT findHostDVDDrive(const com::Utf8Str &aName,
+ ComPtr<IMedium> &aDrive);
+ HRESULT findHostFloppyDrive(const com::Utf8Str &aName,
+ ComPtr<IMedium> &aDrive);
+ HRESULT findHostNetworkInterfaceByName(const com::Utf8Str &aName,
+ ComPtr<IHostNetworkInterface> &aNetworkInterface);
+ HRESULT findHostNetworkInterfaceById(const com::Guid &aId,
+ ComPtr<IHostNetworkInterface> &aNetworkInterface);
+ HRESULT findHostNetworkInterfacesOfType(HostNetworkInterfaceType_T aType,
+ std::vector<ComPtr<IHostNetworkInterface> > &aNetworkInterfaces);
+ HRESULT findUSBDeviceById(const com::Guid &aId,
+ ComPtr<IHostUSBDevice> &aDevice);
+ HRESULT findUSBDeviceByAddress(const com::Utf8Str &aName,
+ ComPtr<IHostUSBDevice> &aDevice);
+ HRESULT generateMACAddress(com::Utf8Str &aAddress);
+
+ HRESULT addUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId, const com::Utf8Str &aAddress,
+ const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues);
+
+ HRESULT removeUSBDeviceSource(const com::Utf8Str &aId);
+
+ // Internal Methods.
+
+ HRESULT i_buildDVDDrivesList(MediaList &list);
+ HRESULT i_buildFloppyDrivesList(MediaList &list);
+ HRESULT i_findHostDriveByNameOrId(DeviceType_T mediumType, const Utf8Str &strNameOrId, ComObjPtr<Medium> &pMedium);
+
+#if defined(RT_OS_SOLARIS) && defined(VBOX_USE_LIBHAL)
+ bool i_getDVDInfoFromHal(std::list< ComObjPtr<Medium> > &list);
+ bool i_getFloppyInfoFromHal(std::list< ComObjPtr<Medium> > &list);
+ HRESULT i_getFixedDrivesFromHal(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &list) RT_NOEXCEPT;
+#endif
+
+#if defined(RT_OS_SOLARIS)
+ void i_getDVDInfoFromDevTree(std::list< ComObjPtr<Medium> > &list);
+ void i_parseMountTable(char *mountTable, std::list< ComObjPtr<Medium> > &list);
+ bool i_validateDevice(const char *deviceNode, bool isCDROM);
+ HRESULT i_getFixedDrivesFromDevTree(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &list) RT_NOEXCEPT;
+#endif
+
+ HRESULT i_updateNetIfList();
+
+#ifndef RT_OS_WINDOWS
+ HRESULT i_parseResolvConf();
+#else
+ HRESULT i_fetchNameResolvingInformation();
+#endif
+
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+ void i_registerMetrics(PerformanceCollector *aCollector);
+ void i_registerDiskMetrics(PerformanceCollector *aCollector);
+ void i_unregisterMetrics(PerformanceCollector *aCollector);
+#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+
+#ifdef RT_OS_WINDOWS
+ HRESULT i_getFixedDrivesFromGlobalNamespace(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &aDriveList) RT_NOEXCEPT;
+#endif
+ HRESULT i_getDrivesPathsList(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &aDriveList) RT_NOEXCEPT;
+
+ struct Data; // opaque data structure, defined in HostImpl.cpp
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_HostImpl_h */
+
diff --git a/src/VBox/Main/include/HostNetworkInterfaceImpl.h b/src/VBox/Main/include/HostNetworkInterfaceImpl.h
new file mode 100644
index 00000000..c41aac87
--- /dev/null
+++ b/src/VBox/Main/include/HostNetworkInterfaceImpl.h
@@ -0,0 +1,145 @@
+/* $Id: HostNetworkInterfaceImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostNetworkInterfaceImpl_h
+#define MAIN_INCLUDED_HostNetworkInterfaceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostNetworkInterfaceWrap.h"
+
+#ifdef VBOX_WITH_HOSTNETIF_API
+struct NETIFINFO;
+#endif
+
+class PerformanceCollector;
+
+class ATL_NO_VTABLE HostNetworkInterface :
+ public HostNetworkInterfaceWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(HostNetworkInterface)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Utf8Str aInterfaceName, Utf8Str aShortName, Guid aGuid, HostNetworkInterfaceType_T ifType);
+#ifdef VBOX_WITH_HOSTNETIF_API
+ HRESULT init(Utf8Str aInterfaceName, HostNetworkInterfaceType_T ifType, struct NETIFINFO *pIfs);
+ HRESULT updateConfig();
+#endif
+
+ HRESULT i_setVirtualBox(VirtualBox *pVirtualBox);
+#ifdef RT_OS_WINDOWS
+ HRESULT i_updatePersistentConfig();
+#endif /* RT_OS_WINDOWS */
+
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+ void i_registerMetrics(PerformanceCollector *aCollector, ComPtr<IUnknown> objptr);
+ void i_unregisterMetrics(PerformanceCollector *aCollector, ComPtr<IUnknown> objptr);
+#endif
+
+private:
+
+ // Wrapped IHostNetworkInterface properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getShortName(com::Utf8Str &aShortName);
+ HRESULT getId(com::Guid &aGuiId);
+ HRESULT getDHCPEnabled(BOOL *aDHCPEnabled);
+ HRESULT getIPAddress(com::Utf8Str &aIPAddress);
+ HRESULT getNetworkMask(com::Utf8Str &aNetworkMask);
+ HRESULT getIPV6Supported(BOOL *aIPV6Supported);
+ HRESULT getIPV6Address(com::Utf8Str &aIPV6Address);
+ HRESULT getIPV6NetworkMaskPrefixLength(ULONG *aIPV6NetworkMaskPrefixLength);
+ HRESULT getHardwareAddress(com::Utf8Str &aHardwareAddress);
+ HRESULT getMediumType(HostNetworkInterfaceMediumType_T *aType);
+ HRESULT getStatus(HostNetworkInterfaceStatus_T *aStatus);
+ HRESULT getInterfaceType(HostNetworkInterfaceType_T *aType);
+ HRESULT getNetworkName(com::Utf8Str &aNetworkName);
+ HRESULT getWireless(BOOL *aWireless);
+
+ // Wrapped IHostNetworkInterface methods
+ HRESULT enableStaticIPConfig(const com::Utf8Str &aIPAddress,
+ const com::Utf8Str &aNetworkMask);
+ HRESULT enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address,
+ ULONG aIPV6NetworkMaskPrefixLength);
+ HRESULT enableDynamicIPConfig();
+ HRESULT dHCPRediscover();
+
+ Utf8Str i_composeNetworkName(const Utf8Str szShortName);
+
+#if defined(RT_OS_WINDOWS)
+ HRESULT eraseAdapterConfigParameter(const char *szParamName);
+ HRESULT saveAdapterConfigParameter(const char *szParamName, const Utf8Str& strValue);
+ HRESULT saveAdapterConfigIPv4Dhcp();
+ HRESULT saveAdapterConfigIPv4(ULONG addr, ULONG mask);
+ HRESULT saveAdapterConfigIPv6(const Utf8Str& addr, ULONG prefix);
+ HRESULT saveAdapterConfig();
+ bool isInConfigFile();
+#endif /* defined(RT_OS_WINDOWS) */
+
+ const Utf8Str mInterfaceName;
+ const Guid mGuid;
+ const Utf8Str mNetworkName;
+ const Utf8Str mShortName;
+ HostNetworkInterfaceType_T mIfType;
+
+ VirtualBox * const mVirtualBox;
+
+ struct Data
+ {
+ Data() : IPAddress(0), networkMask(0), dhcpEnabled(FALSE),
+ mediumType(HostNetworkInterfaceMediumType_Unknown),
+ status(HostNetworkInterfaceStatus_Down), wireless(FALSE){}
+
+ ULONG IPAddress;
+ ULONG networkMask;
+ Utf8Str IPV6Address;
+ ULONG IPV6NetworkMaskPrefixLength;
+ ULONG realIPAddress;
+ ULONG realNetworkMask;
+ Utf8Str realIPV6Address;
+ ULONG realIPV6PrefixLength;
+ BOOL dhcpEnabled;
+ Utf8Str hardwareAddress;
+ HostNetworkInterfaceMediumType_T mediumType;
+ HostNetworkInterfaceStatus_T status;
+ ULONG speedMbits;
+ BOOL wireless;
+ } m;
+
+};
+
+typedef std::list<ComObjPtr<HostNetworkInterface> > HostNetworkInterfaceList;
+
+#endif /* !MAIN_INCLUDED_HostNetworkInterfaceImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/HostOnlyNetworkImpl.h b/src/VBox/Main/include/HostOnlyNetworkImpl.h
new file mode 100644
index 00000000..ec3b75e8
--- /dev/null
+++ b/src/VBox/Main/include/HostOnlyNetworkImpl.h
@@ -0,0 +1,80 @@
+/* $Id: HostOnlyNetworkImpl.h $ */
+/** @file
+ * IHostOnlyNetwork implementation header, lives in VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostOnlyNetworkImpl_h
+#define MAIN_INCLUDED_HostOnlyNetworkImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostOnlyNetworkWrap.h"
+
+namespace settings
+{
+ struct HostOnlyNetwork;
+}
+
+class ATL_NO_VTABLE HostOnlyNetwork :
+ public HostOnlyNetworkWrap
+{
+public:
+
+ DECLARE_EMPTY_CTOR_DTOR(HostOnlyNetwork)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(VirtualBox *aVirtualBox, com::Utf8Str aName);
+ HRESULT i_loadSettings(const settings::HostOnlyNetwork &data);
+ void uninit();
+ HRESULT i_saveSettings(settings::HostOnlyNetwork &data);
+
+ // Internal methods
+ // Utf8Str i_getNetworkName();
+ // Utf8Str i_getNetworkId();
+private:
+
+ // Wrapped IHostOnlyNetwork properties
+ HRESULT getNetworkName(com::Utf8Str &aNetworkName);
+ HRESULT setNetworkName(const com::Utf8Str &aNetworkName);
+ HRESULT getNetworkMask(com::Utf8Str &aNetworkMask);
+ HRESULT setNetworkMask(const com::Utf8Str &aNetworkMask);
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getHostIP(com::Utf8Str &aHostIP);
+ HRESULT getLowerIP(com::Utf8Str &aLowerIP);
+ HRESULT setLowerIP(const com::Utf8Str &aLowerIP);
+ HRESULT getUpperIP(com::Utf8Str &aUpperIP);
+ HRESULT setUpperIP(const com::Utf8Str &aUpperIP);
+ HRESULT getId(com::Guid &aId);
+ HRESULT setId(const com::Guid &aId);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_HostOnlyNetworkImpl_h */
diff --git a/src/VBox/Main/include/HostPower.h b/src/VBox/Main/include/HostPower.h
new file mode 100644
index 00000000..4f0f92dc
--- /dev/null
+++ b/src/VBox/Main/include/HostPower.h
@@ -0,0 +1,136 @@
+/* $Id: HostPower.h $ */
+/** @file
+ *
+ * VirtualBox interface to host's power notification service
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostPower_h
+#define MAIN_INCLUDED_HostPower_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef RT_OS_DARWIN /* first, so we can undef pVM in iprt/cdefs.h */
+# include <IOKit/pwr_mgt/IOPMLib.h>
+# include <Carbon/Carbon.h>
+#endif
+
+#include "VirtualBoxBase.h"
+
+#include <vector>
+
+#ifdef RT_OS_LINUX
+# include <VBox/dbus.h>
+#endif
+
+class HostPowerService
+{
+ public:
+ HostPowerService(VirtualBox *aVirtualBox);
+ virtual ~HostPowerService();
+ void notify(Reason_T aReason);
+
+ protected:
+ VirtualBox *mVirtualBox;
+ std::vector<ComPtr<IInternalSessionControl> > mSessionControls;
+};
+
+# if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
+/**
+ * The Windows hosted Power Service.
+ */
+class HostPowerServiceWin : public HostPowerService
+{
+public:
+
+ HostPowerServiceWin(VirtualBox *aVirtualBox);
+ virtual ~HostPowerServiceWin();
+
+private:
+
+ static DECLCALLBACK(int) NotificationThread(RTTHREAD ThreadSelf, void *pInstance);
+ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ HWND mHwnd;
+ RTTHREAD mThread;
+};
+# endif
+# if defined(RT_OS_LINUX) || defined(DOXYGEN_RUNNING)
+/**
+ * The Linux hosted Power Service.
+ */
+class HostPowerServiceLinux : public HostPowerService
+{
+public:
+
+ HostPowerServiceLinux(VirtualBox *aVirtualBox);
+ virtual ~HostPowerServiceLinux();
+
+private:
+
+ static DECLCALLBACK(int) powerChangeNotificationThread(RTTHREAD ThreadSelf, void *pInstance);
+
+ /* Private member vars */
+ /** Our message thread. */
+ RTTHREAD mThread;
+ /** Our (private) connection to the DBus. Closing this will cause the
+ * message thread to exit. */
+ DBusConnection *mpConnection;
+};
+
+# endif
+# if defined(RT_OS_DARWIN) || defined(DOXYGEN_RUNNING)
+/**
+ * The Darwin hosted Power Service.
+ */
+class HostPowerServiceDarwin : public HostPowerService
+{
+public:
+
+ HostPowerServiceDarwin(VirtualBox *aVirtualBox);
+ virtual ~HostPowerServiceDarwin();
+
+private:
+
+ static DECLCALLBACK(int) powerChangeNotificationThread(RTTHREAD ThreadSelf, void *pInstance);
+ static void powerChangeNotificationHandler(void *pvData, io_service_t service, natural_t messageType, void *pMessageArgument);
+ static void lowPowerHandler(void *pvData);
+
+ void checkBatteryCriticalLevel(bool *pfCriticalChanged = NULL);
+
+ /* Private member vars */
+ RTTHREAD mThread; /* Our message thread. */
+
+ io_connect_t mRootPort; /* A reference to the Root Power Domain IOService */
+ IONotificationPortRef mNotifyPort; /* Notification port allocated by IORegisterForSystemPower */
+ io_object_t mNotifierObject; /* Notifier object, used to deregister later */
+ CFRunLoopRef mRunLoop; /* A reference to the local thread run loop */
+
+ bool mCritical; /* Indicate if the battery was in the critical state last checked */
+};
+# endif
+
+#endif /* !MAIN_INCLUDED_HostPower_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/HostUSBDeviceImpl.h b/src/VBox/Main/include/HostUSBDeviceImpl.h
new file mode 100644
index 00000000..a37851da
--- /dev/null
+++ b/src/VBox/Main/include/HostUSBDeviceImpl.h
@@ -0,0 +1,327 @@
+/* $Id: HostUSBDeviceImpl.h $ */
+/** @file
+ * VirtualBox IHostUSBDevice COM interface implementation.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostUSBDeviceImpl_h
+#define MAIN_INCLUDED_HostUSBDeviceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include "USBDeviceFilterImpl.h"
+#include <VBox/usb.h>
+#include "HostUSBDeviceWrap.h"
+
+class SessionMachine;
+class USBProxyBackend;
+
+/**
+ * The unified state machine of HostUSBDevice.
+ *
+ * This is a super set of USBDEVICESTATE / USBDeviceState_T that
+ * includes additional states for tracking state transitions.
+ *
+ * @remarks
+ * The CapturingForVM and CapturingForProxy states have been merged
+ * into Capturing with a destination state (AttachingToVM or HeldByProxy).
+ *
+ * The DetachingFromVM state is a merge of DetachingFromVMToProxy and
+ * DetachingFromVMToHost and uses the destination state (HeldByProxy
+ * or ReleasingToHost) like Capturing.
+ *
+ * The *AwaitingDetach and *AwaitingReattach substates (optionally used
+ * in Capturing, AttachingToVM, DetachingFromVM and ReleasingToHost) are
+ * implemented via a substate kHostUSBDeviceSubState.
+ */
+typedef enum
+{
+ /** The device is unsupported (HUB).
+ * Next Host: PhysDetached.
+ * Next VBox: No change permitted.
+ */
+ kHostUSBDeviceState_Unsupported = USBDEVICESTATE_UNSUPPORTED,
+ /** The device is used exclusivly by the host or is inaccessible for some other reason.
+ * Next Host: Capturable, Unused, PhysDetached.
+ * Run filters.
+ * Next VBox: No change permitted.
+ */
+ kHostUSBDeviceState_UsedByHost = USBDEVICESTATE_USED_BY_HOST,
+ /** The device is used by the host but can be captured.
+ * Next Host: Unsupported, UsedByHost, Unused, PhysDetached.
+ * Run filters if Unused (for wildcard filters).
+ * Next VBox: CapturingForVM, CapturingForProxy.
+ */
+ kHostUSBDeviceState_Capturable = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE,
+ /** The device is not used by the host and can be captured.
+ * Next Host: UsedByHost, Capturable, PhysDetached
+ * Don't run any filters (done on state entry).
+ * Next VBox: CapturingForVM, CapturingForProxy.
+ */
+ kHostUSBDeviceState_Unused = USBDEVICESTATE_UNUSED,
+ /** The device is held captive by the proxy.
+ * Next Host: PhysDetached
+ * Next VBox: ReleasingHeld, AttachingToVM
+ */
+ kHostUSBDeviceState_HeldByProxy = USBDEVICESTATE_HELD_BY_PROXY,
+ /** The device is in use by a VM.
+ * Next Host: PhysDetachingFromVM
+ * Next VBox: DetachingFromVM
+ */
+ kHostUSBDeviceState_UsedByVM = USBDEVICESTATE_USED_BY_GUEST,
+ /** The device has been detach from both the host and VMs.
+ * This is the final state. */
+ kHostUSBDeviceState_PhysDetached = 9,
+
+
+ /** The start of the transitional states. */
+ kHostUSBDeviceState_FirstTransitional,
+
+ /** The device is being seized from the host, either for HeldByProxy or for AttachToVM.
+ *
+ * On some hosts we will need to re-enumerate the in which case the sub-state
+ * is employed to track this progress. On others, this is synchronous or faked, and
+ * will will then leave the device in this state and poke the service thread to do
+ * the completion state change.
+ *
+ * Next Host: PhysDetached.
+ * Next VBox: HeldByProxy or AttachingToVM on success,
+ * previous state (Unused or Capturable) or UsedByHost on failure.
+ */
+ kHostUSBDeviceState_Capturing = kHostUSBDeviceState_FirstTransitional,
+
+ /** The device is being released back to the host, following VM or Proxy usage.
+ * Most hosts needs to re-enumerate the device and will therefore employ the
+ * sub-state as during capturing. On the others we'll just leave it to the usb
+ * service thread to advance the device state.
+ *
+ * Next Host: Unused, UsedByHost, Capturable.
+ * No filters.
+ * Next VBox: PhysDetached (timeout), HeldByProxy (failure).
+ */
+ kHostUSBDeviceState_ReleasingToHost,
+
+ /** The device is being attached to a VM.
+ *
+ * This requires IPC to the VM and we will not advance the state until
+ * that completes.
+ *
+ * Next Host: PhysDetachingFromVM.
+ * Next VBox: UsedByGuest, HeldByProxy (failure).
+ */
+ kHostUSBDeviceState_AttachingToVM,
+
+ /** The device is being detached from a VM and will be returned to the proxy or host.
+ *
+ * This involves IPC and may or may not also require re-enumeration of the
+ * device. Which means that it might transition directly into the ReleasingToHost state
+ * because the client (VM) will do the actual re-enumeration.
+ *
+ * Next Host: PhysDetachingFromVM (?) or just PhysDetached.
+ * Next VBox: ReleasingToHost, HeldByProxy.
+ */
+ kHostUSBDeviceState_DetachingFromVM,
+
+ /** The device has been physically removed while a VM used it.
+ *
+ * This is the device state while VBoxSVC is doing IPC to the client (VM) telling it
+ * to detach it.
+ *
+ * Next Host: None.
+ * Next VBox: PhysDetached
+ */
+ kHostUSBDeviceState_PhysDetachingFromVM,
+
+ /** Just an invalid state value for use as default for some methods. */
+ kHostUSBDeviceState_Invalid = 0x7fff
+} HostUSBDeviceState;
+
+
+/**
+ * Sub-state for dealing with device re-enumeration.
+ */
+typedef enum
+{
+ /** Not in any sub-state. */
+ kHostUSBDeviceSubState_Default = 0,
+ /** Awaiting a logical device detach following a device re-enumeration. */
+ kHostUSBDeviceSubState_AwaitingDetach,
+ /** Awaiting a logical device re-attach following a device re-enumeration. */
+ kHostUSBDeviceSubState_AwaitingReAttach
+} HostUSBDeviceSubState;
+
+
+/**
+ * Object class used to hold Host USB Device properties.
+ */
+class ATL_NO_VTABLE HostUSBDevice :
+ public HostUSBDeviceWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(HostUSBDevice)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(PUSBDEVICE aUsb, USBProxyBackend *aUSBProxyBackend);
+ void uninit();
+
+ // public methods only for internal purposes
+
+ /** @note Must be called from under the object read lock. */
+ const Guid& i_getId() const { return mId; }
+
+ /** @note Must be called from under the object read lock. */
+ HostUSBDeviceState i_getUnistate() const { return mUniState; }
+
+ /** @note Must be called from under the object read lock. */
+ const char *i_getStateName() { return i_stateName (mUniState, mPendingUniState, mUniSubState); }
+
+ /** @note Must be called from under the object read lock. */
+ bool i_isCapturableOrHeld()
+ {
+ return mUniState == kHostUSBDeviceState_Unused
+ || mUniState == kHostUSBDeviceState_Capturable
+ || mUniState == kHostUSBDeviceState_HeldByProxy;
+ }
+
+ /** @note Must be called from under the object read lock. */
+ ComObjPtr<SessionMachine> &i_getMachine() { return mMachine; }
+
+ /** @note Must be called from under the object read lock. */
+ PCUSBDEVICE i_getUsbData() const { return mUsb; }
+
+ USBProxyBackend *i_getUsbProxyBackend() const { return mUSBProxyBackend; }
+
+ com::Utf8Str i_getName();
+
+ HRESULT i_requestCaptureForVM(SessionMachine *aMachine, bool aSetError,
+ const com::Utf8Str &aCaptureFilename, ULONG aMaskedIfs = 0);
+ HRESULT i_onDetachFromVM(SessionMachine *aMachine, bool aDone, bool *aRunFilters, bool aAbnormal = false);
+ HRESULT i_requestReleaseToHost();
+ HRESULT i_requestHold();
+ bool i_wasActuallyDetached();
+ void i_onPhysicalDetached();
+
+ bool i_isMatch(const USBDeviceFilter::BackupableUSBDeviceFilterData &aData);
+ int i_compare(PCUSBDEVICE aDev2);
+ static int i_compare(PCUSBDEVICE aDev1, PCUSBDEVICE aDev2, bool aIsAwaitingReAttach = false);
+
+ bool i_updateState(PCUSBDEVICE aDev, bool *aRunFilters, SessionMachine **aIgnoreMachine);
+ bool i_updateStateFake(PCUSBDEVICE aDev, bool *aRunFilters, SessionMachine **aIgnoreMachine);
+
+ static const char *i_stateName(HostUSBDeviceState aState,
+ HostUSBDeviceState aPendingState = kHostUSBDeviceState_Invalid,
+ HostUSBDeviceSubState aSubState = kHostUSBDeviceSubState_Default);
+
+ void *i_getBackendUserData() { return m_pvBackendUser; }
+ void i_setBackendUserData(void *pvBackendUser) { m_pvBackendUser = pvBackendUser; }
+
+protected:
+
+ HRESULT i_attachToVM(SessionMachine *aMachine, const com::Utf8Str &aCaptureFilename, ULONG aMaskedIfs = 0);
+ void i_detachFromVM(HostUSBDeviceState aFinalState);
+ void i_onPhysicalDetachedInternal();
+ bool i_hasAsyncOperationTimedOut() const;
+
+ bool i_setState (HostUSBDeviceState aNewState, HostUSBDeviceState aNewPendingState = kHostUSBDeviceState_Invalid,
+ HostUSBDeviceSubState aNewSubState = kHostUSBDeviceSubState_Default);
+ bool i_startTransition (HostUSBDeviceState aNewState, HostUSBDeviceState aFinalState,
+ HostUSBDeviceSubState aNewSubState = kHostUSBDeviceSubState_Default);
+ bool i_advanceTransition(bool aSkipReAttach = false);
+ bool i_failTransition(HostUSBDeviceState a_enmStateHint);
+ USBDeviceState_T i_canonicalState() const;
+
+private:
+
+ // wrapped IUSBDevice properties
+ HRESULT getId(com::Guid &aId);
+ HRESULT getVendorId(USHORT *aVendorId);
+ HRESULT getProductId(USHORT *aProductId);
+ HRESULT getRevision(USHORT *aRevision);
+ HRESULT getManufacturer(com::Utf8Str &aManufacturer);
+ HRESULT getProduct(com::Utf8Str &aProduct);
+ HRESULT getSerialNumber(com::Utf8Str &aSerialNumber);
+ HRESULT getAddress(com::Utf8Str &aAddress);
+ HRESULT getPort(USHORT *aPort);
+ HRESULT getPortPath(com::Utf8Str &aPortPath);
+ HRESULT getVersion(USHORT *aVersion);
+ HRESULT getPortVersion(USHORT *aPortVersion);
+ HRESULT getSpeed(USBConnectionSpeed_T *aSpeed);
+ HRESULT getRemote(BOOL *aRemote);
+ HRESULT getState(USBDeviceState_T *aState);
+ HRESULT getBackend(com::Utf8Str &aBackend);
+ HRESULT getDeviceInfo(std::vector<com::Utf8Str> &aInfo);
+
+
+ const Guid mId;
+
+ /** @name The state machine variables
+ * Only setState(), init() and uninit() will modify these members!
+ * @{ */
+ /** The RTTimeNanoTS() corresponding to the last state change.
+ *
+ * Old state machine: RTTimeNanoTS() of when mIsStatePending was set or mDetaching changed
+ * from kNotDetaching. For operations that cannot be canceled it's 0. */
+ uint64_t mLastStateChangeTS;
+ /** Current state. */
+ HostUSBDeviceState mUniState;
+ /** Sub-state for tracking re-enumeration. */
+ HostUSBDeviceSubState mUniSubState;
+ /** The final state of an pending transition.
+ * This is mainly a measure to reduce the number of HostUSBDeviceState values. */
+ HostUSBDeviceState mPendingUniState;
+ /** Previous state.
+ * This is used for bailing out when a transition like capture fails. */
+ HostUSBDeviceState mPrevUniState;
+ /** Indicator set by onDetachedPhys and check when advancing a transitional state. */
+ bool mIsPhysicallyDetached;
+ /** @} */
+
+ /** The machine the usb device is (being) attached to. */
+ ComObjPtr<SessionMachine> mMachine;
+ /** Pointer to the USB Proxy Backend instance. */
+ USBProxyBackend *mUSBProxyBackend;
+ /** Pointer to the USB Device structure owned by this device.
+ * Only used for host devices. */
+ PUSBDEVICE mUsb;
+ /** The interface mask to be used in the pending capture.
+ * This is a filter property. */
+ ULONG mMaskedIfs;
+ /** The name of this device. */
+ Utf8Str mNameObj;
+ /** The name of this device (for logging purposes).
+ * This points to the string in mNameObj. */
+ const char *mName;
+ /** The filename to capture the USB traffic to. */
+ com::Utf8Str mCaptureFilename;
+ /** Optional opaque user data assigned by the USB proxy backend owning the device. */
+ void *m_pvBackendUser;
+};
+
+#endif /* !MAIN_INCLUDED_HostUSBDeviceImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/HostVideoInputDeviceImpl.h b/src/VBox/Main/include/HostVideoInputDeviceImpl.h
new file mode 100644
index 00000000..9a61a0bd
--- /dev/null
+++ b/src/VBox/Main/include/HostVideoInputDeviceImpl.h
@@ -0,0 +1,82 @@
+/* $Id: HostVideoInputDeviceImpl.h $ */
+/** @file
+ * A host video capture device description.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_HostVideoInputDeviceImpl_h
+#define MAIN_INCLUDED_HostVideoInputDeviceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostVideoInputDeviceWrap.h"
+
+#include <list>
+
+class HostVideoInputDevice;
+
+typedef std::list<ComObjPtr<HostVideoInputDevice> > HostVideoInputDeviceList;
+
+class ATL_NO_VTABLE HostVideoInputDevice :
+ public HostVideoInputDeviceWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(HostVideoInputDevice)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ /* Public initializer/uninitializer for internal purposes only. */
+ HRESULT init(const com::Utf8Str &name, const com::Utf8Str &path, const com::Utf8Str &alias);
+ void uninit();
+
+ static HRESULT queryHostDevices(VirtualBox *pVirtualBox, HostVideoInputDeviceList *pList);
+
+private:
+
+ // wrapped IHostVideoInputDevice properties
+ virtual HRESULT getName(com::Utf8Str &aName) { aName = m.name; return S_OK; }
+ virtual HRESULT getPath(com::Utf8Str &aPath) { aPath = m.path; return S_OK; }
+ virtual HRESULT getAlias(com::Utf8Str &aAlias) { aAlias = m.alias; return S_OK; }
+
+ /* Data. */
+ struct Data
+ {
+ Data()
+ {
+ }
+
+ com::Utf8Str name;
+ com::Utf8Str path;
+ com::Utf8Str alias;
+ };
+
+ Data m;
+};
+
+#endif /* !MAIN_INCLUDED_HostVideoInputDeviceImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/KeyboardImpl.h b/src/VBox/Main/include/KeyboardImpl.h
new file mode 100644
index 00000000..d8130a7d
--- /dev/null
+++ b/src/VBox/Main/include/KeyboardImpl.h
@@ -0,0 +1,110 @@
+/* $Id: KeyboardImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_KeyboardImpl_h
+#define MAIN_INCLUDED_KeyboardImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "KeyboardWrap.h"
+#include "EventImpl.h"
+
+#include <VBox/vmm/pdmdrv.h>
+
+/** Limit of simultaneously attached devices (just USB and/or PS/2). */
+enum { KEYBOARD_MAX_DEVICES = 2 };
+
+/** Simple keyboard event class. */
+class KeyboardEvent
+{
+public:
+ KeyboardEvent() : scan(-1) {}
+ KeyboardEvent(int _scan) : scan(_scan) {}
+ bool i_isValid()
+ {
+ return (scan & ~0x80) && !(scan & ~0xFF);
+ }
+ int scan;
+};
+class Console;
+
+class ATL_NO_VTABLE Keyboard :
+ public KeyboardWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(Keyboard)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Console *aParent);
+ void uninit();
+
+ static const PDMDRVREG DrvReg;
+
+ Console *i_getParent() const
+ {
+ return mParent;
+ }
+
+private:
+
+ // Wrapped Keyboard properties
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getKeyboardLEDs(std::vector<KeyboardLED_T> &aKeyboardLEDs);
+
+ // Wrapped Keyboard members
+ HRESULT putScancode(LONG aScancode);
+ HRESULT putScancodes(const std::vector<LONG> &aScancodes,
+ ULONG *aCodesStored);
+ HRESULT putCAD();
+ HRESULT releaseKeys();
+ HRESULT putUsageCode(LONG aUsageCode, LONG aUsagePage, BOOL fKeyRelease);
+
+ static DECLCALLBACK(void) i_keyboardLedStatusChange(PPDMIKEYBOARDCONNECTOR pInterface, PDMKEYBLEDS enmLeds);
+ static DECLCALLBACK(void) i_keyboardSetActive(PPDMIKEYBOARDCONNECTOR pInterface, bool fActive);
+ static DECLCALLBACK(void *) i_drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) i_drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) i_drvDestruct(PPDMDRVINS pDrvIns);
+
+ void onKeyboardLedsChange(PDMKEYBLEDS enmLeds);
+
+ Console * const mParent;
+ /** Pointer to the associated keyboard driver(s). */
+ struct DRVMAINKEYBOARD *mpDrv[KEYBOARD_MAX_DEVICES];
+
+ /* The current guest keyboard LED status. */
+ PDMKEYBLEDS menmLeds;
+
+ const ComObjPtr<EventSource> mEventSource;
+};
+
+#endif /* !MAIN_INCLUDED_KeyboardImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/LoggingNew.h b/src/VBox/Main/include/LoggingNew.h
new file mode 100644
index 00000000..c368e1a2
--- /dev/null
+++ b/src/VBox/Main/include/LoggingNew.h
@@ -0,0 +1,60 @@
+/* $Id: LoggingNew.h $ */
+/** @file
+ * VirtualBox COM - logging macros and function definitions, for new code.
+ */
+
+/*
+ * Copyright (C) 2017-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_LoggingNew_h
+#define MAIN_INCLUDED_LoggingNew_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef MAIN_INCLUDED_Logging_h
+# error "You must include LoggingNew.h as the first include!"
+#endif
+#define MAIN_INCLUDED_Logging_h /* Prevent Logging.h from being included. */
+
+#ifndef LOG_GROUP
+# error "You must define LOG_GROUP immediately before including LoggingNew.h!"
+#endif
+
+#ifdef LOG_GROUP_MAIN_OVERRIDE
+# error "Please, don't define LOG_GROUP_MAIN_OVERRIDE anymore!"
+#endif
+
+#include <VBox/log.h>
+
+
+#ifndef VBOXSVC_LOG_DEFAULT
+# define VBOXSVC_LOG_DEFAULT "all"
+#endif
+
+#ifndef VBOXSDS_LOG_DEFAULT
+# define VBOXSDS_LOG_DEFAULT "all"
+#endif
+
+#endif /* !MAIN_INCLUDED_LoggingNew_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/src/VBox/Main/include/MachineDebuggerImpl.h b/src/VBox/Main/include/MachineDebuggerImpl.h
new file mode 100644
index 00000000..68ca8740
--- /dev/null
+++ b/src/VBox/Main/include/MachineDebuggerImpl.h
@@ -0,0 +1,176 @@
+/* $Id: MachineDebuggerImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MachineDebuggerImpl_h
+#define MAIN_INCLUDED_MachineDebuggerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MachineDebuggerWrap.h"
+#include <iprt/log.h>
+#include <VBox/vmm/em.h>
+
+class Console;
+class Progress;
+
+class ATL_NO_VTABLE MachineDebugger :
+ public MachineDebuggerWrap
+{
+
+public:
+
+ DECLARE_COMMON_CLASS_METHODS (MachineDebugger)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init (Console *aParent);
+ void uninit();
+
+ // "public-private methods"
+ void i_flushQueuedSettings();
+
+private:
+
+ // wrapped IMachineDeugger properties
+ HRESULT getSingleStep(BOOL *aSingleStep);
+ HRESULT setSingleStep(BOOL aSingleStep);
+ HRESULT getExecuteAllInIEM(BOOL *aExecuteAllInIEM);
+ HRESULT setExecuteAllInIEM(BOOL aExecuteAllInIEM);
+ HRESULT getLogEnabled(BOOL *aLogEnabled);
+ HRESULT setLogEnabled(BOOL aLogEnabled);
+ HRESULT getLogDbgFlags(com::Utf8Str &aLogDbgFlags);
+ HRESULT getLogDbgGroups(com::Utf8Str &aLogDbgGroups);
+ HRESULT getLogDbgDestinations(com::Utf8Str &aLogDbgDestinations);
+ HRESULT getLogRelFlags(com::Utf8Str &aLogRelFlags);
+ HRESULT getLogRelGroups(com::Utf8Str &aLogRelGroups);
+ HRESULT getLogRelDestinations(com::Utf8Str &aLogRelDestinations);
+ HRESULT getExecutionEngine(VMExecutionEngine_T *apenmEngine);
+ HRESULT getHWVirtExNestedPagingEnabled(BOOL *aHWVirtExNestedPagingEnabled);
+ HRESULT getHWVirtExVPIDEnabled(BOOL *aHWVirtExVPIDEnabled);
+ HRESULT getHWVirtExUXEnabled(BOOL *aHWVirtExUXEnabled);
+ HRESULT getOSName(com::Utf8Str &aOSName);
+ HRESULT getOSVersion(com::Utf8Str &aOSVersion);
+ HRESULT getPAEEnabled(BOOL *aPAEEnabled);
+ HRESULT getVirtualTimeRate(ULONG *aVirtualTimeRate);
+ HRESULT setVirtualTimeRate(ULONG aVirtualTimeRate);
+ HRESULT getUptime(LONG64 *aUptime);
+
+ // wrapped IMachineDeugger methods
+ HRESULT dumpGuestCore(const com::Utf8Str &aFilename,
+ const com::Utf8Str &aCompression);
+ HRESULT dumpHostProcessCore(const com::Utf8Str &aFilename,
+ const com::Utf8Str &aCompression);
+ HRESULT info(const com::Utf8Str &aName,
+ const com::Utf8Str &aArgs,
+ com::Utf8Str &aInfo);
+ HRESULT injectNMI();
+ HRESULT modifyLogGroups(const com::Utf8Str &aSettings);
+ HRESULT modifyLogFlags(const com::Utf8Str &aSettings);
+ HRESULT modifyLogDestinations(const com::Utf8Str &aSettings);
+ HRESULT readPhysicalMemory(LONG64 aAddress,
+ ULONG aSize,
+ std::vector<BYTE> &aBytes);
+ HRESULT writePhysicalMemory(LONG64 aAddress,
+ ULONG aSize,
+ const std::vector<BYTE> &aBytes);
+ HRESULT readVirtualMemory(ULONG aCpuId,
+ LONG64 aAddress,
+ ULONG aSize,
+ std::vector<BYTE> &aBytes);
+ HRESULT writeVirtualMemory(ULONG aCpuId,
+ LONG64 aAddress,
+ ULONG aSize,
+ const std::vector<BYTE> &aBytes);
+ HRESULT loadPlugIn(const com::Utf8Str &aName,
+ com::Utf8Str &aPlugInName);
+ HRESULT unloadPlugIn(const com::Utf8Str &aName);
+ HRESULT detectOS(com::Utf8Str &aOs);
+ HRESULT queryOSKernelLog(ULONG aMaxMessages,
+ com::Utf8Str &aDmesg);
+ HRESULT getRegister(ULONG aCpuId,
+ const com::Utf8Str &aName,
+ com::Utf8Str &aValue);
+ HRESULT getRegisters(ULONG aCpuId,
+ std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aValues);
+ HRESULT setRegister(ULONG aCpuId,
+ const com::Utf8Str &aName,
+ const com::Utf8Str &aValue);
+ HRESULT setRegisters(ULONG aCpuId,
+ const std::vector<com::Utf8Str> &aNames,
+ const std::vector<com::Utf8Str> &aValues);
+ HRESULT dumpGuestStack(ULONG aCpuId,
+ com::Utf8Str &aStack);
+ HRESULT resetStats(const com::Utf8Str &aPattern);
+ HRESULT dumpStats(const com::Utf8Str &aPattern);
+ HRESULT getStats(const com::Utf8Str &aPattern,
+ BOOL aWithDescriptions,
+ com::Utf8Str &aStats);
+ HRESULT getCPULoad(ULONG aCpuId, ULONG *aPctExecuting, ULONG *aPctHalted, ULONG *aPctOther, LONG64 *aMsInterval) RT_OVERRIDE;
+ HRESULT takeGuestSample(const com::Utf8Str &aFilename, ULONG aUsInterval, LONG64 aUsSampleTime, ComPtr<IProgress> &pProgress);
+ HRESULT getUVMAndVMMFunctionTable(LONG64 aMagicVersion, LONG64 *aVMMFunctionTable, LONG64 *aUVM);
+
+ // private methods
+ bool i_queueSettings() const;
+ HRESULT i_getEmExecPolicyProperty(EMEXECPOLICY enmPolicy, BOOL *pfEnforced);
+ HRESULT i_setEmExecPolicyProperty(EMEXECPOLICY enmPolicy, BOOL fEnforce);
+
+ /** RTLogGetFlags, RTLogGetGroupSettings and RTLogGetDestinations function. */
+ typedef DECLCALLBACKTYPE(int, FNLOGGETSTR,(PRTLOGGER, char *, size_t));
+ /** Function pointer. */
+ typedef FNLOGGETSTR *PFNLOGGETSTR;
+ HRESULT i_logStringProps(PRTLOGGER pLogger, PFNLOGGETSTR pfnLogGetStr, const char *pszLogGetStr, Utf8Str *pstrSettings);
+
+ static DECLCALLBACK(int) i_dbgfProgressCallback(void *pvUser, unsigned uPercentage);
+
+ Console * const mParent;
+ /** @name Flags whether settings have been queued because they could not be sent
+ * to the VM (not up yet, etc.)
+ * @{ */
+ uint8_t maiQueuedEmExecPolicyParams[EMEXECPOLICY_END];
+ int mSingleStepQueued;
+ int mLogEnabledQueued;
+ uint32_t mVirtualTimeRateQueued;
+ bool mFlushMode;
+ /** @} */
+
+ /** @name Sample report related things.
+ * @{ */
+ /** Sample report handle. */
+ DBGFSAMPLEREPORT m_hSampleReport;
+ /** Progress object for the currently taken guest sample. */
+ ComObjPtr<Progress> m_Progress;
+ /** Filename to dump the report to. */
+ com::Utf8Str m_strFilename;
+ /** @} */
+};
+
+#endif /* !MAIN_INCLUDED_MachineDebuggerImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MachineImpl.h b/src/VBox/Main/include/MachineImpl.h
new file mode 100644
index 00000000..311a80bd
--- /dev/null
+++ b/src/VBox/Main/include/MachineImpl.h
@@ -0,0 +1,1691 @@
+/* $Id: MachineImpl.h $ */
+/** @file
+ * Implementation of IMachine in VBoxSVC - Header.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MachineImpl_h
+#define MAIN_INCLUDED_MachineImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "AuthLibrary.h"
+#include "VirtualBoxBase.h"
+#include "ProgressImpl.h"
+#include "VRDEServerImpl.h"
+#include "MediumAttachmentImpl.h"
+#include "PCIDeviceAttachmentImpl.h"
+#include "MediumLock.h"
+#include "NetworkAdapterImpl.h"
+#include "AudioSettingsImpl.h"
+#include "SerialPortImpl.h"
+#include "ParallelPortImpl.h"
+#include "BIOSSettingsImpl.h"
+#include "RecordingSettingsImpl.h"
+#include "GraphicsAdapterImpl.h"
+#include "StorageControllerImpl.h" // required for MachineImpl.h to compile on Windows
+#include "USBControllerImpl.h" // required for MachineImpl.h to compile on Windows
+#include "BandwidthControlImpl.h"
+#include "BandwidthGroupImpl.h"
+#include "TrustedPlatformModuleImpl.h"
+#include "NvramStoreImpl.h"
+#include "GuestDebugControlImpl.h"
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+# include "Performance.h"
+# include "PerformanceImpl.h"
+#endif
+#include "ThreadTask.h"
+
+// generated header
+#include "SchemaDefs.h"
+
+#include "VBox/com/ErrorInfo.h"
+
+#include <iprt/time.h>
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+# include <VBox/VBoxCryptoIf.h>
+# include <iprt/vfs.h>
+#endif
+
+#include <list>
+#include <vector>
+
+#include "MachineWrap.h"
+
+/** @todo r=klaus after moving the various Machine settings structs to
+ * MachineImpl.cpp it should be possible to eliminate this include. */
+#include <VBox/settings.h>
+
+// defines
+////////////////////////////////////////////////////////////////////////////////
+
+// helper declarations
+////////////////////////////////////////////////////////////////////////////////
+
+class Progress;
+class ProgressProxy;
+class Keyboard;
+class Mouse;
+class Display;
+class MachineDebugger;
+class USBController;
+class USBDeviceFilters;
+class Snapshot;
+class SharedFolder;
+class HostUSBDevice;
+class StorageController;
+class SessionMachine;
+#ifdef VBOX_WITH_UNATTENDED
+class Unattended;
+#endif
+
+// Machine class
+////////////////////////////////////////////////////////////////////////////////
+//
+class ATL_NO_VTABLE Machine :
+ public MachineWrap
+{
+
+public:
+
+ enum StateDependency
+ {
+ AnyStateDep = 0,
+ MutableStateDep,
+ MutableOrSavedStateDep,
+ MutableOrRunningStateDep,
+ MutableOrSavedOrRunningStateDep,
+ };
+
+ /**
+ * Internal machine data.
+ *
+ * Only one instance of this data exists per every machine -- it is shared
+ * by the Machine, SessionMachine and all SnapshotMachine instances
+ * associated with the given machine using the util::Shareable template
+ * through the mData variable.
+ *
+ * @note |const| members are persistent during lifetime so can be
+ * accessed without locking.
+ *
+ * @note There is no need to lock anything inside init() or uninit()
+ * methods, because they are always serialized (see AutoCaller).
+ */
+ struct Data
+ {
+ /**
+ * Data structure to hold information about sessions opened for the
+ * given machine.
+ */
+ struct Session
+ {
+ /** Type of lock which created this session */
+ LockType_T mLockType;
+
+ /** Control of the direct session opened by lockMachine() */
+ ComPtr<IInternalSessionControl> mDirectControl;
+
+ typedef std::list<ComPtr<IInternalSessionControl> > RemoteControlList;
+
+ /** list of controls of all opened remote sessions */
+ RemoteControlList mRemoteControls;
+
+ /** launchVMProcess() and OnSessionEnd() progress indicator */
+ ComObjPtr<ProgressProxy> mProgress;
+
+ /**
+ * PID of the session object that must be passed to openSession()
+ * to finalize the launchVMProcess() request (i.e., PID of the
+ * process created by launchVMProcess())
+ */
+ RTPROCESS mPID;
+
+ /** Current session state */
+ SessionState_T mState;
+
+ /** Session name string (of the primary session) */
+ Utf8Str mName;
+
+ /** Session machine object */
+ ComObjPtr<SessionMachine> mMachine;
+
+ /** Medium object lock collection. */
+ MediumLockListMap mLockedMedia;
+ };
+
+ Data();
+ ~Data();
+
+ const Guid mUuid;
+ BOOL mRegistered;
+
+ Utf8Str m_strConfigFile;
+ Utf8Str m_strConfigFileFull;
+
+ // machine settings XML file
+ settings::MachineConfigFile *pMachineConfigFile;
+ uint32_t flModifications;
+ bool m_fAllowStateModification;
+
+ BOOL mAccessible;
+ com::ErrorInfo mAccessError;
+
+ MachineState_T mMachineState;
+ RTTIMESPEC mLastStateChange;
+
+ /* Note: These are guarded by VirtualBoxBase::stateLockHandle() */
+ uint32_t mMachineStateDeps;
+ RTSEMEVENTMULTI mMachineStateDepsSem;
+ uint32_t mMachineStateChangePending;
+
+ BOOL mCurrentStateModified;
+ /** Guest properties have been modified and need saving since the
+ * machine was started, or there are transient properties which need
+ * deleting and the machine is being shut down. */
+ BOOL mGuestPropertiesModified;
+
+ Session mSession;
+
+ ComObjPtr<Snapshot> mFirstSnapshot;
+ ComObjPtr<Snapshot> mCurrentSnapshot;
+
+ // list of files to delete in Delete(); this list is filled by Unregister()
+ std::list<Utf8Str> llFilesToDelete;
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ /* Store for secret keys. */
+ SecretKeyStore *mpKeyStore;
+ BOOL fEncrypted;
+ /* KeyId of the password encrypting the DEK */
+ com::Utf8Str mstrKeyId;
+ /* Store containing the DEK used for encrypting the VM */
+ com::Utf8Str mstrKeyStore;
+ /* KeyId of the password encrypting the DEK for log files */
+ com::Utf8Str mstrLogKeyId;
+ /* Store containing the DEK used for encrypting the VM's log files */
+ com::Utf8Str mstrLogKeyStore;
+#endif
+ };
+
+ /**
+ * Saved state data.
+ *
+ * It's actually only the state file path string and its encryption
+ * settings, but it needs to be separate from Data, because Machine
+ * and SessionMachine instances share it, while SnapshotMachine does
+ * not.
+ *
+ * The data variable is |mSSData|.
+ */
+ struct SSData
+ {
+ Utf8Str strStateFilePath;
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ /* KeyId of the password encrypting the DEK for saved state */
+ com::Utf8Str strStateKeyId;
+ /* Store containing the DEK used for encrypting saved state */
+ com::Utf8Str strStateKeyStore;
+#endif
+ };
+
+ /**
+ * User changeable machine data.
+ *
+ * This data is common for all machine snapshots, i.e. it is shared
+ * by all SnapshotMachine instances associated with the given machine
+ * using the util::Backupable template through the |mUserData| variable.
+ *
+ * SessionMachine instances can alter this data and discard changes.
+ *
+ * @note There is no need to lock anything inside init() or uninit()
+ * methods, because they are always serialized (see AutoCaller).
+ */
+ struct UserData
+ {
+ settings::MachineUserData s;
+ };
+
+ /**
+ * Hardware data.
+ *
+ * This data is unique for a machine and for every machine snapshot.
+ * Stored using the util::Backupable template in the |mHWData| variable.
+ *
+ * SessionMachine instances can alter this data and discard changes.
+ *
+ * @todo r=klaus move all "pointer" objects out of this struct, as they
+ * need non-obvious handling when creating a new session or when taking
+ * a snapshot. Better do this right straight away, not relying on the
+ * template magic which doesn't work right in this case.
+ */
+ struct HWData
+ {
+ /**
+ * Data structure to hold information about a guest property.
+ */
+ struct GuestProperty {
+ /** Property value */
+ Utf8Str strValue;
+ /** Property timestamp */
+ LONG64 mTimestamp;
+ /** Property flags */
+ ULONG mFlags;
+ };
+
+ HWData();
+ ~HWData();
+
+ Bstr mHWVersion;
+ Guid mHardwareUUID; /**< If Null, use mData.mUuid. */
+ ULONG mMemorySize;
+ ULONG mMemoryBalloonSize;
+ BOOL mPageFusionEnabled;
+ settings::RecordingSettings mRecordSettings;
+ BOOL mHWVirtExEnabled;
+ BOOL mHWVirtExNestedPagingEnabled;
+ BOOL mHWVirtExLargePagesEnabled;
+ BOOL mHWVirtExVPIDEnabled;
+ BOOL mHWVirtExUXEnabled;
+ BOOL mHWVirtExForceEnabled;
+ BOOL mHWVirtExUseNativeApi;
+ BOOL mHWVirtExVirtVmsaveVmload;
+ BOOL mPAEEnabled;
+ settings::Hardware::LongModeType mLongMode;
+ BOOL mTripleFaultReset;
+ BOOL mAPIC;
+ BOOL mX2APIC;
+ BOOL mIBPBOnVMExit;
+ BOOL mIBPBOnVMEntry;
+ BOOL mSpecCtrl;
+ BOOL mSpecCtrlByHost;
+ BOOL mL1DFlushOnSched;
+ BOOL mL1DFlushOnVMEntry;
+ BOOL mMDSClearOnSched;
+ BOOL mMDSClearOnVMEntry;
+ BOOL mNestedHWVirt;
+ ULONG mCPUCount;
+ BOOL mCPUHotPlugEnabled;
+ ULONG mCpuExecutionCap;
+ uint32_t mCpuIdPortabilityLevel;
+ Utf8Str mCpuProfile;
+ BOOL mHPETEnabled;
+
+ BOOL mCPUAttached[SchemaDefs::MaxCPUCount];
+
+ std::list<settings::CpuIdLeaf> mCpuIdLeafList;
+
+ DeviceType_T mBootOrder[SchemaDefs::MaxBootPosition];
+
+ typedef std::list<ComObjPtr<SharedFolder> > SharedFolderList;
+ SharedFolderList mSharedFolders;
+
+ ClipboardMode_T mClipboardMode;
+ BOOL mClipboardFileTransfersEnabled;
+
+ DnDMode_T mDnDMode;
+
+ typedef std::map<Utf8Str, GuestProperty> GuestPropertyMap;
+ GuestPropertyMap mGuestProperties;
+
+ FirmwareType_T mFirmwareType;
+ KeyboardHIDType_T mKeyboardHIDType;
+ PointingHIDType_T mPointingHIDType;
+ ChipsetType_T mChipsetType;
+ IommuType_T mIommuType;
+ ParavirtProvider_T mParavirtProvider;
+ Utf8Str mParavirtDebug;
+ BOOL mEmulatedUSBCardReaderEnabled;
+
+ BOOL mIOCacheEnabled;
+ ULONG mIOCacheSize;
+
+ typedef std::list<ComObjPtr<PCIDeviceAttachment> > PCIDeviceAssignmentList;
+ PCIDeviceAssignmentList mPCIDeviceAssignments;
+
+ settings::Debugging mDebugging;
+ settings::Autostart mAutostart;
+
+ Utf8Str mDefaultFrontend;
+ };
+
+ typedef std::list<ComObjPtr<MediumAttachment> > MediumAttachmentList;
+
+ DECLARE_COMMON_CLASS_METHODS(Machine)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only:
+
+ // initializer for creating a new, empty machine
+ HRESULT init(VirtualBox *aParent,
+ const Utf8Str &strConfigFile,
+ const Utf8Str &strName,
+ const StringsList &llGroups,
+ const Utf8Str &strOsTypeId,
+ GuestOSType *aOsType,
+ const Guid &aId,
+ bool fForceOverwrite,
+ bool fDirectoryIncludesUUID,
+ const com::Utf8Str &aCipher,
+ const com::Utf8Str &aPasswordId,
+ const com::Utf8Str &aPassword);
+
+ // initializer for loading existing machine XML (either registered or not)
+ HRESULT initFromSettings(VirtualBox *aParent,
+ const Utf8Str &strConfigFile,
+ const Guid *aId,
+ const com::Utf8Str &strPassword);
+
+ // initializer for machine config in memory (OVF import)
+ HRESULT init(VirtualBox *aParent,
+ const Utf8Str &strName,
+ const Utf8Str &strSettingsFilename,
+ const settings::MachineConfigFile &config);
+
+ void uninit();
+
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+ // Needed from VirtualBox, for the delayed metrics cleanup.
+ void i_unregisterMetrics(PerformanceCollector *aCollector, Machine *aMachine);
+#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+
+protected:
+ HRESULT initImpl(VirtualBox *aParent,
+ const Utf8Str &strConfigFile);
+ HRESULT initDataAndChildObjects();
+ HRESULT i_registeredInit();
+ HRESULT i_tryCreateMachineConfigFile(bool fForceOverwrite);
+ void uninitDataAndChildObjects();
+
+public:
+
+
+ // public methods only for internal purposes
+
+ virtual bool i_isSnapshotMachine() const
+ {
+ return false;
+ }
+
+ virtual bool i_isSessionMachine() const
+ {
+ return false;
+ }
+
+ /**
+ * Override of the default locking class to be used for validating lock
+ * order with the standard member lock handle.
+ */
+ virtual VBoxLockingClass getLockingClass() const
+ {
+ return LOCKCLASS_MACHINEOBJECT;
+ }
+
+ /// @todo (dmik) add lock and make non-inlined after revising classes
+ // that use it. Note: they should enter Machine lock to keep the returned
+ // information valid!
+ bool i_isRegistered() { return !!mData->mRegistered; }
+
+ // unsafe inline public methods for internal purposes only (ensure there is
+ // a caller and a read lock before calling them!)
+
+ /**
+ * Returns the VirtualBox object this machine belongs to.
+ *
+ * @note This method doesn't check this object's readiness. Intended to be
+ * used by ready Machine children (whose readiness is bound to the parent's
+ * one) or after doing addCaller() manually.
+ */
+ VirtualBox* i_getVirtualBox() const { return mParent; }
+
+ /**
+ * Checks if this machine is accessible, without attempting to load the
+ * config file.
+ *
+ * @note This method doesn't check this object's readiness. Intended to be
+ * used by ready Machine children (whose readiness is bound to the parent's
+ * one) or after doing addCaller() manually.
+ */
+ bool i_isAccessible() const { return !!mData->mAccessible; }
+
+ /**
+ * Returns this machine ID.
+ *
+ * @note This method doesn't check this object's readiness. Intended to be
+ * used by ready Machine children (whose readiness is bound to the parent's
+ * one) or after adding a caller manually.
+ */
+ const Guid& i_getId() const { return mData->mUuid; }
+
+ /**
+ * Returns the snapshot ID this machine represents or an empty UUID if this
+ * instance is not SnapshotMachine.
+ *
+ * @note This method doesn't check this object's readiness. Intended to be
+ * used by ready Machine children (whose readiness is bound to the parent's
+ * one) or after adding a caller manually.
+ */
+ inline const Guid& i_getSnapshotId() const;
+
+ /**
+ * Returns this machine's full settings file path.
+ *
+ * @note This method doesn't lock this object or check its readiness.
+ * Intended to be used only after doing addCaller() manually and locking it
+ * for reading.
+ */
+ const Utf8Str& i_getSettingsFileFull() const { return mData->m_strConfigFileFull; }
+
+ /**
+ * Returns this machine name.
+ *
+ * @note This method doesn't lock this object or check its readiness.
+ * Intended to be used only after doing addCaller() manually and locking it
+ * for reading.
+ */
+ const Utf8Str& i_getName() const { return mUserData->s.strName; }
+
+ enum
+ {
+ IsModified_MachineData = 0x000001,
+ IsModified_Storage = 0x000002,
+ IsModified_NetworkAdapters = 0x000008,
+ IsModified_SerialPorts = 0x000010,
+ IsModified_ParallelPorts = 0x000020,
+ IsModified_VRDEServer = 0x000040,
+ IsModified_AudioSettings = 0x000080,
+ IsModified_USB = 0x000100,
+ IsModified_BIOS = 0x000200,
+ IsModified_SharedFolders = 0x000400,
+ IsModified_Snapshots = 0x000800,
+ IsModified_BandwidthControl = 0x001000,
+ IsModified_Recording = 0x002000,
+ IsModified_GraphicsAdapter = 0x004000,
+ IsModified_TrustedPlatformModule = 0x008000,
+ IsModified_NvramStore = 0x010000,
+ IsModified_GuestDebugControl = 0x020000,
+ };
+
+ /**
+ * Returns various information about this machine.
+ *
+ * @note This method doesn't lock this object or check its readiness.
+ * Intended to be used only after doing addCaller() manually and locking it
+ * for reading.
+ */
+ Utf8Str i_getOSTypeId() const { return mUserData->s.strOsType; }
+ ChipsetType_T i_getChipsetType() const { return mHWData->mChipsetType; }
+ FirmwareType_T i_getFirmwareType() const { return mHWData->mFirmwareType; }
+ ParavirtProvider_T i_getParavirtProvider() const { return mHWData->mParavirtProvider; }
+ Utf8Str i_getParavirtDebug() const { return mHWData->mParavirtDebug; }
+
+ void i_setModified(uint32_t fl, bool fAllowStateModification = true);
+ void i_setModifiedLock(uint32_t fl, bool fAllowStateModification = true);
+
+ MachineState_T i_getMachineState() const { return mData->mMachineState; }
+
+ bool i_isStateModificationAllowed() const { return mData->m_fAllowStateModification; }
+ void i_allowStateModification() { mData->m_fAllowStateModification = true; }
+ void i_disallowStateModification() { mData->m_fAllowStateModification = false; }
+
+ const StringsList &i_getGroups() const { return mUserData->s.llGroups; }
+
+ // callback handlers
+ virtual HRESULT i_onNetworkAdapterChange(INetworkAdapter * /* networkAdapter */, BOOL /* changeAdapter */) { return S_OK; }
+ virtual HRESULT i_onNATRedirectRuleChanged(ULONG /* slot */, BOOL /* fRemove */ , const Utf8Str & /* name */,
+ NATProtocol_T /* protocol */, const Utf8Str & /* host ip */, LONG /* host port */,
+ const Utf8Str & /* guest port */, LONG /* guest port */ ) { return S_OK; }
+ virtual HRESULT i_onAudioAdapterChange(IAudioAdapter * /* audioAdapter */) { return S_OK; }
+ virtual HRESULT i_onHostAudioDeviceChange(IHostAudioDevice *, BOOL /* new */, AudioDeviceState_T, IVirtualBoxErrorInfo *) { return S_OK; }
+ virtual HRESULT i_onSerialPortChange(ISerialPort * /* serialPort */) { return S_OK; }
+ virtual HRESULT i_onParallelPortChange(IParallelPort * /* parallelPort */) { return S_OK; }
+ virtual HRESULT i_onVRDEServerChange(BOOL /* aRestart */) { return S_OK; }
+ virtual HRESULT i_onUSBControllerChange() { return S_OK; }
+ virtual HRESULT i_onStorageControllerChange(const com::Guid & /* aMachineId */, const com::Utf8Str & /* aControllerName */) { return S_OK; }
+ virtual HRESULT i_onCPUChange(ULONG /* aCPU */, BOOL /* aRemove */) { return S_OK; }
+ virtual HRESULT i_onCPUExecutionCapChange(ULONG /* aExecutionCap */) { return S_OK; }
+ virtual HRESULT i_onMediumChange(IMediumAttachment * /* mediumAttachment */, BOOL /* force */) { return S_OK; }
+ virtual HRESULT i_onSharedFolderChange() { return S_OK; }
+ virtual HRESULT i_onVMProcessPriorityChange(VMProcPriority_T /* aPriority */) { return S_OK; }
+ virtual HRESULT i_onClipboardModeChange(ClipboardMode_T /* aClipboardMode */) { return S_OK; }
+ virtual HRESULT i_onClipboardFileTransferModeChange(BOOL /* aEnable */) { return S_OK; }
+ virtual HRESULT i_onDnDModeChange(DnDMode_T /* aDnDMode */) { return S_OK; }
+ virtual HRESULT i_onBandwidthGroupChange(IBandwidthGroup * /* aBandwidthGroup */) { return S_OK; }
+ virtual HRESULT i_onStorageDeviceChange(IMediumAttachment * /* mediumAttachment */, BOOL /* remove */,
+ BOOL /* silent */) { return S_OK; }
+ virtual HRESULT i_onRecordingChange(BOOL /* aEnable */) { return S_OK; }
+ virtual HRESULT i_onGuestDebugControlChange(IGuestDebugControl * /* guestDebugControl */) { return S_OK; }
+
+
+ HRESULT i_saveRegistryEntry(settings::MachineRegistryEntry &data);
+
+ int i_calculateFullPath(const Utf8Str &strPath, Utf8Str &aResult);
+ void i_copyPathRelativeToMachine(const Utf8Str &strSource, Utf8Str &strTarget);
+
+ void i_getLogFolder(Utf8Str &aLogFolder);
+ Utf8Str i_getLogFilename(ULONG idx);
+ Utf8Str i_getHardeningLogFilename(void);
+ Utf8Str i_getDefaultNVRAMFilename();
+ Utf8Str i_getSnapshotNVRAMFilename();
+ SettingsVersion_T i_getSettingsVersion(void);
+
+ void i_composeSavedStateFilename(Utf8Str &strStateFilePath);
+
+ bool i_isUSBControllerPresent();
+
+ HRESULT i_launchVMProcess(IInternalSessionControl *aControl,
+ const Utf8Str &strType,
+ const std::vector<com::Utf8Str> &aEnvironmentChanges,
+ ProgressProxy *aProgress);
+
+ HRESULT i_getDirectControl(ComPtr<IInternalSessionControl> *directControl)
+ {
+ *directControl = mData->mSession.mDirectControl;
+
+ HRESULT hrc;
+ if (!*directControl)
+ hrc = E_ACCESSDENIED;
+ else
+ hrc = S_OK;
+
+ return hrc;
+ }
+
+ bool i_isSessionOpen(ComObjPtr<SessionMachine> &aMachine,
+ ComPtr<IInternalSessionControl> *aControl = NULL,
+ bool aRequireVM = false,
+ bool aAllowClosing = false);
+ bool i_isSessionSpawning();
+
+ bool i_isSessionOpenOrClosing(ComObjPtr<SessionMachine> &aMachine,
+ ComPtr<IInternalSessionControl> *aControl = NULL)
+ { return i_isSessionOpen(aMachine, aControl, false /* aRequireVM */, true /* aAllowClosing */); }
+
+ bool i_isSessionOpenVM(ComObjPtr<SessionMachine> &aMachine,
+ ComPtr<IInternalSessionControl> *aControl = NULL)
+ { return i_isSessionOpen(aMachine, aControl, true /* aRequireVM */, false /* aAllowClosing */); }
+
+ bool i_checkForSpawnFailure();
+
+ HRESULT i_prepareRegister();
+
+ HRESULT i_getSharedFolder(const Utf8Str &aName,
+ ComObjPtr<SharedFolder> &aSharedFolder,
+ bool aSetError = false)
+ {
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ return i_findSharedFolder(aName, aSharedFolder, aSetError);
+ }
+
+ HRESULT i_addStateDependency(StateDependency aDepType = AnyStateDep,
+ MachineState_T *aState = NULL,
+ BOOL *aRegistered = NULL);
+ void i_releaseStateDependency();
+
+ HRESULT i_getStorageControllerByName(const Utf8Str &aName,
+ ComObjPtr<StorageController> &aStorageController,
+ bool aSetError = false);
+
+ HRESULT i_getMediumAttachmentsOfController(const Utf8Str &aName,
+ MediumAttachmentList &aAttachments);
+
+ HRESULT i_getUSBControllerByName(const Utf8Str &aName,
+ ComObjPtr<USBController> &aUSBController,
+ bool aSetError = false);
+
+ HRESULT i_getBandwidthGroup(const Utf8Str &strBandwidthGroup,
+ ComObjPtr<BandwidthGroup> &pBandwidthGroup,
+ bool fSetError = false)
+ {
+ return mBandwidthControl->i_getBandwidthGroupByName(strBandwidthGroup,
+ pBandwidthGroup,
+ fSetError);
+ }
+
+ static HRESULT i_setErrorStatic(HRESULT aResultCode, const char *pcszMsg, ...);
+
+protected:
+
+ class ClientToken;
+
+ HRESULT i_checkStateDependency(StateDependency aDepType);
+
+ Machine *i_getMachine();
+
+ void i_ensureNoStateDependencies(AutoWriteLock &alock);
+
+ virtual HRESULT i_setMachineState(MachineState_T aMachineState);
+
+ HRESULT i_findSharedFolder(const Utf8Str &aName,
+ ComObjPtr<SharedFolder> &aSharedFolder,
+ bool aSetError = false);
+
+ HRESULT i_loadSettings(bool aRegistered);
+ HRESULT i_loadMachineDataFromSettings(const settings::MachineConfigFile &config,
+ const Guid *puuidRegistry);
+ HRESULT i_loadSnapshot(const settings::Snapshot &data,
+ const Guid &aCurSnapshotId);
+ HRESULT i_loadHardware(const Guid *puuidRegistry,
+ const Guid *puuidSnapshot,
+ const settings::Hardware &data,
+ const settings::Debugging *pDbg,
+ const settings::Autostart *pAutostart,
+ const settings::RecordingSettings &recording);
+ HRESULT i_loadDebugging(const settings::Debugging *pDbg);
+ HRESULT i_loadAutostart(const settings::Autostart *pAutostart);
+ HRESULT i_loadStorageControllers(const settings::Storage &data,
+ const Guid *puuidRegistry,
+ const Guid *puuidSnapshot);
+ HRESULT i_loadStorageDevices(StorageController *aStorageController,
+ const settings::StorageController &data,
+ const Guid *puuidRegistry,
+ const Guid *puuidSnapshot);
+
+ HRESULT i_findSnapshotById(const Guid &aId,
+ ComObjPtr<Snapshot> &aSnapshot,
+ bool aSetError = false);
+ HRESULT i_findSnapshotByName(const Utf8Str &strName,
+ ComObjPtr<Snapshot> &aSnapshot,
+ bool aSetError = false);
+
+ ULONG i_getUSBControllerCountByType(USBControllerType_T enmType);
+
+ enum
+ {
+ /* flags for #saveSettings() */
+ SaveS_ResetCurStateModified = 0x01,
+ SaveS_Force = 0x04,
+ SaveS_RemoveBackup = 0x08,
+ /* flags for #saveStateSettings() */
+ SaveSTS_CurStateModified = 0x20,
+ SaveSTS_StateFilePath = 0x40,
+ SaveSTS_StateTimeStamp = 0x80
+ };
+
+ HRESULT i_prepareSaveSettings(bool *pfNeedsGlobalSaveSettings,
+ bool *pfSettingsFileIsNew);
+ HRESULT i_saveSettings(bool *pfNeedsGlobalSaveSettings, AutoWriteLock &alock, int aFlags = 0);
+
+ void i_copyMachineDataToSettings(settings::MachineConfigFile &config);
+ HRESULT i_saveAllSnapshots(settings::MachineConfigFile &config);
+ HRESULT i_saveHardware(settings::Hardware &data, settings::Debugging *pDbg,
+ settings::Autostart *pAutostart, settings::RecordingSettings &recording);
+ HRESULT i_saveStorageControllers(settings::Storage &data);
+ HRESULT i_saveStorageDevices(ComObjPtr<StorageController> aStorageController,
+ settings::StorageController &data);
+ HRESULT i_saveStateSettings(int aFlags);
+
+ void i_addMediumToRegistry(ComObjPtr<Medium> &pMedium);
+
+ HRESULT i_deleteFile(const Utf8Str &strFile, bool fIgnoreFailures = false, const Utf8Str &strWhat = "", int *prc = NULL);
+
+ HRESULT i_createImplicitDiffs(IProgress *aProgress,
+ ULONG aWeight,
+ bool aOnline);
+ HRESULT i_deleteImplicitDiffs(bool aOnline);
+
+ MediumAttachment* i_findAttachment(const MediumAttachmentList &ll,
+ const Utf8Str &aControllerName,
+ LONG aControllerPort,
+ LONG aDevice);
+ MediumAttachment* i_findAttachment(const MediumAttachmentList &ll,
+ ComObjPtr<Medium> pMedium);
+ MediumAttachment* i_findAttachment(const MediumAttachmentList &ll,
+ Guid &id);
+
+ HRESULT i_detachDevice(MediumAttachment *pAttach,
+ AutoWriteLock &writeLock,
+ Snapshot *pSnapshot);
+
+ HRESULT i_detachAllMedia(AutoWriteLock &writeLock,
+ Snapshot *pSnapshot,
+ CleanupMode_T cleanupMode,
+ MediaList &llMedia);
+
+ void i_commitMedia(bool aOnline = false);
+ void i_rollbackMedia();
+
+ bool i_isInOwnDir(Utf8Str *aSettingsDir = NULL) const;
+
+ void i_rollback(bool aNotify);
+ void i_commit();
+ void i_copyFrom(Machine *aThat);
+ bool i_isControllerHotplugCapable(StorageControllerType_T enmCtrlType);
+
+ Utf8Str i_getExtraData(const Utf8Str &strKey);
+
+ com::Utf8Str i_controllerNameFromBusType(StorageBus_T aBusType);
+
+#ifdef VBOX_WITH_GUEST_PROPS
+ HRESULT i_getGuestPropertyFromService(const com::Utf8Str &aName, com::Utf8Str &aValue,
+ LONG64 *aTimestamp, com::Utf8Str &aFlags) const;
+ HRESULT i_setGuestPropertyToService(const com::Utf8Str &aName, const com::Utf8Str &aValue,
+ const com::Utf8Str &aFlags, bool fDelete);
+ HRESULT i_getGuestPropertyFromVM(const com::Utf8Str &aName, com::Utf8Str &aValue,
+ LONG64 *aTimestamp, com::Utf8Str &aFlags) const;
+ HRESULT i_setGuestPropertyToVM(const com::Utf8Str &aName, const com::Utf8Str &aValue,
+ const com::Utf8Str &aFlags, bool fDelete);
+ HRESULT i_enumerateGuestPropertiesInService(const com::Utf8Str &aPatterns,
+ std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<com::Utf8Str> &aFlags);
+ HRESULT i_enumerateGuestPropertiesOnVM(const com::Utf8Str &aPatterns,
+ std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<com::Utf8Str> &aFlags);
+
+#endif /* VBOX_WITH_GUEST_PROPS */
+
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+ void i_getDiskList(MediaList &list);
+ void i_registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid);
+
+ pm::CollectorGuest *mCollectorGuest;
+#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+
+ Machine * const mPeer;
+
+ VirtualBox * const mParent;
+
+ Shareable<Data> mData;
+ Shareable<SSData> mSSData;
+
+ Backupable<UserData> mUserData;
+ Backupable<HWData> mHWData;
+
+ /**
+ * Hard disk and other media data.
+ *
+ * The usage policy is the same as for mHWData, but a separate field
+ * is necessary because hard disk data requires different procedures when
+ * taking or deleting snapshots, etc.
+ *
+ * @todo r=klaus change this to a regular list and use the normal way to
+ * handle the settings when creating a session or taking a snapshot.
+ * Same thing applies to mStorageControllers and mUSBControllers.
+ */
+ Backupable<MediumAttachmentList> mMediumAttachments;
+
+ // the following fields need special backup/rollback/commit handling,
+ // so they cannot be a part of HWData
+
+ const ComObjPtr<VRDEServer> mVRDEServer;
+ const ComObjPtr<SerialPort> mSerialPorts[SchemaDefs::SerialPortCount];
+ const ComObjPtr<ParallelPort> mParallelPorts[SchemaDefs::ParallelPortCount];
+ const ComObjPtr<AudioSettings> mAudioSettings;
+ const ComObjPtr<USBDeviceFilters> mUSBDeviceFilters;
+ const ComObjPtr<BIOSSettings> mBIOSSettings;
+ const ComObjPtr<RecordingSettings> mRecordingSettings;
+ const ComObjPtr<GraphicsAdapter> mGraphicsAdapter;
+ const ComObjPtr<BandwidthControl> mBandwidthControl;
+ const ComObjPtr<GuestDebugControl> mGuestDebugControl;
+
+ const ComObjPtr<TrustedPlatformModule> mTrustedPlatformModule;
+ const ComObjPtr<NvramStore> mNvramStore;
+
+ typedef std::vector<ComObjPtr<NetworkAdapter> > NetworkAdapterVector;
+ NetworkAdapterVector mNetworkAdapters;
+
+ typedef std::list<ComObjPtr<StorageController> > StorageControllerList;
+ Backupable<StorageControllerList> mStorageControllers;
+
+ typedef std::list<ComObjPtr<USBController> > USBControllerList;
+ Backupable<USBControllerList> mUSBControllers;
+
+ uint64_t uRegistryNeedsSaving;
+
+ /**
+ * Abstract base class for all Machine or SessionMachine related
+ * asynchronous tasks. This is necessary since RTThreadCreate cannot call
+ * a (non-static) method as its thread function, so instead we have it call
+ * the static Machine::taskHandler, which then calls the handler() method
+ * in here (implemented by the subclasses).
+ */
+ class Task : public ThreadTask
+ {
+ public:
+ Task(Machine *m, Progress *p, const Utf8Str &t)
+ : ThreadTask(t),
+ m_pMachine(m),
+ m_machineCaller(m),
+ m_pProgress(p),
+ m_machineStateBackup(m->mData->mMachineState) // save the current machine state
+ {}
+ virtual ~Task(){}
+
+ void modifyBackedUpState(MachineState_T s)
+ {
+ *const_cast<MachineState_T *>(&m_machineStateBackup) = s;
+ }
+
+ ComObjPtr<Machine> m_pMachine;
+ AutoCaller m_machineCaller;
+ ComObjPtr<Progress> m_pProgress;
+ const MachineState_T m_machineStateBackup;
+ };
+
+ class DeleteConfigTask;
+ void i_deleteConfigHandler(DeleteConfigTask &task);
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ class ChangeEncryptionTask;
+ void i_changeEncryptionHandler(ChangeEncryptionTask &task);
+ HRESULT i_changeEncryptionForComponent(ChangeEncryptionTask &task, const com::Utf8Str strDirectory,
+ const com::Utf8Str strFilePattern, com::Utf8Str &strKeyStore,
+ com::Utf8Str &strKeyId, int iCipherMode);
+ int i_findFiles(std::list<com::Utf8Str> &lstFiles, const com::Utf8Str &strDir,
+ const com::Utf8Str &strPattern);
+ int i_createIoStreamForFile(const char *pszFilename, PCVBOXCRYPTOIF pCryptoIf,
+ const char *pszKeyStore, const char *pszPassword,
+ uint64_t fOpen, PRTVFSIOSTREAM phVfsIos);
+#endif
+
+ friend class Appliance;
+ friend class RecordingSettings;
+ friend class RecordingScreenSettings;
+ friend class SessionMachine;
+ friend class SnapshotMachine;
+ friend class VirtualBox;
+
+ friend class MachineCloneVM;
+ friend class MachineMoveVM;
+private:
+ // wrapped IMachine properties
+ HRESULT getParent(ComPtr<IVirtualBox> &aParent);
+ HRESULT getIcon(std::vector<BYTE> &aIcon);
+ HRESULT setIcon(const std::vector<BYTE> &aIcon);
+ HRESULT getAccessible(BOOL *aAccessible);
+ HRESULT getAccessError(ComPtr<IVirtualBoxErrorInfo> &aAccessError);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT setDescription(const com::Utf8Str &aDescription);
+ HRESULT getId(com::Guid &aId);
+ HRESULT getGroups(std::vector<com::Utf8Str> &aGroups);
+ HRESULT setGroups(const std::vector<com::Utf8Str> &aGroups);
+ HRESULT getOSTypeId(com::Utf8Str &aOSTypeId);
+ HRESULT setOSTypeId(const com::Utf8Str &aOSTypeId);
+ HRESULT getHardwareVersion(com::Utf8Str &aHardwareVersion);
+ HRESULT setHardwareVersion(const com::Utf8Str &aHardwareVersion);
+ HRESULT getHardwareUUID(com::Guid &aHardwareUUID);
+ HRESULT setHardwareUUID(const com::Guid &aHardwareUUID);
+ HRESULT getCPUCount(ULONG *aCPUCount);
+ HRESULT setCPUCount(ULONG aCPUCount);
+ HRESULT getCPUHotPlugEnabled(BOOL *aCPUHotPlugEnabled);
+ HRESULT setCPUHotPlugEnabled(BOOL aCPUHotPlugEnabled);
+ HRESULT getCPUExecutionCap(ULONG *aCPUExecutionCap);
+ HRESULT setCPUExecutionCap(ULONG aCPUExecutionCap);
+ HRESULT getCPUIDPortabilityLevel(ULONG *aCPUIDPortabilityLevel);
+ HRESULT setCPUIDPortabilityLevel(ULONG aCPUIDPortabilityLevel);
+ HRESULT getCPUProfile(com::Utf8Str &aCPUProfile);
+ HRESULT setCPUProfile(const com::Utf8Str &aCPUProfile);
+ HRESULT getMemorySize(ULONG *aMemorySize);
+ HRESULT setMemorySize(ULONG aMemorySize);
+ HRESULT getMemoryBalloonSize(ULONG *aMemoryBalloonSize);
+ HRESULT setMemoryBalloonSize(ULONG aMemoryBalloonSize);
+ HRESULT getPageFusionEnabled(BOOL *aPageFusionEnabled);
+ HRESULT setPageFusionEnabled(BOOL aPageFusionEnabled);
+ HRESULT getGraphicsAdapter(ComPtr<IGraphicsAdapter> &aGraphicsAdapter);
+ HRESULT getBIOSSettings(ComPtr<IBIOSSettings> &aBIOSSettings);
+ HRESULT getTrustedPlatformModule(ComPtr<ITrustedPlatformModule> &aTrustedPlatformModule);
+ HRESULT getNonVolatileStore(ComPtr<INvramStore> &aNvramStore);
+ HRESULT getRecordingSettings(ComPtr<IRecordingSettings> &aRecordingSettings);
+ HRESULT getFirmwareType(FirmwareType_T *aFirmwareType);
+ HRESULT setFirmwareType(FirmwareType_T aFirmwareType);
+ HRESULT getPointingHIDType(PointingHIDType_T *aPointingHIDType);
+ HRESULT setPointingHIDType(PointingHIDType_T aPointingHIDType);
+ HRESULT getKeyboardHIDType(KeyboardHIDType_T *aKeyboardHIDType);
+ HRESULT setKeyboardHIDType(KeyboardHIDType_T aKeyboardHIDType);
+ HRESULT getHPETEnabled(BOOL *aHPETEnabled);
+ HRESULT setHPETEnabled(BOOL aHPETEnabled);
+ HRESULT getChipsetType(ChipsetType_T *aChipsetType);
+ HRESULT setChipsetType(ChipsetType_T aChipsetType);
+ HRESULT getIommuType(IommuType_T *aIommuType);
+ HRESULT setIommuType(IommuType_T aIommuType);
+ HRESULT getSnapshotFolder(com::Utf8Str &aSnapshotFolder);
+ HRESULT setSnapshotFolder(const com::Utf8Str &aSnapshotFolder);
+ HRESULT getVRDEServer(ComPtr<IVRDEServer> &aVRDEServer);
+ HRESULT getEmulatedUSBCardReaderEnabled(BOOL *aEmulatedUSBCardReaderEnabled);
+ HRESULT setEmulatedUSBCardReaderEnabled(BOOL aEmulatedUSBCardReaderEnabled);
+ HRESULT getMediumAttachments(std::vector<ComPtr<IMediumAttachment> > &aMediumAttachments);
+ HRESULT getUSBControllers(std::vector<ComPtr<IUSBController> > &aUSBControllers);
+ HRESULT getUSBDeviceFilters(ComPtr<IUSBDeviceFilters> &aUSBDeviceFilters);
+ HRESULT getAudioSettings(ComPtr<IAudioSettings> &aAudioSettings);
+ HRESULT getStorageControllers(std::vector<ComPtr<IStorageController> > &aStorageControllers);
+ HRESULT getSettingsFilePath(com::Utf8Str &aSettingsFilePath);
+ HRESULT getSettingsAuxFilePath(com::Utf8Str &aSettingsAuxFilePath);
+ HRESULT getSettingsModified(BOOL *aSettingsModified);
+ HRESULT getSessionState(SessionState_T *aSessionState);
+ HRESULT getSessionType(SessionType_T *aSessionType);
+ HRESULT getSessionName(com::Utf8Str &aSessionType);
+ HRESULT getSessionPID(ULONG *aSessionPID);
+ HRESULT getState(MachineState_T *aState);
+ HRESULT getLastStateChange(LONG64 *aLastStateChange);
+ HRESULT getStateFilePath(com::Utf8Str &aStateFilePath);
+ HRESULT getLogFolder(com::Utf8Str &aLogFolder);
+ HRESULT getCurrentSnapshot(ComPtr<ISnapshot> &aCurrentSnapshot);
+ HRESULT getSnapshotCount(ULONG *aSnapshotCount);
+ HRESULT getCurrentStateModified(BOOL *aCurrentStateModified);
+ HRESULT getSharedFolders(std::vector<ComPtr<ISharedFolder> > &aSharedFolders);
+ HRESULT getClipboardMode(ClipboardMode_T *aClipboardMode);
+ HRESULT setClipboardMode(ClipboardMode_T aClipboardMode);
+ HRESULT getClipboardFileTransfersEnabled(BOOL *aEnabled);
+ HRESULT setClipboardFileTransfersEnabled(BOOL aEnabled);
+ HRESULT getDnDMode(DnDMode_T *aDnDMode);
+ HRESULT setDnDMode(DnDMode_T aDnDMode);
+ HRESULT getTeleporterEnabled(BOOL *aTeleporterEnabled);
+ HRESULT setTeleporterEnabled(BOOL aTeleporterEnabled);
+ HRESULT getTeleporterPort(ULONG *aTeleporterPort);
+ HRESULT setTeleporterPort(ULONG aTeleporterPort);
+ HRESULT getTeleporterAddress(com::Utf8Str &aTeleporterAddress);
+ HRESULT setTeleporterAddress(const com::Utf8Str &aTeleporterAddress);
+ HRESULT getTeleporterPassword(com::Utf8Str &aTeleporterPassword);
+ HRESULT setTeleporterPassword(const com::Utf8Str &aTeleporterPassword);
+ HRESULT getParavirtProvider(ParavirtProvider_T *aParavirtProvider);
+ HRESULT setParavirtProvider(ParavirtProvider_T aParavirtProvider);
+ HRESULT getParavirtDebug(com::Utf8Str &aParavirtDebug);
+ HRESULT setParavirtDebug(const com::Utf8Str &aParavirtDebug);
+ HRESULT getRTCUseUTC(BOOL *aRTCUseUTC);
+ HRESULT setRTCUseUTC(BOOL aRTCUseUTC);
+ HRESULT getIOCacheEnabled(BOOL *aIOCacheEnabled);
+ HRESULT setIOCacheEnabled(BOOL aIOCacheEnabled);
+ HRESULT getIOCacheSize(ULONG *aIOCacheSize);
+ HRESULT setIOCacheSize(ULONG aIOCacheSize);
+ HRESULT getPCIDeviceAssignments(std::vector<ComPtr<IPCIDeviceAttachment> > &aPCIDeviceAssignments);
+ HRESULT getBandwidthControl(ComPtr<IBandwidthControl> &aBandwidthControl);
+ HRESULT getTracingEnabled(BOOL *aTracingEnabled);
+ HRESULT setTracingEnabled(BOOL aTracingEnabled);
+ HRESULT getTracingConfig(com::Utf8Str &aTracingConfig);
+ HRESULT setTracingConfig(const com::Utf8Str &aTracingConfig);
+ HRESULT getAllowTracingToAccessVM(BOOL *aAllowTracingToAccessVM);
+ HRESULT setAllowTracingToAccessVM(BOOL aAllowTracingToAccessVM);
+ HRESULT getAutostartEnabled(BOOL *aAutostartEnabled);
+ HRESULT setAutostartEnabled(BOOL aAutostartEnabled);
+ HRESULT getAutostartDelay(ULONG *aAutostartDelay);
+ HRESULT setAutostartDelay(ULONG aAutostartDelay);
+ HRESULT getAutostopType(AutostopType_T *aAutostopType);
+ HRESULT setAutostopType(AutostopType_T aAutostopType);
+ HRESULT getDefaultFrontend(com::Utf8Str &aDefaultFrontend);
+ HRESULT setDefaultFrontend(const com::Utf8Str &aDefaultFrontend);
+ HRESULT getUSBProxyAvailable(BOOL *aUSBProxyAvailable);
+ HRESULT getVMProcessPriority(VMProcPriority_T *aVMProcessPriority);
+ HRESULT setVMProcessPriority(VMProcPriority_T aVMProcessPriority);
+ HRESULT getStateKeyId(com::Utf8Str &aKeyId);
+ HRESULT getStateKeyStore(com::Utf8Str &aKeyStore);
+ HRESULT getLogKeyId(com::Utf8Str &aKeyId);
+ HRESULT getLogKeyStore(com::Utf8Str &aKeyStore);
+ HRESULT getGuestDebugControl(ComPtr<IGuestDebugControl> &aGuestDebugControl);
+
+ // wrapped IMachine methods
+ HRESULT lockMachine(const ComPtr<ISession> &aSession,
+ LockType_T aLockType);
+ HRESULT launchVMProcess(const ComPtr<ISession> &aSession,
+ const com::Utf8Str &aType,
+ const std::vector<com::Utf8Str> &aEnvironmentChanges,
+ ComPtr<IProgress> &aProgress);
+ HRESULT setBootOrder(ULONG aPosition,
+ DeviceType_T aDevice);
+ HRESULT getBootOrder(ULONG aPosition,
+ DeviceType_T *aDevice);
+ HRESULT attachDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ DeviceType_T aType,
+ const ComPtr<IMedium> &aMedium);
+ HRESULT attachDeviceWithoutMedium(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ DeviceType_T aType);
+ HRESULT detachDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice);
+ HRESULT passthroughDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ BOOL aPassthrough);
+ HRESULT temporaryEjectDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ BOOL aTemporaryEject);
+ HRESULT nonRotationalDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ BOOL aNonRotational);
+ HRESULT setAutoDiscardForDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ BOOL aDiscard);
+ HRESULT setHotPluggableForDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ BOOL aHotPluggable);
+ HRESULT setBandwidthGroupForDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ const ComPtr<IBandwidthGroup> &aBandwidthGroup);
+ HRESULT setNoBandwidthGroupForDevice(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice);
+ HRESULT unmountMedium(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ BOOL aForce);
+ HRESULT mountMedium(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ const ComPtr<IMedium> &aMedium,
+ BOOL aForce);
+ HRESULT getMedium(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ ComPtr<IMedium> &aMedium);
+ HRESULT getMediumAttachmentsOfController(const com::Utf8Str &aName,
+ std::vector<ComPtr<IMediumAttachment> > &aMediumAttachments);
+ HRESULT getMediumAttachment(const com::Utf8Str &aName,
+ LONG aControllerPort,
+ LONG aDevice,
+ ComPtr<IMediumAttachment> &aAttachment);
+ HRESULT attachHostPCIDevice(LONG aHostAddress,
+ LONG aDesiredGuestAddress,
+ BOOL aTryToUnbind);
+ HRESULT detachHostPCIDevice(LONG aHostAddress);
+ HRESULT getNetworkAdapter(ULONG aSlot,
+ ComPtr<INetworkAdapter> &aAdapter);
+ HRESULT addStorageController(const com::Utf8Str &aName,
+ StorageBus_T aConnectionType,
+ ComPtr<IStorageController> &aController);
+ HRESULT getStorageControllerByName(const com::Utf8Str &aName,
+ ComPtr<IStorageController> &aStorageController);
+ HRESULT getStorageControllerByInstance(StorageBus_T aConnectionType,
+ ULONG aInstance,
+ ComPtr<IStorageController> &aStorageController);
+ HRESULT removeStorageController(const com::Utf8Str &aName);
+ HRESULT setStorageControllerBootable(const com::Utf8Str &aName,
+ BOOL aBootable);
+ HRESULT addUSBController(const com::Utf8Str &aName,
+ USBControllerType_T aType,
+ ComPtr<IUSBController> &aController);
+ HRESULT removeUSBController(const com::Utf8Str &aName);
+ HRESULT getUSBControllerByName(const com::Utf8Str &aName,
+ ComPtr<IUSBController> &aController);
+ HRESULT getUSBControllerCountByType(USBControllerType_T aType,
+ ULONG *aControllers);
+ HRESULT getSerialPort(ULONG aSlot,
+ ComPtr<ISerialPort> &aPort);
+ HRESULT getParallelPort(ULONG aSlot,
+ ComPtr<IParallelPort> &aPort);
+ HRESULT getExtraDataKeys(std::vector<com::Utf8Str> &aKeys);
+ HRESULT getExtraData(const com::Utf8Str &aKey,
+ com::Utf8Str &aValue);
+ HRESULT setExtraData(const com::Utf8Str &aKey,
+ const com::Utf8Str &aValue);
+ HRESULT getCPUProperty(CPUPropertyType_T aProperty,
+ BOOL *aValue);
+ HRESULT setCPUProperty(CPUPropertyType_T aProperty,
+ BOOL aValue);
+ HRESULT getCPUIDLeafByOrdinal(ULONG aOrdinal,
+ ULONG *aIdx,
+ ULONG *aSubIdx,
+ ULONG *aValEax,
+ ULONG *aValEbx,
+ ULONG *aValEcx,
+ ULONG *aValEdx);
+ HRESULT getCPUIDLeaf(ULONG aIdx, ULONG aSubIdx,
+ ULONG *aValEax,
+ ULONG *aValEbx,
+ ULONG *aValEcx,
+ ULONG *aValEdx);
+ HRESULT setCPUIDLeaf(ULONG aIdx, ULONG aSubIdx,
+ ULONG aValEax,
+ ULONG aValEbx,
+ ULONG aValEcx,
+ ULONG aValEdx);
+ HRESULT removeCPUIDLeaf(ULONG aIdx, ULONG aSubIdx);
+ HRESULT removeAllCPUIDLeaves();
+ HRESULT getHWVirtExProperty(HWVirtExPropertyType_T aProperty,
+ BOOL *aValue);
+ HRESULT setHWVirtExProperty(HWVirtExPropertyType_T aProperty,
+ BOOL aValue);
+ HRESULT setSettingsFilePath(const com::Utf8Str &aSettingsFilePath,
+ ComPtr<IProgress> &aProgress);
+ HRESULT saveSettings();
+ HRESULT discardSettings();
+ HRESULT unregister(AutoCaller &aAutoCaller,
+ CleanupMode_T aCleanupMode,
+ std::vector<ComPtr<IMedium> > &aMedia);
+ HRESULT deleteConfig(const std::vector<ComPtr<IMedium> > &aMedia,
+ ComPtr<IProgress> &aProgress);
+ HRESULT exportTo(const ComPtr<IAppliance> &aAppliance,
+ const com::Utf8Str &aLocation,
+ ComPtr<IVirtualSystemDescription> &aDescription);
+ HRESULT findSnapshot(const com::Utf8Str &aNameOrId,
+ ComPtr<ISnapshot> &aSnapshot);
+ HRESULT createSharedFolder(const com::Utf8Str &aName,
+ const com::Utf8Str &aHostPath,
+ BOOL aWritable,
+ BOOL aAutomount,
+ const com::Utf8Str &aAutoMountPoint);
+ HRESULT removeSharedFolder(const com::Utf8Str &aName);
+ HRESULT canShowConsoleWindow(BOOL *aCanShow);
+ HRESULT showConsoleWindow(LONG64 *aWinId);
+ HRESULT getGuestProperty(const com::Utf8Str &aName,
+ com::Utf8Str &aValue,
+ LONG64 *aTimestamp,
+ com::Utf8Str &aFlags);
+ HRESULT getGuestPropertyValue(const com::Utf8Str &aProperty,
+ com::Utf8Str &aValue);
+ HRESULT getGuestPropertyTimestamp(const com::Utf8Str &aProperty,
+ LONG64 *aValue);
+ HRESULT setGuestProperty(const com::Utf8Str &aProperty,
+ const com::Utf8Str &aValue,
+ const com::Utf8Str &aFlags);
+ HRESULT setGuestPropertyValue(const com::Utf8Str &aProperty,
+ const com::Utf8Str &aValue);
+ HRESULT deleteGuestProperty(const com::Utf8Str &aName);
+ HRESULT enumerateGuestProperties(const com::Utf8Str &aPatterns,
+ std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<com::Utf8Str> &aFlags);
+ HRESULT querySavedGuestScreenInfo(ULONG aScreenId,
+ ULONG *aOriginX,
+ ULONG *aOriginY,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ BOOL *aEnabled);
+ HRESULT readSavedThumbnailToArray(ULONG aScreenId,
+ BitmapFormat_T aBitmapFormat,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ std::vector<BYTE> &aData);
+ HRESULT querySavedScreenshotInfo(ULONG aScreenId,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ std::vector<BitmapFormat_T> &aBitmapFormats);
+ HRESULT readSavedScreenshotToArray(ULONG aScreenId,
+ BitmapFormat_T aBitmapFormat,
+ ULONG *aWidth,
+ ULONG *aHeight,
+ std::vector<BYTE> &aData);
+
+ HRESULT hotPlugCPU(ULONG aCpu);
+ HRESULT hotUnplugCPU(ULONG aCpu);
+ HRESULT getCPUStatus(ULONG aCpu,
+ BOOL *aAttached);
+ HRESULT getEffectiveParavirtProvider(ParavirtProvider_T *aParavirtProvider);
+ HRESULT queryLogFilename(ULONG aIdx,
+ com::Utf8Str &aFilename);
+ HRESULT readLog(ULONG aIdx,
+ LONG64 aOffset,
+ LONG64 aSize,
+ std::vector<BYTE> &aData);
+ HRESULT cloneTo(const ComPtr<IMachine> &aTarget,
+ CloneMode_T aMode,
+ const std::vector<CloneOptions_T> &aOptions,
+ ComPtr<IProgress> &aProgress);
+ HRESULT moveTo(const com::Utf8Str &aTargetPath,
+ const com::Utf8Str &aType,
+ ComPtr<IProgress> &aProgress);
+ HRESULT saveState(ComPtr<IProgress> &aProgress);
+ HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
+ HRESULT discardSavedState(BOOL aFRemoveFile);
+ HRESULT takeSnapshot(const com::Utf8Str &aName,
+ const com::Utf8Str &aDescription,
+ BOOL aPause,
+ com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteSnapshot(const com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteSnapshotAndAllChildren(const com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteSnapshotRange(const com::Guid &aStartId,
+ const com::Guid &aEndId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
+ ComPtr<IProgress> &aProgress);
+ HRESULT applyDefaults(const com::Utf8Str &aFlags);
+ HRESULT changeEncryption(const com::Utf8Str &aCurrentPassword,
+ const com::Utf8Str &aCipher,
+ const com::Utf8Str &aNewPassword,
+ const com::Utf8Str &aNewPasswordId,
+ BOOL aForce,
+ ComPtr<IProgress> &aProgress);
+ HRESULT getEncryptionSettings(com::Utf8Str &aCipher,
+ com::Utf8Str &aPasswordId);
+ HRESULT checkEncryptionPassword(const com::Utf8Str &aPassword);
+ HRESULT addEncryptionPassword(const com::Utf8Str &aId,
+ const com::Utf8Str &aPassword);
+ HRESULT addEncryptionPasswords(const std::vector<com::Utf8Str> &aIds,
+ const std::vector<com::Utf8Str> &aPasswords);
+ HRESULT removeEncryptionPassword(AutoCaller &autoCaller,
+ const com::Utf8Str &aId);
+ HRESULT clearAllEncryptionPasswords(AutoCaller &autoCaller);
+
+ // wrapped IInternalMachineControl properties
+
+ // wrapped IInternalMachineControl methods
+ HRESULT updateState(MachineState_T aState);
+ HRESULT beginPowerUp(const ComPtr<IProgress> &aProgress);
+ HRESULT endPowerUp(LONG aResult);
+ HRESULT beginPoweringDown(ComPtr<IProgress> &aProgress);
+ HRESULT endPoweringDown(LONG aResult,
+ const com::Utf8Str &aErrMsg);
+ HRESULT runUSBDeviceFilters(const ComPtr<IUSBDevice> &aDevice,
+ BOOL *aMatched,
+ ULONG *aMaskedInterfaces);
+ HRESULT captureUSBDevice(const com::Guid &aId,
+ const com::Utf8Str &aCaptureFilename);
+ HRESULT detachUSBDevice(const com::Guid &aId,
+ BOOL aDone);
+ HRESULT autoCaptureUSBDevices();
+ HRESULT detachAllUSBDevices(BOOL aDone);
+ HRESULT onSessionEnd(const ComPtr<ISession> &aSession,
+ ComPtr<IProgress> &aProgress);
+ HRESULT finishOnlineMergeMedium();
+ HRESULT pullGuestProperties(std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<com::Utf8Str> &aFlags);
+ HRESULT pushGuestProperty(const com::Utf8Str &aName,
+ const com::Utf8Str &aValue,
+ LONG64 aTimestamp,
+ const com::Utf8Str &aFlags,
+ BOOL fWasDeleted);
+ HRESULT lockMedia();
+ HRESULT unlockMedia();
+ HRESULT ejectMedium(const ComPtr<IMediumAttachment> &aAttachment,
+ ComPtr<IMediumAttachment> &aNewAttachment);
+ HRESULT reportVmStatistics(ULONG aValidStats,
+ ULONG aCpuUser,
+ ULONG aCpuKernel,
+ ULONG aCpuIdle,
+ ULONG aMemTotal,
+ ULONG aMemFree,
+ ULONG aMemBalloon,
+ ULONG aMemShared,
+ ULONG aMemCache,
+ ULONG aPagedTotal,
+ ULONG aMemAllocTotal,
+ ULONG aMemFreeTotal,
+ ULONG aMemBalloonTotal,
+ ULONG aMemSharedTotal,
+ ULONG aVmNetRx,
+ ULONG aVmNetTx);
+ HRESULT authenticateExternal(const std::vector<com::Utf8Str> &aAuthParams,
+ com::Utf8Str &aResult);
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ HRESULT i_setInaccessible(void);
+#endif
+};
+
+// SessionMachine class
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @note Notes on locking objects of this class:
+ * SessionMachine shares some data with the primary Machine instance (pointed
+ * to by the |mPeer| member). In order to provide data consistency it also
+ * shares its lock handle. This means that whenever you lock a SessionMachine
+ * instance using Auto[Reader]Lock or AutoMultiLock, the corresponding Machine
+ * instance is also locked in the same lock mode. Keep it in mind.
+ */
+class ATL_NO_VTABLE SessionMachine :
+ public Machine
+{
+public:
+ VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(SessionMachine, IMachine)
+
+ DECLARE_NOT_AGGREGATABLE(SessionMachine)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(SessionMachine)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+ COM_INTERFACE_ENTRY(IMachine)
+ COM_INTERFACE_ENTRY2(IDispatch, IMachine)
+ COM_INTERFACE_ENTRY(IInternalMachineControl)
+ VBOX_TWEAK_INTERFACE_ENTRY(IMachine)
+ END_COM_MAP()
+
+ DECLARE_COMMON_CLASS_METHODS(SessionMachine)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ struct Uninit
+ {
+ enum Reason { Unexpected, Abnormal, Normal };
+ };
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aMachine);
+ void uninit() { uninit(Uninit::Unexpected); }
+ void uninit(Uninit::Reason aReason);
+
+
+ // util::Lockable interface
+ RWLockHandle *lockHandle() const;
+
+ // public methods only for internal purposes
+
+ virtual bool i_isSessionMachine() const
+ {
+ return true;
+ }
+
+#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
+ bool i_checkForDeath();
+
+ void i_getTokenId(Utf8Str &strTokenId);
+#else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+ IToken *i_getToken();
+#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
+ // getClientToken must be only used by callers who can guarantee that
+ // the object cannot be deleted in the mean time, i.e. have a caller/lock.
+ ClientToken *i_getClientToken();
+
+ HRESULT i_onNetworkAdapterChange(INetworkAdapter *networkAdapter, BOOL changeAdapter);
+ HRESULT i_onNATRedirectRuleChanged(ULONG ulSlot, BOOL aNatRuleRemove, const Utf8Str &aRuleName,
+ NATProtocol_T aProto, const Utf8Str &aHostIp, LONG aHostPort,
+ const Utf8Str &aGuestIp, LONG aGuestPort) RT_OVERRIDE;
+ HRESULT i_onStorageControllerChange(const com::Guid &aMachineId, const com::Utf8Str &aControllerName);
+ HRESULT i_onMediumChange(IMediumAttachment *aMediumAttachment, BOOL aForce);
+ HRESULT i_onVMProcessPriorityChange(VMProcPriority_T aPriority);
+ HRESULT i_onAudioAdapterChange(IAudioAdapter *audioAdapter);
+ HRESULT i_onHostAudioDeviceChange(IHostAudioDevice *aDevice, BOOL aNew, AudioDeviceState_T aState, IVirtualBoxErrorInfo *aErrInfo);
+ HRESULT i_onSerialPortChange(ISerialPort *serialPort);
+ HRESULT i_onParallelPortChange(IParallelPort *parallelPort);
+ HRESULT i_onCPUChange(ULONG aCPU, BOOL aRemove);
+ HRESULT i_onVRDEServerChange(BOOL aRestart);
+ HRESULT i_onRecordingChange(BOOL aEnable);
+ HRESULT i_onUSBControllerChange();
+ HRESULT i_onUSBDeviceAttach(IUSBDevice *aDevice,
+ IVirtualBoxErrorInfo *aError,
+ ULONG aMaskedIfs,
+ const com::Utf8Str &aCaptureFilename);
+ HRESULT i_onUSBDeviceDetach(IN_BSTR aId,
+ IVirtualBoxErrorInfo *aError);
+ HRESULT i_onSharedFolderChange();
+ HRESULT i_onClipboardModeChange(ClipboardMode_T aClipboardMode);
+ HRESULT i_onClipboardFileTransferModeChange(BOOL aEnable);
+ HRESULT i_onDnDModeChange(DnDMode_T aDnDMode);
+ HRESULT i_onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
+ HRESULT i_onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove, BOOL aSilent);
+ HRESULT i_onCPUExecutionCapChange(ULONG aCpuExecutionCap);
+ HRESULT i_onGuestDebugControlChange(IGuestDebugControl *guestDebugControl);
+
+ bool i_hasMatchingUSBFilter(const ComObjPtr<HostUSBDevice> &aDevice, ULONG *aMaskedIfs);
+
+ HRESULT i_lockMedia();
+ HRESULT i_unlockMedia();
+
+ HRESULT i_saveStateWithReason(Reason_T aReason, ComPtr<IProgress> &aProgress);
+
+private:
+
+ // wrapped IInternalMachineControl properties
+
+ // wrapped IInternalMachineControl methods
+ HRESULT setRemoveSavedStateFile(BOOL aRemove);
+ HRESULT updateState(MachineState_T aState);
+ HRESULT beginPowerUp(const ComPtr<IProgress> &aProgress);
+ HRESULT endPowerUp(LONG aResult);
+ HRESULT beginPoweringDown(ComPtr<IProgress> &aProgress);
+ HRESULT endPoweringDown(LONG aResult,
+ const com::Utf8Str &aErrMsg);
+ HRESULT runUSBDeviceFilters(const ComPtr<IUSBDevice> &aDevice,
+ BOOL *aMatched,
+ ULONG *aMaskedInterfaces);
+ HRESULT captureUSBDevice(const com::Guid &aId, const com::Utf8Str &aCaptureFilename);
+ HRESULT detachUSBDevice(const com::Guid &aId,
+ BOOL aDone);
+ HRESULT autoCaptureUSBDevices();
+ HRESULT detachAllUSBDevices(BOOL aDone);
+ HRESULT onSessionEnd(const ComPtr<ISession> &aSession,
+ ComPtr<IProgress> &aProgress);
+ HRESULT finishOnlineMergeMedium();
+ HRESULT pullGuestProperties(std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<com::Utf8Str> &aFlags);
+ HRESULT pushGuestProperty(const com::Utf8Str &aName,
+ const com::Utf8Str &aValue,
+ LONG64 aTimestamp,
+ const com::Utf8Str &aFlags,
+ BOOL fWasDeleted);
+ HRESULT lockMedia();
+ HRESULT unlockMedia();
+ HRESULT ejectMedium(const ComPtr<IMediumAttachment> &aAttachment,
+ ComPtr<IMediumAttachment> &aNewAttachment);
+ HRESULT reportVmStatistics(ULONG aValidStats,
+ ULONG aCpuUser,
+ ULONG aCpuKernel,
+ ULONG aCpuIdle,
+ ULONG aMemTotal,
+ ULONG aMemFree,
+ ULONG aMemBalloon,
+ ULONG aMemShared,
+ ULONG aMemCache,
+ ULONG aPagedTotal,
+ ULONG aMemAllocTotal,
+ ULONG aMemFreeTotal,
+ ULONG aMemBalloonTotal,
+ ULONG aMemSharedTotal,
+ ULONG aVmNetRx,
+ ULONG aVmNetTx);
+ HRESULT authenticateExternal(const std::vector<com::Utf8Str> &aAuthParams,
+ com::Utf8Str &aResult);
+
+
+ struct ConsoleTaskData
+ {
+ ConsoleTaskData()
+ : mLastState(MachineState_Null),
+ mDeleteSnapshotInfo(NULL)
+ { }
+
+ MachineState_T mLastState;
+ ComObjPtr<Progress> mProgress;
+
+ // used when deleting online snaphshot
+ void *mDeleteSnapshotInfo;
+ };
+
+ class SaveStateTask;
+ class SnapshotTask;
+ class TakeSnapshotTask;
+ class DeleteSnapshotTask;
+ class RestoreSnapshotTask;
+
+ void i_saveStateHandler(SaveStateTask &aTask);
+
+ // Override some functionality for SessionMachine, this is where the
+ // real action happens (the Machine methods are just dummies).
+ HRESULT saveState(ComPtr<IProgress> &aProgress);
+ HRESULT adoptSavedState(const com::Utf8Str &aSavedStateFile);
+ HRESULT discardSavedState(BOOL aFRemoveFile);
+ HRESULT takeSnapshot(const com::Utf8Str &aName,
+ const com::Utf8Str &aDescription,
+ BOOL aPause,
+ com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteSnapshot(const com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteSnapshotAndAllChildren(const com::Guid &aId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteSnapshotRange(const com::Guid &aStartId,
+ const com::Guid &aEndId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT restoreSnapshot(const ComPtr<ISnapshot> &aSnapshot,
+ ComPtr<IProgress> &aProgress);
+
+ void i_releaseSavedStateFile(const Utf8Str &strSavedStateFile, Snapshot *pSnapshotToIgnore);
+
+ void i_takeSnapshotHandler(TakeSnapshotTask &aTask);
+ static void i_takeSnapshotProgressCancelCallback(void *pvUser);
+ HRESULT i_finishTakingSnapshot(TakeSnapshotTask &aTask, AutoWriteLock &alock, bool aSuccess);
+ HRESULT i_deleteSnapshot(const com::Guid &aStartId,
+ const com::Guid &aEndId,
+ BOOL aDeleteAllChildren,
+ ComPtr<IProgress> &aProgress);
+ void i_deleteSnapshotHandler(DeleteSnapshotTask &aTask);
+ void i_restoreSnapshotHandler(RestoreSnapshotTask &aTask);
+
+ HRESULT i_prepareDeleteSnapshotMedium(const ComObjPtr<Medium> &aHD,
+ const Guid &machineId,
+ const Guid &snapshotId,
+ bool fOnlineMergePossible,
+ MediumLockList *aVMMALockList,
+ ComObjPtr<Medium> &aSource,
+ ComObjPtr<Medium> &aTarget,
+ bool &fMergeForward,
+ ComObjPtr<Medium> &pParentForTarget,
+ MediumLockList * &aChildrenToReparent,
+ bool &fNeedOnlineMerge,
+ MediumLockList * &aMediumLockList,
+ ComPtr<IToken> &aHDLockToken);
+ void i_cancelDeleteSnapshotMedium(const ComObjPtr<Medium> &aHD,
+ const ComObjPtr<Medium> &aSource,
+ MediumLockList *aChildrenToReparent,
+ bool fNeedsOnlineMerge,
+ MediumLockList *aMediumLockList,
+ const ComPtr<IToken> &aHDLockToken,
+ const Guid &aMediumId,
+ const Guid &aSnapshotId);
+ HRESULT i_onlineMergeMedium(const ComObjPtr<MediumAttachment> &aMediumAttachment,
+ const ComObjPtr<Medium> &aSource,
+ const ComObjPtr<Medium> &aTarget,
+ bool fMergeForward,
+ const ComObjPtr<Medium> &pParentForTarget,
+ MediumLockList *aChildrenToReparent,
+ MediumLockList *aMediumLockList,
+ ComObjPtr<Progress> &aProgress,
+ bool *pfNeedsMachineSaveSettings);
+
+ HRESULT i_setMachineState(MachineState_T aMachineState);
+ HRESULT i_updateMachineStateOnClient();
+
+ bool mRemoveSavedState;
+
+ ConsoleTaskData mConsoleTaskData;
+
+ /** client token for this machine */
+ ClientToken *mClientToken;
+
+ int miNATNetworksStarted;
+
+ AUTHLIBRARYCONTEXT mAuthLibCtx;
+};
+
+// SnapshotMachine class
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @note Notes on locking objects of this class:
+ * SnapshotMachine shares some data with the primary Machine instance (pointed
+ * to by the |mPeer| member). In order to provide data consistency it also
+ * shares its lock handle. This means that whenever you lock a SessionMachine
+ * instance using Auto[Reader]Lock or AutoMultiLock, the corresponding Machine
+ * instance is also locked in the same lock mode. Keep it in mind.
+ */
+class ATL_NO_VTABLE SnapshotMachine :
+ public Machine
+{
+public:
+ VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(SnapshotMachine, IMachine)
+
+ DECLARE_NOT_AGGREGATABLE(SnapshotMachine)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(SnapshotMachine)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+ COM_INTERFACE_ENTRY(IMachine)
+ COM_INTERFACE_ENTRY2(IDispatch, IMachine)
+ VBOX_TWEAK_INTERFACE_ENTRY(IMachine)
+ END_COM_MAP()
+
+ DECLARE_COMMON_CLASS_METHODS(SnapshotMachine)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(SessionMachine *aSessionMachine,
+ IN_GUID aSnapshotId,
+ const Utf8Str &aStateFilePath);
+ HRESULT initFromSettings(Machine *aMachine,
+ const settings::Hardware &hardware,
+ const settings::Debugging *pDbg,
+ const settings::Autostart *pAutostart,
+ const settings::RecordingSettings &recording,
+ IN_GUID aSnapshotId,
+ const Utf8Str &aStateFilePath);
+ void uninit();
+
+ // util::Lockable interface
+ RWLockHandle *lockHandle() const;
+
+ // public methods only for internal purposes
+
+ virtual bool i_isSnapshotMachine() const
+ {
+ return true;
+ }
+
+ HRESULT i_onSnapshotChange(Snapshot *aSnapshot);
+
+ // unsafe inline public methods for internal purposes only (ensure there is
+ // a caller and a read lock before calling them!)
+
+ const Guid& i_getSnapshotId() const { return mSnapshotId; }
+
+private:
+
+ Guid mSnapshotId;
+ /** This field replaces mPeer for SessionMachine instances, as having
+ * a peer reference is plain meaningless and causes many subtle problems
+ * with saving settings and the like. */
+ Machine * const mMachine;
+
+ friend class Snapshot;
+};
+
+// third party methods that depend on SnapshotMachine definition
+
+inline const Guid &Machine::i_getSnapshotId() const
+{
+ return (i_isSnapshotMachine())
+ ? static_cast<const SnapshotMachine*>(this)->i_getSnapshotId()
+ : Guid::Empty;
+}
+
+
+#endif /* !MAIN_INCLUDED_MachineImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MachineImplCloneVM.h b/src/VBox/Main/include/MachineImplCloneVM.h
new file mode 100644
index 00000000..9983911d
--- /dev/null
+++ b/src/VBox/Main/include/MachineImplCloneVM.h
@@ -0,0 +1,63 @@
+/* $Id: MachineImplCloneVM.h $ */
+/** @file
+ * Definition of MachineCloneVM
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MachineImplCloneVM_h
+#define MAIN_INCLUDED_MachineImplCloneVM_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MachineImpl.h"
+#include "ProgressImpl.h"
+
+/* Forward declaration of the d-pointer. */
+struct MachineCloneVMPrivate;
+
+class MachineCloneVM
+{
+public:
+ DECLARE_TRANSLATE_METHODS(MachineCloneVM)
+
+ MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts);
+ ~MachineCloneVM();
+
+ HRESULT start(IProgress **pProgress);
+
+protected:
+ HRESULT run();
+ void destroy();
+
+ /* d-pointer */
+ MachineCloneVM(MachineCloneVMPrivate &d);
+ MachineCloneVMPrivate *d_ptr;
+
+ friend struct MachineCloneVMPrivate;
+};
+
+#endif /* !MAIN_INCLUDED_MachineImplCloneVM_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/src/VBox/Main/include/MachineImplMoveVM.h b/src/VBox/Main/include/MachineImplMoveVM.h
new file mode 100644
index 00000000..f8e8eb8d
--- /dev/null
+++ b/src/VBox/Main/include/MachineImplMoveVM.h
@@ -0,0 +1,146 @@
+/* $Id: MachineImplMoveVM.h $ */
+/** @file
+ * Definition of MachineMoveVM
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MachineImplMoveVM_h
+#define MAIN_INCLUDED_MachineImplMoveVM_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MachineImpl.h"
+#include "ProgressImpl.h"
+#include "ThreadTask.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+enum VBoxFolder_t
+{
+ VBox_UnknownFolderType = 0,
+ VBox_OutsideVMfolder,
+ VBox_SettingFolder,
+ VBox_LogFolder,
+ VBox_StateFolder,
+ VBox_SnapshotFolder
+};
+
+typedef struct
+{
+ bool fSnapshot;
+ Utf8Str strBaseName;
+ ComPtr<IMedium> pMedium;
+ uint32_t uIdx;
+ ULONG uWeight;
+} MEDIUMTASKMOVE;
+
+typedef struct
+{
+ RTCList<MEDIUMTASKMOVE> chain;
+ DeviceType_T devType;
+ bool fCreateDiffs;
+ bool fAttachLinked;
+} MEDIUMTASKCHAINMOVE;
+
+typedef struct
+{
+ Guid snapshotUuid;
+ Utf8Str strFile;
+ ULONG uWeight;
+} SNAPFILETASKMOVE;
+
+struct fileList_t;
+
+class MachineMoveVM : public ThreadTask
+{
+ std::vector<ComObjPtr<Machine> > machineList;
+ RTCList<MEDIUMTASKCHAINMOVE> m_llMedia;
+ RTCList<SNAPFILETASKMOVE> m_llSaveStateFiles;
+ RTCList<SNAPFILETASKMOVE> m_llNVRAMFiles;
+ std::map<Utf8Str, MEDIUMTASKMOVE> m_finalMediaMap;
+ std::map<Utf8Str, SNAPFILETASKMOVE> m_finalSaveStateFilesMap;
+ std::map<Utf8Str, SNAPFILETASKMOVE> m_finalNVRAMFilesMap;
+ std::map<VBoxFolder_t, Utf8Str> m_vmFolders;
+
+ ComObjPtr<Machine> m_pMachine;
+ ComObjPtr<Progress> m_pProgress;
+ ComObjPtr<Progress> m_pRollBackProgress;
+ Utf8Str m_targetPath;
+ Utf8Str m_type;
+ HRESULT m_result;
+
+public:
+ DECLARE_TRANSLATE_METHODS(MachineMoveVM)
+
+ MachineMoveVM(ComObjPtr<Machine> aMachine,
+ const com::Utf8Str &aTargetPath,
+ const com::Utf8Str &aType,
+ ComObjPtr<Progress> &aProgress)
+ : ThreadTask("TaskMoveVM")
+ , m_pMachine(aMachine)
+ , m_pProgress(aProgress)
+ , m_targetPath(aTargetPath)
+ , m_type(aType.isEmpty() ? "basic" : aType)
+ , m_result(S_OK)
+ {
+ }
+
+ virtual ~MachineMoveVM()
+ {
+ }
+
+ HRESULT init();
+private:
+ static DECLCALLBACK(int) updateProgress(unsigned uPercent, void *pvUser);
+ static DECLCALLBACK(int) copyFileProgress(unsigned uPercentage, void *pvUser);
+ static void i_MoveVMThreadTask(MachineMoveVM *task);
+
+public:
+ void handler()
+ {
+ i_MoveVMThreadTask(this);
+ }
+
+private:
+ HRESULT createMachineList(const ComPtr<ISnapshot> &pSnapshot);
+ inline HRESULT queryBaseName(const ComPtr<IMedium> &pMedium, Utf8Str &strBaseName) const;
+ HRESULT queryMediaForAllStates();
+ void updateProgressStats(MEDIUMTASKCHAINMOVE &mtc, ULONG &uCount, ULONG &uTotalWeight) const;
+ HRESULT addSaveState(const ComObjPtr<Machine> &machine);
+ HRESULT addNVRAM(const ComObjPtr<Machine> &machine);
+ void printStateFile(settings::SnapshotsList &snl);
+ HRESULT getFilesList(const Utf8Str &strRootFolder, fileList_t &filesList);
+ HRESULT getFolderSize(const Utf8Str &strRootFolder, uint64_t &size);
+ HRESULT deleteFiles(const RTCList<Utf8Str> &listOfFiles);
+ void updatePathsToStateFiles(const Utf8Str &sourcePath, const Utf8Str &targetPath);
+ void updatePathsToNVRAMFiles(const Utf8Str &sourcePath, const Utf8Str &targetPath);
+ HRESULT moveAllDisks(const std::map<Utf8Str, MEDIUMTASKMOVE> &listOfDisks, const Utf8Str &strTargetFolder = Utf8Str::Empty);
+ HRESULT restoreAllDisks(const std::map<Utf8Str, MEDIUMTASKMOVE> &listOfDisks);
+ HRESULT isMediumTypeSupportedForMoving(const ComPtr<IMedium> &pMedium);
+};
+
+#endif /* !MAIN_INCLUDED_MachineImplMoveVM_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/src/VBox/Main/include/MachineLaunchVMCommonWorker.h b/src/VBox/Main/include/MachineLaunchVMCommonWorker.h
new file mode 100644
index 00000000..20b0a355
--- /dev/null
+++ b/src/VBox/Main/include/MachineLaunchVMCommonWorker.h
@@ -0,0 +1,49 @@
+/* $Id: MachineLaunchVMCommonWorker.h $ */
+/** @file
+ * VirtualBox Main - VM process launcher helper for VBoxSVC & VBoxSDS.
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MachineLaunchVMCommonWorker_h
+#define MAIN_INCLUDED_MachineLaunchVMCommonWorker_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <vector>
+#include "VirtualBoxBase.h"
+
+int MachineLaunchVMCommonWorker(const Utf8Str &aNameOrId,
+ const Utf8Str &aComment,
+ const Utf8Str &aFrontend,
+ const std::vector<com::Utf8Str> &aEnvironmentChanges,
+ const Utf8Str &aExtraArg,
+ const Utf8Str &aFilename,
+ uint32_t aFlags,
+ void *aExtraData,
+ RTPROCESS &aPid);
+
+#endif /* !MAIN_INCLUDED_MachineLaunchVMCommonWorker_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/src/VBox/Main/include/Makefile.kup b/src/VBox/Main/include/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Main/include/Makefile.kup
diff --git a/src/VBox/Main/include/Matching.h b/src/VBox/Main/include/Matching.h
new file mode 100644
index 00000000..ba5540ee
--- /dev/null
+++ b/src/VBox/Main/include/Matching.h
@@ -0,0 +1,540 @@
+/* $Id: Matching.h $ */
+/** @file
+ * Declaration of template classes that provide simple API to
+ * do matching between values and value filters constructed from strings.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_Matching_h
+#define MAIN_INCLUDED_Matching_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/string.h>
+
+#include <list>
+#include <limits>
+#include <algorithm>
+
+// min and max don't allow us to use numeric_limits::min() and max()
+#if defined (_MSC_VER)
+#undef min
+#undef max
+#endif
+
+namespace matching
+{
+
+using namespace std;
+using namespace com;
+
+class ParsedFilter_base
+{
+public:
+
+ ParsedFilter_base() : mValid (false), mNull (true), mErrorPosition (0) {};
+
+ /**
+ * Returns @c true if the filter is valid, @c false otherwise.
+ */
+ bool isValid() const { return mNull || mValid; }
+ bool isNull() const { return mNull; }
+
+ /**
+ * Returns the error position from the beginning of the filter
+ * string if #isValid() is false. Positions are zero-based.
+ */
+ size_t errorPosition() const { return mErrorPosition; }
+
+protected:
+
+ /**
+ * Returns @c true if current isNull() and isValid() values make further
+ * detailed matching meaningful, otherwise returns @c false.
+ * Must be called as a first method of every isMatch() implementation,
+ * so that isMatch() will immediately return @c false if isPreMatch() returns
+ * false.
+ */
+ bool isPreMatch() const
+ {
+ if (isNull() || !isValid())
+ return false;
+ return true;
+ }
+
+ bool mValid : 1;
+ bool mNull : 1;
+ size_t mErrorPosition;
+};
+
+class ParsedIntervalFilter_base : public ParsedFilter_base
+{
+public:
+ virtual ~ParsedIntervalFilter_base() { /* Make VC++ 14.2 happy */ }
+
+protected:
+
+ enum Mode { Single, Start, End };
+
+ union Widest
+ {
+ int64_t ll;
+ uint64_t ull;
+ };
+
+ struct Limits
+ {
+ Widest min;
+ Widest max;
+ };
+
+ ParsedIntervalFilter_base() {}
+
+ /**
+ * Called by #parse when a value token is encountered.
+ * This method can modify mNull, mValid and mErrorPosition when
+ * appropriate. Parsing stops if mValid is false after this method
+ * returns (mErrorPosition most point to the error position in this case).
+ */
+ virtual void parseValue (const char *aFilter, size_t aStart, size_t aEnd,
+ Mode aMode) = 0;
+
+ static void parse (const char *aFilter,
+ ParsedIntervalFilter_base *that);
+
+ static size_t parseValue (const char *aFilter, size_t aStart, size_t aEnd,
+ bool aIsSigned, const Limits &aLimits,
+ Widest &val);
+};
+
+/**
+ * Represents a parsed interval filter.
+ * The string format is:
+ * "int:(\<m\>|([\<m\>]-[\<n\>]))|(\<m\>|([\<m\>]-[\<n\>]))+"
+ * where \<m\> and \<n\> are numbers in the decimal, hex (0xNNN) or octal
+ * (0NNN) form, and \<m\> \< \<n\>. Spaces are allowed around \<m\> and \<n\>.
+ *
+ * @tparam T type of values to match. Must be a fundamental integer type.
+ */
+template <class T>
+class ParsedIntervalFilter : public ParsedIntervalFilter_base
+{
+ typedef ParsedIntervalFilter_base Base;
+ typedef numeric_limits <T> Lim;
+
+ typedef std::list <T> List;
+ typedef std::pair <T, T> Pair;
+ typedef std::list <Pair> PairList;
+
+public:
+
+ ParsedIntervalFilter() {}
+
+ ParsedIntervalFilter (const Bstr &aFilter) { Base::parse (Utf8Str (aFilter), this); }
+
+ ParsedIntervalFilter &operator= (const Bstr &aFilter)
+ {
+ mValues.clear();
+ mIntervals.clear();
+ Base::parse (Utf8Str (aFilter), this);
+ return *this;
+ }
+
+ bool isMatch (const T &aValue) const
+ {
+ if (!isPreMatch())
+ return false;
+
+ {
+ typename List::const_iterator it =
+ std::find (mValues.begin(), mValues.end(), aValue);
+ if (it != mValues.end())
+ return true;
+ }
+
+ for (typename PairList::const_iterator it = mIntervals.begin();
+ it != mIntervals.end(); ++ it)
+ {
+ if ((*it).first <= aValue &&
+ aValue <= (*it).second)
+ return true;
+ }
+
+ return false;
+ }
+
+protected:
+
+ struct Limits : public Base::Limits
+ {
+ Limits()
+ {
+ if (Lim::is_signed)
+ {
+ min.ll = (int64_t) Lim::min();
+ max.ll = (int64_t) Lim::max();
+ }
+ else
+ {
+ min.ull = (uint64_t) Lim::min();
+ max.ull = (uint64_t) Lim::max();
+ }
+ }
+
+ static T toValue (const Widest &aWidest)
+ {
+ if (Lim::is_signed)
+ return (T) aWidest.ll;
+ else
+ return (T) aWidest.ull;
+ }
+ };
+
+ virtual void parseValue (const char *aFilter, size_t aStart, size_t aEnd,
+ Mode aMode)
+ {
+ AssertReturn (Lim::is_integer, (void) 0);
+ AssertReturn (
+ (Lim::is_signed && Lim::digits <= numeric_limits <int64_t>::digits) ||
+ (!Lim::is_signed && Lim::digits <= numeric_limits <uint64_t>::digits),
+ (void) 0);
+
+ Limits limits;
+ Widest val;
+ size_t parsed = aEnd;
+
+ if (aStart != aEnd)
+ parsed = Base::parseValue (aFilter, aStart, aEnd,
+ Lim::is_signed, limits, val);
+
+ if (parsed != aEnd)
+ {
+ mValid = false;
+ mErrorPosition = parsed;
+ return;
+ }
+
+ switch (aMode)
+ {
+ /// @todo (dmik): future optimizations:
+ // 1) join intervals when they overlap
+ // 2) ignore single values that are within any existing interval
+ case Base::Single:
+ {
+ if (aStart == aEnd)
+ {
+ // an empty string (contains only spaces after "int:")
+ mValid = false;
+ mErrorPosition = aEnd;
+ AssertReturn (!mValues.size() && !mIntervals.size(), (void) 0);
+ break;
+ }
+ mValues.push_back (limits.toValue (val));
+ break;
+ }
+ case Base::Start:
+ {
+ // aStart == aEnd means smth. like "-[NNN]"
+ T m = aStart == aEnd ? limits.toValue (limits.min)
+ : limits.toValue (val);
+ mIntervals.push_back (Pair (m, m));
+ break;
+ }
+ case Base::End:
+ {
+ // aStart == aEnd means smth. like "[NNN]-"
+ T n = aStart == aEnd ? limits.toValue (limits.max)
+ : limits.toValue (val);
+ if (n < mIntervals.back().first)
+ {
+ // error at the beginning of N
+ mValid = false;
+ mErrorPosition = aStart;
+ break;
+ }
+ mIntervals.back().second = n;
+ break;
+ }
+ }
+ }
+
+ std::list <T> mValues;
+ std::list <std::pair <T, T> > mIntervals;
+};
+
+/**
+ * Represents a boolean filter.
+ * The string format is: "true|false|yes|no|1|0" or an empty string (any match).
+ */
+
+class ParsedBoolFilter : public ParsedFilter_base
+{
+public:
+
+ ParsedBoolFilter() : mValue (false), mValueAny (false) {}
+
+ ParsedBoolFilter (const Bstr &aFilter) { parse (aFilter); }
+
+ ParsedBoolFilter &operator= (const Bstr &aFilter)
+ {
+ parse (aFilter);
+ return *this;
+ }
+
+ bool isMatch (const bool aValue) const
+ {
+ if (!isPreMatch())
+ return false;
+
+ return mValueAny || mValue == aValue;
+ }
+
+ bool isMatch (const BOOL aValue) const
+ {
+ return isMatch (bool (aValue == TRUE));
+ }
+
+private:
+
+ void parse (const Bstr &aFilter);
+
+ bool mValue : 1;
+ bool mValueAny : 1;
+};
+
+class ParsedRegexpFilter_base : public ParsedFilter_base
+{
+protected:
+
+ ParsedRegexpFilter_base (bool aDefIgnoreCase = false,
+ size_t aMinLen = 0, size_t aMaxLen = 0)
+ : mIgnoreCase (aDefIgnoreCase)
+ , mMinLen (aMinLen)
+ , mMaxLen (aMaxLen)
+ {}
+
+ ParsedRegexpFilter_base (const Bstr &aFilter, bool aDefIgnoreCase = false,
+ size_t aMinLen = 0, size_t aMaxLen = 0)
+ : mIgnoreCase (aDefIgnoreCase)
+ , mMinLen (aMinLen)
+ , mMaxLen (aMaxLen)
+ {
+ parse (aFilter);
+ }
+
+ ParsedRegexpFilter_base &operator= (const Bstr &aFilter)
+ {
+ parse (aFilter);
+ return *this;
+ }
+
+ bool isMatch (const Bstr &aValue) const;
+
+private:
+
+ void parse (const Bstr &aFilter);
+
+ bool mIgnoreCase : 1;
+
+ size_t mMinLen;
+ size_t mMaxLen;
+
+ Bstr mSimple;
+};
+
+/**
+ * Represents a parsed regexp filter.
+ *
+ * The string format is: "rx:\<regexp\>" or "\<string\>"
+ * where \<regexp\> is a valid regexp and \<string\> is the exact match.
+ *
+ * @tparam Conv
+ * class that must define a public static function
+ * <tt>Bstr toBstr (T aValue)</tt>, where T is the
+ * type of values that should be accepted by #isMatch().
+ * This function is used to get the string representation of T
+ * for regexp matching.
+ * @tparam aIgnoreCase
+ * true if the case insensitive comparison should be done by default
+ * and false otherwise
+ * @tparam aMinLen
+ * minimum string length, or 0 if not limited.
+ * Used only when the filter string represents the exact match.
+ * @tparam aMaxLen
+ * maximum string length, or 0 if not limited.
+ * Used only when the filter string represents the exact match.
+ */
+template <class Conv, bool aIgnoreCase, size_t aMinLen = 0, size_t aMaxLen = 0>
+class ParsedRegexpFilter : public ParsedRegexpFilter_base
+{
+public:
+
+ enum { IgnoreCase = aIgnoreCase, MinLen = aMinLen, MaxLen = aMaxLen };
+
+ ParsedRegexpFilter() : ParsedRegexpFilter_base (IgnoreCase, MinLen, MaxLen) {}
+
+ ParsedRegexpFilter (const Bstr &aFilter)
+ : ParsedRegexpFilter_base (aFilter, IgnoreCase, MinLen, MaxLen) {}
+
+ ParsedRegexpFilter &operator= (const Bstr &aFilter)
+ {
+ ParsedRegexpFilter_base::operator= (aFilter);
+ return *this;
+ }
+
+ template <class T>
+ bool isMatch (const T &aValue) const
+ {
+ if (!this->isPreMatch())
+ return false;
+
+ return ParsedRegexpFilter_base::isMatch (Conv::toBstr (aValue));
+ }
+
+protected:
+};
+
+/**
+ * Joins two filters into one.
+ * Only one filter is active (i.e. used for matching or for error reporting)
+ * at any given time. The active filter is chosen every time when a new
+ * filter string is assigned to an instance of this class -- the filter
+ * for which isNull() = false after parsing the string becomes the active
+ * one (F1 is tried first).
+ *
+ * Both filters must have <tt>bool isMatch(const T&)</tt> methods where T is
+ * the same type as used in #isMatch().
+ *
+ * @tparam F1 first filter class
+ * @tparam F2 second filter class
+ */
+template <class F1, class F2>
+class TwoParsedFilters
+{
+public:
+
+ TwoParsedFilters() {}
+
+ TwoParsedFilters (const Bstr &aFilter)
+ {
+ mFilter1 = aFilter;
+ if (mFilter1.isNull())
+ mFilter2 = aFilter;
+ }
+
+ TwoParsedFilters &operator= (const Bstr &aFilter)
+ {
+ mFilter1 = aFilter;
+ if (mFilter1.isNull())
+ mFilter2 = aFilter;
+ else
+ mFilter2 = F2(); // reset to null
+ return *this;
+ }
+
+ template <class T>
+ bool isMatch (const T &aValue) const
+ {
+ return mFilter1.isMatch (aValue) || mFilter2.isMatch (aValue);
+ }
+
+ bool isValid() const { return isNull() || (mFilter1.isValid() && mFilter2.isValid()); }
+
+ bool isNull() const { return mFilter1.isNull() && mFilter2.isNull(); }
+
+ size_t errorPosition() const
+ {
+ return !mFilter1.isValid() ? mFilter1.errorPosition() :
+ !mFilter2.isValid() ? mFilter2.errorPosition() : 0;
+ }
+
+ const F1 &first() const { return mFilter1; }
+ const F2 &second() const { return mFilter2; }
+
+private:
+
+ F1 mFilter1;
+ F2 mFilter2;
+};
+
+/**
+ * Inherits from the given parsed filter class and keeps the string used to
+ * construct the filter as a member.
+ *
+ * @tparam F parsed filter class
+ */
+template <class F>
+class Matchable : public F
+{
+public:
+
+ Matchable() {}
+
+ /**
+ * Creates a new parsed filter from the given filter string.
+ * If the string format is invalid, #isValid() will return false.
+ */
+ Matchable (const Bstr &aString)
+ : F (aString), mString (aString) {}
+
+ Matchable (CBSTR aString)
+ : F (Bstr (aString)), mString (aString) {}
+
+ /**
+ * Assigns a new filter string to this object and recreates the parser.
+ * If the string format is invalid, #isValid() will return false.
+ */
+ Matchable &operator= (const Bstr &aString)
+ {
+ F::operator= (aString);
+ mString = aString;
+ return *this;
+ }
+
+ Matchable &operator= (CBSTR aString)
+ {
+ F::operator= (Bstr (aString));
+ mString = aString;
+ return *this;
+ }
+
+ /**
+ * Returns the filter string allowing to use the instance where
+ * Str can be used.
+ */
+ operator const Bstr&() const { return mString; }
+
+ /** Returns the filter string */
+ const Bstr& string() const { return mString; }
+
+private:
+
+ Bstr mString;
+};
+
+} /* namespace matching */
+
+#endif /* !MAIN_INCLUDED_Matching_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MediumAttachmentImpl.h b/src/VBox/Main/include/MediumAttachmentImpl.h
new file mode 100644
index 00000000..b3568aa7
--- /dev/null
+++ b/src/VBox/Main/include/MediumAttachmentImpl.h
@@ -0,0 +1,146 @@
+/* $Id: MediumAttachmentImpl.h $ */
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MediumAttachmentImpl_h
+#define MAIN_INCLUDED_MediumAttachmentImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MediumAttachmentWrap.h"
+
+class ATL_NO_VTABLE MediumAttachment :
+ public MediumAttachmentWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(MediumAttachment)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent,
+ Medium *aMedium,
+ const Utf8Str &aControllerName,
+ LONG aPort,
+ LONG aDevice,
+ DeviceType_T aType,
+ bool aImplicit,
+ bool aPassthrough,
+ bool aTempEject,
+ bool aNonRotational,
+ bool aDiscard,
+ bool aHotPluggable,
+ const Utf8Str &strBandwidthGroup);
+ HRESULT initCopy(Machine *aParent, MediumAttachment *aThat);
+ void uninit();
+
+ // public internal methods
+ void i_rollback();
+ void i_commit();
+
+ // unsafe public methods for internal purposes only (ensure there is
+ // a caller and a read lock before calling them!)
+ bool i_isImplicit() const;
+ void i_setImplicit(bool aImplicit);
+
+ const ComObjPtr<Medium>& i_getMedium() const;
+ const Utf8Str &i_getControllerName() const;
+ LONG i_getPort() const;
+ LONG i_getDevice() const;
+ DeviceType_T i_getType() const;
+ bool i_getPassthrough() const;
+ bool i_getTempEject() const;
+ bool i_getNonRotational() const;
+ bool i_getDiscard() const;
+ Utf8Str& i_getBandwidthGroup() const;
+ bool i_getHotPluggable() const;
+
+ bool i_matches(const Utf8Str &aControllerName, LONG aPort, LONG aDevice);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateName(const Utf8Str &aName);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateMedium(const ComObjPtr<Medium> &aMedium);
+
+ /** Must be called from under this object's write lock. */
+ void i_updatePassthrough(bool aPassthrough);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateTempEject(bool aTempEject);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateNonRotational(bool aNonRotational);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateDiscard(bool aDiscard);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateEjected();
+
+ /** Must be called from under this object's write lock. */
+ void i_updateBandwidthGroup(const Utf8Str &aBandwidthGroup);
+
+ void i_updateParentMachine(Machine * const pMachine);
+
+ /** Must be called from under this object's write lock. */
+ void i_updateHotPluggable(bool aHotPluggable);
+
+ /** Construct a unique and somewhat descriptive name for logging. */
+ void i_updateLogName(void);
+
+ /** Get a unique and somewhat descriptive name for logging. */
+ const char *i_getLogName(void) const { return mLogName.c_str(); }
+
+private:
+
+ // Wrapped IMediumAttachment properties
+ HRESULT getMachine(ComPtr<IMachine> &aMachine);
+ HRESULT getMedium(ComPtr<IMedium> &aHardDisk);
+ HRESULT getController(com::Utf8Str &aController);
+ HRESULT getPort(LONG *aPort);
+ HRESULT getDevice(LONG *aDevice);
+ HRESULT getType(DeviceType_T *aType);
+ HRESULT getPassthrough(BOOL *aPassthrough);
+ HRESULT getTemporaryEject(BOOL *aTemporaryEject);
+ HRESULT getIsEjected(BOOL *aEjected);
+ HRESULT getDiscard(BOOL *aDiscard);
+ HRESULT getNonRotational(BOOL *aNonRotational);
+ HRESULT getBandwidthGroup(ComPtr<IBandwidthGroup> &aBandwidthGroup);
+ HRESULT getHotPluggable(BOOL *aHotPluggable);
+
+ struct Data;
+ Data *m;
+
+ Utf8Str mLogName; /**< For logging purposes */
+};
+
+#endif /* !MAIN_INCLUDED_MediumAttachmentImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MediumFormatImpl.h b/src/VBox/Main/include/MediumFormatImpl.h
new file mode 100644
index 00000000..625583c4
--- /dev/null
+++ b/src/VBox/Main/include/MediumFormatImpl.h
@@ -0,0 +1,125 @@
+/* $Id: MediumFormatImpl.h $ */
+/** @file
+ * MediumFormat COM class implementation
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MediumFormatImpl_h
+#define MAIN_INCLUDED_MediumFormatImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MediumFormatWrap.h"
+
+
+struct VDBACKENDINFO;
+
+/**
+ * The MediumFormat class represents the backend used to store medium data
+ * (IMediumFormat interface).
+ *
+ * @note Instances of this class are permanently caller-referenced by Medium
+ * objects (through addCaller()) so that an attempt to uninitialize or delete
+ * them before all Medium objects are uninitialized will produce an endless
+ * wait!
+ */
+class ATL_NO_VTABLE MediumFormat :
+ public MediumFormatWrap
+{
+public:
+
+ struct Property
+ {
+ Utf8Str strName;
+ Utf8Str strDescription;
+ DataType_T type;
+ ULONG flags;
+ Utf8Str strDefaultValue;
+ };
+
+ typedef std::vector<Property> PropertyArray;
+ typedef std::vector<com::Utf8Str> StrArray;
+
+ DECLARE_COMMON_CLASS_METHODS(MediumFormat)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(const VDBACKENDINFO *aVDInfo);
+ void uninit();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+
+ /** Const, no need to lock */
+ const Utf8Str &i_getId() const { return m.strId; }
+ /** Const, no need to lock */
+ const Utf8Str &i_getName() const { return m.strName; }
+ /** Const, no need to lock */
+ const StrArray &i_getFileExtensions() const { return m.maFileExtensions; }
+ /** Const, no need to lock */
+ MediumFormatCapabilities_T i_getCapabilities() const { return m.capabilities; }
+ /** Const, no need to lock */
+ const PropertyArray &i_getProperties() const { return m.maProperties; }
+
+private:
+
+ // wrapped IMediumFormat properties
+ HRESULT getId(com::Utf8Str &aId);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getCapabilities(std::vector<MediumFormatCapabilities_T> &aCapabilities);
+
+ // wrapped IMediumFormat methods
+ HRESULT describeFileExtensions(std::vector<com::Utf8Str> &aExtensions,
+ std::vector<DeviceType_T> &aTypes);
+ HRESULT describeProperties(std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aDescriptions,
+ std::vector<DataType_T> &aTypes,
+ std::vector<ULONG> &aFlags,
+ std::vector<com::Utf8Str> &aDefaults);
+
+ // types
+ typedef std::vector<DeviceType_T> DeviceTypeArray;
+
+ // data
+ struct Data
+ {
+ Data() : capabilities((MediumFormatCapabilities_T)0) {}
+
+ const Utf8Str strId;
+ const Utf8Str strName;
+ const StrArray maFileExtensions;
+ const DeviceTypeArray maDeviceTypes;
+ const MediumFormatCapabilities_T capabilities;
+ const PropertyArray maProperties;
+ };
+
+ Data m;
+};
+
+#endif /* !MAIN_INCLUDED_MediumFormatImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MediumIOImpl.h b/src/VBox/Main/include/MediumIOImpl.h
new file mode 100644
index 00000000..c6e13976
--- /dev/null
+++ b/src/VBox/Main/include/MediumIOImpl.h
@@ -0,0 +1,92 @@
+/* $Id: MediumIOImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation - MediumIO.
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MediumIOImpl_h
+#define MAIN_INCLUDED_MediumIOImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MediumIOWrap.h"
+#include "VirtualBoxBase.h"
+#include "AutoCaller.h"
+
+class ATL_NO_VTABLE MediumIO :
+ public MediumIOWrap
+{
+public:
+ /** @name Dummy/standard constructors and destructors.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(MediumIO)
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ /** @} */
+
+ /** @name Initializer & uninitializer.
+ * @{ */
+ HRESULT initForMedium(Medium *pMedium, VirtualBox *pVirtualBox, bool fWritable,
+ com::Utf8Str const &rStrKeyId, com::Utf8Str const &rStrPassword);
+ void uninit();
+ /** @} */
+
+private:
+ /** @name Wrapped IMediumIO properties
+ * @{ */
+ HRESULT getMedium(ComPtr<IMedium> &a_rPtrMedium);
+ HRESULT getWritable(BOOL *a_fWritable);
+ HRESULT getExplorer(ComPtr<IVFSExplorer> &a_rPtrExplorer);
+ /** @} */
+
+ /** @name Wrapped IMediumIO methods
+ * @{ */
+ HRESULT read(LONG64 a_off, ULONG a_cbRead, std::vector<BYTE> &a_rData);
+ HRESULT write(LONG64 a_off, const std::vector<BYTE> &a_rData, ULONG *a_pcbWritten);
+ HRESULT formatFAT(BOOL a_fQuick);
+ HRESULT initializePartitionTable(PartitionTableType_T a_enmFormat, BOOL a_fWholeDiskInOneEntry);
+ HRESULT convertToStream(const com::Utf8Str &aFormat,
+ const std::vector<MediumVariant_T> &aVariant,
+ ULONG aBufferSize,
+ ComPtr<IDataStream> &aStream,
+ ComPtr<IProgress> &aProgress);
+ HRESULT close();
+ /** @} */
+
+ /** @name Internal workers.
+ * @{ */
+ void i_close();
+ /** @} */
+
+ struct Data;
+ Data *m;
+
+ class StreamTask;
+ friend class StreamTask;
+};
+
+#endif /* !MAIN_INCLUDED_MediumIOImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/src/VBox/Main/include/MediumImpl.h b/src/VBox/Main/include/MediumImpl.h
new file mode 100644
index 00000000..d0292141
--- /dev/null
+++ b/src/VBox/Main/include/MediumImpl.h
@@ -0,0 +1,474 @@
+/* $Id: MediumImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MediumImpl_h
+#define MAIN_INCLUDED_MediumImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/vd.h>
+#include "MediumWrap.h"
+#include "VirtualBoxBase.h"
+#include "AutoCaller.h"
+#include "SecretKeyStore.h"
+class Progress;
+class MediumFormat;
+class MediumLockList;
+struct MediumCryptoFilterSettings;
+
+namespace settings
+{
+ struct Medium;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Medium component class for all media types.
+ */
+class ATL_NO_VTABLE Medium :
+ public MediumWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(Medium)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ enum HDDOpenMode { OpenReadWrite, OpenReadOnly };
+ // have to use a special enum for the overloaded init() below;
+ // can't use AccessMode_T from XIDL because that's mapped to an int
+ // and would be ambiguous
+
+ // public initializer/uninitializer for internal purposes only
+
+ // initializer to create empty medium (VirtualBox::CreateMedium())
+ HRESULT init(VirtualBox *aVirtualBox,
+ const Utf8Str &aFormat,
+ const Utf8Str &aLocation,
+ const Guid &uuidMachineRegistry,
+ const DeviceType_T aDeviceType);
+
+ // initializer for opening existing media
+ // (VirtualBox::OpenMedium(); Machine::AttachDevice())
+ HRESULT init(VirtualBox *aVirtualBox,
+ const Utf8Str &aLocation,
+ HDDOpenMode enOpenMode,
+ bool fForceNewUuid,
+ DeviceType_T aDeviceType);
+
+ // initializer used when loading settings
+ HRESULT initOne(Medium *aParent,
+ DeviceType_T aDeviceType,
+ const Guid &uuidMachineRegistry,
+ const Utf8Str &strMachineFolder,
+ const settings::Medium &data);
+ static HRESULT initFromSettings(VirtualBox *aVirtualBox,
+ DeviceType_T aDeviceType,
+ const Guid &uuidMachineRegistry,
+ const Utf8Str &strMachineFolder,
+ const settings::Medium &data,
+ AutoWriteLock &mediaTreeLock,
+ std::list<std::pair<Guid, DeviceType_T> > &uIdsForNotify);
+
+ // initializer for host floppy/DVD
+ HRESULT init(VirtualBox *aVirtualBox,
+ DeviceType_T aDeviceType,
+ const Utf8Str &aLocation,
+ const Utf8Str &aDescription = Utf8Str::Empty);
+
+ void uninit();
+
+ void i_deparent();
+ void i_setParent(const ComObjPtr<Medium> &pParent);
+
+ // unsafe methods for internal purposes only (ensure there is
+ // a caller and a read lock before calling them!)
+ const ComObjPtr<Medium>& i_getParent() const;
+ const MediaList& i_getChildren() const;
+
+ const Guid& i_getId() const;
+ MediumState_T i_getState() const;
+ MediumVariant_T i_getVariant() const;
+ bool i_isHostDrive() const;
+ bool i_isClosing() const;
+ const Utf8Str& i_getLocationFull() const;
+ const Utf8Str& i_getFormat() const;
+ const ComObjPtr<MediumFormat> & i_getMediumFormat() const;
+ bool i_isMediumFormatFile() const;
+ uint64_t i_getSize() const;
+ uint64_t i_getLogicalSize() const;
+ DeviceType_T i_getDeviceType() const;
+ MediumType_T i_getType() const;
+ Utf8Str i_getName();
+
+ /* handles caller/locking itself */
+ bool i_addRegistry(const Guid &id);
+ bool i_addRegistryNoCallerCheck(const Guid &id);
+ /* handles caller/locking itself, caller is responsible for tree lock */
+ bool i_addRegistryAll(const Guid &id);
+ /* handles caller/locking itself */
+ bool i_removeRegistry(const Guid& id);
+ /* handles caller/locking itself, caller is responsible for tree lock */
+ bool i_removeRegistryAll(const Guid& id);
+ bool i_isInRegistry(const Guid& id);
+ bool i_getFirstRegistryMachineId(Guid &uuid) const;
+ void i_markRegistriesModified();
+
+ HRESULT i_setPropertyDirect(const Utf8Str &aName, const Utf8Str &aValue);
+
+ HRESULT i_addBackReference(const Guid &aMachineId,
+ const Guid &aSnapshotId = Guid::Empty);
+ HRESULT i_removeBackReference(const Guid &aMachineId,
+ const Guid &aSnapshotId = Guid::Empty);
+
+
+ const Guid* i_getFirstMachineBackrefId() const;
+ const Guid* i_getAnyMachineBackref(const Guid &aId) const;
+ const Guid* i_getFirstMachineBackrefSnapshotId() const;
+ size_t i_getMachineBackRefCount() const;
+
+#ifdef DEBUG
+ void i_dumpBackRefs();
+#endif
+
+ HRESULT i_updatePath(const Utf8Str &strOldPath, const Utf8Str &strNewPath);
+
+ /* handles caller/locking itself */
+ ComObjPtr<Medium> i_getBase(uint32_t *aLevel = NULL);
+ /* handles caller/locking itself */
+ uint32_t i_getDepth();
+
+ bool i_isReadOnly();
+ void i_updateId(const Guid &id);
+
+ void i_saveSettingsOne(settings::Medium &data,
+ const Utf8Str &strHardDiskFolder);
+ HRESULT i_saveSettings(settings::Medium &data,
+ const Utf8Str &strHardDiskFolder);
+
+ HRESULT i_createMediumLockList(bool fFailIfInaccessible,
+ Medium *pToLock,
+ bool fMediumLockWriteAll,
+ Medium *pToBeParent,
+ MediumLockList &mediumLockList);
+
+ HRESULT i_createDiffStorage(ComObjPtr<Medium> &aTarget,
+ MediumVariant_T aVariant,
+ MediumLockList *pMediumLockList,
+ ComObjPtr<Progress> *aProgress,
+ bool aWait,
+ bool aNotify);
+ Utf8Str i_getPreferredDiffFormat();
+ MediumVariant_T i_getPreferredDiffVariant();
+
+ HRESULT i_close(AutoCaller &autoCaller);
+ HRESULT i_unlockRead(MediumState_T *aState);
+ HRESULT i_unlockWrite(MediumState_T *aState);
+ HRESULT i_deleteStorage(ComObjPtr<Progress> *aProgress, bool aWait, bool aNotify);
+ HRESULT i_markForDeletion();
+ HRESULT i_unmarkForDeletion();
+ HRESULT i_markLockedForDeletion();
+ HRESULT i_unmarkLockedForDeletion();
+
+ HRESULT i_queryPreferredMergeDirection(const ComObjPtr<Medium> &pOther,
+ bool &fMergeForward);
+
+ HRESULT i_prepareMergeTo(const ComObjPtr<Medium> &pTarget,
+ const Guid *aMachineId,
+ const Guid *aSnapshotId,
+ bool fLockMedia,
+ bool &fMergeForward,
+ ComObjPtr<Medium> &pParentForTarget,
+ MediumLockList * &aChildrenToReparent,
+ MediumLockList * &aMediumLockList);
+ HRESULT i_mergeTo(const ComObjPtr<Medium> &pTarget,
+ bool fMergeForward,
+ const ComObjPtr<Medium> &pParentForTarget,
+ MediumLockList *aChildrenToReparent,
+ MediumLockList *aMediumLockList,
+ ComObjPtr<Progress> *aProgress,
+ bool aWait,
+ bool aNotify);
+ void i_cancelMergeTo(MediumLockList *aChildrenToReparent,
+ MediumLockList *aMediumLockList);
+
+ HRESULT i_resize(uint64_t aLogicalSize,
+ MediumLockList *aMediumLockList,
+ ComObjPtr<Progress> *aProgress,
+ bool aWait,
+ bool aNotify);
+
+ HRESULT i_fixParentUuidOfChildren(MediumLockList *pChildrenToReparent);
+
+ HRESULT i_addRawToFss(const char *aFilename, SecretKeyStore *pKeyStore, RTVFSFSSTREAM hVfsFssDst,
+ const ComObjPtr<Progress> &aProgress, bool fSparse);
+
+ HRESULT i_exportFile(const char *aFilename,
+ const ComObjPtr<MediumFormat> &aFormat,
+ MediumVariant_T aVariant,
+ SecretKeyStore *pKeyStore,
+ RTVFSIOSTREAM hVfsIosDst,
+ const ComObjPtr<Progress> &aProgress);
+ HRESULT i_importFile(const char *aFilename,
+ const ComObjPtr<MediumFormat> &aFormat,
+ MediumVariant_T aVariant,
+ RTVFSIOSTREAM hVfsIosSrc,
+ const ComObjPtr<Medium> &aParent,
+ const ComObjPtr<Progress> &aProgress,
+ bool aNotify);
+
+ HRESULT i_cloneToEx(const ComObjPtr<Medium> &aTarget, MediumVariant_T aVariant,
+ const ComObjPtr<Medium> &aParent, IProgress **aProgress,
+ uint32_t idxSrcImageSame, uint32_t idxDstImageSame, bool aNotify);
+
+ const Utf8Str& i_getKeyId();
+
+ HRESULT i_openForIO(bool fWritable, SecretKeyStore *pKeyStore, PVDISK *ppHdd, MediumLockList *pMediumLockList,
+ struct MediumCryptoFilterSettings *pCryptoSettings);
+
+private:
+
+ // wrapped IMedium properties
+ HRESULT getId(com::Guid &aId);
+ HRESULT getDescription(AutoCaller &autoCaller, com::Utf8Str &aDescription);
+ HRESULT setDescription(AutoCaller &autoCaller, const com::Utf8Str &aDescription);
+ HRESULT getState(MediumState_T *aState);
+ HRESULT getVariant(std::vector<MediumVariant_T> &aVariant);
+ HRESULT getLocation(com::Utf8Str &aLocation);
+ HRESULT setLocation(const com::Utf8Str &aLocation);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getDeviceType(DeviceType_T *aDeviceType);
+ HRESULT getHostDrive(BOOL *aHostDrive);
+ HRESULT getSize(LONG64 *aSize);
+ HRESULT getFormat(com::Utf8Str &aFormat);
+ HRESULT getMediumFormat(ComPtr<IMediumFormat> &aMediumFormat);
+ HRESULT getType(AutoCaller &autoCaller, MediumType_T *aType);
+ HRESULT setType(AutoCaller &autoCaller, MediumType_T aType);
+ HRESULT getAllowedTypes(std::vector<MediumType_T> &aAllowedTypes);
+ HRESULT getParent(AutoCaller &autoCaller, ComPtr<IMedium> &aParent);
+ HRESULT getChildren(AutoCaller &autoCaller, std::vector<ComPtr<IMedium> > &aChildren);
+ HRESULT getBase(AutoCaller &autoCaller, ComPtr<IMedium> &aBase);
+ HRESULT getReadOnly(AutoCaller &autoCaller, BOOL *aReadOnly);
+ HRESULT getLogicalSize(LONG64 *aLogicalSize);
+ HRESULT getAutoReset(BOOL *aAutoReset);
+ HRESULT setAutoReset(BOOL aAutoReset);
+ HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
+ HRESULT getMachineIds(std::vector<com::Guid> &aMachineIds);
+
+ // wrapped IMedium methods
+ HRESULT setIds(AutoCaller &aAutoCaller,
+ BOOL aSetImageId,
+ const com::Guid &aImageId,
+ BOOL aSetParentId,
+ const com::Guid &aParentId);
+ HRESULT refreshState(AutoCaller &aAutoCaller,
+ MediumState_T *aState);
+ HRESULT getSnapshotIds(const com::Guid &aMachineId,
+ std::vector<com::Guid> &aSnapshotIds);
+ HRESULT lockRead(ComPtr<IToken> &aToken);
+ HRESULT lockWrite(ComPtr<IToken> &aToken);
+ HRESULT close(AutoCaller &aAutoCaller);
+ HRESULT getProperty(const com::Utf8Str &aName,
+ com::Utf8Str &aValue);
+ HRESULT setProperty(const com::Utf8Str &aName,
+ const com::Utf8Str &aValue);
+ HRESULT getProperties(const com::Utf8Str &aNames,
+ std::vector<com::Utf8Str> &aReturnNames,
+ std::vector<com::Utf8Str> &aReturnValues);
+ HRESULT setProperties(const std::vector<com::Utf8Str> &aNames,
+ const std::vector<com::Utf8Str> &aValues);
+ HRESULT createBaseStorage(LONG64 aLogicalSize,
+ const std::vector<MediumVariant_T> &aVariant,
+ ComPtr<IProgress> &aProgress);
+ HRESULT deleteStorage(ComPtr<IProgress> &aProgress);
+ HRESULT createDiffStorage(AutoCaller &autoCaller,
+ const ComPtr<IMedium> &aTarget,
+ const std::vector<MediumVariant_T> &aVariant,
+ ComPtr<IProgress> &aProgress);
+ HRESULT mergeTo(const ComPtr<IMedium> &aTarget,
+ ComPtr<IProgress> &aProgress);
+ HRESULT cloneTo(const ComPtr<IMedium> &aTarget,
+ const std::vector<MediumVariant_T> &aVariant,
+ const ComPtr<IMedium> &aParent,
+ ComPtr<IProgress> &aProgress);
+ HRESULT resizeAndCloneTo(const ComPtr<IMedium> &aTarget,
+ LONG64 aLogicalSize,
+ const std::vector<MediumVariant_T> &aVariant,
+ const ComPtr<IMedium> &aParent,
+ ComPtr<IProgress> &aProgress);
+ HRESULT cloneToBase(const ComPtr<IMedium> &aTarget,
+ const std::vector<MediumVariant_T> &aVariant,
+ ComPtr<IProgress> &aProgress);
+ HRESULT moveTo(AutoCaller &autoCaller,
+ const com::Utf8Str &aLocation,
+ ComPtr<IProgress> &aProgress);
+ HRESULT compact(ComPtr<IProgress> &aProgress);
+ HRESULT resize(LONG64 aLogicalSize,
+ ComPtr<IProgress> &aProgress);
+ HRESULT reset(AutoCaller &autoCaller, ComPtr<IProgress> &aProgress);
+ HRESULT changeEncryption(const com::Utf8Str &aCurrentPassword, const com::Utf8Str &aCipher,
+ const com::Utf8Str &aNewPassword, const com::Utf8Str &aNewPasswordId,
+ ComPtr<IProgress> &aProgress);
+ HRESULT getEncryptionSettings(AutoCaller &autoCaller, com::Utf8Str &aCipher, com::Utf8Str &aPasswordId);
+ HRESULT checkEncryptionPassword(const com::Utf8Str &aPassword);
+ HRESULT openForIO(BOOL aWritable, com::Utf8Str const &aPassword, ComPtr<IMediumIO> &aMediumIO);
+
+ // Private internal nmethods
+ HRESULT i_queryInfo(bool fSetImageId, bool fSetParentId, AutoCaller &autoCaller);
+ HRESULT i_canClose();
+ HRESULT i_unregisterWithVirtualBox();
+ HRESULT i_setStateError();
+ HRESULT i_setLocation(const Utf8Str &aLocation, const Utf8Str &aFormat = Utf8Str::Empty);
+ HRESULT i_setFormat(const Utf8Str &aFormat);
+ VDTYPE i_convertDeviceType();
+ DeviceType_T i_convertToDeviceType(VDTYPE enmType);
+ Utf8Str i_vdError(int aVRC);
+
+ bool i_isPropertyForFilter(const com::Utf8Str &aName);
+
+ HRESULT i_getFilterProperties(std::vector<com::Utf8Str> &aReturnNames,
+ std::vector<com::Utf8Str> &aReturnValues);
+
+ HRESULT i_preparationForMoving(const Utf8Str &aLocation);
+ bool i_isMoveOperation(const ComObjPtr<Medium> &pTarget) const;
+ bool i_resetMoveOperationData();
+ Utf8Str i_getNewLocationForMoving() const;
+
+ static DECLCALLBACK(void) i_vdErrorCall(void *pvUser, int vrc, RT_SRC_POS_DECL,
+ const char *pszFormat, va_list va);
+ static DECLCALLBACK(bool) i_vdConfigAreKeysValid(void *pvUser,
+ const char *pszzValid);
+ static DECLCALLBACK(int) i_vdConfigQuerySize(void *pvUser, const char *pszName,
+ size_t *pcbValue);
+ static DECLCALLBACK(int) i_vdConfigUpdate(void *pvUser, bool fCreate,
+ const char *pszName, const char *pszValue);
+
+ static DECLCALLBACK(int) i_vdConfigQuery(void *pvUser, const char *pszName,
+ char *pszValue, size_t cchValue);
+
+ static DECLCALLBACK(bool) i_vdCryptoConfigAreKeysValid(void *pvUser,
+ const char *pszzValid);
+ static DECLCALLBACK(int) i_vdCryptoConfigQuerySize(void *pvUser, const char *pszName,
+ size_t *pcbValue);
+ static DECLCALLBACK(int) i_vdCryptoConfigQuery(void *pvUser, const char *pszName,
+ char *pszValue, size_t cchValue);
+
+ static DECLCALLBACK(int) i_vdCryptoKeyRetain(void *pvUser, const char *pszId,
+ const uint8_t **ppbKey, size_t *pcbKey);
+ static DECLCALLBACK(int) i_vdCryptoKeyRelease(void *pvUser, const char *pszId);
+ static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRetain(void *pvUser, const char *pszId, const char **ppszPassword);
+ static DECLCALLBACK(int) i_vdCryptoKeyStorePasswordRelease(void *pvUser, const char *pszId);
+ static DECLCALLBACK(int) i_vdCryptoKeyStoreSave(void *pvUser, const void *pvKeyStore, size_t cbKeyStore);
+ static DECLCALLBACK(int) i_vdCryptoKeyStoreReturnParameters(void *pvUser, const char *pszCipher,
+ const uint8_t *pbDek, size_t cbDek);
+
+ class Task;
+ class CreateBaseTask;
+ class CreateDiffTask;
+ class CloneTask;
+ class MoveTask;
+ class CompactTask;
+ class ResizeTask;
+ class ResetTask;
+ class DeleteTask;
+ class MergeTask;
+ class ImportTask;
+ class EncryptTask;
+ friend class Task;
+ friend class CreateBaseTask;
+ friend class CreateDiffTask;
+ friend class CloneTask;
+ friend class MoveTask;
+ friend class CompactTask;
+ friend class ResizeTask;
+ friend class ResetTask;
+ friend class DeleteTask;
+ friend class MergeTask;
+ friend class ImportTask;
+ friend class EncryptTask;
+
+ HRESULT i_taskCreateBaseHandler(Medium::CreateBaseTask &task);
+ HRESULT i_taskCreateDiffHandler(Medium::CreateDiffTask &task);
+ HRESULT i_taskMergeHandler(Medium::MergeTask &task);
+ HRESULT i_taskCloneHandler(Medium::CloneTask &task);
+ HRESULT i_taskMoveHandler(Medium::MoveTask &task);
+ HRESULT i_taskDeleteHandler(Medium::DeleteTask &task);
+ HRESULT i_taskResetHandler(Medium::ResetTask &task);
+ HRESULT i_taskCompactHandler(Medium::CompactTask &task);
+ HRESULT i_taskResizeHandler(Medium::ResizeTask &task);
+ HRESULT i_taskImportHandler(Medium::ImportTask &task);
+ HRESULT i_taskEncryptHandler(Medium::EncryptTask &task);
+
+ void i_taskEncryptSettingsSetup(struct MediumCryptoFilterSettings *pSettings, const char *pszCipher,
+ const char *pszKeyStore, const char *pszPassword,
+ bool fCreateKeyStore);
+
+ struct Data; // opaque data struct, defined in MediumImpl.cpp
+ Data *m;
+};
+
+
+/**
+ * Settings for a crypto filter instance.
+ */
+struct MediumCryptoFilterSettings
+{
+ MediumCryptoFilterSettings()
+ : fCreateKeyStore(false),
+ pszPassword(NULL),
+ pszKeyStore(NULL),
+ pszKeyStoreLoad(NULL),
+ pbDek(NULL),
+ cbDek(0),
+ pszCipher(NULL),
+ pszCipherReturned(NULL)
+ { }
+
+ bool fCreateKeyStore;
+ const char *pszPassword;
+ char *pszKeyStore;
+ const char *pszKeyStoreLoad;
+
+ const uint8_t *pbDek;
+ size_t cbDek;
+ const char *pszCipher;
+
+ /** The cipher returned by the crypto filter. */
+ char *pszCipherReturned;
+
+ PVDINTERFACE vdFilterIfaces;
+
+ VDINTERFACECONFIG vdIfCfg;
+ VDINTERFACECRYPTO vdIfCrypto;
+};
+
+
+
+#endif /* !MAIN_INCLUDED_MediumImpl_h */
+
diff --git a/src/VBox/Main/include/MediumLock.h b/src/VBox/Main/include/MediumLock.h
new file mode 100644
index 00000000..d01fb9f3
--- /dev/null
+++ b/src/VBox/Main/include/MediumLock.h
@@ -0,0 +1,354 @@
+/* $Id: MediumLock.h $ */
+
+/** @file
+ *
+ * VirtualBox medium object lock collections
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MediumLock_h
+#define MAIN_INCLUDED_MediumLock_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/* interface definitions */
+#include "VBox/com/VirtualBox.h"
+#include "VirtualBoxBase.h"
+#include "AutoCaller.h"
+
+#include <iprt/types.h>
+
+#include <list>
+#include <map>
+
+class Medium;
+class MediumAttachment;
+
+/**
+ * Single entry for medium lock lists. Has a medium object reference,
+ * information about what kind of lock should be taken, and if it is
+ * locked right now.
+ */
+class MediumLock
+{
+public:
+ /**
+ * Default medium lock constructor.
+ */
+ MediumLock();
+
+ /**
+ * Default medium lock destructor.
+ */
+ ~MediumLock();
+
+ /**
+ * Create a new medium lock description
+ *
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ MediumLock(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Copy constructor. Needed because we contain an AutoCaller
+ * instance which is deliberately not copyable. The copy is not
+ * marked as locked, so be careful.
+ *
+ * @param aMediumLock Reference to source object.
+ */
+ MediumLock(const MediumLock &aMediumLock);
+
+ /**
+ * Update a medium lock description.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT UpdateLock(bool aLockWrite);
+
+ /**
+ * Get medium object reference.
+ */
+ const ComObjPtr<Medium> &GetMedium() const;
+
+ /**
+ * Get medium object lock request type.
+ */
+ bool GetLockRequest() const;
+
+ /**
+ * Check if this medium object has been locked by this MediumLock.
+ */
+ bool IsLocked() const;
+
+ /**
+ * Acquire a medium lock.
+ *
+ * @return COM status code
+ * @param aIgnoreLockedMedia If set ignore all media which is already
+ * locked in an incompatible way.
+ */
+ HRESULT Lock(bool aIgnoreLockedMedia = false);
+
+ /**
+ * Release a medium lock.
+ *
+ * @return COM status code
+ */
+ HRESULT Unlock();
+
+private:
+ ComObjPtr<Medium> mMedium;
+ ComPtr<IToken> mToken;
+ AutoCaller mMediumCaller;
+ bool mLockWrite;
+ bool mIsLocked;
+ /** Flag whether the medium was skipped when taking the locks.
+ * Only existing and accessible media objects need to be locked. */
+ bool mLockSkipped;
+};
+
+
+/**
+ * Medium lock list. Meant for storing the ordered locking information
+ * for a single medium chain.
+ */
+class MediumLockList
+{
+public:
+
+ /* Base list data type. */
+ typedef std::list<MediumLock> Base;
+
+ /**
+ * Default medium lock list constructor.
+ */
+ MediumLockList();
+
+ /**
+ * Default medium lock list destructor.
+ */
+ ~MediumLockList();
+
+ /**
+ * Checks if medium lock declaration list is empty.
+ *
+ * @return true if list is empty.
+ */
+ bool IsEmpty();
+
+ /**
+ * Add a new medium lock declaration to the end of the list.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT Append(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Add a new medium lock declaration to the beginning of the list.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT Prepend(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Update a medium lock declaration.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aMedium Reference to medium object
+ * @param aLockWrite @c true means a write lock should be taken
+ */
+ HRESULT Update(const ComObjPtr<Medium> &aMedium, bool aLockWrite);
+
+ /**
+ * Remove a medium lock declaration and return an updated iterator.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aIt Iterator for the element to remove
+ */
+ HRESULT RemoveByIterator(Base::iterator &aIt);
+
+ /**
+ * Clear all medium lock declarations.
+ *
+ * @note Implicitly unlocks all locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Clear();
+
+ /**
+ * Get iterator begin() for base list.
+ */
+ Base::iterator GetBegin();
+
+ /**
+ * Get iterator end() for base list.
+ */
+ Base::iterator GetEnd();
+
+ /**
+ * Acquire all medium locks "atomically", i.e. all or nothing.
+ *
+ * @return COM status code
+ * @param aSkipOverLockedMedia If set ignore all media which is already
+ * locked for reading or writing. For callers
+ * which need to know which medium objects
+ * have been locked by this lock list you
+ * can iterate over the list and check the
+ * MediumLock state.
+ */
+ HRESULT Lock(bool aSkipOverLockedMedia = false);
+
+ /**
+ * Release all medium locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Unlock();
+
+private:
+ Base mMediumLocks;
+ bool mIsLocked;
+};
+
+/**
+ * Medium lock list map. Meant for storing a collection of lock lists.
+ * The usual use case is creating such a map when locking all medium chains
+ * belonging to one VM, however that's not the limit. Be creative.
+ */
+class MediumLockListMap
+{
+public:
+
+ /**
+ * Default medium lock list map constructor.
+ */
+ MediumLockListMap();
+
+ /**
+ * Default medium lock list map destructor.
+ */
+ ~MediumLockListMap();
+
+ /**
+ * Checks if medium lock list map is empty.
+ *
+ * @return true if list is empty.
+ */
+ bool IsEmpty();
+
+ /**
+ * Insert a new medium lock list into the map.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachment Reference to medium attachment object, the key.
+ * @param aMediumLockList Reference to medium lock list object
+ */
+ HRESULT Insert(const ComObjPtr<MediumAttachment> &aMediumAttachment, MediumLockList *aMediumLockList);
+
+ /**
+ * Replace the medium lock list key by a different one.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachmentOld Reference to medium attachment object.
+ * @param aMediumAttachmentNew Reference to medium attachment object.
+ */
+ HRESULT ReplaceKey(const ComObjPtr<MediumAttachment> &aMediumAttachmentOld, const ComObjPtr<MediumAttachment> &aMediumAttachmentNew);
+
+ /**
+ * Remove a medium lock list from the map. The list will get deleted.
+ *
+ * @note May be only used in unlocked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachment Reference to medium attachment object, the key.
+ */
+ HRESULT Remove(const ComObjPtr<MediumAttachment> &aMediumAttachment);
+
+ /**
+ * Clear all medium lock declarations in this map.
+ *
+ * @note Implicitly unlocks all locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Clear();
+
+ /**
+ * Get the medium lock list identified by the given key.
+ *
+ * @note May be used in locked state.
+ *
+ * @return COM status code
+ * @param aMediumAttachment Key for medium attachment object.
+ * @param aMediumLockList Out: medium attachment object reference.
+ */
+ HRESULT Get(const ComObjPtr<MediumAttachment> &aMediumAttachment, MediumLockList * &aMediumLockList);
+
+ /**
+ * Acquire all medium locks "atomically", i.e. all or nothing.
+ *
+ * @return COM status code
+ */
+ HRESULT Lock();
+
+ /**
+ * Release all medium locks.
+ *
+ * @return COM status code
+ */
+ HRESULT Unlock();
+
+ /** Introspection. */
+ bool IsLocked(void) const { return mIsLocked; }
+
+private:
+ typedef std::map<ComObjPtr<MediumAttachment>, MediumLockList *> Base;
+ Base mMediumLocks;
+ bool mIsLocked;
+};
+
+#endif /* !MAIN_INCLUDED_MediumLock_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MouseImpl.h b/src/VBox/Main/include/MouseImpl.h
new file mode 100644
index 00000000..8636ce3e
--- /dev/null
+++ b/src/VBox/Main/include/MouseImpl.h
@@ -0,0 +1,175 @@
+/* $Id: MouseImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_MouseImpl_h
+#define MAIN_INCLUDED_MouseImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MouseWrap.h"
+#include "ConsoleImpl.h"
+#include "EventImpl.h"
+#include <VBox/vmm/pdmdrv.h>
+
+/** Maximum number of devices supported */
+enum { MOUSE_MAX_DEVICES = 4 };
+/** Mouse driver instance data. */
+typedef struct DRVMAINMOUSE DRVMAINMOUSE, *PDRVMAINMOUSE;
+
+class ATL_NO_VTABLE Mouse :
+ public MouseWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS (Mouse)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(ConsoleMouseInterface *parent);
+ void uninit();
+
+ static const PDMDRVREG DrvReg;
+
+ ConsoleMouseInterface *i_getParent() const
+ {
+ return mParent;
+ }
+
+ /** notify the front-end of guest capability changes */
+ void i_onVMMDevGuestCapsChange(uint32_t fCaps)
+ {
+ mfVMMDevGuestCaps = fCaps;
+ i_sendMouseCapsNotifications();
+ }
+
+ void updateMousePointerShape(bool fVisible, bool fAlpha,
+ uint32_t hotX, uint32_t hotY,
+ uint32_t width, uint32_t height,
+ const uint8_t *pu8Shape, uint32_t cbShape);
+private:
+
+ // Wrapped IMouse properties
+ HRESULT getAbsoluteSupported(BOOL *aAbsoluteSupported);
+ HRESULT getRelativeSupported(BOOL *aRelativeSupported);
+ HRESULT getTouchScreenSupported(BOOL *aTouchScreenSupported);
+ HRESULT getTouchPadSupported(BOOL *aTouchPadSupported);
+ HRESULT getNeedsHostCursor(BOOL *aNeedsHostCursor);
+ HRESULT getPointerShape(ComPtr<IMousePointerShape> &aPointerShape);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+
+ // Wrapped IMouse methods
+ HRESULT putMouseEvent(LONG aDx,
+ LONG aDy,
+ LONG aDz,
+ LONG aDw,
+ LONG aButtonState);
+ HRESULT putMouseEventAbsolute(LONG aX,
+ LONG aY,
+ LONG aDz,
+ LONG aDw,
+ LONG aButtonState);
+ HRESULT putEventMultiTouch(LONG aCount,
+ const std::vector<LONG64> &aContacts,
+ BOOL isTouchScreen,
+ ULONG aScanTime);
+ HRESULT putEventMultiTouchString(LONG aCount,
+ const com::Utf8Str &aContacts,
+ BOOL isTouchScreen,
+ ULONG aScanTime);
+
+
+ static DECLCALLBACK(void *) i_drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(void) i_mouseReportModes(PPDMIMOUSECONNECTOR pInterface, bool fRel, bool fAbs, bool fMTAbs, bool fMTRel);
+ static DECLCALLBACK(int) i_drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) i_drvDestruct(PPDMDRVINS pDrvIns);
+
+ HRESULT i_updateVMMDevMouseCaps(uint32_t fCapsAdded, uint32_t fCapsRemoved);
+ HRESULT i_reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
+ int32_t dw, uint32_t fButtons);
+ HRESULT i_reportAbsEventToMouseDev(int32_t x, int32_t y, int32_t dz,
+ int32_t dw, uint32_t fButtons);
+ HRESULT i_reportMTEventToMouseDev(int32_t x, int32_t z, uint32_t cContact,
+ uint32_t fContact);
+ HRESULT i_reportMultiTouchEventToDevice(uint8_t cContacts, const uint64_t *pau64Contacts, bool fTouchScreen, uint32_t u32ScanTime);
+ HRESULT i_reportAbsEventToVMMDev(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons);
+ HRESULT i_reportAbsEventToInputDevices(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons,
+ bool fUsesVMMDevEvent);
+ HRESULT i_reportAbsEventToDisplayDevice(int32_t x, int32_t y);
+ HRESULT i_convertDisplayRes(LONG x, LONG y, int32_t *pxAdj, int32_t *pyAdj,
+ bool *pfValid);
+ HRESULT i_putEventMultiTouch(LONG aCount, const LONG64 *paContacts, BOOL isTouchScreen, ULONG aScanTime);
+
+ uint32_t i_getDeviceCaps(void);
+ void i_sendMouseCapsNotifications(void);
+ bool i_guestNeedsHostCursor(void);
+ bool i_vmmdevCanAbs(void);
+ bool i_deviceCanAbs(void);
+ bool i_supportsAbs(uint32_t fCaps) const;
+ bool i_supportsAbs(void);
+ bool i_supportsRel(void);
+ bool i_supportsTS(void);
+ bool i_supportsTP(void);
+
+ ConsoleMouseInterface * const mParent;
+ /** Pointer to the associated mouse driver. */
+ struct DRVMAINMOUSE *mpDrv[MOUSE_MAX_DEVICES];
+
+ uint32_t mfVMMDevGuestCaps; /** We cache this to avoid access races */
+ int32_t mcLastX;
+ int32_t mcLastY;
+ uint32_t mfLastButtons;
+
+ ComPtr<IMousePointerShape> mPointerShape;
+ struct
+ {
+ bool fVisible;
+ bool fAlpha;
+ uint32_t hotX;
+ uint32_t hotY;
+ uint32_t width;
+ uint32_t height;
+ uint8_t *pu8Shape;
+ uint32_t cbShape;
+ } mPointerData;
+
+ const ComObjPtr<EventSource> mEventSource;
+ VBoxEventDesc mMouseEvent;
+
+ void i_fireMouseEvent(bool fAbsolute, LONG x, LONG y, LONG dz, LONG dw,
+ LONG fButtons);
+
+ void i_fireMultiTouchEvent(uint8_t cContacts,
+ const LONG64 *paContacts,
+ bool fTouchScreen,
+ uint32_t u32ScanTime);
+};
+
+#endif /* !MAIN_INCLUDED_MouseImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/NATEngineImpl.h b/src/VBox/Main/include/NATEngineImpl.h
new file mode 100644
index 00000000..2f21000b
--- /dev/null
+++ b/src/VBox/Main/include/NATEngineImpl.h
@@ -0,0 +1,124 @@
+/* $Id: NATEngineImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_NATEngineImpl_h
+#define MAIN_INCLUDED_NATEngineImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "NATEngineWrap.h"
+
+namespace settings
+{
+ struct NAT;
+}
+
+
+class ATL_NO_VTABLE NATEngine :
+ public NATEngineWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(NATEngine)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(Machine *aParent, INetworkAdapter *aAdapter);
+ HRESULT init(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat);
+ HRESULT initCopy(Machine *aParent, INetworkAdapter *aAdapter, NATEngine *aThat);
+ void uninit();
+
+ bool i_isModified();
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(NATEngine *aThat);
+ void i_applyDefaults();
+ bool i_hasDefaults();
+ HRESULT i_loadSettings(const settings::NAT &data);
+ HRESULT i_saveSettings(settings::NAT &data);
+
+private:
+
+ // wrapped INATEngine properties
+ HRESULT setNetwork(const com::Utf8Str &aNetwork);
+ HRESULT getNetwork(com::Utf8Str &aNetwork);
+ HRESULT setHostIP(const com::Utf8Str &aHostIP);
+ HRESULT getHostIP(com::Utf8Str &aBindIP);
+ HRESULT setLocalhostReachable(BOOL fLocalhostReachable);
+ HRESULT getLocalhostReachable(BOOL *pfLocalhostReachable);
+ /* TFTP properties */
+ HRESULT setTFTPPrefix(const com::Utf8Str &aTFTPPrefix);
+ HRESULT getTFTPPrefix(com::Utf8Str &aTFTPPrefix);
+ HRESULT setTFTPBootFile(const com::Utf8Str &aTFTPBootFile);
+ HRESULT getTFTPBootFile(com::Utf8Str &aTFTPBootFile);
+ HRESULT setTFTPNextServer(const com::Utf8Str &aTFTPNextServer);
+ HRESULT getTFTPNextServer(com::Utf8Str &aTFTPNextServer);
+ /* DNS properties */
+ HRESULT setDNSPassDomain(BOOL aDNSPassDomain);
+ HRESULT getDNSPassDomain(BOOL *aDNSPassDomain);
+ HRESULT setDNSProxy(BOOL aDNSProxy);
+ HRESULT getDNSProxy(BOOL *aDNSProxy);
+ HRESULT getDNSUseHostResolver(BOOL *aDNSUseHostResolver);
+ HRESULT setDNSUseHostResolver(BOOL aDNSUseHostResolver);
+ /* Alias properties */
+ HRESULT setAliasMode(ULONG aAliasMode);
+ HRESULT getAliasMode(ULONG *aAliasMode);
+
+ HRESULT getRedirects(std::vector<com::Utf8Str> &aRedirects);
+
+ HRESULT setNetworkSettings(ULONG aMtu,
+ ULONG aSockSnd,
+ ULONG aSockRcv,
+ ULONG aTcpWndSnd,
+ ULONG aTcpWndRcv);
+
+ HRESULT getNetworkSettings(ULONG *aMtu,
+ ULONG *aSockSnd,
+ ULONG *aSockRcv,
+ ULONG *aTcpWndSnd,
+ ULONG *aTcpWndRcv);
+
+ HRESULT addRedirect(const com::Utf8Str &aName,
+ NATProtocol_T aProto,
+ const com::Utf8Str &aHostIP,
+ USHORT aHostPort,
+ const com::Utf8Str &aGuestIP,
+ USHORT aGuestPort);
+
+ HRESULT removeRedirect(const com::Utf8Str &aName);
+
+ struct Data;
+ Data *mData;
+ const ComObjPtr<NATEngine> mPeer;
+ Machine * const mParent;
+ INetworkAdapter * const mAdapter;
+};
+#endif /* !MAIN_INCLUDED_NATEngineImpl_h */
diff --git a/src/VBox/Main/include/NATNetworkImpl.h b/src/VBox/Main/include/NATNetworkImpl.h
new file mode 100644
index 00000000..1a59aa62
--- /dev/null
+++ b/src/VBox/Main/include/NATNetworkImpl.h
@@ -0,0 +1,143 @@
+/* $Id: NATNetworkImpl.h $ */
+/** @file
+ * INATNetwork implementation header, lives in VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_NATNetworkImpl_h
+#define MAIN_INCLUDED_NATNetworkImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VBoxEvents.h"
+#include "NATNetworkWrap.h"
+
+#ifdef VBOX_WITH_HOSTNETIF_API
+struct NETIFINFO;
+#endif
+
+namespace settings
+{
+ struct NATNetwork;
+ struct NATRule;
+ typedef std::map<com::Utf8Str, NATRule> NATRulesMap;
+}
+
+#ifdef RT_OS_WINDOWS
+# define NATSR_EXECUTABLE_NAME "VBoxNetNAT.exe"
+#else
+# define NATSR_EXECUTABLE_NAME "VBoxNetNAT"
+#endif
+
+#undef ADDR_ANY ///@todo ADDR_ANY collides with some windows header!
+
+enum ADDRESSLOOKUPTYPE
+{
+ ADDR_GATEWAY,
+ ADDR_DHCP,
+ ADDR_DHCPLOWERIP,
+ ADDR_ANY
+};
+
+class NATNetworkServiceRunner: public NetworkServiceRunner
+{
+public:
+ NATNetworkServiceRunner(): NetworkServiceRunner(NATSR_EXECUTABLE_NAME){}
+ ~NATNetworkServiceRunner(){}
+};
+
+class ATL_NO_VTABLE NATNetwork :
+ public NATNetworkWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(NATNetwork)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(VirtualBox *aVirtualBox, com::Utf8Str aName);
+ HRESULT i_loadSettings(const settings::NATNetwork &data);
+ void uninit();
+ HRESULT i_saveSettings(settings::NATNetwork &data);
+
+private:
+
+ // Wrapped INATNetwork properties
+ HRESULT getNetworkName(com::Utf8Str &aNetworkName);
+ HRESULT setNetworkName(const com::Utf8Str &aNetworkName);
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getNetwork(com::Utf8Str &aNetwork);
+ HRESULT setNetwork(const com::Utf8Str &aNetwork);
+ HRESULT getGateway(com::Utf8Str &aGateway);
+ HRESULT getIPv6Enabled(BOOL *aIPv6Enabled);
+ HRESULT setIPv6Enabled(BOOL aIPv6Enabled);
+ HRESULT getIPv6Prefix(com::Utf8Str &aIPv6Prefix);
+ HRESULT setIPv6Prefix(const com::Utf8Str &aIPv6Prefix);
+ HRESULT getAdvertiseDefaultIPv6RouteEnabled(BOOL *aAdvertiseDefaultIPv6RouteEnabled);
+ HRESULT setAdvertiseDefaultIPv6RouteEnabled(BOOL aAdvertiseDefaultIPv6RouteEnabled);
+ HRESULT getNeedDhcpServer(BOOL *aNeedDhcpServer);
+ HRESULT setNeedDhcpServer(BOOL aNeedDhcpServer);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getPortForwardRules4(std::vector<com::Utf8Str> &aPortForwardRules4);
+ HRESULT getLocalMappings(std::vector<com::Utf8Str> &aLocalMappings);
+ HRESULT getLoopbackIp6(LONG *aLoopbackIp6);
+ HRESULT setLoopbackIp6(LONG aLoopbackIp6);
+ HRESULT getPortForwardRules6(std::vector<com::Utf8Str> &aPortForwardRules6);
+
+ // wrapped INATNetwork methods
+ HRESULT addLocalMapping(const com::Utf8Str &aHostid,
+ LONG aOffset);
+ HRESULT addPortForwardRule(BOOL aIsIpv6,
+ const com::Utf8Str &aRuleName,
+ NATProtocol_T aProto,
+ const com::Utf8Str &aHostIP,
+ USHORT aHostPort,
+ const com::Utf8Str &aGuestIP,
+ USHORT aGuestPort);
+ HRESULT removePortForwardRule(BOOL aISipv6,
+ const com::Utf8Str &aRuleName);
+ HRESULT start();
+ HRESULT stop();
+
+ // Internal methods
+ HRESULT setErrorBusy();
+
+ int i_recalculateIpv4AddressAssignments();
+ int i_findFirstAvailableOffset(ADDRESSLOOKUPTYPE, uint32_t *);
+ int i_recalculateIPv6Prefix();
+
+ void i_getPortForwardRulesFromMap(std::vector<Utf8Str> &aPortForwardRules, settings::NATRulesMap &aRules);
+
+ void i_updateDnsOptions();
+ void i_updateDomainNameOption(ComPtr<IHost> &host);
+ void i_updateDomainNameServerOption(ComPtr<IHost> &host);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_NATNetworkImpl_h */
diff --git a/src/VBox/Main/include/NetworkAdapterImpl.h b/src/VBox/Main/include/NetworkAdapterImpl.h
new file mode 100644
index 00000000..3efcd332
--- /dev/null
+++ b/src/VBox/Main/include/NetworkAdapterImpl.h
@@ -0,0 +1,141 @@
+/* $Id: NetworkAdapterImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_NetworkAdapterImpl_h
+#define MAIN_INCLUDED_NetworkAdapterImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "NetworkAdapterWrap.h"
+
+class GuestOSType;
+class BandwidthControl;
+class BandwidthGroup;
+class NATEngine;
+
+namespace settings
+{
+ struct NetworkAdapter;
+}
+
+class ATL_NO_VTABLE NetworkAdapter :
+ public NetworkAdapterWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(NetworkAdapter)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent, ULONG aSlot);
+ HRESULT init(Machine *aParent, NetworkAdapter *aThat, bool aReshare = false);
+ HRESULT initCopy(Machine *aParent, NetworkAdapter *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(BandwidthControl *bwctl, const settings::NetworkAdapter &data);
+ HRESULT i_saveSettings(settings::NetworkAdapter &data);
+
+ bool i_isModified();
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(NetworkAdapter *aThat);
+ void i_applyDefaults(GuestOSType *aOsType);
+ bool i_hasDefaults();
+
+ ComObjPtr<NetworkAdapter> i_getPeer();
+
+private:
+
+ // wrapped INetworkAdapter properties
+ HRESULT getAdapterType(NetworkAdapterType_T *aAdapterType);
+ HRESULT setAdapterType(NetworkAdapterType_T aAdapterType);
+ HRESULT getSlot(ULONG *aSlot);
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getMACAddress(com::Utf8Str &aMACAddress);
+ HRESULT setMACAddress(const com::Utf8Str &aMACAddress);
+ HRESULT getAttachmentType(NetworkAttachmentType_T *aAttachmentType);
+ HRESULT setAttachmentType(NetworkAttachmentType_T aAttachmentType);
+ HRESULT getBridgedInterface(com::Utf8Str &aBridgedInterface);
+ HRESULT setBridgedInterface(const com::Utf8Str &aBridgedInterface);
+ HRESULT getHostOnlyInterface(com::Utf8Str &aHostOnlyInterface);
+ HRESULT setHostOnlyInterface(const com::Utf8Str &aHostOnlyInterface);
+ HRESULT getHostOnlyNetwork(com::Utf8Str &aHostOnlyNetwork);
+ HRESULT setHostOnlyNetwork(const com::Utf8Str &aHostOnlyNetwork);
+ HRESULT getInternalNetwork(com::Utf8Str &aInternalNetwork);
+ HRESULT setInternalNetwork(const com::Utf8Str &aInternalNetwork);
+ HRESULT getNATNetwork(com::Utf8Str &aNATNetwork);
+ HRESULT setNATNetwork(const com::Utf8Str &aNATNetwork);
+ HRESULT getGenericDriver(com::Utf8Str &aGenericDriver);
+ HRESULT setGenericDriver(const com::Utf8Str &aGenericDriver);
+ HRESULT getCloudNetwork(com::Utf8Str &aCloudNetwork);
+ HRESULT setCloudNetwork(const com::Utf8Str &aCloudNetwork);
+ HRESULT getCableConnected(BOOL *aCableConnected);
+ HRESULT setCableConnected(BOOL aCableConnected);
+ HRESULT getLineSpeed(ULONG *aLineSpeed);
+ HRESULT setLineSpeed(ULONG aLineSpeed);
+ HRESULT getPromiscModePolicy(NetworkAdapterPromiscModePolicy_T *aPromiscModePolicy);
+ HRESULT setPromiscModePolicy(NetworkAdapterPromiscModePolicy_T aPromiscModePolicy);
+ HRESULT getTraceEnabled(BOOL *aTraceEnabled);
+ HRESULT setTraceEnabled(BOOL aTraceEnabled);
+ HRESULT getTraceFile(com::Utf8Str &aTraceFile);
+ HRESULT setTraceFile(const com::Utf8Str &aTraceFile);
+ HRESULT getNATEngine(ComPtr<INATEngine> &aNATEngine);
+ HRESULT getBootPriority(ULONG *aBootPriority);
+ HRESULT setBootPriority(ULONG aBootPriority);
+ HRESULT getBandwidthGroup(ComPtr<IBandwidthGroup> &aBandwidthGroup);
+ HRESULT setBandwidthGroup(const ComPtr<IBandwidthGroup> &aBandwidthGroup);
+
+ // wrapped INetworkAdapter methods
+ HRESULT getProperty(const com::Utf8Str &aKey,
+ com::Utf8Str &aValue);
+ HRESULT setProperty(const com::Utf8Str &aKey,
+ const com::Utf8Str &aValue);
+ HRESULT getProperties(const com::Utf8Str &aNames,
+ std::vector<com::Utf8Str> &aReturnNames,
+ std::vector<com::Utf8Str> &aReturnValues);
+ // Misc.
+ void i_generateMACAddress();
+ HRESULT i_updateMacAddress(Utf8Str aMacAddress);
+ void i_updateBandwidthGroup(BandwidthGroup *aBwGroup);
+ HRESULT i_switchFromNatNetworking(const com::Utf8Str &aNatnetworkName);
+ HRESULT i_switchToNatNetworking(const com::Utf8Str &aNatNetworkName);
+
+
+ Machine * const mParent;
+ const ComObjPtr<NetworkAdapter> mPeer;
+ const ComObjPtr<NATEngine> mNATEngine;
+
+ Backupable<settings::NetworkAdapter> mData;
+};
+
+#endif /* !MAIN_INCLUDED_NetworkAdapterImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/NetworkServiceRunner.h b/src/VBox/Main/include/NetworkServiceRunner.h
new file mode 100644
index 00000000..6b0dd3ce
--- /dev/null
+++ b/src/VBox/Main/include/NetworkServiceRunner.h
@@ -0,0 +1,87 @@
+/* $Id: NetworkServiceRunner.h $ */
+/** @file
+ * VirtualBox Main - interface for VBox DHCP server.
+ */
+
+/*
+ * Copyright (C) 2009-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_NetworkServiceRunner_h
+#define MAIN_INCLUDED_NetworkServiceRunner_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/string.h>
+
+
+/** @name Internal networking trunk type option values (NetworkServiceRunner::kpszKeyTrunkType)
+ * @{ */
+#define TRUNKTYPE_WHATEVER "whatever"
+#define TRUNKTYPE_NETFLT "netflt"
+#define TRUNKTYPE_NETADP "netadp"
+#define TRUNKTYPE_SRVNAT "srvnat"
+/** @} */
+
+/**
+ * Network service runner.
+ *
+ * Build arguments, starts and stops network service processes.
+ */
+class NetworkServiceRunner
+{
+public:
+ NetworkServiceRunner(const char *aProcName);
+ virtual ~NetworkServiceRunner();
+
+ /** @name Argument management
+ * @{ */
+ int addArgument(const char *pszArgument);
+ int addArgPair(const char *pszOption, const char *pszValue);
+ void resetArguments();
+ /** @} */
+
+ int start(bool aKillProcessOnStop);
+ int stop();
+ void detachFromServer();
+ bool isRunning();
+
+ RTPROCESS getPid() const;
+
+ /** @name Common options
+ * @{ */
+ static const char * const kpszKeyNetwork;
+ static const char * const kpszKeyTrunkType;
+ static const char * const kpszTrunkName;
+ static const char * const kpszMacAddress;
+ static const char * const kpszIpAddress;
+ static const char * const kpszIpNetmask;
+ static const char * const kpszKeyNeedMain;
+ /** @} */
+
+private:
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_NetworkServiceRunner_h */
+
diff --git a/src/VBox/Main/include/NvramStoreImpl.h b/src/VBox/Main/include/NvramStoreImpl.h
new file mode 100644
index 00000000..f863975b
--- /dev/null
+++ b/src/VBox/Main/include/NvramStoreImpl.h
@@ -0,0 +1,156 @@
+/* $Id: NvramStoreImpl.h $ */
+/** @file
+ * VirtualBox COM NVRAM store class implementation
+ */
+
+/*
+ * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_NvramStoreImpl_h
+#define MAIN_INCLUDED_NvramStoreImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "NvramStoreWrap.h"
+#include "SecretKeyStore.h"
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/VBoxCryptoIf.h>
+
+
+#ifdef VBOX_COM_INPROC
+class Console;
+#else
+class GuestOSType;
+
+namespace settings
+{
+ struct NvramSettings;
+}
+#endif
+
+class ATL_NO_VTABLE NvramStore :
+ public NvramStoreWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(NvramStore)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+#ifdef VBOX_COM_INPROC
+ HRESULT init(Console *aParent, const com::Utf8Str &strNonVolatileStorageFile);
+#else
+ HRESULT init(Machine *parent);
+ HRESULT init(Machine *parent, NvramStore *that);
+ HRESULT initCopy(Machine *parent, NvramStore *that);
+#endif
+ void uninit();
+
+ // public methods for internal purposes only
+#ifndef VBOX_COM_INPROC
+ HRESULT i_loadSettings(const settings::NvramSettings &data);
+ HRESULT i_saveSettings(settings::NvramSettings &data);
+#endif
+
+#ifdef VBOX_COM_INPROC
+ static const PDMDRVREG DrvReg;
+#else
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(NvramStore *aThat);
+ HRESULT i_applyDefaults(GuestOSType *aOSType);
+#endif
+
+ com::Utf8Str i_getNonVolatileStorageFile();
+ void i_updateNonVolatileStorageFile(const com::Utf8Str &aNonVolatileStorageFile);
+
+ int i_loadStore(const char *pszPath);
+ int i_saveStore(void);
+
+#ifndef VBOX_COM_INPROC
+ HRESULT i_retainUefiVarStore(PRTVFS phVfs, bool fReadonly);
+ HRESULT i_releaseUefiVarStore(RTVFS hVfs);
+#endif
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ HRESULT i_updateEncryptionSettings(const com::Utf8Str &strKeyId,
+ const com::Utf8Str &strKeyStore);
+ HRESULT i_getEncryptionSettings(com::Utf8Str &strKeyId,
+ com::Utf8Str &strKeyStore);
+
+ int i_addPassword(const Utf8Str &strKeyId, const Utf8Str &strPassword);
+ int i_removePassword(const Utf8Str &strKeyId);
+ int i_removeAllPasswords();
+#endif
+
+private:
+
+ int initImpl(void);
+
+ // Wrapped NVRAM store properties
+ HRESULT getNonVolatileStorageFile(com::Utf8Str &aNonVolatileStorageFile);
+ HRESULT getUefiVariableStore(ComPtr<IUefiVariableStore> &aUefiVarStore);
+ HRESULT getKeyId(com::Utf8Str &aKeyId);
+ HRESULT getKeyStore(com::Utf8Str &aKeyStore);
+
+ // Wrapped NVRAM store members
+ HRESULT initUefiVariableStore(ULONG aSize);
+
+ int i_loadStoreFromTar(RTVFSFSSTREAM hVfsFssTar);
+ int i_saveStoreAsTar(const char *pszPath);
+
+ int i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf);
+ int i_releaseCryptoIf(PCVBOXCRYPTOIF pCryptoIf);
+
+#ifdef VBOX_WITH_FULL_VM_ENCRYPTION
+ int i_setupEncryptionOrDecryption(RTVFSIOSTREAM hVfsIosInOut, bool fEncrypt,
+ PCVBOXCRYPTOIF *ppCryptoIf, SecretKey **ppKey,
+ PRTVFSIOSTREAM phVfsIos);
+ void i_releaseEncryptionOrDecryptionResources(RTVFSIOSTREAM hVfsIos, PCVBOXCRYPTOIF pCryptoIf,
+ SecretKey *pKey);
+#endif
+
+#ifdef VBOX_COM_INPROC
+ static DECLCALLBACK(int) i_SsmSaveExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+ static DECLCALLBACK(int) i_SsmLoadExec(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+
+ static DECLCALLBACK(int) i_nvramStoreQuerySize(PPDMIVFSCONNECTOR pInterface, const char *pszNamespace, const char *pszPath,
+ uint64_t *pcb);
+ static DECLCALLBACK(int) i_nvramStoreReadAll(PPDMIVFSCONNECTOR pInterface, const char *pszNamespace, const char *pszPath,
+ void *pvBuf, size_t cbRead);
+ static DECLCALLBACK(int) i_nvramStoreWriteAll(PPDMIVFSCONNECTOR pInterface, const char *pszNamespace, const char *pszPath,
+ const void *pvBuf, size_t cbWrite);
+ static DECLCALLBACK(int) i_nvramStoreDelete(PPDMIVFSCONNECTOR pInterface, const char *pszNamespace, const char *pszPath);
+ static DECLCALLBACK(void *) i_drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) i_drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) i_drvDestruct(PPDMDRVINS pDrvIns);
+#endif
+
+ struct Data; // opaque data struct, defined in NvramStoreImpl.cpp
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_NvramStoreImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ObjectState.h b/src/VBox/Main/include/ObjectState.h
new file mode 100644
index 00000000..8006fe5e
--- /dev/null
+++ b/src/VBox/Main/include/ObjectState.h
@@ -0,0 +1,150 @@
+/* $Id: ObjectState.h $ */
+/** @file
+ *
+ * VirtualBox object state handling definitions
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ObjectState_h
+#define MAIN_INCLUDED_ObjectState_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VBox/com/defs.h"
+#include "VBox/com/AutoLock.h"
+#include "VBox/com/ErrorInfo.h"
+
+// Forward declaration needed, but nothing more.
+class VirtualBoxBase;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// ObjectState
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Thec functionality implemented by this class is the primary object state
+ * (used by VirtualBoxBase and thus part of all API classes) that indicates
+ * if the object is ready to serve the calls, and if not, what stage it is
+ * currently at. Here is the primary state diagram:
+ *
+ * +-------------------------------------------------------+
+ * | |
+ * | (InitFailed) -----------------------+ |
+ * | ^ | |
+ * v | v |
+ * [*] ---> NotReady ----> (InInit) -----> Ready -----> (InUninit) ----+
+ * ^ |
+ * | v
+ * | Limited
+ * | |
+ * +-------+
+ *
+ * The object is fully operational only when its state is Ready. The Limited
+ * state means that only some vital part of the object is operational, and it
+ * requires some sort of reinitialization to become fully operational. The
+ * NotReady state means the object is basically dead: it either was not yet
+ * initialized after creation at all, or was uninitialized and is waiting to be
+ * destroyed when the last reference to it is released. All other states are
+ * transitional.
+ *
+ * The NotReady->InInit->Ready, NotReady->InInit->Limited and
+ * NotReady->InInit->InitFailed transition is done by the AutoInitSpan smart
+ * class.
+ *
+ * The Limited->InInit->Ready, Limited->InInit->Limited and
+ * Limited->InInit->InitFailed transition is done by the AutoReinitSpan smart
+ * class.
+ *
+ * The Ready->InUninit->NotReady and InitFailed->InUninit->NotReady
+ * transitions are done by the AutoUninitSpan smart class.
+ *
+ * In order to maintain the primary state integrity and declared functionality
+ * the following rules apply everywhere:
+ *
+ * 1) Use the above Auto*Span classes to perform state transitions. See the
+ * individual class descriptions for details.
+ *
+ * 2) All public methods of subclasses (i.e. all methods that can be called
+ * directly, not only from within other methods of the subclass) must have a
+ * standard prolog as described in the AutoCaller and AutoLimitedCaller
+ * documentation. Alternatively, they must use #addCaller() and
+ * #releaseCaller() directly (and therefore have both the prolog and the
+ * epilog), but this is not recommended because it is easy to forget the
+ * matching release, e.g. returning before reaching the call.
+ */
+class ObjectState
+{
+public:
+ enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited };
+
+ ObjectState(VirtualBoxBase *aObj);
+ ~ObjectState();
+
+ State getState();
+
+ HRESULT addCaller(bool aLimited = false);
+ void releaseCaller();
+
+ bool autoInitSpanConstructor(State aExpectedState);
+ void autoInitSpanDestructor(State aNewState, HRESULT aFailedRC, com::ErrorInfo *aFailedEI);
+ State autoUninitSpanConstructor(bool fTry);
+ void autoUninitSpanDestructor();
+
+private:
+ ObjectState();
+
+ void setState(State aState);
+
+ /** Pointer to the managed object, mostly for error signalling or debugging
+ * purposes, not used much. Guaranteed to be valid during the lifetime of
+ * this object, no need to mess with refcount. */
+ VirtualBoxBase *mObj;
+ /** Primary state of this object */
+ State mState;
+ /** Thread that caused the last state change */
+ RTTHREAD mStateChangeThread;
+ /** Result code for failed object initialization */
+ HRESULT mFailedRC;
+ /** Error information for failed object initialization */
+ com::ErrorInfo *mpFailedEI;
+ /** Total number of active calls to this object */
+ unsigned mCallers;
+ /** Posted when the number of callers drops to zero */
+ RTSEMEVENT mZeroCallersSem;
+ /** Posted when the object goes from InInit/InUninit to some other state */
+ RTSEMEVENTMULTI mInitUninitSem;
+ /** Number of threads waiting for mInitUninitDoneSem */
+ unsigned mInitUninitWaiters;
+
+ /** Protects access to state related data members */
+ util::RWLockHandle mStateLock;
+
+private:
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(ObjectState); /* Shuts up MSC warning C4625. */
+};
+
+#endif /* !MAIN_INCLUDED_ObjectState_h */
diff --git a/src/VBox/Main/include/PCIDeviceAttachmentImpl.h b/src/VBox/Main/include/PCIDeviceAttachmentImpl.h
new file mode 100644
index 00000000..ca3cbbed
--- /dev/null
+++ b/src/VBox/Main/include/PCIDeviceAttachmentImpl.h
@@ -0,0 +1,79 @@
+/* $Id: PCIDeviceAttachmentImpl.h $ */
+
+/** @file
+ *
+ * PCI attachment information implmentation.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_PCIDeviceAttachmentImpl_h
+#define MAIN_INCLUDED_PCIDeviceAttachmentImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "PCIDeviceAttachmentWrap.h"
+
+namespace settings
+{
+ struct HostPCIDeviceAttachment;
+}
+
+class ATL_NO_VTABLE PCIDeviceAttachment :
+ public PCIDeviceAttachmentWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(PCIDeviceAttachment)
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(IMachine * aParent,
+ const Utf8Str &aDevName,
+ LONG aHostAddess,
+ LONG aGuestAddress,
+ BOOL fPhysical);
+ HRESULT initCopy(IMachine *aParent, PCIDeviceAttachment *aThat);
+ void uninit();
+
+ // settings
+ HRESULT i_loadSettings(IMachine * aParent,
+ const settings::HostPCIDeviceAttachment& aHpda);
+ HRESULT i_saveSettings(settings::HostPCIDeviceAttachment &data);
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+private:
+
+ // wrapped IPCIDeviceAttachment properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getIsPhysicalDevice(BOOL *aIsPhysicalDevice);
+ HRESULT getHostAddress(LONG *aHostAddress);
+ HRESULT getGuestAddress(LONG *aGuestAddress);
+
+ struct Data;
+ Data* m;
+};
+
+#endif /* !MAIN_INCLUDED_PCIDeviceAttachmentImpl_h */
diff --git a/src/VBox/Main/include/PCIRawDevImpl.h b/src/VBox/Main/include/PCIRawDevImpl.h
new file mode 100644
index 00000000..717937f4
--- /dev/null
+++ b/src/VBox/Main/include/PCIRawDevImpl.h
@@ -0,0 +1,64 @@
+/* $Id: PCIRawDevImpl.h $ */
+/** @file
+ * VirtualBox Driver interface to raw PCI device
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_PCIRawDevImpl_h
+#define MAIN_INCLUDED_PCIRawDevImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/vmm/pdmdrv.h>
+
+class Console;
+struct DRVMAINPCIRAWDEV;
+
+class PCIRawDev
+{
+ public:
+ PCIRawDev(Console *console);
+ virtual ~PCIRawDev();
+
+ static const PDMDRVREG DrvReg;
+
+ Console *getParent() const
+ {
+ return mParent;
+ }
+
+ private:
+ static DECLCALLBACK(void *) drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(int) drvDeviceConstructComplete(PPDMIPCIRAWCONNECTOR pInterface, const char *pcszName,
+ uint32_t uHostPCIAddress, uint32_t uGuestPCIAddress,
+ int vrc);
+
+ Console * const mParent;
+ struct DRVMAINPCIRAWDEV *mpDrv;
+};
+
+#endif /* !MAIN_INCLUDED_PCIRawDevImpl_h */
diff --git a/src/VBox/Main/include/ParallelPortImpl.h b/src/VBox/Main/include/ParallelPortImpl.h
new file mode 100644
index 00000000..72c4ea49
--- /dev/null
+++ b/src/VBox/Main/include/ParallelPortImpl.h
@@ -0,0 +1,87 @@
+/* $Id: ParallelPortImpl.h $ */
+
+/** @file
+ * VirtualBox COM class implementation.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ParallelPortImpl_h
+#define MAIN_INCLUDED_ParallelPortImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "ParallelPortWrap.h"
+
+namespace settings
+{
+ struct ParallelPort;
+}
+
+class ATL_NO_VTABLE ParallelPort :
+ public ParallelPortWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(ParallelPort)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent, ULONG aSlot);
+ HRESULT init(Machine *aParent, ParallelPort *aThat);
+ HRESULT initCopy(Machine *parent, ParallelPort *aThat);
+ void uninit();
+
+ HRESULT i_loadSettings(const settings::ParallelPort &data);
+ HRESULT i_saveSettings(settings::ParallelPort &data);
+
+ // public methods only for internal purposes
+ bool i_isModified();
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(ParallelPort *aThat);
+ void i_applyDefaults();
+ bool i_hasDefaults();
+
+private:
+
+ // Wrapped IParallelPort properties
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getSlot(ULONG *aSlot);
+ HRESULT getIRQ(ULONG *aIRQ);
+ HRESULT setIRQ(ULONG aIRQ);
+ HRESULT getIOBase(ULONG *aIOBase);
+ HRESULT setIOBase(ULONG aIOBase);
+ HRESULT getPath(com::Utf8Str &aPath);
+ HRESULT setPath(const com::Utf8Str &aPath);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_ParallelPortImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/Performance.h b/src/VBox/Main/include/Performance.h
new file mode 100644
index 00000000..e8d1fa1a
--- /dev/null
+++ b/src/VBox/Main/include/Performance.h
@@ -0,0 +1,915 @@
+/* $Id: Performance.h $ */
+/** @file
+ * VirtualBox Main - Performance Classes declaration.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_Performance_h
+#define MAIN_INCLUDED_Performance_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/com/defs.h>
+#include <VBox/com/ptr.h>
+#include <VBox/com/string.h>
+#include <VBox/com/VirtualBox.h>
+
+#include <iprt/types.h>
+#include <iprt/err.h>
+#include <iprt/cpp/lock.h>
+
+#include <algorithm>
+#include <functional> /* For std::fun_ptr in testcase */
+#include <list>
+#include <vector>
+#include <queue>
+
+#include "MediumImpl.h"
+
+/* Forward decl. */
+class Machine;
+
+namespace pm
+{
+ /* CPU load is measured in 1/1000 of per cent. */
+ const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
+ /* Network load is measured in 1/1000 of per cent. */
+ const uint64_t PM_NETWORK_LOAD_MULTIPLIER = UINT64_C(100000);
+ /* Disk load is measured in 1/1000 of per cent. */
+ const uint64_t PM_DISK_LOAD_MULTIPLIER = UINT64_C(100000);
+ /* Sampler precision in milliseconds. */
+ const uint64_t PM_SAMPLER_PRECISION_MS = 50;
+
+ /* Sub Metrics **********************************************************/
+ class CircularBuffer
+ {
+ public:
+ CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
+ ~CircularBuffer() { if (mData) RTMemFree(mData); };
+ void init(ULONG length);
+ ULONG length();
+ ULONG getSequenceNumber() { return mSequenceNumber; }
+ void put(ULONG value);
+ void copyTo(ULONG *data);
+ private:
+ ULONG *mData;
+ ULONG mLength;
+ ULONG mEnd;
+ ULONG mSequenceNumber;
+ bool mWrapped;
+ };
+
+ class SubMetric : public CircularBuffer
+ {
+ public:
+ SubMetric(com::Utf8Str name, const char *description)
+ : mName(name), mDescription(description) {};
+ void query(ULONG *data);
+ const char *getName() { return mName.c_str(); };
+ const char *getDescription() { return mDescription; };
+ private:
+ const com::Utf8Str mName;
+ const char *mDescription;
+ };
+
+
+ enum {
+ COLLECT_NONE = 0x0,
+ COLLECT_CPU_LOAD = 0x1,
+ COLLECT_RAM_USAGE = 0x2,
+ COLLECT_GUEST_STATS = 0x4
+ };
+ typedef int HintFlags;
+ typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
+
+ class CollectorHints
+ {
+ public:
+ typedef std::list<ProcessFlagsPair> ProcessList;
+
+ CollectorHints() : mHostFlags(COLLECT_NONE) {}
+ void collectHostCpuLoad()
+ { mHostFlags |= COLLECT_CPU_LOAD; }
+ void collectHostRamUsage()
+ { mHostFlags |= COLLECT_RAM_USAGE; }
+ void collectHostRamVmm()
+ { mHostFlags |= COLLECT_GUEST_STATS; }
+ void collectProcessCpuLoad(RTPROCESS process)
+ { findProcess(process).second |= COLLECT_CPU_LOAD; }
+ void collectProcessRamUsage(RTPROCESS process)
+ { findProcess(process).second |= COLLECT_RAM_USAGE; }
+ void collectGuestStats(RTPROCESS process)
+ { findProcess(process).second |= COLLECT_GUEST_STATS; }
+ bool isHostCpuLoadCollected() const
+ { return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
+ bool isHostRamUsageCollected() const
+ { return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
+ bool isHostRamVmmCollected() const
+ { return (mHostFlags & COLLECT_GUEST_STATS) != 0; }
+ bool isProcessCpuLoadCollected(RTPROCESS process)
+ { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
+ bool isProcessRamUsageCollected(RTPROCESS process)
+ { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
+ bool isGuestStatsCollected(RTPROCESS process)
+ { return (findProcess(process).second & COLLECT_GUEST_STATS) != 0; }
+ void getProcesses(std::vector<RTPROCESS>& processes) const
+ {
+ processes.clear();
+ processes.reserve(mProcesses.size());
+ for (ProcessList::const_iterator it = mProcesses.begin(); it != mProcesses.end(); ++it)
+ processes.push_back(it->first);
+ }
+ const ProcessList& getProcessFlags() const
+ {
+ return mProcesses;
+ }
+ private:
+ HintFlags mHostFlags;
+ ProcessList mProcesses;
+
+ ProcessFlagsPair& findProcess(RTPROCESS process)
+ {
+ ProcessList::iterator it;
+ for (it = mProcesses.begin(); it != mProcesses.end(); ++it)
+ if (it->first == process)
+ return *it;
+
+ /* Not found -- add new */
+ mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
+ return mProcesses.back();
+ }
+ };
+
+ /* Guest Collector Classes *********************************/
+ /*
+ * WARNING! The bits in the following masks must correspond to parameters
+ * of CollectorGuest::updateStats().
+ */
+ typedef enum
+ {
+ VMSTATMASK_NONE = 0x00000000,
+ VMSTATMASK_GUEST_CPUUSER = 0x00000001,
+ VMSTATMASK_GUEST_CPUKERNEL = 0x00000002,
+ VMSTATMASK_GUEST_CPUIDLE = 0x00000004,
+ VMSTATMASK_GUEST_MEMTOTAL = 0x00000008,
+ VMSTATMASK_GUEST_MEMFREE = 0x00000010,
+ VMSTATMASK_GUEST_MEMBALLOON = 0x00000020,
+ VMSTATMASK_GUEST_MEMSHARED = 0x00000040,
+ VMSTATMASK_GUEST_MEMCACHE = 0x00000080,
+ VMSTATMASK_GUEST_PAGETOTAL = 0x00000100,
+ VMSTATMASK_VMM_ALLOC = 0x00010000,
+ VMSTATMASK_VMM_FREE = 0x00020000,
+ VMSTATMASK_VMM_BALOON = 0x00040000,
+ VMSTATMASK_VMM_SHARED = 0x00080000,
+ VMSTATMASK_NET_RX = 0x01000000,
+ VMSTATMASK_NET_TX = 0x02000000
+ } VMSTATMASK;
+
+ const ULONG VMSTATS_GUEST_CPULOAD =
+ VMSTATMASK_GUEST_CPUUSER | VMSTATMASK_GUEST_CPUKERNEL |
+ VMSTATMASK_GUEST_CPUIDLE;
+ const ULONG VMSTATS_GUEST_RAMUSAGE =
+ VMSTATMASK_GUEST_MEMTOTAL | VMSTATMASK_GUEST_MEMFREE |
+ VMSTATMASK_GUEST_MEMBALLOON | VMSTATMASK_GUEST_MEMSHARED |
+ VMSTATMASK_GUEST_MEMCACHE | VMSTATMASK_GUEST_PAGETOTAL;
+ const ULONG VMSTATS_VMM_RAM =
+ VMSTATMASK_VMM_ALLOC | VMSTATMASK_VMM_FREE|
+ VMSTATMASK_VMM_BALOON | VMSTATMASK_VMM_SHARED;
+ const ULONG VMSTATS_NET_RATE =
+ VMSTATMASK_NET_RX | VMSTATMASK_NET_TX;
+ const ULONG VMSTATS_ALL =
+ VMSTATS_GUEST_CPULOAD | VMSTATS_GUEST_RAMUSAGE |
+ VMSTATS_VMM_RAM | VMSTATS_NET_RATE;
+ class CollectorGuest;
+
+ class CollectorGuestRequest
+ {
+ public:
+ CollectorGuestRequest()
+ : mCGuest(0) {};
+ virtual ~CollectorGuestRequest() {};
+ void setGuest(CollectorGuest *aGuest) { mCGuest = aGuest; };
+ CollectorGuest *getGuest() { return mCGuest; };
+ virtual HRESULT execute() = 0;
+
+ virtual void debugPrint(void *aObject, const char *aFunction, const char *aText) = 0;
+ protected:
+ CollectorGuest *mCGuest;
+ const char *mDebugName;
+ };
+
+ class CGRQEnable : public CollectorGuestRequest
+ {
+ public:
+ CGRQEnable(ULONG aMask)
+ : mMask(aMask) {};
+ HRESULT execute();
+
+ void debugPrint(void *aObject, const char *aFunction, const char *aText);
+ private:
+ ULONG mMask;
+ };
+
+ class CGRQDisable : public CollectorGuestRequest
+ {
+ public:
+ CGRQDisable(ULONG aMask)
+ : mMask(aMask) {};
+ HRESULT execute();
+
+ void debugPrint(void *aObject, const char *aFunction, const char *aText);
+ private:
+ ULONG mMask;
+ };
+
+ class CGRQAbort : public CollectorGuestRequest
+ {
+ public:
+ CGRQAbort() {};
+ HRESULT execute();
+
+ void debugPrint(void *aObject, const char *aFunction, const char *aText);
+ };
+
+ class CollectorGuestQueue
+ {
+ public:
+ CollectorGuestQueue();
+ ~CollectorGuestQueue();
+ void push(CollectorGuestRequest* rq);
+ CollectorGuestRequest* pop();
+ private:
+ RTCLockMtx mLockMtx;
+ RTSEMEVENT mEvent;
+ std::queue<CollectorGuestRequest*> mQueue;
+ };
+
+ class CollectorGuestManager;
+
+ class CollectorGuest
+ {
+ public:
+ CollectorGuest(Machine *machine, RTPROCESS process);
+ ~CollectorGuest();
+
+ void setManager(CollectorGuestManager *aManager)
+ { mManager = aManager; };
+ bool isUnregistered() { return mUnregistered; };
+ bool isEnabled() { return mEnabled != 0; };
+ bool isValid(ULONG mask) { return (mValid & mask) == mask; };
+ void invalidate(ULONG mask) { mValid &= ~mask; };
+ void unregister() { mUnregistered = true; };
+ void updateStats(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM,
+ ULONG aVmNetRx, ULONG aVmNetTx);
+ HRESULT enable(ULONG mask);
+ HRESULT disable(ULONG mask);
+
+ HRESULT enqueueRequest(CollectorGuestRequest *aRequest);
+ HRESULT enableInternal(ULONG mask);
+ HRESULT disableInternal(ULONG mask);
+
+ const com::Utf8Str& getVMName() const { return mMachineName; };
+
+ RTPROCESS getProcess() { return mProcess; };
+ ULONG getCpuUser() { return mCpuUser; };
+ ULONG getCpuKernel() { return mCpuKernel; };
+ ULONG getCpuIdle() { return mCpuIdle; };
+ ULONG getMemTotal() { return mMemTotal; };
+ ULONG getMemFree() { return mMemFree; };
+ ULONG getMemBalloon() { return mMemBalloon; };
+ ULONG getMemShared() { return mMemShared; };
+ ULONG getMemCache() { return mMemCache; };
+ ULONG getPageTotal() { return mPageTotal; };
+ ULONG getAllocVMM() { return mAllocVMM; };
+ ULONG getFreeVMM() { return mFreeVMM; };
+ ULONG getBalloonedVMM() { return mBalloonedVMM; };
+ ULONG getSharedVMM() { return mSharedVMM; };
+ ULONG getVmNetRx() { return mVmNetRx; };
+ ULONG getVmNetTx() { return mVmNetTx; };
+
+ private:
+ HRESULT enableVMMStats(bool mCollectVMMStats);
+
+ CollectorGuestManager *mManager;
+
+ bool mUnregistered;
+ ULONG mEnabled;
+ ULONG mValid;
+ Machine *mMachine;
+ com::Utf8Str mMachineName;
+ RTPROCESS mProcess;
+ ComPtr<IConsole> mConsole;
+ ComPtr<IGuest> mGuest;
+ ULONG mCpuUser;
+ ULONG mCpuKernel;
+ ULONG mCpuIdle;
+ ULONG mMemTotal;
+ ULONG mMemFree;
+ ULONG mMemBalloon;
+ ULONG mMemShared;
+ ULONG mMemCache;
+ ULONG mPageTotal;
+ ULONG mAllocVMM;
+ ULONG mFreeVMM;
+ ULONG mBalloonedVMM;
+ ULONG mSharedVMM;
+ ULONG mVmNetRx;
+ ULONG mVmNetTx;
+ };
+
+ typedef std::list<CollectorGuest*> CollectorGuestList;
+ class CollectorGuestManager
+ {
+ public:
+ CollectorGuestManager();
+ ~CollectorGuestManager();
+ void registerGuest(CollectorGuest* pGuest);
+ void unregisterGuest(CollectorGuest* pGuest);
+ CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void destroyUnregistered();
+ HRESULT enqueueRequest(CollectorGuestRequest *aRequest);
+
+ CollectorGuest *getBlockedGuest() { return mGuestBeingCalled; };
+
+ static DECLCALLBACK(int) requestProcessingThread(RTTHREAD aThread, void *pvUser);
+ private:
+ RTTHREAD mThread;
+ CollectorGuestList mGuests;
+ CollectorGuest *mVMMStatsProvider;
+ CollectorGuestQueue mQueue;
+ CollectorGuest *mGuestBeingCalled;
+ };
+
+ /* Collector Hardware Abstraction Layer *********************************/
+ typedef std::list<RTCString> DiskList;
+
+ class CollectorHAL
+ {
+ public:
+ CollectorHAL() {};
+ virtual ~CollectorHAL() { };
+ virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
+ /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
+ virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
+ /** Returns the average frequency in MHz across all host's CPUs. */
+ virtual int getHostCpuMHz(ULONG *mhz);
+ /** Returns the amount of physical memory in kilobytes. */
+ virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
+ /** Returns file system counters in megabytes. */
+ virtual int getHostFilesystemUsage(const char *name, ULONG *total, ULONG *used, ULONG *available);
+ /** Returns disk size in bytes. */
+ virtual int getHostDiskSize(const char *name, uint64_t *size);
+ /** Returns CPU usage in 1/1000th per cent by a particular process. */
+ virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
+ /** Returns the amount of memory used by a process in kilobytes. */
+ virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
+
+ /** Returns CPU usage counters in platform-specific units. */
+ virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
+ /** Returns received and transmitted bytes. */
+ virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
+ /** Returns disk usage counters in platform-specific units. */
+ virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms);
+ /** Returns process' CPU usage counter in platform-specific units. */
+ virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
+
+ /** Returns the lists of disks (aggregate and physical) used by the specified file system. */
+ virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
+ };
+
+ extern CollectorHAL *createHAL();
+
+ /* Base Metrics *********************************************************/
+ class BaseMetric
+ {
+ public:
+ BaseMetric(CollectorHAL *hal, const com::Utf8Str name, ComPtr<IUnknown> object)
+ : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
+ mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
+ virtual ~BaseMetric() {};
+
+ virtual void init(ULONG period, ULONG length) = 0;
+ virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
+ virtual void collect() = 0;
+ virtual const char *getUnit() = 0;
+ virtual ULONG getMinValue() = 0;
+ virtual ULONG getMaxValue() = 0;
+ virtual ULONG getScale() = 0;
+
+ bool collectorBeat(uint64_t nowAt);
+
+ virtual HRESULT enable() { mEnabled = true; return S_OK; };
+ virtual HRESULT disable() { mEnabled = false; return S_OK; };
+ void unregister() { mUnregistered = true; };
+
+ bool isUnregistered() { return mUnregistered; };
+ bool isEnabled() { return mEnabled; };
+ ULONG getPeriod() { return mPeriod; };
+ ULONG getLength() { return mLength; };
+ const char *getName() { return mName.c_str(); };
+ ComPtr<IUnknown> getObject() { return mObject; };
+ bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
+
+ protected:
+ ULONG mPeriod;
+ ULONG mLength;
+ CollectorHAL *mHAL;
+ const com::Utf8Str mName;
+ ComPtr<IUnknown> mObject;
+ uint64_t mLastSampleTaken;
+ bool mEnabled;
+ bool mUnregistered;
+ };
+
+ class BaseGuestMetric : public BaseMetric
+ {
+ public:
+ BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
+ : BaseMetric(NULL, name, object), mCGuest(cguest) {};
+ protected:
+ CollectorGuest *mCGuest;
+ };
+
+ class HostCpuLoad : public BaseMetric
+ {
+ public:
+ HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+ : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
+ ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
+
+ void init(ULONG period, ULONG length);
+
+ void collect();
+ const char *getUnit() { return "%"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
+ ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
+
+ protected:
+ SubMetric *mUser;
+ SubMetric *mKernel;
+ SubMetric *mIdle;
+ };
+
+ class HostCpuLoadRaw : public HostCpuLoad
+ {
+ public:
+ HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+ : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ private:
+ uint64_t mUserPrev;
+ uint64_t mKernelPrev;
+ uint64_t mIdlePrev;
+ };
+
+ class HostCpuMhz : public BaseMetric
+ {
+ public:
+ HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
+ : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
+ ~HostCpuMhz() { delete mMHz; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
+ void collect();
+ const char *getUnit() { return "MHz"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ SubMetric *mMHz;
+ };
+
+ class HostRamUsage : public BaseMetric
+ {
+ public:
+ HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
+ : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
+ ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "kB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ SubMetric *mTotal;
+ SubMetric *mUsed;
+ SubMetric *mAvailable;
+ };
+
+ class HostNetworkSpeed : public BaseMetric
+ {
+ public:
+ HostNetworkSpeed(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str /* ifname */, uint32_t speed, SubMetric *linkspeed)
+ : BaseMetric(hal, name, object), mShortName(shortname), mSpeed(speed), mLinkSpeed(linkspeed) {};
+ ~HostNetworkSpeed() { delete mLinkSpeed; };
+
+ void init(ULONG period, ULONG length);
+
+ void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {};
+ void collect() { if (mSpeed) mLinkSpeed->put(mSpeed); };
+ const char *getUnit() { return "mbit/s"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ com::Utf8Str mShortName;
+ uint32_t mSpeed;
+ SubMetric *mLinkSpeed;
+ };
+
+ class HostNetworkLoadRaw : public BaseMetric
+ {
+ public:
+ HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str ifname, uint32_t speed, SubMetric *rx, SubMetric *tx)
+ : BaseMetric(hal, name, object), mShortName(shortname), mInterfaceName(ifname), mRx(rx), mTx(tx), mRxPrev(0), mTxPrev(0), mRc(VINF_SUCCESS) { mSpeed = (uint64_t)speed * (1000000/8); /* Convert to bytes/sec */ };
+ ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
+
+ void init(ULONG period, ULONG length);
+
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "%"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
+ ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
+
+ private:
+ com::Utf8Str mShortName;
+ com::Utf8Str mInterfaceName;
+ SubMetric *mRx;
+ SubMetric *mTx;
+ uint64_t mRxPrev;
+ uint64_t mTxPrev;
+ uint64_t mSpeed;
+ int mRc;
+ };
+
+ class HostFilesystemUsage : public BaseMetric
+ {
+ public:
+ HostFilesystemUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str fsname, SubMetric *total, SubMetric *used, SubMetric *available)
+ : BaseMetric(hal, name, object), mFsName(fsname), mTotal(total), mUsed(used), mAvailable(available) {};
+ ~HostFilesystemUsage() { delete mTotal; delete mUsed; delete mAvailable; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "MB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ com::Utf8Str mFsName;
+ SubMetric *mTotal;
+ SubMetric *mUsed;
+ SubMetric *mAvailable;
+ };
+
+ class HostDiskUsage : public BaseMetric
+ {
+ public:
+ HostDiskUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *total)
+ : BaseMetric(hal, name, object), mDiskName(diskname), mTotal(total) {};
+ ~HostDiskUsage() { delete mTotal; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "MB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ com::Utf8Str mDiskName;
+ SubMetric *mTotal;
+ };
+
+ class HostDiskLoadRaw : public BaseMetric
+ {
+ public:
+ HostDiskLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *util)
+ : BaseMetric(hal, name, object), mDiskName(diskname), mUtil(util), mDiskPrev(0), mTotalPrev(0) {};
+ ~HostDiskLoadRaw() { delete mUtil; };
+
+ void init(ULONG period, ULONG length);
+
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "%"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return PM_DISK_LOAD_MULTIPLIER; };
+ ULONG getScale() { return PM_DISK_LOAD_MULTIPLIER / 100; }
+
+ private:
+ com::Utf8Str mDiskName;
+ SubMetric *mUtil;
+ uint64_t mDiskPrev;
+ uint64_t mTotalPrev;
+ };
+
+
+#ifndef VBOX_COLLECTOR_TEST_CASE
+ class HostRamVmm : public BaseMetric
+ {
+ public:
+ HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
+ : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
+ mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
+ mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
+ ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ HRESULT enable();
+ HRESULT disable();
+ const char *getUnit() { return "kB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+
+ private:
+ CollectorGuestManager *mCollectorGuestManager;
+ SubMetric *mAllocVMM;
+ SubMetric *mFreeVMM;
+ SubMetric *mBalloonVMM;
+ SubMetric *mSharedVMM;
+ ULONG mAllocCurrent;
+ ULONG mFreeCurrent;
+ ULONG mBalloonedCurrent;
+ ULONG mSharedCurrent;
+ };
+#endif /* VBOX_COLLECTOR_TEST_CASE */
+
+ class MachineCpuLoad : public BaseMetric
+ {
+ public:
+ MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
+ : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
+ ~MachineCpuLoad() { delete mUser; delete mKernel; };
+
+ void init(ULONG period, ULONG length);
+ void collect();
+ const char *getUnit() { return "%"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
+ ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
+ protected:
+ RTPROCESS mProcess;
+ SubMetric *mUser;
+ SubMetric *mKernel;
+ };
+
+ class MachineCpuLoadRaw : public MachineCpuLoad
+ {
+ public:
+ MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
+ : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
+
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ private:
+ uint64_t mHostTotalPrev;
+ uint64_t mProcessUserPrev;
+ uint64_t mProcessKernelPrev;
+ };
+
+ class MachineRamUsage : public BaseMetric
+ {
+ public:
+ MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
+ : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
+ ~MachineRamUsage() { delete mUsed; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "kB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ RTPROCESS mProcess;
+ SubMetric *mUsed;
+ };
+
+
+#ifndef VBOX_COLLECTOR_TEST_CASE
+ typedef std::list<ComObjPtr<Medium> > MediaList;
+ class MachineDiskUsage : public BaseMetric
+ {
+ public:
+ MachineDiskUsage(CollectorHAL *hal, ComPtr<IUnknown> object, MediaList &disks, SubMetric *used)
+ : BaseMetric(hal, "Disk/Usage", object), mDisks(disks), mUsed(used) {};
+ ~MachineDiskUsage() { delete mUsed; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ const char *getUnit() { return "MB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ MediaList mDisks;
+ SubMetric *mUsed;
+ };
+
+ /*
+ * Although MachineNetRate is measured for VM, not for the guest, it is
+ * derived from BaseGuestMetric since it uses the same mechanism for
+ * data collection -- values get pushed by Guest class along with other
+ * guest statistics.
+ */
+ class MachineNetRate : public BaseGuestMetric
+ {
+ public:
+ MachineNetRate(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *rx, SubMetric *tx)
+ : BaseGuestMetric(cguest, "Net/Rate", object), mRx(rx), mTx(tx) {};
+ ~MachineNetRate() { delete mRx; delete mTx; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ HRESULT enable();
+ HRESULT disable();
+ const char *getUnit() { return "B/s"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ SubMetric *mRx, *mTx;
+ };
+
+ class GuestCpuLoad : public BaseGuestMetric
+ {
+ public:
+ GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+ : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
+ ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ HRESULT enable();
+ HRESULT disable();
+ const char *getUnit() { return "%"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
+ ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
+ protected:
+ SubMetric *mUser;
+ SubMetric *mKernel;
+ SubMetric *mIdle;
+ };
+
+ class GuestRamUsage : public BaseGuestMetric
+ {
+ public:
+ GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
+ : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
+ ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
+
+ void init(ULONG period, ULONG length);
+ void preCollect(CollectorHints& hints, uint64_t iTick);
+ void collect();
+ HRESULT enable();
+ HRESULT disable();
+ const char *getUnit() { return "kB"; };
+ ULONG getMinValue() { return 0; };
+ ULONG getMaxValue() { return INT32_MAX; };
+ ULONG getScale() { return 1; }
+ private:
+ SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
+ };
+#endif /* VBOX_COLLECTOR_TEST_CASE */
+
+ /* Aggregate Functions **************************************************/
+ class Aggregate
+ {
+ public:
+ virtual ULONG compute(ULONG *data, ULONG length) = 0;
+ virtual const char *getName() = 0;
+ virtual ~Aggregate() {}
+ };
+
+ class AggregateAvg : public Aggregate
+ {
+ public:
+ virtual ULONG compute(ULONG *data, ULONG length);
+ virtual const char *getName();
+ };
+
+ class AggregateMin : public Aggregate
+ {
+ public:
+ virtual ULONG compute(ULONG *data, ULONG length);
+ virtual const char *getName();
+ };
+
+ class AggregateMax : public Aggregate
+ {
+ public:
+ virtual ULONG compute(ULONG *data, ULONG length);
+ virtual const char *getName();
+ };
+
+ /* Metric Class *********************************************************/
+ class Metric
+ {
+ public:
+ Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
+ mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
+ {
+ if (mAggregate)
+ {
+ mName.append(":");
+ mName.append(mAggregate->getName());
+ }
+ }
+
+ ~Metric()
+ {
+ delete mAggregate;
+ }
+ bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
+
+ const char *getName() { return mName.c_str(); };
+ ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
+ const char *getDescription()
+ { return mAggregate ? "" : mSubMetric->getDescription(); };
+ const char *getUnit() { return mBaseMetric->getUnit(); };
+ ULONG getMinValue() { return mBaseMetric->getMinValue(); };
+ ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
+ ULONG getPeriod() { return mBaseMetric->getPeriod(); };
+ ULONG getLength()
+ { return mAggregate ? 1 : mBaseMetric->getLength(); };
+ ULONG getScale() { return mBaseMetric->getScale(); }
+ void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
+
+ private:
+ RTCString mName;
+ BaseMetric *mBaseMetric;
+ SubMetric *mSubMetric;
+ Aggregate *mAggregate;
+ };
+
+ /* Filter Class *********************************************************/
+
+ class Filter
+ {
+ public:
+ Filter(const std::vector<com::Utf8Str> &metricNames,
+ const std::vector<ComPtr<IUnknown> > &objects);
+ Filter(const com::Utf8Str &name, const ComPtr<IUnknown> &aObject);
+ static bool patternMatch(const char *pszPat, const char *pszName,
+ bool fSeenColon = false);
+ bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
+ private:
+ typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
+ typedef std::list<FilterElement> ElementList;
+
+ ElementList mElements;
+
+ void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
+ };
+}
+#endif /* !MAIN_INCLUDED_Performance_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/PerformanceImpl.h b/src/VBox/Main/include/PerformanceImpl.h
new file mode 100644
index 00000000..bc01d8a3
--- /dev/null
+++ b/src/VBox/Main/include/PerformanceImpl.h
@@ -0,0 +1,206 @@
+/* $Id: PerformanceImpl.h $ */
+
+/** @file
+ *
+ * VBox Performance COM class implementation.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_PerformanceImpl_h
+#define MAIN_INCLUDED_PerformanceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "PerformanceCollectorWrap.h"
+#include "PerformanceMetricWrap.h"
+
+#include <VBox/com/com.h>
+#include <VBox/com/array.h>
+//#ifdef VBOX_WITH_RESOURCE_USAGE_API
+#include <iprt/timer.h>
+//#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+
+#include <list>
+
+namespace pm
+{
+ class Metric;
+ class BaseMetric;
+ class CollectorHAL;
+ class CollectorGuest;
+ class CollectorGuestManager;
+}
+
+#undef min
+#undef max
+
+/* Each second we obtain new CPU load stats. */
+#define VBOX_USAGE_SAMPLER_MIN_INTERVAL 1000
+
+class ATL_NO_VTABLE PerformanceMetric :
+ public PerformanceMetricWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(PerformanceMetric)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(pm::Metric *aMetric);
+ HRESULT init(pm::BaseMetric *aMetric);
+ void uninit();
+
+private:
+
+ // wrapped IPerformanceMetric properties
+ HRESULT getMetricName(com::Utf8Str &aMetricName);
+ HRESULT getObject(ComPtr<IUnknown> &aObject);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT getPeriod(ULONG *aPeriod);
+ HRESULT getCount(ULONG *aCount);
+ HRESULT getUnit(com::Utf8Str &aUnit);
+ HRESULT getMinimumValue(LONG *aMinimumValue);
+ HRESULT getMaximumValue(LONG *aMaximumValue);
+
+ struct Data
+ {
+ /* Constructor. */
+ Data()
+ : period(0), count(0), min(0), max(0)
+ {
+ }
+
+ Utf8Str name;
+ ComPtr<IUnknown> object;
+ Utf8Str description;
+ ULONG period;
+ ULONG count;
+ Utf8Str unit;
+ LONG min;
+ LONG max;
+ };
+
+ Data m;
+};
+
+
+class ATL_NO_VTABLE PerformanceCollector :
+ public PerformanceCollectorWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(PerformanceCollector)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializers/uninitializers only for internal purposes
+ HRESULT init();
+ void uninit();
+
+ // public methods only for internal purposes
+
+ void registerBaseMetric(pm::BaseMetric *baseMetric);
+ void registerMetric(pm::Metric *metric);
+ void unregisterBaseMetricsFor(const ComPtr<IUnknown> &object, const Utf8Str name = "*");
+ void unregisterMetricsFor(const ComPtr<IUnknown> &object, const Utf8Str name = "*");
+ void registerGuest(pm::CollectorGuest* pGuest);
+ void unregisterGuest(pm::CollectorGuest* pGuest);
+
+ void suspendSampling();
+ void resumeSampling();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+
+ pm::CollectorHAL *getHAL() { return m.hal; };
+ pm::CollectorGuestManager *getGuestManager() { return m.gm; };
+
+private:
+
+ // wrapped IPerformanceCollector properties
+ HRESULT getMetricNames(std::vector<com::Utf8Str> &aMetricNames);
+
+ // wrapped IPerformanceCollector methods
+ HRESULT getMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+ const std::vector<ComPtr<IUnknown> > &aObjects,
+ std::vector<ComPtr<IPerformanceMetric> > &aMetrics);
+ HRESULT setupMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+ const std::vector<ComPtr<IUnknown> > &aObjects,
+ ULONG aPeriod,
+ ULONG aCount,
+ std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics);
+ HRESULT enableMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+ const std::vector<ComPtr<IUnknown> > &aObjects,
+ std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics);
+ HRESULT disableMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+ const std::vector<ComPtr<IUnknown> > &aObjects,
+ std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics);
+ HRESULT queryMetricsData(const std::vector<com::Utf8Str> &aMetricNames,
+ const std::vector<ComPtr<IUnknown> > &aObjects,
+ std::vector<com::Utf8Str> &aReturnMetricNames,
+ std::vector<ComPtr<IUnknown> > &aReturnObjects,
+ std::vector<com::Utf8Str> &aReturnUnits,
+ std::vector<ULONG> &aReturnScales,
+ std::vector<ULONG> &aReturnSequenceNumbers,
+ std::vector<ULONG> &aReturnDataIndices,
+ std::vector<ULONG> &aReturnDataLengths,
+ std::vector<LONG> &aReturnData);
+
+
+ HRESULT toIPerformanceMetric(pm::Metric *src, ComPtr<IPerformanceMetric> &dst);
+ HRESULT toIPerformanceMetric(pm::BaseMetric *src, ComPtr<IPerformanceMetric> &dst);
+
+ static DECLCALLBACK(void) staticSamplerCallback(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
+ void samplerCallback(uint64_t iTick);
+
+ const Utf8Str& getFailedGuestName();
+
+ typedef std::list<pm::Metric*> MetricList;
+ typedef std::list<pm::BaseMetric*> BaseMetricList;
+
+/** PerformanceMetric::mMagic value. */
+#define PERFORMANCE_METRIC_MAGIC UINT32_C(0xABBA1972)
+ uint32_t mMagic;
+ const Utf8Str mUnknownGuest;
+
+ struct Data
+ {
+ Data() : hal(0) {};
+
+ BaseMetricList baseMetrics;
+ MetricList metrics;
+ RTTIMERLR sampler;
+ pm::CollectorHAL *hal;
+ pm::CollectorGuestManager *gm;
+ };
+
+ Data m;
+};
+
+#endif /* !MAIN_INCLUDED_PerformanceImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/ProgressImpl.h b/src/VBox/Main/include/ProgressImpl.h
new file mode 100644
index 00000000..341a6672
--- /dev/null
+++ b/src/VBox/Main/include/ProgressImpl.h
@@ -0,0 +1,259 @@
+/* $Id: ProgressImpl.h $ */
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ProgressImpl_h
+#define MAIN_INCLUDED_ProgressImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "ProgressWrap.h"
+#include "VirtualBoxBase.h"
+#include "EventImpl.h"
+
+#include <iprt/semaphore.h>
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Class for progress objects.
+ */
+class ATL_NO_VTABLE Progress :
+ public ProgressWrap
+{
+public:
+ DECLARE_NOT_AGGREGATABLE(Progress)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+
+ /**
+ * Simplified constructor for progress objects that have only one
+ * operation as a task.
+ * @param aParent
+ * @param aInitiator
+ * @param aDescription
+ * @param aCancelable
+ * @return
+ */
+ HRESULT init(
+#if !defined(VBOX_COM_INPROC)
+ VirtualBox *aParent,
+#endif
+ IUnknown *aInitiator,
+ const Utf8Str &aDescription,
+ BOOL aCancelable)
+ {
+ return init(
+#if !defined(VBOX_COM_INPROC)
+ aParent,
+#endif
+ aInitiator,
+ aDescription,
+ aCancelable,
+ 1, // cOperations
+ 1, // ulTotalOperationsWeight
+ aDescription, // aFirstOperationDescription
+ 1); // ulFirstOperationWeight
+ }
+
+ /**
+ * Not quite so simplified constructor for progress objects that have
+ * more than one operation, but all sub-operations are weighed the same.
+ * @param aParent
+ * @param aInitiator
+ * @param aDescription
+ * @param aCancelable
+ * @param cOperations
+ * @param aFirstOperationDescription
+ * @return
+ */
+ HRESULT init(
+#if !defined(VBOX_COM_INPROC)
+ VirtualBox *aParent,
+#endif
+ IUnknown *aInitiator,
+ const Utf8Str &aDescription, BOOL aCancelable,
+ ULONG cOperations,
+ const Utf8Str &aFirstOperationDescription)
+ {
+ return init(
+#if !defined(VBOX_COM_INPROC)
+ aParent,
+#endif
+ aInitiator,
+ aDescription,
+ aCancelable,
+ cOperations, // cOperations
+ cOperations, // ulTotalOperationsWeight = cOperations
+ aFirstOperationDescription, // aFirstOperationDescription
+ 1); // ulFirstOperationWeight: weigh them all the same
+ }
+
+ HRESULT init(
+#if !defined(VBOX_COM_INPROC)
+ VirtualBox *aParent,
+#endif
+ IUnknown *aInitiator,
+ const Utf8Str &aDescription,
+ BOOL aCancelable,
+ ULONG cOperations,
+ ULONG ulTotalOperationsWeight,
+ const Utf8Str &aFirstOperationDescription,
+ ULONG ulFirstOperationWeight);
+
+ HRESULT init(BOOL aCancelable,
+ ULONG aOperationCount,
+ const Utf8Str &aOperationDescription);
+
+ void uninit();
+
+
+ // public methods only for internal purposes
+ HRESULT i_notifyComplete(HRESULT aResultCode);
+ HRESULT i_notifyComplete(HRESULT aResultCode,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const char *aText,
+ ...);
+ HRESULT i_notifyCompleteV(HRESULT aResultCode,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const char *aText,
+ va_list va);
+ HRESULT i_notifyCompleteBoth(HRESULT aResultCode,
+ int vrc,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const char *aText,
+ ...);
+ HRESULT i_notifyCompleteBothV(HRESULT aResultCode,
+ int vrc,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const char *aText,
+ va_list va);
+
+ bool i_setCancelCallback(void (*pfnCallback)(void *), void *pvUser);
+
+ static DECLCALLBACK(int) i_iprtProgressCallback(unsigned uPercentage, void *pvUser);
+ static DECLCALLBACK(int) i_vdProgressCallback(void *pvUser, unsigned uPercentage);
+
+protected:
+ DECLARE_COMMON_CLASS_METHODS(Progress)
+
+#if !defined(VBOX_COM_INPROC)
+ /** Weak parent. */
+ VirtualBox * const mParent;
+#endif
+ const ComObjPtr<EventSource> pEventSource;
+ const ComPtr<IUnknown> mInitiator;
+
+ const Guid mId;
+ const com::Utf8Str mDescription;
+
+ uint64_t m_ullTimestamp; // progress object creation timestamp, for ETA computation
+
+ void (*m_pfnCancelCallback)(void *);
+ void *m_pvCancelUserArg;
+
+ /* The fields below are to be properly initialized by subclasses */
+
+ BOOL mCompleted;
+ BOOL mCancelable;
+ BOOL mCanceled;
+ HRESULT mResultCode;
+ ComPtr<IVirtualBoxErrorInfo> mErrorInfo;
+
+ ULONG m_cOperations; // number of operations (so that progress dialog can
+ // display something like 1/3)
+ ULONG m_ulTotalOperationsWeight; // sum of weights of all operations, given to constructor
+
+ ULONG m_ulOperationsCompletedWeight; // summed-up weight of operations that have been completed; initially 0
+
+ ULONG m_ulCurrentOperation; // operations counter, incremented with
+ // each setNextOperation()
+ com::Utf8Str m_operationDescription; // name of current operation; initially
+ // from constructor, changed with setNextOperation()
+ ULONG m_ulCurrentOperationWeight; // weight of current operation, given to setNextOperation()
+ ULONG m_ulOperationPercent; // percentage of current operation, set with setCurrentOperationProgress()
+ ULONG m_cMsTimeout; /**< Automatic timeout value. 0 means none. */
+
+private:
+ // wrapped IProgress properties
+ HRESULT getId(com::Guid &aId);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT getInitiator(ComPtr<IUnknown> &aInitiator);
+ HRESULT getCancelable(BOOL *aCancelable);
+ HRESULT getPercent(ULONG *aPercent);
+ HRESULT getTimeRemaining(LONG *aTimeRemaining);
+ HRESULT getCompleted(BOOL *aCompleted);
+ HRESULT getCanceled(BOOL *aCanceled);
+ HRESULT getResultCode(LONG *aResultCode);
+ HRESULT getErrorInfo(ComPtr<IVirtualBoxErrorInfo> &aErrorInfo);
+ HRESULT getOperationCount(ULONG *aOperationCount);
+ HRESULT getOperation(ULONG *aOperation);
+ HRESULT getOperationDescription(com::Utf8Str &aOperationDescription);
+ HRESULT getOperationPercent(ULONG *aOperationPercent);
+ HRESULT getOperationWeight(ULONG *aOperationWeight);
+ HRESULT getTimeout(ULONG *aTimeout);
+ HRESULT setTimeout(ULONG aTimeout);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+
+ // wrapped IProgress methods
+ HRESULT waitForCompletion(LONG aTimeout);
+ HRESULT waitForOperationCompletion(ULONG aOperation,
+ LONG aTimeout);
+ HRESULT cancel();
+
+ // wrapped IInternalProgressControl methods
+ HRESULT setCurrentOperationProgress(ULONG aPercent);
+ HRESULT waitForOtherProgressCompletion(const ComPtr<IProgress> &aProgressOther,
+ ULONG aTimeoutMS);
+ HRESULT setNextOperation(const com::Utf8Str &aNextOperationDescription,
+ ULONG aNextOperationsWeight);
+ HRESULT notifyPointOfNoReturn();
+ HRESULT notifyComplete(LONG aResultCode,
+ const ComPtr<IVirtualBoxErrorInfo> &aErrorInfo);
+
+ // internal helper methods
+ HRESULT i_notifyCompleteWorker(HRESULT aResultCode, const ComPtr<IVirtualBoxErrorInfo> &aErrorInfo);
+ double i_calcTotalPercent();
+ void i_checkForAutomaticTimeout(void);
+
+ RTSEMEVENTMULTI mCompletedSem;
+ ULONG mWaitersCount;
+
+private:
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(Progress); /* Shuts up MSC warning C4625. */
+};
+
+#endif /* !MAIN_INCLUDED_ProgressImpl_h */
+
diff --git a/src/VBox/Main/include/ProgressProxyImpl.h b/src/VBox/Main/include/ProgressProxyImpl.h
new file mode 100644
index 00000000..40cc2e39
--- /dev/null
+++ b/src/VBox/Main/include/ProgressProxyImpl.h
@@ -0,0 +1,130 @@
+/* $Id: ProgressProxyImpl.h $ */
+/** @file
+ * IProgress implementation for Machine::LaunchVMProcess in VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ProgressProxyImpl_h
+#define MAIN_INCLUDED_ProgressProxyImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "ProgressImpl.h"
+#include "AutoCaller.h"
+
+
+/**
+ * The ProgressProxy class allows proxying the important Progress calls and
+ * attributes to a different IProgress object for a period of time.
+ */
+class ATL_NO_VTABLE ProgressProxy :
+ public Progress
+{
+public:
+ VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(ProgressProxy, IProgress)
+
+ DECLARE_NOT_AGGREGATABLE(ProgressProxy)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(ProgressProxy)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+ COM_INTERFACE_ENTRY(IProgress)
+ COM_INTERFACE_ENTRY2(IDispatch, IProgress)
+ VBOX_TWEAK_INTERFACE_ENTRY(IProgress)
+ END_COM_MAP()
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+ HRESULT init(
+#ifndef VBOX_COM_INPROC
+ VirtualBox *pParent,
+#endif
+ IUnknown *pInitiator,
+ Utf8Str strDescription,
+ BOOL fCancelable);
+ HRESULT init(
+#ifndef VBOX_COM_INPROC
+ VirtualBox *pParent,
+#endif
+ IUnknown *pInitiator,
+ Utf8Str strDescription,
+ BOOL fCancelable,
+ ULONG uTotalOperationsWeight,
+ Utf8Str strFirstOperationDescription,
+ ULONG uFirstOperationWeight,
+ ULONG cOtherProgressObjectOperations);
+ void uninit();
+
+ // IProgress properties
+ STDMETHOD(COMGETTER(Cancelable))(BOOL *aCancelable);
+ STDMETHOD(COMGETTER(Percent))(ULONG *aPercent);
+ STDMETHOD(COMGETTER(TimeRemaining))(LONG *aTimeRemaining);
+ STDMETHOD(COMGETTER(Completed))(BOOL *aCompleted);
+ STDMETHOD(COMGETTER(Canceled))(BOOL *aCanceled);
+ STDMETHOD(COMGETTER(ResultCode))(LONG *aResultCode);
+ STDMETHOD(COMGETTER(ErrorInfo))(IVirtualBoxErrorInfo **aErrorInfo);
+ //STDMETHOD(COMGETTER(OperationCount))(ULONG *aOperationCount); - not necessary
+ STDMETHOD(COMGETTER(Operation))(ULONG *aOperation);
+ STDMETHOD(COMGETTER(OperationDescription))(BSTR *aOperationDescription);
+ STDMETHOD(COMGETTER(OperationPercent))(ULONG *aOperationPercent);
+ STDMETHOD(COMSETTER(Timeout))(ULONG aTimeout);
+ STDMETHOD(COMGETTER(Timeout))(ULONG *aTimeout);
+
+ // IProgress methods
+ STDMETHOD(WaitForCompletion)(LONG aTimeout);
+ STDMETHOD(WaitForOperationCompletion)(ULONG aOperation, LONG aTimeout);
+ STDMETHOD(Cancel)();
+ STDMETHOD(SetCurrentOperationProgress)(ULONG aPercent);
+ STDMETHOD(SetNextOperation)(IN_BSTR bstrNextOperationDescription, ULONG ulNextOperationsWeight);
+
+ // public methods only for internal purposes
+
+ HRESULT notifyComplete(HRESULT aResultCode);
+ HRESULT notifyComplete(HRESULT aResultCode,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const char *aText, ...);
+ bool setOtherProgressObject(IProgress *pOtherProgress);
+
+protected:
+ void clearOtherProgressObjectInternal(bool fEarly);
+ void copyProgressInfo(IProgress *pOtherProgress, bool fEarly);
+
+private:
+ /** The other progress object. This can be NULL. */
+ ComPtr<IProgress> mptrOtherProgress;
+ /** Set if the other progress object has multiple operations. */
+ bool mfMultiOperation;
+ /** The weight the other progress object started at. */
+ ULONG muOtherProgressStartWeight;
+ /** The weight of other progress object. */
+ ULONG muOtherProgressWeight;
+ /** The operation number the other progress object started at. */
+ ULONG muOtherProgressStartOperation;
+
+};
+
+#endif /* !MAIN_INCLUDED_ProgressProxyImpl_h */
+
diff --git a/src/VBox/Main/include/QMTranslator.h b/src/VBox/Main/include/QMTranslator.h
new file mode 100644
index 00000000..95616fa5
--- /dev/null
+++ b/src/VBox/Main/include/QMTranslator.h
@@ -0,0 +1,79 @@
+/* $Id: QMTranslator.h $ */
+/** @file
+ * VirtualBox API translation handling class
+ */
+
+/*
+ * Copyright (C) 2014-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_QMTranslator_h
+#define MAIN_INCLUDED_QMTranslator_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+class QMTranslator_Impl;
+
+class QMTranslator
+{
+public:
+ QMTranslator();
+ virtual ~QMTranslator();
+
+ /**
+ * Gets translation from loaded QM file
+ *
+ * @param pszContext QM context to look for translation
+ * @param pszSource Source string in one-byte encoding
+ * @param ppszSafeSource Where to return pointer to a safe copy of @a
+ * pszSource for the purpose of reverse translation.
+ * Will be set to NULL if @a pszSource is returned.
+ * @param pszDisamb Disambiguationg comment, empty by default
+ * @param aNum Plural form indicator.
+ *
+ * @returns Pointer to a translation (UTF-8 encoding), source string on failure.
+ */
+ const char *translate(const char *pszContext, const char *pszSource, const char **ppszSafeSource,
+ const char *pszDisamb = NULL, const size_t aNum = ~(size_t)0) const RT_NOEXCEPT;
+
+ /**
+ * Loads and parses QM file
+ *
+ * @param pszFilename The name of the file to load
+ * @param hStrCache The string cache to use for storing strings.
+ *
+ * @returns VBox status code.
+ */
+ int load(const char *pszFilename, RTSTRCACHE hStrCache) RT_NOEXCEPT;
+
+private:
+ /** QMTranslator implementation.
+ * To separate all the code from the interface */
+ QMTranslator_Impl *m_impl;
+
+ /* If copying is required, please define the following operators */
+ void operator=(QMTranslator &);
+ QMTranslator(const QMTranslator &);
+};
+
+#endif /* !MAIN_INCLUDED_QMTranslator_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/Recording.h b/src/VBox/Main/include/Recording.h
new file mode 100644
index 00000000..2679ae2b
--- /dev/null
+++ b/src/VBox/Main/include/Recording.h
@@ -0,0 +1,174 @@
+/* $Id: Recording.h $ */
+/** @file
+ * Recording code header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_Recording_h
+#define MAIN_INCLUDED_Recording_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/err.h>
+#include <VBox/settings.h>
+
+#include "RecordingStream.h"
+
+class Console;
+
+/**
+ * Class for managing a recording context.
+ */
+class RecordingContext
+{
+public:
+
+ RecordingContext();
+
+ RecordingContext(Console *ptrConsole, const settings::RecordingSettings &Settings);
+
+ virtual ~RecordingContext(void);
+
+public:
+
+ const settings::RecordingSettings &GetConfig(void) const;
+ RecordingStream *GetStream(unsigned uScreen) const;
+ size_t GetStreamCount(void) const;
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ PRECORDINGCODEC GetCodecAudio(void) { return &this->m_CodecAudio; }
+#endif
+
+ int Create(Console *pConsole, const settings::RecordingSettings &Settings);
+ void Destroy(void);
+
+ int Start(void);
+ int Stop(void);
+
+ int SendAudioFrame(const void *pvData, size_t cbData, uint64_t uTimestampMs);
+ int SendVideoFrame(uint32_t uScreen,
+ uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP,
+ uint32_t uBytesPerLine, uint32_t uSrcWidth, uint32_t uSrcHeight,
+ uint8_t *puSrcData, uint64_t msTimestamp);
+public:
+
+ bool IsFeatureEnabled(RecordingFeature_T enmFeature);
+ bool IsReady(void);
+ bool IsReady(uint32_t uScreen, uint64_t msTimestamp);
+ bool IsStarted(void);
+ bool IsLimitReached(void);
+ bool IsLimitReached(uint32_t uScreen, uint64_t msTimestamp);
+ bool NeedsUpdate(uint32_t uScreen, uint64_t msTimestamp);
+
+ DECLCALLBACK(int) OnLimitReached(uint32_t uScreen, int vrc);
+
+protected:
+
+ int createInternal(Console *ptrConsole, const settings::RecordingSettings &Settings);
+ int startInternal(void);
+ int stopInternal(void);
+
+ void destroyInternal(void);
+
+ RecordingStream *getStreamInternal(unsigned uScreen) const;
+
+ int processCommonData(RecordingBlockMap &mapCommon, RTMSINTERVAL msTimeout);
+ int writeCommonData(RecordingBlockMap &mapCommon, PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags);
+
+ int lock(void);
+ int unlock(void);
+
+ static DECLCALLBACK(int) threadMain(RTTHREAD hThreadSelf, void *pvUser);
+
+ int threadNotify(void);
+
+protected:
+
+ int audioInit(const settings::RecordingScreenSettings &screenSettings);
+
+ static DECLCALLBACK(int) audioCodecWriteDataCallback(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser);
+
+protected:
+
+ /**
+ * Enumeration for a recording context state.
+ */
+ enum RECORDINGSTS
+ {
+ /** Context not initialized. */
+ RECORDINGSTS_UNINITIALIZED = 0,
+ /** Context was created. */
+ RECORDINGSTS_CREATED = 1,
+ /** Context was started. */
+ RECORDINGSTS_STARTED = 2,
+ /** The usual 32-bit hack. */
+ RECORDINGSTS_32BIT_HACK = 0x7fffffff
+ };
+
+ /** Pointer to the console object. */
+ Console *m_pConsole;
+ /** Used recording configuration. */
+ settings::RecordingSettings m_Settings;
+ /** The current state. */
+ RECORDINGSTS m_enmState;
+ /** Critical section to serialize access. */
+ RTCRITSECT m_CritSect;
+ /** Semaphore to signal the encoding worker thread. */
+ RTSEMEVENT m_WaitEvent;
+ /** Shutdown indicator. */
+ bool m_fShutdown;
+ /** Encoding worker thread. */
+ RTTHREAD m_Thread;
+ /** Vector of current recording streams.
+ * Per VM screen (display) one recording stream is being used. */
+ RecordingStreams m_vecStreams;
+ /** Number of streams in vecStreams which currently are enabled for recording. */
+ uint16_t m_cStreamsEnabled;
+ /** Timestamp (in ms) of when recording has been started. */
+ uint64_t m_tsStartMs;
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ /** Audio codec to use.
+ *
+ * We multiplex audio data from this recording context to all streams,
+ * to avoid encoding the same audio data for each stream. We ASSUME that
+ * all audio data of a VM will be the same for each stream at a given
+ * point in time. */
+ RECORDINGCODEC m_CodecAudio;
+#endif /* VBOX_WITH_AUDIO_RECORDING */
+ /** Block map of raw common data blocks which need to get encoded first. */
+ RecordingBlockMap m_mapBlocksRaw;
+ /** Block map of encoded common blocks.
+ *
+ * Only do the encoding of common data blocks only once and then multiplex
+ * the encoded data to all affected recording streams.
+ *
+ * This avoids doing the (expensive) encoding + multiplexing work in other
+ * threads like EMT / audio async I/O..
+ *
+ * For now this only affects audio, e.g. all recording streams
+ * need to have the same audio data at a specific point in time. */
+ RecordingBlockMap m_mapBlocksEncoded;
+};
+#endif /* !MAIN_INCLUDED_Recording_h */
+
diff --git a/src/VBox/Main/include/RecordingInternals.h b/src/VBox/Main/include/RecordingInternals.h
new file mode 100644
index 00000000..a98f1be5
--- /dev/null
+++ b/src/VBox/Main/include/RecordingInternals.h
@@ -0,0 +1,504 @@
+/* $Id: RecordingInternals.h $ */
+/** @file
+ * Recording internals header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RecordingInternals_h
+#define MAIN_INCLUDED_RecordingInternals_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <list>
+
+#include <iprt/assert.h>
+#include <iprt/types.h> /* drag in stdint.h before vpx does it. */
+
+#include "VBox/com/string.h"
+#include "VBox/com/VirtualBox.h"
+#include "VBox/settings.h"
+#include <VBox/vmm/pdmaudioifs.h>
+
+#ifdef VBOX_WITH_LIBVPX
+# define VPX_CODEC_DISABLE_COMPAT 1
+# include "vpx/vp8cx.h"
+# include "vpx/vpx_image.h"
+# include "vpx/vpx_encoder.h"
+#endif /* VBOX_WITH_LIBVPX */
+
+#ifdef VBOX_WITH_LIBVORBIS
+# include "vorbis/vorbisenc.h"
+#endif
+
+
+/*********************************************************************************************************************************
+* Defines *
+*********************************************************************************************************************************/
+#define VBOX_RECORDING_VORBIS_HZ_MAX 48000 /**< Maximum sample rate (in Hz) Vorbis can handle. */
+#define VBOX_RECORDING_VORBIS_FRAME_MS_DEFAULT 20 /**< Default Vorbis frame size (in ms). */
+
+
+/*********************************************************************************************************************************
+* Prototypes *
+*********************************************************************************************************************************/
+struct RECORDINGCODEC;
+typedef RECORDINGCODEC *PRECORDINGCODEC;
+
+struct RECORDINGFRAME;
+typedef RECORDINGFRAME *PRECORDINGFRAME;
+
+
+/*********************************************************************************************************************************
+* Internal structures, defines and APIs *
+*********************************************************************************************************************************/
+
+/**
+ * Enumeration for specifying a (generic) codec type.
+ */
+typedef enum RECORDINGCODECTYPE
+{
+ /** Invalid codec type. Do not use. */
+ RECORDINGCODECTYPE_INVALID = 0,
+ /** Video codec. */
+ RECORDINGCODECTYPE_VIDEO,
+ /** Audio codec. */
+ RECORDINGCODECTYPE_AUDIO
+} RECORDINGCODECTYPE;
+
+/**
+ * Structure for keeping a codec operations table.
+ */
+typedef struct RECORDINGCODECOPS
+{
+ /**
+ * Initializes a codec.
+ *
+ * @returns VBox status code.
+ * @param pCodec Codec instance to initialize.
+ */
+ DECLCALLBACKMEMBER(int, pfnInit, (PRECORDINGCODEC pCodec));
+
+ /**
+ * Destroys a codec.
+ *
+ * @returns VBox status code.
+ * @param pCodec Codec instance to destroy.
+ */
+ DECLCALLBACKMEMBER(int, pfnDestroy, (PRECORDINGCODEC pCodec));
+
+ /**
+ * Parses an options string to configure advanced / hidden / experimental features of a recording stream.
+ * Unknown values will be skipped. Optional.
+ *
+ * @returns VBox status code.
+ * @param pCodec Codec instance to parse options for.
+ * @param strOptions Options string to parse.
+ */
+ DECLCALLBACKMEMBER(int, pfnParseOptions, (PRECORDINGCODEC pCodec, const com::Utf8Str &strOptions));
+
+ /**
+ * Feeds the codec encoder with data to encode.
+ *
+ * @returns VBox status code.
+ * @param pCodec Codec instance to use.
+ * @param pFrame Pointer to frame data to encode.
+ * @param pcEncoded Where to return the number of encoded blocks in \a pvDst on success. Optional.
+ * @param pcbEncoded Where to return the number of encoded bytes in \a pvDst on success. Optional.
+ */
+ DECLCALLBACKMEMBER(int, pfnEncode, (PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded));
+
+ /**
+ * Tells the codec to finalize the current stream. Optional.
+ *
+ * @returns VBox status code.
+ * @param pCodec Codec instance to finalize stream for.
+ */
+ DECLCALLBACKMEMBER(int, pfnFinalize, (PRECORDINGCODEC pCodec));
+} RECORDINGCODECOPS, *PRECORDINGCODECOPS;
+
+/** No encoding flags set. */
+#define RECORDINGCODEC_ENC_F_NONE UINT32_C(0)
+/** Data block is a key block. */
+#define RECORDINGCODEC_ENC_F_BLOCK_IS_KEY RT_BIT_32(0)
+/** Data block is invisible. */
+#define RECORDINGCODEC_ENC_F_BLOCK_IS_INVISIBLE RT_BIT_32(1)
+/** Encoding flags valid mask. */
+#define RECORDINGCODEC_ENC_F_VALID_MASK 0x1
+
+/**
+ * Structure for keeping a codec callback table.
+ */
+typedef struct RECORDINGCODECCALLBACKS
+{
+ /**
+ * Callback for notifying that encoded data has been written.
+ *
+ * @returns VBox status code.
+ * @param pCodec Pointer to codec instance which has written the data.
+ * @param pvData Pointer to written data (encoded).
+ * @param cbData Size (in bytes) of \a pvData.
+ * @param msAbsPTS Absolute PTS (in ms) of the written data.
+ * @param uFlags Encoding flags of type RECORDINGCODEC_ENC_F_XXX.
+ * @param pvUser User-supplied pointer.
+ */
+ DECLCALLBACKMEMBER(int, pfnWriteData, (PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser));
+ /** User-supplied data pointer. */
+ void *pvUser;
+} RECORDINGCODECCALLBACKS, *PRECORDINGCODECCALLBACKS;
+
+/**
+ * Structure for keeping generic codec parameters.
+ */
+typedef struct RECORDINGCODECPARMS
+{
+ /** The generic codec type. */
+ RECORDINGCODECTYPE enmType;
+ /** The specific codec type, based on \a enmType. */
+ union
+ {
+ /** The container's video codec to use. */
+ RecordingVideoCodec_T enmVideoCodec;
+ /** The container's audio codec to use. */
+ RecordingAudioCodec_T enmAudioCodec;
+ };
+ union
+ {
+ struct
+ {
+ /** Frames per second. */
+ uint8_t uFPS;
+ /** Target width (in pixels) of encoded video image. */
+ uint16_t uWidth;
+ /** Target height (in pixels) of encoded video image. */
+ uint16_t uHeight;
+ /** Minimal delay (in ms) between two video frames.
+ * This value is based on the configured FPS rate. */
+ uint32_t uDelayMs;
+ } Video;
+ struct
+ {
+ /** The codec's used PCM properties. */
+ PDMAUDIOPCMPROPS PCMProps;
+ } Audio;
+ };
+ /** Desired (average) bitrate (in kbps) to use, for codecs which support bitrate management.
+ * Set to 0 to use a variable bit rate (VBR) (if available, otherwise fall back to CBR). */
+ uint32_t uBitrate;
+ /** Time (in ms) the encoder expects us to send data to encode.
+ *
+ * For Vorbis, valid frame sizes are powers of two from 64 to 8192 bytes.
+ */
+ uint32_t msFrame;
+ /** The frame size in bytes (based on \a msFrame). */
+ uint32_t cbFrame;
+ /** The frame size in samples per frame (based on \a msFrame). */
+ uint32_t csFrame;
+} RECORDINGCODECPARMS, *PRECORDINGCODECPARMS;
+
+#ifdef VBOX_WITH_LIBVPX
+/**
+ * VPX encoder state (needs libvpx).
+ */
+typedef struct RECORDINGCODECVPX
+{
+ /** VPX codec context. */
+ vpx_codec_ctx_t Ctx;
+ /** VPX codec configuration. */
+ vpx_codec_enc_cfg_t Cfg;
+ /** VPX image context. */
+ vpx_image_t RawImage;
+ /** Pointer to the codec's internal YUV buffer. */
+ uint8_t *pu8YuvBuf;
+ /** The encoder's deadline (in ms).
+ * The more time the encoder is allowed to spend encoding, the better the encoded
+ * result, in exchange for higher CPU usage and time spent encoding. */
+ unsigned int uEncoderDeadline;
+} RECORDINGCODECVPX;
+/** Pointer to a VPX encoder state. */
+typedef RECORDINGCODECVPX *PRECORDINGCODECVPX;
+#endif /* VBOX_WITH_LIBVPX */
+
+#ifdef VBOX_WITH_LIBVORBIS
+/**
+ * Vorbis encoder state (needs libvorbis + libogg).
+ */
+typedef struct RECORDINGCODECVORBIS
+{
+ /** Basic information about the audio in a Vorbis bitstream. */
+ vorbis_info info;
+ /** Encoder state. */
+ vorbis_dsp_state dsp_state;
+ /** Current block being worked on. */
+ vorbis_block block_cur;
+} RECORDINGCODECVORBIS;
+/** Pointer to a Vorbis encoder state. */
+typedef RECORDINGCODECVORBIS *PRECORDINGCODECVORBIS;
+#endif /* VBOX_WITH_LIBVORBIS */
+
+/**
+ * Structure for keeping a codec's internal state.
+ */
+typedef struct RECORDINGCODECSTATE
+{
+ /** Timestamp Timestamp (PTS, in ms) of the last frame was encoded. */
+ uint64_t tsLastWrittenMs;
+ /** Number of encoding errors. */
+ uint64_t cEncErrors;
+} RECORDINGCODECSTATE;
+/** Pointer to an internal encoder state. */
+typedef RECORDINGCODECSTATE *PRECORDINGCODECSTATE;
+
+/**
+ * Structure for keeping codec-specific data.
+ */
+typedef struct RECORDINGCODEC
+{
+ /** Callback table for codec operations. */
+ RECORDINGCODECOPS Ops;
+ /** Table for user-supplied callbacks. */
+ RECORDINGCODECCALLBACKS Callbacks;
+ /** Generic codec parameters. */
+ RECORDINGCODECPARMS Parms;
+ /** Generic codec parameters. */
+ RECORDINGCODECSTATE State;
+
+#ifdef VBOX_WITH_LIBVPX
+ union
+ {
+ RECORDINGCODECVPX VPX;
+ } Video;
+#endif
+
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ union
+ {
+# ifdef VBOX_WITH_LIBVORBIS
+ RECORDINGCODECVORBIS Vorbis;
+# endif /* VBOX_WITH_LIBVORBIS */
+ } Audio;
+#endif /* VBOX_WITH_AUDIO_RECORDING */
+
+ /** Internal scratch buffer for en-/decoding steps. */
+ void *pvScratch;
+ /** Size (in bytes) of \a pvScratch. */
+ uint32_t cbScratch;
+
+#ifdef VBOX_WITH_STATISTICS /** @todo Register these values with STAM. */
+ struct
+ {
+ /** Number of frames encoded. */
+ uint64_t cEncBlocks;
+ /** Total time (in ms) of already encoded audio data. */
+ uint64_t msEncTotal;
+ } STAM;
+#endif
+} RECORDINGCODEC, *PRECORDINGCODEC;
+
+/**
+ * Enumeration for supported pixel formats.
+ */
+enum RECORDINGPIXELFMT
+{
+ /** Unknown pixel format. */
+ RECORDINGPIXELFMT_UNKNOWN = 0,
+ /** RGB 24. */
+ RECORDINGPIXELFMT_RGB24 = 1,
+ /** RGB 24. */
+ RECORDINGPIXELFMT_RGB32 = 2,
+ /** RGB 565. */
+ RECORDINGPIXELFMT_RGB565 = 3,
+ /** The usual 32-bit hack. */
+ RECORDINGPIXELFMT_32BIT_HACK = 0x7fffffff
+};
+
+/**
+ * Enumeration for a recording frame type.
+ */
+enum RECORDINGFRAME_TYPE
+{
+ /** Invalid frame type; do not use. */
+ RECORDINGFRAME_TYPE_INVALID = 0,
+ /** Frame is an audio frame. */
+ RECORDINGFRAME_TYPE_AUDIO = 1,
+ /** Frame is an video frame. */
+ RECORDINGFRAME_TYPE_VIDEO = 2,
+ /** Frame contains a video frame pointer. */
+ RECORDINGFRAME_TYPE_VIDEO_PTR = 3
+};
+
+/**
+ * Structure for keeping a single recording video frame.
+ */
+typedef struct RECORDINGVIDEOFRAME
+{
+ /** X origin (in pixel) of this frame. */
+ uint16_t uX;
+ /** X origin (in pixel) of this frame. */
+ uint16_t uY;
+ /** X resolution (in pixel) of this frame. */
+ uint16_t uWidth;
+ /** Y resolution (in pixel) of this frame. */
+ uint16_t uHeight;
+ /** Bits per pixel (BPP). */
+ uint8_t uBPP;
+ /** Pixel format of this frame. */
+ RECORDINGPIXELFMT enmPixelFmt;
+ /** Bytes per scan line. */
+ uint16_t uBytesPerLine;
+ /** RGB buffer containing the unmodified frame buffer data from Main's display. */
+ uint8_t *pu8RGBBuf;
+ /** Size (in bytes) of the RGB buffer. */
+ size_t cbRGBBuf;
+} RECORDINGVIDEOFRAME, *PRECORDINGVIDEOFRAME;
+
+/**
+ * Structure for keeping a single recording audio frame.
+ */
+typedef struct RECORDINGAUDIOFRAME
+{
+ /** Pointer to audio data. */
+ uint8_t *pvBuf;
+ /** Size (in bytes) of audio data. */
+ size_t cbBuf;
+} RECORDINGAUDIOFRAME, *PRECORDINGAUDIOFRAME;
+
+/**
+ * Structure for keeping a single recording audio frame.
+ */
+typedef struct RECORDINGFRAME
+{
+ /** List node. */
+ RTLISTNODE Node;
+ /** Stream index (hint) where this frame should go to.
+ * Specify UINT16_MAX to broadcast to all streams. */
+ uint16_t idStream;
+ /** The frame type. */
+ RECORDINGFRAME_TYPE enmType;
+ /** Timestamp (PTS, in ms). */
+ uint64_t msTimestamp;
+ union
+ {
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ /** Audio frame data. */
+ RECORDINGAUDIOFRAME Audio;
+#endif
+ /** Video frame data. */
+ RECORDINGVIDEOFRAME Video;
+ /** A (weak) pointer to a video frame. */
+ RECORDINGVIDEOFRAME *VideoPtr;
+ };
+} RECORDINGFRAME, *PRECORDINGFRAME;
+
+/**
+ * Enumeration for specifying a video recording block type.
+ */
+typedef enum RECORDINGBLOCKTYPE
+{
+ /** Uknown block type, do not use. */
+ RECORDINGBLOCKTYPE_UNKNOWN = 0,
+ /** The block is a video frame. */
+ RECORDINGBLOCKTYPE_VIDEO,
+ /** The block is an audio frame. */
+ RECORDINGBLOCKTYPE_AUDIO
+} RECORDINGBLOCKTYPE;
+
+#ifdef VBOX_WITH_AUDIO_RECORDING
+int RecordingVideoFrameInit(PRECORDINGVIDEOFRAME pFrame, int w, int h, uint8_t uBPP, RECORDINGPIXELFMT enmPixelFmt);
+void RecordingVideoFrameDestroy(PRECORDINGVIDEOFRAME pFrame);
+void RecordingAudioFrameFree(PRECORDINGAUDIOFRAME pFrame);
+#endif
+void RecordingVideoFrameFree(PRECORDINGVIDEOFRAME pFrame);
+void RecordingFrameFree(PRECORDINGFRAME pFrame);
+
+/**
+ * Generic structure for keeping a single video recording (data) block.
+ */
+struct RecordingBlock
+{
+ RecordingBlock()
+ : enmType(RECORDINGBLOCKTYPE_UNKNOWN)
+ , cRefs(0)
+ , uFlags(RECORDINGCODEC_ENC_F_NONE)
+ , pvData(NULL)
+ , cbData(0) { }
+
+ virtual ~RecordingBlock()
+ {
+ Reset();
+ }
+
+ void Reset(void)
+ {
+ switch (enmType)
+ {
+ case RECORDINGBLOCKTYPE_UNKNOWN:
+ break;
+
+ case RECORDINGBLOCKTYPE_VIDEO:
+ RecordingVideoFrameFree((PRECORDINGVIDEOFRAME)pvData);
+ break;
+
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ case RECORDINGBLOCKTYPE_AUDIO:
+ RecordingAudioFrameFree((PRECORDINGAUDIOFRAME)pvData);
+ break;
+#endif
+ default:
+ AssertFailed();
+ break;
+ }
+
+ enmType = RECORDINGBLOCKTYPE_UNKNOWN;
+ cRefs = 0;
+ pvData = NULL;
+ cbData = 0;
+ }
+
+ /** The block's type. */
+ RECORDINGBLOCKTYPE enmType;
+ /** Number of references held of this block. */
+ uint16_t cRefs;
+ /** Block flags of type RECORDINGCODEC_ENC_F_XXX. */
+ uint64_t uFlags;
+ /** The (absolute) timestamp (in ms, PTS) of this block. */
+ uint64_t msTimestamp;
+ /** Opaque data block to the actual block data, depending on the block's type. */
+ void *pvData;
+ /** Size (in bytes) of the (opaque) data block. */
+ size_t cbData;
+};
+
+/** List for keeping video recording (data) blocks. */
+typedef std::list<RecordingBlock *> RecordingBlockList;
+
+int recordingCodecCreateAudio(PRECORDINGCODEC pCodec, RecordingAudioCodec_T enmAudioCodec);
+int recordingCodecCreateVideo(PRECORDINGCODEC pCodec, RecordingVideoCodec_T enmVideoCodec);
+int recordingCodecInit(const PRECORDINGCODEC pCodec, const PRECORDINGCODECCALLBACKS pCallbacks, const settings::RecordingScreenSettings &Settings);
+int recordingCodecDestroy(PRECORDINGCODEC pCodec);
+int recordingCodecEncode(PRECORDINGCODEC pCodec, const PRECORDINGFRAME pFrame, size_t *pcEncoded, size_t *pcbEncoded);
+int recordingCodecFinalize(PRECORDINGCODEC pCodec);
+bool recordingCodecIsInitialized(const PRECORDINGCODEC pCodec);
+uint32_t recordingCodecGetWritable(const PRECORDINGCODEC pCodec, uint64_t msTimestamp);
+#endif /* !MAIN_INCLUDED_RecordingInternals_h */
diff --git a/src/VBox/Main/include/RecordingScreenSettingsImpl.h b/src/VBox/Main/include/RecordingScreenSettingsImpl.h
new file mode 100644
index 00000000..55c25f2c
--- /dev/null
+++ b/src/VBox/Main/include/RecordingScreenSettingsImpl.h
@@ -0,0 +1,141 @@
+/* $Id: RecordingScreenSettingsImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation - Recording settings of one virtual screen.
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RecordingScreenSettingsImpl_h
+#define MAIN_INCLUDED_RecordingScreenSettingsImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "RecordingScreenSettingsWrap.h"
+
+class RecordingSettings;
+
+namespace settings
+{
+ struct RecordingScreenSettings;
+}
+
+class ATL_NO_VTABLE RecordingScreenSettings :
+ public RecordingScreenSettingsWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(RecordingScreenSettings)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(RecordingSettings *aParent, uint32_t uScreenId, const settings::RecordingScreenSettings& aThat);
+ HRESULT init(RecordingSettings *aParent, RecordingScreenSettings *aThat);
+ HRESULT initCopy(RecordingSettings *aParent, RecordingScreenSettings *aThat);
+ void uninit(void);
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::RecordingScreenSettings &data);
+ HRESULT i_saveSettings(settings::RecordingScreenSettings &data);
+
+ void i_rollback(void);
+ void i_commit(void);
+ void i_copyFrom(RecordingScreenSettings *aThat);
+ void i_applyDefaults(void);
+
+ settings::RecordingScreenSettings &i_getData(void);
+
+ int32_t i_reference(void);
+ int32_t i_release(void);
+ int32_t i_getReferences(void);
+
+private:
+
+ // wrapped IRecordingScreenSettings methods
+ HRESULT isFeatureEnabled(RecordingFeature_T aFeature, BOOL *aEnabled);
+
+ // wrapped IRecordingScreenSettings properties
+ HRESULT getId(ULONG *id);
+ HRESULT getEnabled(BOOL *enabled);
+ HRESULT setEnabled(BOOL enabled);
+ HRESULT getFeatures(std::vector<RecordingFeature_T> &aFeatures);
+ HRESULT setFeatures(const std::vector<RecordingFeature_T> &aFeatures);
+ HRESULT getDestination(RecordingDestination_T *aDestination);
+ HRESULT setDestination(RecordingDestination_T aDestination);
+
+ HRESULT getFilename(com::Utf8Str &aFilename);
+ HRESULT setFilename(const com::Utf8Str &aFilename);
+ HRESULT getMaxTime(ULONG *aMaxTimeS);
+ HRESULT setMaxTime(ULONG aMaxTimeS);
+ HRESULT getMaxFileSize(ULONG *aMaxFileSizeMB);
+ HRESULT setMaxFileSize(ULONG aMaxFileSizeMB);
+ HRESULT getOptions(com::Utf8Str &aOptions);
+ HRESULT setOptions(const com::Utf8Str &aOptions);
+
+ HRESULT getAudioCodec(RecordingAudioCodec_T *aCodec);
+ HRESULT setAudioCodec(RecordingAudioCodec_T aCodec);
+ HRESULT getAudioDeadline(RecordingCodecDeadline_T *aDeadline);
+ HRESULT setAudioDeadline(RecordingCodecDeadline_T aDeadline);
+ HRESULT getAudioRateControlMode(RecordingRateControlMode_T *aMode);
+ HRESULT setAudioRateControlMode(RecordingRateControlMode_T aMode);
+ HRESULT getAudioHz(ULONG *aHz);
+ HRESULT setAudioHz(ULONG aHz);
+ HRESULT getAudioBits(ULONG *aBits);
+ HRESULT setAudioBits(ULONG aBits);
+ HRESULT getAudioChannels(ULONG *aChannels);
+ HRESULT setAudioChannels(ULONG aChannels);
+
+ HRESULT getVideoCodec(RecordingVideoCodec_T *aCodec);
+ HRESULT setVideoCodec(RecordingVideoCodec_T aCodec);
+ HRESULT getVideoDeadline(RecordingCodecDeadline_T *aDeadline);
+ HRESULT setVideoDeadline(RecordingCodecDeadline_T aDeadline);
+ HRESULT getVideoWidth(ULONG *aVideoWidth);
+ HRESULT setVideoWidth(ULONG aVideoWidth);
+ HRESULT getVideoHeight(ULONG *aVideoHeight);
+ HRESULT setVideoHeight(ULONG aVideoHeight);
+ HRESULT getVideoRate(ULONG *aVideoRate);
+ HRESULT setVideoRate(ULONG aVideoRate);
+ HRESULT getVideoRateControlMode(RecordingRateControlMode_T *aMode);
+ HRESULT setVideoRateControlMode(RecordingRateControlMode_T aMode);
+ HRESULT getVideoFPS(ULONG *aVideoFPS);
+ HRESULT setVideoFPS(ULONG aVideoFPS);
+ HRESULT getVideoScalingMode(RecordingVideoScalingMode_T *aMode);
+ HRESULT setVideoScalingMode(RecordingVideoScalingMode_T aMode);
+
+private:
+
+ // internal methods
+ int i_initInternal();
+
+private:
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_RecordingScreenSettingsImpl_h */
+
diff --git a/src/VBox/Main/include/RecordingSettingsImpl.h b/src/VBox/Main/include/RecordingSettingsImpl.h
new file mode 100644
index 00000000..6f4f9aba
--- /dev/null
+++ b/src/VBox/Main/include/RecordingSettingsImpl.h
@@ -0,0 +1,102 @@
+/* $Id: RecordingSettingsImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation - Machine recording screen settings.
+ */
+
+/*
+ * Copyright (C) 2018-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RecordingSettingsImpl_h
+#define MAIN_INCLUDED_RecordingSettingsImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "RecordingSettingsWrap.h"
+
+namespace settings
+{
+ struct RecordingSettings;
+ struct RecordingScreenSettings;
+}
+
+class RecordingScreenSettings;
+
+class ATL_NO_VTABLE RecordingSettings
+ : public RecordingSettingsWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(RecordingSettings)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *parent);
+ HRESULT init(Machine *parent, RecordingSettings *aThat);
+ HRESULT initCopy(Machine *parent, RecordingSettings *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::RecordingSettings &data);
+ HRESULT i_saveSettings(settings::RecordingSettings &data);
+
+ void i_rollback(void);
+ void i_commit(void);
+ HRESULT i_copyFrom(RecordingSettings *aThat);
+ void i_applyDefaults(void);
+
+ int i_getDefaultFilename(Utf8Str &strFile, uint32_t idScreen, bool fWithFileExtension);
+ int i_getFilename(Utf8Str &strFile, uint32_t idScreen, const Utf8Str &strTemplate);
+ bool i_canChangeSettings(void);
+ void i_onSettingsChanged(void);
+
+private:
+
+ /** Map of screen settings objects. The key specifies the screen ID. */
+ typedef std::map <uint32_t, ComObjPtr<RecordingScreenSettings> > RecordingScreenSettingsObjMap;
+
+ void i_reset(void);
+ int i_syncToMachineDisplays(uint32_t cDisplays);
+ int i_createScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap, uint32_t idScreen, const settings::RecordingScreenSettings &data);
+ int i_destroyScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap, uint32_t idScreen);
+ int i_destroyAllScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap);
+
+private:
+
+ // wrapped IRecordingSettings properties
+ HRESULT getEnabled(BOOL *enabled);
+ HRESULT setEnabled(BOOL enable);
+ HRESULT getScreens(std::vector<ComPtr<IRecordingScreenSettings> > &aRecordScreenSettings);
+
+ // wrapped IRecordingSettings methods
+ HRESULT getScreenSettings(ULONG uScreenId, ComPtr<IRecordingScreenSettings> &aRecordScreenSettings);
+
+private:
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_RecordingSettingsImpl_h */
+
diff --git a/src/VBox/Main/include/RecordingStream.h b/src/VBox/Main/include/RecordingStream.h
new file mode 100644
index 00000000..7d9dc48d
--- /dev/null
+++ b/src/VBox/Main/include/RecordingStream.h
@@ -0,0 +1,234 @@
+/* $Id: RecordingStream.h $ */
+/** @file
+ * Recording stream code header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RecordingStream_h
+#define MAIN_INCLUDED_RecordingStream_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <map>
+#include <vector>
+
+#include <iprt/critsect.h>
+
+#include "RecordingInternals.h"
+
+class WebMWriter;
+class RecordingContext;
+
+/** Structure for queuing all blocks bound to a single timecode.
+ * This can happen if multiple tracks are being involved. */
+struct RecordingBlocks
+{
+ virtual ~RecordingBlocks()
+ {
+ Clear();
+ }
+
+ /**
+ * Resets a recording block list by removing (destroying)
+ * all current elements.
+ */
+ void Clear()
+ {
+ while (!List.empty())
+ {
+ RecordingBlock *pBlock = List.front();
+ List.pop_front();
+ delete pBlock;
+ }
+
+ Assert(List.size() == 0);
+ }
+
+ /** The actual block list for this timecode. */
+ RecordingBlockList List;
+};
+
+/** A block map containing all currently queued blocks.
+ * The key specifies a unique timecode, whereas the value
+ * is a list of blocks which all correlate to the same key (timecode). */
+typedef std::map<uint64_t, RecordingBlocks *> RecordingBlockMap;
+
+/**
+ * Structure for holding a set of recording (data) blocks.
+ */
+struct RecordingBlockSet
+{
+ virtual ~RecordingBlockSet()
+ {
+ Clear();
+ }
+
+ /**
+ * Resets a recording block set by removing (destroying)
+ * all current elements.
+ */
+ void Clear(void)
+ {
+ RecordingBlockMap::iterator it = Map.begin();
+ while (it != Map.end())
+ {
+ it->second->Clear();
+ delete it->second;
+ Map.erase(it);
+ it = Map.begin();
+ }
+
+ Assert(Map.size() == 0);
+ }
+
+ /** Timestamp (in ms) when this set was last processed. */
+ uint64_t tsLastProcessedMs;
+ /** All blocks related to this block set. */
+ RecordingBlockMap Map;
+};
+
+/**
+ * Class for managing a recording stream.
+ *
+ * A recording stream represents one entity to record (e.g. on screen / monitor),
+ * so there is a 1:1 mapping (stream <-> monitors).
+ */
+class RecordingStream
+{
+public:
+
+ RecordingStream(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &Settings);
+
+ virtual ~RecordingStream(void);
+
+public:
+
+ int Init(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &Settings);
+ int Uninit(void);
+
+ int Process(RecordingBlockMap &mapBlocksCommon);
+ int SendAudioFrame(const void *pvData, size_t cbData, uint64_t msTimestamp);
+ int SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelFormat, uint32_t uBPP, uint32_t uBytesPerLine,
+ uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData, uint64_t msTimestamp);
+
+ const settings::RecordingScreenSettings &GetConfig(void) const;
+ uint16_t GetID(void) const { return this->m_uScreenID; };
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ PRECORDINGCODEC GetAudioCodec(void) { return this->m_pCodecAudio; };
+#endif
+ PRECORDINGCODEC GetVideoCodec(void) { return &this->m_CodecVideo; };
+
+ bool IsLimitReached(uint64_t msTimestamp) const;
+ bool IsReady(void) const;
+ bool NeedsUpdate(uint64_t msTimestamp) const;
+
+public:
+
+ static DECLCALLBACK(int) codecWriteDataCallback(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags, void *pvUser);
+
+protected:
+
+ int open(const settings::RecordingScreenSettings &screenSettings);
+ int close(void);
+
+ int initInternal(RecordingContext *pCtx, uint32_t uScreen, const settings::RecordingScreenSettings &screenSettings);
+ int uninitInternal(void);
+
+ int initVideo(const settings::RecordingScreenSettings &screenSettings);
+ int unitVideo(void);
+
+ bool isLimitReachedInternal(uint64_t msTimestamp) const;
+ int iterateInternal(uint64_t msTimestamp);
+
+ int codecWriteToWebM(PRECORDINGCODEC pCodec, const void *pvData, size_t cbData, uint64_t msAbsPTS, uint32_t uFlags);
+
+ void lock(void);
+ void unlock(void);
+
+protected:
+
+ /**
+ * Enumeration for a recording stream state.
+ */
+ enum RECORDINGSTREAMSTATE
+ {
+ /** Stream not initialized. */
+ RECORDINGSTREAMSTATE_UNINITIALIZED = 0,
+ /** Stream was initialized. */
+ RECORDINGSTREAMSTATE_INITIALIZED = 1,
+ /** The usual 32-bit hack. */
+ RECORDINGSTREAMSTATE_32BIT_HACK = 0x7fffffff
+ };
+
+ /** Recording context this stream is associated to. */
+ RecordingContext *m_pCtx;
+ /** The current state. */
+ RECORDINGSTREAMSTATE m_enmState;
+ struct
+ {
+ /** File handle to use for writing. */
+ RTFILE m_hFile;
+ /** Pointer to WebM writer instance being used. */
+ WebMWriter *m_pWEBM;
+ } File;
+ bool m_fEnabled;
+ /** Track number of audio stream.
+ * Set to UINT8_MAX if not being used. */
+ uint8_t m_uTrackAudio;
+ /** Track number of video stream.
+ * Set to UINT8_MAX if not being used. */
+ uint8_t m_uTrackVideo;
+ /** Screen ID. */
+ uint16_t m_uScreenID;
+ /** Critical section to serialize access. */
+ RTCRITSECT m_CritSect;
+ /** Timestamp (in ms) of when recording has been started. */
+ uint64_t m_tsStartMs;
+#ifdef VBOX_WITH_AUDIO_RECORDING
+ /** Pointer to audio codec instance data to use.
+ *
+ * We multiplex audio data from the recording context to all streams,
+ * to avoid encoding the same audio data for each stream. We ASSUME that
+ * all audio data of a VM will be the same for each stream at a given
+ * point in time.
+ *
+ * Might be NULL if not being used. */
+ PRECORDINGCODEC m_pCodecAudio;
+#endif /* VBOX_WITH_AUDIO_RECORDING */
+ /** Video codec instance data to use. */
+ RECORDINGCODEC m_CodecVideo;
+ /** Screen settings to use. */
+ settings::RecordingScreenSettings
+ m_ScreenSettings;
+ /** Common set of recording (data) blocks, needed for
+ * multiplexing to all recording streams. */
+ RecordingBlockSet m_Blocks;
+};
+
+/** Vector of recording streams. */
+typedef std::vector <RecordingStream *> RecordingStreams;
+
+#endif /* !MAIN_INCLUDED_RecordingStream_h */
+
diff --git a/src/VBox/Main/include/RecordingUtils.h b/src/VBox/Main/include/RecordingUtils.h
new file mode 100644
index 00000000..f8fa1356
--- /dev/null
+++ b/src/VBox/Main/include/RecordingUtils.h
@@ -0,0 +1,217 @@
+/* $Id: RecordingUtils.h $ */
+/** @file
+ * Recording utility header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RecordingUtils_h
+#define MAIN_INCLUDED_RecordingUtils_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "RecordingInternals.h"
+
+
+/**
+ * Iterator class for running through a BGRA32 image buffer and converting
+ * it to RGB.
+ */
+class ColorConvBGRA32Iter
+{
+private:
+ enum { PIX_SIZE = 4 };
+public:
+ ColorConvBGRA32Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuf)
+ {
+ mPos = 0;
+ mSize = aWidth * aHeight * PIX_SIZE;
+ mBuf = aBuf;
+ }
+
+ /**
+ * Convert the next pixel to RGB.
+ *
+ * @returns true on success, false if we have reached the end of the buffer
+ * @param aRed where to store the red value.
+ * @param aGreen where to store the green value.
+ * @param aBlue where to store the blue value.
+ */
+ bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue)
+ {
+ bool rc = false;
+ if (mPos + PIX_SIZE <= mSize)
+ {
+ *aRed = mBuf[mPos + 2];
+ *aGreen = mBuf[mPos + 1];
+ *aBlue = mBuf[mPos ];
+ mPos += PIX_SIZE;
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Skip forward by a certain number of pixels.
+ *
+ * @param aPixels How many pixels to skip.
+ */
+ void skip(unsigned aPixels)
+ {
+ mPos += PIX_SIZE * aPixels;
+ }
+private:
+ /** Size of the picture buffer. */
+ unsigned mSize;
+ /** Current position in the picture buffer. */
+ unsigned mPos;
+ /** Address of the picture buffer. */
+ uint8_t *mBuf;
+};
+
+/**
+ * Iterator class for running through an BGR24 image buffer and converting
+ * it to RGB.
+ */
+class ColorConvBGR24Iter
+{
+private:
+ enum { PIX_SIZE = 3 };
+public:
+ ColorConvBGR24Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuf)
+ {
+ mPos = 0;
+ mSize = aWidth * aHeight * PIX_SIZE;
+ mBuf = aBuf;
+ }
+
+ /**
+ * Convert the next pixel to RGB.
+ *
+ * @returns true on success, false if we have reached the end of the buffer.
+ * @param aRed where to store the red value.
+ * @param aGreen where to store the green value.
+ * @param aBlue where to store the blue value.
+ */
+ bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue)
+ {
+ bool rc = false;
+ if (mPos + PIX_SIZE <= mSize)
+ {
+ *aRed = mBuf[mPos + 2];
+ *aGreen = mBuf[mPos + 1];
+ *aBlue = mBuf[mPos ];
+ mPos += PIX_SIZE;
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Skip forward by a certain number of pixels.
+ *
+ * @param aPixels How many pixels to skip.
+ */
+ void skip(unsigned aPixels)
+ {
+ mPos += PIX_SIZE * aPixels;
+ }
+private:
+ /** Size of the picture buffer. */
+ unsigned mSize;
+ /** Current position in the picture buffer. */
+ unsigned mPos;
+ /** Address of the picture buffer. */
+ uint8_t *mBuf;
+};
+
+/**
+ * Iterator class for running through an BGR565 image buffer and converting
+ * it to RGB.
+ */
+class ColorConvBGR565Iter
+{
+private:
+ enum { PIX_SIZE = 2 };
+public:
+ ColorConvBGR565Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuf)
+ {
+ mPos = 0;
+ mSize = aWidth * aHeight * PIX_SIZE;
+ mBuf = aBuf;
+ }
+
+ /**
+ * Convert the next pixel to RGB.
+ *
+ * @returns true on success, false if we have reached the end of the buffer.
+ * @param aRed Where to store the red value.
+ * @param aGreen where to store the green value.
+ * @param aBlue where to store the blue value.
+ */
+ bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue)
+ {
+ bool rc = false;
+ if (mPos + PIX_SIZE <= mSize)
+ {
+ unsigned uFull = (((unsigned) mBuf[mPos + 1]) << 8)
+ | ((unsigned) mBuf[mPos]);
+ *aRed = (uFull >> 8) & ~7;
+ *aGreen = (uFull >> 3) & ~3 & 0xff;
+ *aBlue = (uFull << 3) & ~7 & 0xff;
+ mPos += PIX_SIZE;
+ rc = true;
+ }
+ return rc;
+ }
+
+ /**
+ * Skip forward by a certain number of pixels.
+ *
+ * @param aPixels How many pixels to skip.
+ */
+ void skip(unsigned aPixels)
+ {
+ mPos += PIX_SIZE * aPixels;
+ }
+private:
+ /** Size of the picture buffer. */
+ unsigned mSize;
+ /** Current position in the picture buffer. */
+ unsigned mPos;
+ /** Address of the picture buffer. */
+ uint8_t *mBuf;
+};
+
+int RecordingUtilsRGBToYUV(RECORDINGPIXELFMT enmPixelFormat,
+ uint8_t *paDst, uint32_t uDstWidth, uint32_t uDstHeight,
+ uint8_t *paSrc, uint32_t uSrcWidth, uint32_t uSrcHeight);
+
+#ifdef DEBUG
+int RecordingUtilsDbgDumpFrameEx(const uint8_t *pu8RGBBuf, size_t cbRGBBuf, const char *pszPath, const char *pszPrefx, uint16_t uWidth, uint32_t uHeight, uint8_t uBPP);
+int RecordingUtilsDbgDumpFrame(const PRECORDINGFRAME pFrame);
+#endif
+
+#endif /* !MAIN_INCLUDED_RecordingUtils_h */
+
diff --git a/src/VBox/Main/include/RemoteUSBBackend.h b/src/VBox/Main/include/RemoteUSBBackend.h
new file mode 100644
index 00000000..a8902969
--- /dev/null
+++ b/src/VBox/Main/include/RemoteUSBBackend.h
@@ -0,0 +1,153 @@
+/* $Id: RemoteUSBBackend.h $ */
+/** @file
+ *
+ * VirtualBox Remote USB backend
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RemoteUSBBackend_h
+#define MAIN_INCLUDED_RemoteUSBBackend_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "RemoteUSBDeviceImpl.h"
+
+#include <VBox/RemoteDesktop/VRDE.h>
+#include <VBox/vrdpusb.h>
+
+#include <iprt/critsect.h>
+
+//typedef enum
+//{
+// RDLIdle = 0,
+// RDLReqSent,
+// RDLObtained
+//} RDLState;
+
+class Console;
+class ConsoleVRDPServer;
+
+DECLCALLBACK(int) USBClientResponseCallback (void *pv, uint32_t u32ClientId, uint8_t code, const void *pvRet, uint32_t cbRet);
+
+
+/* How many remote devices can be attached to a remote client.
+ * Normally a client computer has 2-8 physical USB ports, so 16 devices
+ * should be usually enough.
+ */
+#define VRDP_MAX_USB_DEVICES_PER_CLIENT (16)
+
+class RemoteUSBBackendListable
+{
+ public:
+ RemoteUSBBackendListable *pNext;
+ RemoteUSBBackendListable *pPrev;
+
+ RemoteUSBBackendListable() : pNext (NULL), pPrev (NULL) {};
+};
+
+class RemoteUSBBackend: public RemoteUSBBackendListable
+{
+ public:
+ RemoteUSBBackend(Console *console, ConsoleVRDPServer *server, uint32_t u32ClientId);
+ ~RemoteUSBBackend();
+
+ uint32_t ClientId (void) { return mu32ClientId; }
+
+ void AddRef (void);
+ void Release (void);
+
+ REMOTEUSBCALLBACK *GetBackendCallbackPointer (void) { return &mCallback; }
+
+ void NotifyDelete (void);
+
+ void PollRemoteDevices (void);
+
+ public: /* Functions for internal use. */
+ ConsoleVRDPServer *VRDPServer (void) { return mServer; };
+
+ bool pollingEnabledURB (void) { return mfPollURB; }
+
+ int saveDeviceList (const void *pvList, uint32_t cbList);
+
+ int negotiateResponse (const VRDEUSBREQNEGOTIATERET *pret, uint32_t cbRet);
+
+ int reapURB (const void *pvBody, uint32_t cbBody);
+
+ void request (void);
+ void release (void);
+
+ PREMOTEUSBDEVICE deviceFromId (VRDEUSBDEVID id);
+
+ void addDevice (PREMOTEUSBDEVICE pDevice);
+ void removeDevice (PREMOTEUSBDEVICE pDevice);
+
+ bool addUUID (const Guid *pUuid);
+ bool findUUID (const Guid *pUuid);
+ void removeUUID (const Guid *pUuid);
+
+ private:
+ Console *mConsole;
+ ConsoleVRDPServer *mServer;
+
+ int cRefs;
+
+ uint32_t mu32ClientId;
+
+ RTCRITSECT mCritsect;
+
+ REMOTEUSBCALLBACK mCallback;
+
+ bool mfHasDeviceList;
+
+ void *mpvDeviceList;
+ uint32_t mcbDeviceList;
+
+ typedef enum {
+ PollRemoteDevicesStatus_Negotiate,
+ PollRemoteDevicesStatus_WaitNegotiateResponse,
+ PollRemoteDevicesStatus_SendRequest,
+ PollRemoteDevicesStatus_WaitResponse,
+ PollRemoteDevicesStatus_Dereferenced
+ } PollRemoteDevicesStatus;
+
+ PollRemoteDevicesStatus menmPollRemoteDevicesStatus;
+
+ bool mfPollURB;
+
+ PREMOTEUSBDEVICE mpDevices;
+
+ bool mfWillBeDeleted;
+
+ Guid aGuids[VRDP_MAX_USB_DEVICES_PER_CLIENT];
+
+ /* VRDP_USB_VERSION_2: the client version. */
+ uint32_t mClientVersion;
+
+ /* VRDP_USB_VERSION_3: the client sends VRDE_USB_REQ_DEVICE_LIST_EXT_RET. */
+ bool mfDescExt;
+};
+
+#endif /* !MAIN_INCLUDED_RemoteUSBBackend_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/RemoteUSBDeviceImpl.h b/src/VBox/Main/include/RemoteUSBDeviceImpl.h
new file mode 100644
index 00000000..b6d801a1
--- /dev/null
+++ b/src/VBox/Main/include/RemoteUSBDeviceImpl.h
@@ -0,0 +1,136 @@
+/* $Id: RemoteUSBDeviceImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox IHostUSBDevice COM interface implementation
+ * for remote (VRDP) USB devices
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_RemoteUSBDeviceImpl_h
+#define MAIN_INCLUDED_RemoteUSBDeviceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "HostUSBDeviceWrap.h"
+
+struct _VRDEUSBDEVICEDESC;
+typedef _VRDEUSBDEVICEDESC VRDEUSBDEVICEDESC;
+
+class ATL_NO_VTABLE RemoteUSBDevice :
+ public HostUSBDeviceWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(RemoteUSBDevice)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(uint32_t u32ClientId, VRDEUSBDEVICEDESC const *pDevDesc, bool fDescExt);
+ void uninit();
+
+ // public methods only for internal purposes
+ bool dirty(void) const { return mData.dirty; }
+ void dirty(bool aDirty) { mData.dirty = aDirty; }
+
+ uint16_t devId(void) const { return mData.devId; }
+ uint32_t clientId(void) { return mData.clientId; }
+
+ bool captured(void) const { return mData.state == USBDeviceState_Captured; }
+ void captured(bool aCaptured)
+ {
+ if (aCaptured)
+ {
+ Assert(mData.state == USBDeviceState_Available);
+ mData.state = USBDeviceState_Captured;
+ }
+ else
+ {
+ Assert(mData.state == USBDeviceState_Captured);
+ mData.state = USBDeviceState_Available;
+ }
+ }
+
+private:
+
+ // wrapped IUSBDevice properties
+ HRESULT getId(com::Guid &aId);
+ HRESULT getVendorId(USHORT *aVendorId);
+ HRESULT getProductId(USHORT *aProductId);
+ HRESULT getRevision(USHORT *aRevision);
+ HRESULT getManufacturer(com::Utf8Str &aManufacturer);
+ HRESULT getProduct(com::Utf8Str &aProduct);
+ HRESULT getSerialNumber(com::Utf8Str &aSerialNumber);
+ HRESULT getAddress(com::Utf8Str &aAddress);
+ HRESULT getPort(USHORT *aPort);
+ HRESULT getVersion(USHORT *aVersion);
+ HRESULT getPortPath(com::Utf8Str &aAddress);
+ HRESULT getSpeed(USBConnectionSpeed_T *aSpeed);
+ HRESULT getRemote(BOOL *aRemote);
+ HRESULT getBackend(com::Utf8Str &aBackend);
+ HRESULT getDeviceInfo(std::vector<com::Utf8Str> &aInfo);
+
+ // wrapped IHostUSBDevice properties
+ HRESULT getState(USBDeviceState_T *aState);
+
+
+ struct Data
+ {
+ Data() : vendorId(0), productId(0), revision(0), port(0), version(1),
+ speed(USBConnectionSpeed_Null), dirty(FALSE),
+ devId(0), clientId(0) {}
+
+ const Guid id;
+
+ const uint16_t vendorId;
+ const uint16_t productId;
+ const uint16_t revision;
+
+ const Utf8Str manufacturer;
+ const Utf8Str product;
+ const Utf8Str serialNumber;
+
+ const Utf8Str address;
+ const Utf8Str backend;
+
+ const uint16_t port;
+ const Utf8Str portPath;
+ const uint16_t version;
+ const USBConnectionSpeed_T speed;
+
+ USBDeviceState_T state;
+ bool dirty;
+
+ const uint16_t devId;
+ const uint32_t clientId;
+ };
+
+ Data mData;
+};
+
+#endif /* !MAIN_INCLUDED_RemoteUSBDeviceImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/SecretKeyStore.h b/src/VBox/Main/include/SecretKeyStore.h
new file mode 100644
index 00000000..faebfe4a
--- /dev/null
+++ b/src/VBox/Main/include/SecretKeyStore.h
@@ -0,0 +1,216 @@
+/* $Id: SecretKeyStore.h $ */
+/** @file
+ * Main - Secret key interface.
+ */
+
+/*
+ * Copyright (C) 2015-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_SecretKeyStore_h
+#define MAIN_INCLUDED_SecretKeyStore_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include "VBox/com/array.h"
+
+class SecretKey
+{
+ public:
+
+ /**
+ * Constructor for a secret key.
+ *
+ * @param pbKey The key buffer.
+ * @param cbKey Size of the key.
+ * @param fKeyBufNonPageable Flag whether the key buffer should be non pageable.
+ */
+ SecretKey(const uint8_t *pbKey, size_t cbKey, bool fKeyBufNonPageable);
+
+ /**
+ * Secret key destructor.
+ */
+ ~SecretKey();
+
+ /**
+ * Increments the reference counter of the key.
+ *
+ * @returns The new reference count.
+ */
+ uint32_t retain();
+
+ /**
+ * Releases a reference of the key.
+ * If the reference counter reaches 0 the key buffer might be protected
+ * against further access or the data will become scrambled.
+ *
+ * @returns The new reference count.
+ */
+ uint32_t release();
+
+ /**
+ * Returns the reference count of the secret key.
+ */
+ uint32_t refCount();
+
+ /**
+ * Sets the possible number of users for this key.
+ *
+ * @returns VBox status code.
+ * @param cUsers The possible number of user for this key.
+ */
+ int setUsers(uint32_t cUsers);
+
+ /**
+ * Returns the possible amount of users.
+ *
+ * @returns Possible amount of users.
+ */
+ uint32_t getUsers();
+
+ /**
+ * Sets the remove on suspend flag.
+ *
+ * @returns VBox status code.
+ * @param fRemoveOnSuspend Flag whether to remove the key on host suspend.
+ */
+ int setRemoveOnSuspend(bool fRemoveOnSuspend);
+
+ /**
+ * Returns whether the key should be destroyed on suspend.
+ */
+ bool getRemoveOnSuspend();
+
+ /**
+ * Returns the buffer to the key.
+ */
+ const void *getKeyBuffer();
+
+ /**
+ * Returns the size of the key.
+ */
+ size_t getKeySize();
+
+ private:
+ /** Reference counter of the key. */
+ volatile uint32_t m_cRefs;
+ /** Key material. */
+ uint8_t *m_pbKey;
+ /** Size of the key in bytes. */
+ size_t m_cbKey;
+ /** Flag whether to remove the key on suspend. */
+ bool m_fRemoveOnSuspend;
+ /** Number of entities which will use this key. */
+ uint32_t m_cUsers;
+};
+
+class SecretKeyStore
+{
+ public:
+
+ typedef std::map<com::Utf8Str, SecretKey *> SecretKeyMap;
+
+ /**
+ * Constructor for a secret key store.
+ *
+ * @param fKeyBufNonPageable Flag whether the key buffer is required to
+ * be non pageable.
+ */
+ SecretKeyStore(bool fKeyBufNonPageable);
+
+ /**
+ * Destructor of a secret key store. This will free all stored secret keys
+ * inluding the key buffers. Make sure there no one accesses one of the keys
+ * stored.
+ */
+ ~SecretKeyStore();
+
+ /**
+ * Add a secret key to the store.
+ *
+ * @returns VBox status code.
+ * @param strKeyId The key identifier.
+ * @param pbKey The key to store.
+ * @param cbKey Size of the key.
+ */
+ int addSecretKey(const com::Utf8Str &strKeyId, const uint8_t *pbKey, size_t cbKey);
+
+ /**
+ * Deletes a key from the key store associated with the given identifier.
+ *
+ * @returns VBox status code.
+ * @param strKeyId The key identifier.
+ */
+ int deleteSecretKey(const com::Utf8Str &strKeyId);
+
+ /**
+ * Returns the secret key object associated with the given identifier.
+ * This increments the reference counter of the secret key object.
+ *
+ * @returns VBox status code.
+ * @param strKeyId The key identifier.
+ * @param ppKey Where to store the secret key object on success.
+ */
+ int retainSecretKey(const com::Utf8Str &strKeyId, SecretKey **ppKey);
+
+ /**
+ * Releases a reference to the secret key object.
+ *
+ * @returns VBox status code.
+ * @param strKeyId The key identifier.
+ */
+ int releaseSecretKey(const com::Utf8Str &strKeyId);
+
+ /**
+ * Deletes all secret keys from the key store.
+ *
+ * @returns VBox status code.
+ * @param fSuspend Flag whether to delete only keys which are
+ * marked for deletion during a suspend.
+ * @param fForce Flag whether to force deletion if some keys
+ * are still in use. Otherwise an error is returned.
+ */
+ int deleteAllSecretKeys(bool fSuspend, bool fForce);
+
+ /**
+ * Iterators for enumerating keys
+ */
+ SecretKeyMap::iterator begin()
+ {
+ return m_mapSecretKeys.begin();
+ }
+
+ SecretKeyMap::iterator end()
+ {
+ return m_mapSecretKeys.end();
+ }
+
+ private:
+
+ /** The map to map key identifers to secret keys. */
+ SecretKeyMap m_mapSecretKeys;
+ /** Flag whether key buffers should be non pagable. */
+ bool m_fKeyBufNonPageable;
+};
+
+#endif /* !MAIN_INCLUDED_SecretKeyStore_h */
diff --git a/src/VBox/Main/include/SerialPortImpl.h b/src/VBox/Main/include/SerialPortImpl.h
new file mode 100644
index 00000000..631410a3
--- /dev/null
+++ b/src/VBox/Main/include/SerialPortImpl.h
@@ -0,0 +1,102 @@
+/* $Id: SerialPortImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_SerialPortImpl_h
+#define MAIN_INCLUDED_SerialPortImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SerialPortWrap.h"
+
+class GuestOSType;
+
+namespace settings
+{
+ struct SerialPort;
+}
+
+class ATL_NO_VTABLE SerialPort :
+ public SerialPortWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(SerialPort)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent, ULONG aSlot);
+ HRESULT init(Machine *aParent, SerialPort *aThat);
+ HRESULT initCopy(Machine *parent, SerialPort *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::SerialPort &data);
+ HRESULT i_saveSettings(settings::SerialPort &data);
+
+ bool i_isModified();
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(SerialPort *aThat);
+
+ void i_applyDefaults(GuestOSType *aOsType);
+ bool i_hasDefaults();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+
+private:
+
+ HRESULT i_checkSetPath(const Utf8Str &str);
+
+ // Wrapped ISerialPort properties
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getHostMode(PortMode_T *aHostMode);
+ HRESULT setHostMode(PortMode_T aHostMode);
+ HRESULT getSlot(ULONG *aSlot);
+ HRESULT getIRQ(ULONG *aIRQ);
+ HRESULT setIRQ(ULONG aIRQ);
+ HRESULT getIOBase(ULONG *aIOBase);
+ HRESULT setIOBase(ULONG aIOBase);
+ HRESULT getServer(BOOL *aServer);
+ HRESULT setServer(BOOL aServer);
+ HRESULT getPath(com::Utf8Str &aPath);
+ HRESULT setPath(const com::Utf8Str &aPath);
+ HRESULT getUartType(UartType_T *aUartType);
+ HRESULT setUartType(UartType_T aUartType);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_SerialPortImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/SessionImpl.h b/src/VBox/Main/include/SessionImpl.h
new file mode 100644
index 00000000..afa0c7df
--- /dev/null
+++ b/src/VBox/Main/include/SessionImpl.h
@@ -0,0 +1,188 @@
+/* $Id: SessionImpl.h $ */
+/** @file
+ * VBox Client Session COM Class definition
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_SessionImpl_h
+#define MAIN_INCLUDED_SessionImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SessionWrap.h"
+#include "ConsoleImpl.h"
+
+#ifdef RT_OS_WINDOWS
+# include "win/resource.h"
+#endif
+
+#if defined(RT_OS_WINDOWS) && !RT_MSC_PREREQ(RT_MSC_VER_VC140)
+[threading(free)]
+#endif
+class ATL_NO_VTABLE Session :
+ public SessionWrap
+#ifdef RT_OS_WINDOWS
+ , public ATL::CComCoClass<Session, &CLSID_Session>
+#endif
+{
+public:
+
+ DECLARE_CLASSFACTORY()
+
+ // Do not use any ATL registry support.
+ //DECLARE_REGISTRY_RESOURCEID(IDR_VIRTUALBOX)
+
+ DECLARE_NOT_AGGREGATABLE(Session)
+
+ DECLARE_COMMON_CLASS_METHODS(Session)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializers/uninitializers only for internal purposes
+ HRESULT init();
+ void uninit();
+
+private:
+
+ // Wrapped ISession properties
+ HRESULT getState(SessionState_T *aState);
+ HRESULT getType(SessionType_T *aType);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getMachine(ComPtr<IMachine> &aMachine);
+ HRESULT getConsole(ComPtr<IConsole> &aConsole);
+
+ // Wrapped ISession methods
+ HRESULT unlockMachine();
+
+ // Wrapped IInternalSessionControl properties
+ HRESULT getPID(ULONG *aPid);
+ HRESULT getRemoteConsole(ComPtr<IConsole> &aRemoteConsole);
+ HRESULT getNominalState(MachineState_T *aNominalState);
+
+ // Wrapped IInternalSessionControl methods
+#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
+ HRESULT assignMachine(const ComPtr<IMachine> &aMachine,
+ LockType_T aLockType,
+ const com::Utf8Str &aTokenId);
+#else
+ HRESULT assignMachine(const ComPtr<IMachine> &aMachine,
+ LockType_T aLockType,
+ const ComPtr<IToken> &aToken);
+#endif /* !VBOX_WITH_GENERIC_SESSION_WATCHER */
+ HRESULT assignRemoteMachine(const ComPtr<IMachine> &aMachine,
+ const ComPtr<IConsole> &aConsole);
+ HRESULT updateMachineState(MachineState_T aMachineState);
+ HRESULT uninitialize();
+ HRESULT onNetworkAdapterChange(const ComPtr<INetworkAdapter> &aNetworkAdapter,
+ BOOL aChangeAdapter);
+ HRESULT onAudioAdapterChange(const ComPtr<IAudioAdapter> &aAudioAdapter);
+ HRESULT onHostAudioDeviceChange(const ComPtr<IHostAudioDevice> &aDevice,
+ BOOL aNew, AudioDeviceState_T aState,
+ const ComPtr<IVirtualBoxErrorInfo> &aErrInfo);
+ HRESULT onSerialPortChange(const ComPtr<ISerialPort> &aSerialPort);
+ HRESULT onParallelPortChange(const ComPtr<IParallelPort> &aParallelPort);
+ HRESULT onStorageControllerChange(const Guid &aMachineId, const com::Utf8Str& aControllerName);
+ HRESULT onMediumChange(const ComPtr<IMediumAttachment> &aMediumAttachment,
+ BOOL aForce);
+ HRESULT onStorageDeviceChange(const ComPtr<IMediumAttachment> &aMediumAttachment,
+ BOOL aRemove,
+ BOOL aSilent);
+ HRESULT onVMProcessPriorityChange(VMProcPriority_T priority);
+ HRESULT onClipboardModeChange(ClipboardMode_T aClipboardMode);
+ HRESULT onClipboardFileTransferModeChange(BOOL aEnabled);
+ HRESULT onDnDModeChange(DnDMode_T aDndMode);
+ HRESULT onCPUChange(ULONG aCpu,
+ BOOL aAdd);
+ HRESULT onCPUExecutionCapChange(ULONG aExecutionCap);
+ HRESULT onVRDEServerChange(BOOL aRestart);
+ HRESULT onRecordingChange(BOOL aEnable);
+ HRESULT onUSBControllerChange();
+ HRESULT onSharedFolderChange(BOOL aGlobal);
+ HRESULT onGuestDebugControlChange(const ComPtr<IGuestDebugControl> &aGuestDebugControl);
+ HRESULT onUSBDeviceAttach(const ComPtr<IUSBDevice> &aDevice,
+ const ComPtr<IVirtualBoxErrorInfo> &aError,
+ ULONG aMaskedInterfaces,
+ const com::Utf8Str &aCaptureFilename);
+ HRESULT onUSBDeviceDetach(const com::Guid &aId,
+ const ComPtr<IVirtualBoxErrorInfo> &aError);
+ HRESULT onShowWindow(BOOL aCheck,
+ BOOL *aCanShow,
+ LONG64 *aWinId);
+ HRESULT onBandwidthGroupChange(const ComPtr<IBandwidthGroup> &aBandwidthGroup);
+ HRESULT accessGuestProperty(const com::Utf8Str &aName,
+ const com::Utf8Str &aValue,
+ const com::Utf8Str &aFlags,
+ ULONG aAccessMode,
+ com::Utf8Str &aRetValue,
+ LONG64 *aRetTimestamp,
+ com::Utf8Str &aRetFlags);
+ HRESULT enumerateGuestProperties(const com::Utf8Str &aPatterns,
+ std::vector<com::Utf8Str> &aKeys,
+ std::vector<com::Utf8Str> &aValues,
+ std::vector<LONG64> &aTimestamps,
+ std::vector<com::Utf8Str> &aFlags);
+ HRESULT onlineMergeMedium(const ComPtr<IMediumAttachment> &aMediumAttachment,
+ ULONG aSourceIdx,
+ ULONG aTargetIdx,
+ const ComPtr<IProgress> &aProgress);
+ HRESULT reconfigureMediumAttachments(const std::vector<ComPtr<IMediumAttachment> > &aAttachments);
+ HRESULT enableVMMStatistics(BOOL aEnable);
+ HRESULT pauseWithReason(Reason_T aReason);
+ HRESULT resumeWithReason(Reason_T aReason);
+ HRESULT saveStateWithReason(Reason_T aReason,
+ const ComPtr<IProgress> &aProgress,
+ const ComPtr<ISnapshot> &aSnapshot,
+ const Utf8Str &aStateFilePath,
+ BOOL aPauseVM,
+ BOOL *aLeftPaused);
+ HRESULT cancelSaveStateWithReason();
+
+
+ HRESULT i_unlockMachine(bool aFinalRelease, bool aFromServer, AutoWriteLock &aLockW);
+
+ SessionState_T mState;
+ SessionType_T mType;
+ Utf8Str mName;
+
+ ComPtr<IInternalMachineControl> mControl;
+
+#ifndef VBOX_COM_INPROC_API_CLIENT
+ ComObjPtr<Console> mConsole;
+#endif
+
+ ComPtr<IMachine> mRemoteMachine;
+ ComPtr<IConsole> mRemoteConsole;
+
+ ComPtr<IVirtualBox> mVirtualBox;
+
+ class ClientTokenHolder;
+
+ ClientTokenHolder *mClientTokenHolder;
+};
+
+#endif /* !MAIN_INCLUDED_SessionImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/SharedFolderImpl.h b/src/VBox/Main/include/SharedFolderImpl.h
new file mode 100644
index 00000000..cdb19fc2
--- /dev/null
+++ b/src/VBox/Main/include/SharedFolderImpl.h
@@ -0,0 +1,125 @@
+/* $Id: SharedFolderImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_SharedFolderImpl_h
+#define MAIN_INCLUDED_SharedFolderImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SharedFolderWrap.h"
+#include <VBox/shflsvc.h>
+
+class Console;
+
+class ATL_NO_VTABLE SharedFolder :
+ public SharedFolderWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS (SharedFolder)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aMachine, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
+ bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
+ HRESULT initCopy(Machine *aMachine, SharedFolder *aThat);
+// HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
+// bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
+// HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
+// bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
+ void uninit();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+
+ /**
+ * Public internal method. Returns the shared folder's name. Needs caller! Locking not necessary.
+ * @return
+ */
+ const Utf8Str &i_getName() const;
+
+ /**
+ * Public internal method. Returns the shared folder's host path. Needs caller! Locking not necessary.
+ * @return
+ */
+ const Utf8Str &i_getHostPath() const;
+
+ /**
+ * Public internal method. Returns true if the shared folder is writable. Needs caller and locking!
+ * @return
+ */
+ bool i_isWritable() const;
+
+ /**
+ * Public internal method. Returns true if the shared folder is auto-mounted. Needs caller and locking!
+ * @return
+ */
+ bool i_isAutoMounted() const;
+
+ /**
+ * Public internal method for getting the auto mount point.
+ */
+ const Utf8Str &i_getAutoMountPoint() const;
+
+protected:
+
+ HRESULT i_protectedInit(VirtualBoxBase *aParent,
+ const Utf8Str &aName,
+ const Utf8Str &aHostPath,
+ bool aWritable,
+ bool aAutoMount,
+ const com::Utf8Str &aAutoMountPoint,
+ bool fFailOnError);
+private:
+
+ // wrapped ISharedFolder properies.
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getHostPath(com::Utf8Str &aHostPath);
+ HRESULT getAccessible(BOOL *aAccessible);
+ HRESULT getWritable(BOOL *aWritable);
+ HRESULT setWritable(BOOL aWritable);
+ HRESULT getAutoMount(BOOL *aAutoMount);
+ HRESULT setAutoMount(BOOL aAutoMount);
+ HRESULT getAutoMountPoint(com::Utf8Str &aAutoMountPoint);
+ HRESULT setAutoMountPoint(com::Utf8Str const &aAutoMountPoint);
+ HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
+
+ VirtualBoxBase * const mParent;
+
+ /* weak parents (only one of them is not null) */
+ Machine * const mMachine;
+ VirtualBox * const mVirtualBox;
+
+ struct Data; // opaque data struct, defined in MachineSharedFolderImpl.cpp
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_SharedFolderImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/SnapshotImpl.h b/src/VBox/Main/include/SnapshotImpl.h
new file mode 100644
index 00000000..59b8ea7c
--- /dev/null
+++ b/src/VBox/Main/include/SnapshotImpl.h
@@ -0,0 +1,142 @@
+/* $Id: SnapshotImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_SnapshotImpl_h
+#define MAIN_INCLUDED_SnapshotImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "SnapshotWrap.h"
+
+class SnapshotMachine;
+
+namespace settings
+{
+ struct Snapshot;
+}
+
+class ATL_NO_VTABLE Snapshot :
+ public SnapshotWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(Snapshot)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer only for internal purposes
+ HRESULT init(VirtualBox *aVirtualBox,
+ const Guid &aId,
+ const com::Utf8Str &aName,
+ const com::Utf8Str &aDescription,
+ const RTTIMESPEC &aTimeStamp,
+ SnapshotMachine *aMachine,
+ Snapshot *aParent);
+ void uninit();
+
+ void i_beginSnapshotDelete();
+
+ void i_deparent();
+
+ // public methods only for internal purposes
+
+ /**
+ * Override of the default locking class to be used for validating lock
+ * order with the standard member lock handle.
+ */
+ virtual VBoxLockingClass getLockingClass() const
+ {
+ return LOCKCLASS_SNAPSHOTOBJECT;
+ }
+
+ const ComObjPtr<Snapshot>& i_getParent() const;
+ const ComObjPtr<Snapshot> i_getFirstChild() const;
+
+ const Utf8Str& i_getStateFilePath() const;
+
+ uint32_t i_getDepth();
+
+ ULONG i_getChildrenCount();
+ ULONG i_getAllChildrenCount();
+
+ const ComObjPtr<SnapshotMachine>& i_getSnapshotMachine() const;
+
+ Guid i_getId() const;
+ const Utf8Str& i_getName() const;
+ RTTIMESPEC i_getTimeStamp() const;
+
+ ComObjPtr<Snapshot> i_findChildOrSelf(IN_GUID aId);
+ ComObjPtr<Snapshot> i_findChildOrSelf(const com::Utf8Str &aName);
+
+ void i_updateSavedStatePaths(const Utf8Str &strOldPath,
+ const Utf8Str &strNewPath);
+ void i_updateSavedStatePathsImpl(const Utf8Str &strOldPath,
+ const Utf8Str &strNewPath);
+
+ bool i_sharesSavedStateFile(const Utf8Str &strPath,
+ Snapshot *pSnapshotToIgnore);
+
+ void i_updateNVRAMPaths(const Utf8Str &strOldPath,
+ const Utf8Str &strNewPath);
+ void i_updateNVRAMPathsImpl(const Utf8Str &strOldPath,
+ const Utf8Str &strNewPath);
+
+ HRESULT i_saveSnapshotOne(settings::Snapshot &data) const;
+ HRESULT i_saveSnapshot(settings::Snapshot &data) const;
+
+ HRESULT i_uninitAll(AutoWriteLock &writeLock,
+ CleanupMode_T cleanupMode,
+ MediaList &llMedia,
+ std::list<Utf8Str> &llFilenames);
+
+
+private:
+
+ struct Data; // opaque, defined in SnapshotImpl.cpp
+
+ // wrapped ISnapshot properties
+ HRESULT getId(com::Guid &aId);
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getDescription(com::Utf8Str &aDescription);
+ HRESULT setDescription(const com::Utf8Str &aDescription);
+ HRESULT getTimeStamp(LONG64 *aTimeStamp);
+ HRESULT getOnline(BOOL *aOnline);
+ HRESULT getMachine(ComPtr<IMachine> &aMachine);
+ HRESULT getParent(ComPtr<ISnapshot> &aParent);
+ HRESULT getChildren(std::vector<ComPtr<ISnapshot> > &aChildren);
+
+ // wrapped ISnapshot methods
+ HRESULT getChildrenCount(ULONG *aChildrenCount);
+
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_SnapshotImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/StorageControllerImpl.h b/src/VBox/Main/include/StorageControllerImpl.h
new file mode 100644
index 00000000..d069aea6
--- /dev/null
+++ b/src/VBox/Main/include/StorageControllerImpl.h
@@ -0,0 +1,107 @@
+/* $Id: StorageControllerImpl.h $ */
+
+/** @file
+ *
+ * VBox StorageController COM Class declaration.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_StorageControllerImpl_h
+#define MAIN_INCLUDED_StorageControllerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+#include "StorageControllerWrap.h"
+
+class ATL_NO_VTABLE StorageController :
+ public StorageControllerWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(StorageController)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent,
+ const com::Utf8Str &aName,
+ StorageBus_T aBus,
+ ULONG aInstance,
+ bool fBootable);
+ HRESULT init(Machine *aParent,
+ StorageController *aThat,
+ bool aReshare = false);
+ HRESULT initCopy(Machine *aParent,
+ StorageController *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ const Utf8Str &i_getName() const;
+ StorageControllerType_T i_getControllerType() const;
+ StorageBus_T i_getStorageBus() const;
+ ULONG i_getInstance() const;
+ bool i_getBootable() const;
+ HRESULT i_checkPortAndDeviceValid(LONG aControllerPort,
+ LONG aDevice);
+ void i_setBootable(BOOL fBootable);
+ void i_rollback();
+ void i_commit();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+
+ void i_unshare();
+
+ /** @note this doesn't require a read lock since mParent is constant. */
+ Machine* i_getMachine();
+ ComObjPtr<StorageController> i_getPeer();
+
+private:
+
+ // Wrapped IStorageController properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getMaxDevicesPerPortCount(ULONG *aMaxDevicesPerPortCount);
+ HRESULT getMinPortCount(ULONG *aMinPortCount);
+ HRESULT getMaxPortCount(ULONG *aMaxPortCount);
+ HRESULT getInstance(ULONG *aInstance);
+ HRESULT setInstance(ULONG aInstance);
+ HRESULT getPortCount(ULONG *aPortCount);
+ HRESULT setPortCount(ULONG aPortCount);
+ HRESULT getBus(StorageBus_T *aBus);
+ HRESULT getControllerType(StorageControllerType_T *aControllerType);
+ HRESULT setControllerType(StorageControllerType_T aControllerType);
+ HRESULT getUseHostIOCache(BOOL *aUseHostIOCache);
+ HRESULT setUseHostIOCache(BOOL aUseHostIOCache);
+ HRESULT getBootable(BOOL *aBootable);
+
+ void i_printList();
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_StorageControllerImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/SystemPropertiesImpl.h b/src/VBox/Main/include/SystemPropertiesImpl.h
new file mode 100644
index 00000000..0216d06f
--- /dev/null
+++ b/src/VBox/Main/include/SystemPropertiesImpl.h
@@ -0,0 +1,220 @@
+/* $Id: SystemPropertiesImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_SystemPropertiesImpl_h
+#define MAIN_INCLUDED_SystemPropertiesImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "MediumFormatImpl.h"
+#include "SystemPropertiesWrap.h"
+
+class CPUProfile;
+
+namespace settings
+{
+ struct SystemProperties;
+}
+
+class ATL_NO_VTABLE SystemProperties :
+ public SystemPropertiesWrap
+{
+public:
+ typedef std::list<ComObjPtr<MediumFormat> > MediumFormatList;
+ typedef std::list<ComObjPtr<CPUProfile> > CPUProfileList_T;
+
+ DECLARE_COMMON_CLASS_METHODS(SystemProperties)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(VirtualBox *aParent);
+ void uninit();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+ HRESULT i_loadSettings(const settings::SystemProperties &data);
+ HRESULT i_saveSettings(settings::SystemProperties &data);
+
+ ComObjPtr<MediumFormat> i_mediumFormat(const Utf8Str &aFormat);
+ ComObjPtr<MediumFormat> i_mediumFormatFromExtension(const Utf8Str &aExt);
+
+ int i_loadVDPlugin(const char *pszPluginLibrary);
+ int i_unloadVDPlugin(const char *pszPluginLibrary);
+
+ HRESULT i_getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO);
+
+private:
+
+ // wrapped ISystemProperties properties
+ HRESULT getMinGuestRAM(ULONG *aMinGuestRAM) RT_OVERRIDE;
+ HRESULT getMaxGuestRAM(ULONG *aMaxGuestRAM) RT_OVERRIDE;
+ HRESULT getMinGuestVRAM(ULONG *aMinGuestVRAM) RT_OVERRIDE;
+ HRESULT getMaxGuestVRAM(ULONG *aMaxGuestVRAM) RT_OVERRIDE;
+ HRESULT getMinGuestCPUCount(ULONG *aMinGuestCPUCount) RT_OVERRIDE;
+ HRESULT getMaxGuestCPUCount(ULONG *aMaxGuestCPUCount) RT_OVERRIDE;
+ HRESULT getMaxGuestMonitors(ULONG *aMaxGuestMonitors) RT_OVERRIDE;
+ HRESULT getInfoVDSize(LONG64 *aInfoVDSize) RT_OVERRIDE;
+ HRESULT getSerialPortCount(ULONG *aSerialPortCount) RT_OVERRIDE;
+ HRESULT getParallelPortCount(ULONG *aParallelPortCount) RT_OVERRIDE;
+ HRESULT getMaxBootPosition(ULONG *aMaxBootPosition) RT_OVERRIDE;
+ HRESULT getRawModeSupported(BOOL *aRawModeSupported) RT_OVERRIDE;
+ HRESULT getExclusiveHwVirt(BOOL *aExclusiveHwVirt) RT_OVERRIDE;
+ HRESULT setExclusiveHwVirt(BOOL aExclusiveHwVirt) RT_OVERRIDE;
+ HRESULT getDefaultMachineFolder(com::Utf8Str &aDefaultMachineFolder) RT_OVERRIDE;
+ HRESULT setDefaultMachineFolder(const com::Utf8Str &aDefaultMachineFolder) RT_OVERRIDE;
+ HRESULT getLoggingLevel(com::Utf8Str &aLoggingLevel) RT_OVERRIDE;
+ HRESULT setLoggingLevel(const com::Utf8Str &aLoggingLevel) RT_OVERRIDE;
+ HRESULT getMediumFormats(std::vector<ComPtr<IMediumFormat> > &aMediumFormats) RT_OVERRIDE;
+ HRESULT getDefaultHardDiskFormat(com::Utf8Str &aDefaultHardDiskFormat) RT_OVERRIDE;
+ HRESULT setDefaultHardDiskFormat(const com::Utf8Str &aDefaultHardDiskFormat) RT_OVERRIDE;
+ HRESULT getFreeDiskSpaceWarning(LONG64 *aFreeDiskSpaceWarning) RT_OVERRIDE;
+ HRESULT setFreeDiskSpaceWarning(LONG64 aFreeDiskSpaceWarning) RT_OVERRIDE;
+ HRESULT getFreeDiskSpacePercentWarning(ULONG *aFreeDiskSpacePercentWarning) RT_OVERRIDE;
+ HRESULT setFreeDiskSpacePercentWarning(ULONG aFreeDiskSpacePercentWarning) RT_OVERRIDE;
+ HRESULT getFreeDiskSpaceError(LONG64 *aFreeDiskSpaceError) RT_OVERRIDE;
+ HRESULT setFreeDiskSpaceError(LONG64 aFreeDiskSpaceError) RT_OVERRIDE;
+ HRESULT getFreeDiskSpacePercentError(ULONG *aFreeDiskSpacePercentError) RT_OVERRIDE;
+ HRESULT setFreeDiskSpacePercentError(ULONG aFreeDiskSpacePercentError) RT_OVERRIDE;
+ HRESULT getVRDEAuthLibrary(com::Utf8Str &aVRDEAuthLibrary) RT_OVERRIDE;
+ HRESULT setVRDEAuthLibrary(const com::Utf8Str &aVRDEAuthLibrary) RT_OVERRIDE;
+ HRESULT getWebServiceAuthLibrary(com::Utf8Str &aWebServiceAuthLibrary) RT_OVERRIDE;
+ HRESULT setWebServiceAuthLibrary(const com::Utf8Str &aWebServiceAuthLibrary) RT_OVERRIDE;
+ HRESULT getDefaultVRDEExtPack(com::Utf8Str &aDefaultVRDEExtPack) RT_OVERRIDE;
+ HRESULT setDefaultVRDEExtPack(const com::Utf8Str &aDefaultVRDEExtPack) RT_OVERRIDE;
+ HRESULT getDefaultCryptoExtPack(com::Utf8Str &aDefaultCryptoExtPack) RT_OVERRIDE;
+ HRESULT setDefaultCryptoExtPack(const com::Utf8Str &aDefaultCryptoExtPack) RT_OVERRIDE;
+ HRESULT getLogHistoryCount(ULONG *aLogHistoryCount) RT_OVERRIDE;
+ HRESULT setLogHistoryCount(ULONG aLogHistoryCount) RT_OVERRIDE;
+ HRESULT getDefaultAudioDriver(AudioDriverType_T *aDefaultAudioDriver) RT_OVERRIDE;
+ HRESULT getAutostartDatabasePath(com::Utf8Str &aAutostartDatabasePath) RT_OVERRIDE;
+ HRESULT setAutostartDatabasePath(const com::Utf8Str &aAutostartDatabasePath) RT_OVERRIDE;
+ HRESULT getDefaultAdditionsISO(com::Utf8Str &aDefaultAdditionsISO) RT_OVERRIDE;
+ HRESULT setDefaultAdditionsISO(const com::Utf8Str &aDefaultAdditionsISO) RT_OVERRIDE;
+ HRESULT getDefaultFrontend(com::Utf8Str &aDefaultFrontend) RT_OVERRIDE;
+ HRESULT setDefaultFrontend(const com::Utf8Str &aDefaultFrontend) RT_OVERRIDE;
+ HRESULT getScreenShotFormats(std::vector<BitmapFormat_T> &aScreenShotFormats) RT_OVERRIDE;
+ HRESULT getProxyMode(ProxyMode_T *pProxyMode) RT_OVERRIDE;
+ HRESULT setProxyMode(ProxyMode_T aProxyMode) RT_OVERRIDE;
+ HRESULT getProxyURL(com::Utf8Str &aProxyURL) RT_OVERRIDE;
+ HRESULT setProxyURL(const com::Utf8Str &aProxyURL) RT_OVERRIDE;
+ HRESULT getSupportedParavirtProviders(std::vector<ParavirtProvider_T> &aSupportedParavirtProviders) RT_OVERRIDE;
+ HRESULT getSupportedClipboardModes(std::vector<ClipboardMode_T> &aSupportedClipboardModes) RT_OVERRIDE;
+ HRESULT getSupportedDnDModes(std::vector<DnDMode_T> &aSupportedDnDModes) RT_OVERRIDE;
+ HRESULT getSupportedFirmwareTypes(std::vector<FirmwareType_T> &aSupportedFirmwareTypes) RT_OVERRIDE;
+ HRESULT getSupportedPointingHIDTypes(std::vector<PointingHIDType_T> &aSupportedPointingHIDTypes) RT_OVERRIDE;
+ HRESULT getSupportedKeyboardHIDTypes(std::vector<KeyboardHIDType_T> &aSupportedKeyboardHIDTypes) RT_OVERRIDE;
+ HRESULT getSupportedVFSTypes(std::vector<VFSType_T> &aSupportedVFSTypes) RT_OVERRIDE;
+ HRESULT getSupportedImportOptions(std::vector<ImportOptions_T> &aSupportedImportOptions) RT_OVERRIDE;
+ HRESULT getSupportedExportOptions(std::vector<ExportOptions_T> &aSupportedExportOptions) RT_OVERRIDE;
+ HRESULT getSupportedRecordingFeatures(std::vector<RecordingFeature_T> &aSupportedRecordingFeatures) RT_OVERRIDE;
+ HRESULT getSupportedRecordingAudioCodecs(std::vector<RecordingAudioCodec_T> &aSupportedRecordingAudioCodecs) RT_OVERRIDE;
+ HRESULT getSupportedRecordingVideoCodecs(std::vector<RecordingVideoCodec_T> &aSupportedRecordingVideoCodecs) RT_OVERRIDE;
+ HRESULT getSupportedRecordingVSModes(std::vector<RecordingVideoScalingMode_T> &aSupportedRecordingVideoScalingModes) RT_OVERRIDE;
+ HRESULT getSupportedRecordingARCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingAudioRateControlModes) RT_OVERRIDE;
+ HRESULT getSupportedRecordingVRCModes(std::vector<RecordingRateControlMode_T> &aSupportedRecordingVideoRateControlModes) RT_OVERRIDE;
+ HRESULT getSupportedGraphicsControllerTypes(std::vector<GraphicsControllerType_T> &aSupportedGraphicsControllerTypes) RT_OVERRIDE;
+ HRESULT getSupportedCloneOptions(std::vector<CloneOptions_T> &aSupportedCloneOptions) RT_OVERRIDE;
+ HRESULT getSupportedAutostopTypes(std::vector<AutostopType_T> &aSupportedAutostopTypes) RT_OVERRIDE;
+ HRESULT getSupportedVMProcPriorities(std::vector<VMProcPriority_T> &aSupportedVMProcPriorities) RT_OVERRIDE;
+ HRESULT getSupportedNetworkAttachmentTypes(std::vector<NetworkAttachmentType_T> &aSupportedNetworkAttachmentTypes) RT_OVERRIDE;
+ HRESULT getSupportedNetworkAdapterTypes(std::vector<NetworkAdapterType_T> &aSupportedNetworkAdapterTypes) RT_OVERRIDE;
+ HRESULT getSupportedPortModes(std::vector<PortMode_T> &aSupportedPortModes) RT_OVERRIDE;
+ HRESULT getSupportedUartTypes(std::vector<UartType_T> &aSupportedUartTypes) RT_OVERRIDE;
+ HRESULT getSupportedUSBControllerTypes(std::vector<USBControllerType_T> &aSupportedUSBControllerTypes) RT_OVERRIDE;
+ HRESULT getSupportedAudioDriverTypes(std::vector<AudioDriverType_T> &aSupportedAudioDriverTypes) RT_OVERRIDE;
+ HRESULT getSupportedAudioControllerTypes(std::vector<AudioControllerType_T> &aSupportedAudioControllerTypes) RT_OVERRIDE;
+ HRESULT getSupportedStorageBuses(std::vector<StorageBus_T> &aSupportedStorageBuses) RT_OVERRIDE;
+ HRESULT getSupportedStorageControllerTypes(std::vector<StorageControllerType_T> &aSupportedStorageControllerTypes) RT_OVERRIDE;
+ HRESULT getSupportedChipsetTypes(std::vector<ChipsetType_T> &aSupportedChipsetTypes) RT_OVERRIDE;
+ HRESULT getSupportedIommuTypes(std::vector<IommuType_T> &aSupportedIommuTypes) RT_OVERRIDE;
+ HRESULT getSupportedTpmTypes(std::vector<TpmType_T> &aSupportedTpmTypes) RT_OVERRIDE;
+ HRESULT getLanguageId(com::Utf8Str &aLanguageId) RT_OVERRIDE;
+ HRESULT setLanguageId(const com::Utf8Str &aLanguageId) RT_OVERRIDE;
+
+ // wrapped ISystemProperties methods
+ HRESULT getMaxNetworkAdapters(ChipsetType_T aChipset,
+ ULONG *aMaxNetworkAdapters) RT_OVERRIDE;
+ HRESULT getMaxNetworkAdaptersOfType(ChipsetType_T aChipset,
+ NetworkAttachmentType_T aType,
+ ULONG *aMaxNetworkAdapters) RT_OVERRIDE;
+ HRESULT getMaxDevicesPerPortForStorageBus(StorageBus_T aBus,
+ ULONG *aMaxDevicesPerPort) RT_OVERRIDE;
+ HRESULT getMinPortCountForStorageBus(StorageBus_T aBus,
+ ULONG *aMinPortCount) RT_OVERRIDE;
+ HRESULT getMaxPortCountForStorageBus(StorageBus_T aBus,
+ ULONG *aMaxPortCount) RT_OVERRIDE;
+ HRESULT getMaxInstancesOfStorageBus(ChipsetType_T aChipset,
+ StorageBus_T aBus,
+ ULONG *aMaxInstances) RT_OVERRIDE;
+ HRESULT getDeviceTypesForStorageBus(StorageBus_T aBus,
+ std::vector<DeviceType_T> &aDeviceTypes) RT_OVERRIDE;
+ HRESULT getStorageBusForStorageControllerType(StorageControllerType_T aStorageControllerType,
+ StorageBus_T *aStorageBus) RT_OVERRIDE;
+ HRESULT getStorageControllerTypesForStorageBus(StorageBus_T aStorageBus,
+ std::vector<StorageControllerType_T> &aStorageControllerTypes) RT_OVERRIDE;
+ HRESULT getDefaultIoCacheSettingForStorageController(StorageControllerType_T aControllerType,
+ BOOL *aEnabled) RT_OVERRIDE;
+ HRESULT getStorageControllerHotplugCapable(StorageControllerType_T aControllerType,
+ BOOL *aHotplugCapable) RT_OVERRIDE;
+ HRESULT getMaxInstancesOfUSBControllerType(ChipsetType_T aChipset,
+ USBControllerType_T aType,
+ ULONG *aMaxInstances) RT_OVERRIDE;
+ HRESULT getCPUProfiles(CPUArchitecture_T aArchitecture, const com::Utf8Str &aNamePattern,
+ std::vector<ComPtr<ICPUProfile> > &aProfiles) RT_OVERRIDE;
+
+ HRESULT i_getUserHomeDirectory(Utf8Str &strPath);
+ HRESULT i_setDefaultMachineFolder(const Utf8Str &strPath);
+ HRESULT i_setLoggingLevel(const com::Utf8Str &aLoggingLevel);
+ HRESULT i_setDefaultHardDiskFormat(const com::Utf8Str &aFormat);
+ HRESULT i_setVRDEAuthLibrary(const com::Utf8Str &aPath);
+
+ HRESULT i_setWebServiceAuthLibrary(const com::Utf8Str &aPath);
+ HRESULT i_setDefaultVRDEExtPack(const com::Utf8Str &aExtPack);
+ HRESULT i_setDefaultCryptoExtPack(const com::Utf8Str &aExtPack);
+ HRESULT i_setAutostartDatabasePath(const com::Utf8Str &aPath);
+ HRESULT i_setDefaultAdditionsISO(const com::Utf8Str &aPath);
+ HRESULT i_setDefaultFrontend(const com::Utf8Str &aDefaultFrontend);
+
+ VirtualBox * const mParent;
+
+ settings::SystemProperties *m;
+
+ MediumFormatList m_llMediumFormats;
+
+ bool m_fLoadedX86CPUProfiles; /**< Set if we've loaded the x86 and AMD64 CPU profiles. */
+ CPUProfileList_T m_llCPUProfiles; /**< List of loaded CPU profiles. */
+
+ friend class VirtualBox;
+};
+
+#endif /* !MAIN_INCLUDED_SystemPropertiesImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/TextScript.h b/src/VBox/Main/include/TextScript.h
new file mode 100644
index 00000000..39fe92d6
--- /dev/null
+++ b/src/VBox/Main/include/TextScript.h
@@ -0,0 +1,251 @@
+/* $Id: TextScript.h $ */
+/** @file
+ * Classes for reading/parsing/saving text scripts (unattended installation, ++).
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_TextScript_h
+#define MAIN_INCLUDED_TextScript_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include <iprt/cpp/utils.h>
+#include <vector>
+
+
+/**
+ * Base class for all the script readers/editors.
+ *
+ * @todo get rid of this silly bugger.
+ */
+class AbstractScript
+ : public RTCNonCopyable
+{
+protected:
+ /** For setting errors.
+ * Yeah, class isn't entirely abstract now. */
+ VirtualBoxBase *mpSetError;
+
+private: /* no default constructors for children. */
+ AbstractScript() {}
+
+public:
+ DECLARE_TRANSLATE_METHODS(AbstractScript)
+
+ AbstractScript(VirtualBoxBase *pSetError) : mpSetError(pSetError) {}
+ virtual ~AbstractScript() {}
+
+ /**
+ * Read a script from a file
+ */
+ virtual HRESULT read(const Utf8Str &rStrFilename) = 0;
+
+ /**
+ * Read a script from a VFS file handle.
+ */
+ virtual HRESULT readFromHandle(RTVFSFILE hVfsFile, const char *pszFilename) = 0;
+
+ /**
+ * Parse the script
+ */
+ virtual HRESULT parse() = 0;
+
+ /**
+ * Save a script to a string.
+ *
+ * This is used by save() and later others to deloy the script.
+ */
+ virtual HRESULT saveToString(Utf8Str &rStrDst) = 0;
+
+ /**
+ * Save a script to a file.
+ * @param rStrPath Where to save the script. This normally points to a
+ * file, but in a number of child use cases it's
+ * actually giving a directory to put the script in
+ * using the default deloyment filename. One day we
+ * might make the caller do this path joining.
+ * @param fOverwrite Whether to overwrite the file or not.
+ */
+ virtual HRESULT save(const Utf8Str &rStrPath, bool fOverwrite) = 0;
+
+ /**
+ * Path where an actual script with user's data is located
+ */
+ virtual const Utf8Str &getActualScriptPath() const = 0;
+};
+
+/**
+ * Base class for text based script readers/editors.
+ *
+ * This deals with reading the file into a string data member, writing it back
+ * out to a file, and remember the filenames.
+ */
+class BaseTextScript : public AbstractScript
+{
+protected:
+ const char * const mpszDefaultTemplateFilename; /**< The default template filename. Can be empty. */
+ const char * const mpszDefaultFilename; /**< Filename to use when someone calls save() with a directory path. Can be NULL. */
+ RTCString mStrScriptFullContent; /**< Raw text file content. Produced by read() and typically only used by parse(). */
+ Utf8Str mStrOriginalPath; /**< Path where an original script is located (set by read()). */
+ Utf8Str mStrSavedPath; /**< Path where an saved script with user's data is located (set by save()). */
+
+public:
+ DECLARE_TRANSLATE_METHODS(BaseTextScript)
+
+ BaseTextScript(VirtualBoxBase *pSetError, const char *pszDefaultTemplateFilename, const char *pszDefaultFilename)
+ : AbstractScript(pSetError)
+ , mpszDefaultTemplateFilename(pszDefaultTemplateFilename)
+ , mpszDefaultFilename(pszDefaultFilename)
+ { }
+ virtual ~BaseTextScript() {}
+
+ HRESULT read(const Utf8Str &rStrFilename);
+ HRESULT readFromHandle(RTVFSFILE hVfsFile, const char *pszFilename);
+ HRESULT save(const Utf8Str &rStrFilename, bool fOverwrite);
+
+ /**
+ * Gets the default filename for this class of scripts (empty if none).
+ *
+ * @note Just the filename, no path.
+ */
+ const char *getDefaultFilename() const
+ {
+ return mpszDefaultFilename;
+ }
+
+ /**
+ * Gets the default template filename for this class of scripts (empty if none).
+ *
+ * @note Just the filename, no path.
+ */
+ const char *getDefaultTemplateFilename() const
+ {
+ return mpszDefaultTemplateFilename;
+ }
+
+ /**
+ * Path to the file we last saved the script as.
+ */
+ const Utf8Str &getActualScriptPath() const
+ {
+ return mStrSavedPath;
+ }
+
+ /**
+ * Path where an original script is located
+ */
+ const Utf8Str &getOriginalScriptPath() const
+ {
+ return mStrOriginalPath;
+ }
+};
+
+
+/**
+ * Generic line based text script editor.
+ *
+ * This is used for editing isolinux configuratin files among other things.
+ */
+class GeneralTextScript : public BaseTextScript
+{
+protected:
+ RTCList<RTCString> mScriptContentByLines; /**< Content index by line. This contains the edited version. */
+ bool mfDataParsed; /**< Indicates whether the script has been parse() yet. */
+
+public:
+ DECLARE_TRANSLATE_METHODS(GeneralTextScript)
+
+ GeneralTextScript(VirtualBoxBase *pSetError, const char *pszDefaultTemplateFilename = NULL, const char *pszDefaultFilename = NULL)
+ : BaseTextScript(pSetError, pszDefaultTemplateFilename, pszDefaultFilename), mfDataParsed(false)
+ {}
+ virtual ~GeneralTextScript() {}
+
+ HRESULT parse();
+ HRESULT saveToString(Utf8Str &rStrDst);
+
+ //////////////////New functions//////////////////////////////
+
+ bool isDataParsed() const
+ {
+ return mfDataParsed;
+ }
+
+ /**
+ * Returns the actual size of script in lines
+ */
+ size_t getLineNumbersOfScript() const
+ {
+ return mScriptContentByLines.size();
+ }
+
+ /**
+ * Gets a read-only reference to the given line, returning Utf8Str::Empty if
+ * idxLine is out of range.
+ *
+ * @returns Line string reference or Utf8Str::Empty.
+ * @param idxLine The line number.
+ *
+ * @todo RTCList doesn't allow this method to be const.
+ */
+ RTCString const &getContentOfLine(size_t idxLine);
+
+ /**
+ * Set new content of line
+ */
+ HRESULT setContentOfLine(size_t idxLine, const Utf8Str &newContent);
+
+ /**
+ * Find a substring in the script
+ * Returns a list with the found lines
+ * @throws std::bad_alloc
+ */
+ std::vector<size_t> findTemplate(const Utf8Str &rStrNeedle, RTCString::CaseSensitivity enmCase = RTCString::CaseSensitive);
+
+ /**
+ * In line @a idxLine replace the first occurence of @a rStrNeedle with
+ * @a rStrRelacement.
+ */
+ HRESULT findAndReplace(size_t idxLine, const Utf8Str &rStrNeedle, const Utf8Str &rStrReplacement);
+
+ /**
+ * Append a string into the end of the given line.
+ */
+ HRESULT appendToLine(size_t idxLine, const Utf8Str &rStrToAppend);
+
+ /**
+ * Prepend a string in the beginning of the given line.
+ */
+ HRESULT prependToLine(size_t idxLine, const Utf8Str &rStrToPrepend);
+
+ /**
+ * Append a new line at the end of the list of line.
+ */
+ HRESULT appendLine(const Utf8Str &rStrLineToAppend);
+ //////////////////New functions//////////////////////////////
+};
+
+
+#endif /* !MAIN_INCLUDED_TextScript_h */
diff --git a/src/VBox/Main/include/ThreadTask.h b/src/VBox/Main/include/ThreadTask.h
new file mode 100644
index 00000000..3fbcdd10
--- /dev/null
+++ b/src/VBox/Main/include/ThreadTask.h
@@ -0,0 +1,78 @@
+/** @file
+ * VirtualBox ThreadTask class definition
+ */
+
+/*
+ * Copyright (C) 2015-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ThreadTask_h
+#define MAIN_INCLUDED_ThreadTask_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VBox/com/string.h"
+
+/**
+ * The class ThreadVoidData is used as a base class for any data which we want to pass into a thread
+ */
+struct ThreadVoidData
+{
+public:
+ ThreadVoidData() { }
+ virtual ~ThreadVoidData() { }
+};
+
+
+class ThreadTask
+{
+public:
+ ThreadTask(const Utf8Str &t)
+ : m_strTaskName(t)
+ , mAsync(false)
+ { }
+
+ virtual ~ThreadTask()
+ { }
+
+ HRESULT createThread(void);
+ HRESULT createThreadWithType(RTTHREADTYPE enmType);
+
+ inline Utf8Str getTaskName() const { return m_strTaskName; }
+ bool isAsync() { return mAsync; }
+
+protected:
+ HRESULT createThreadInternal(RTTHREADTYPE enmType);
+ static DECLCALLBACK(int) taskHandlerThreadProc(RTTHREAD thread, void *pvUser);
+
+ ThreadTask() : m_strTaskName("GenericTask")
+ { }
+
+ Utf8Str m_strTaskName;
+ bool mAsync;
+
+private:
+ virtual void handler() = 0;
+};
+
+#endif /* !MAIN_INCLUDED_ThreadTask_h */
+
diff --git a/src/VBox/Main/include/TokenImpl.h b/src/VBox/Main/include/TokenImpl.h
new file mode 100644
index 00000000..d08491cf
--- /dev/null
+++ b/src/VBox/Main/include/TokenImpl.h
@@ -0,0 +1,118 @@
+/* $Id: TokenImpl.h $ */
+/** @file
+ * Token COM class implementations - MachineToken and MediumLockToken
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_TokenImpl_h
+#define MAIN_INCLUDED_TokenImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "TokenWrap.h"
+#include "MachineImpl.h"
+
+
+/**
+ * The MachineToken class automates cleanup of a SessionMachine object.
+ */
+class ATL_NO_VTABLE MachineToken :
+ public TokenWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(MachineToken)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(const ComObjPtr<SessionMachine> &pSessionMachine);
+ void uninit(bool fAbandon);
+
+private:
+
+ // wrapped IToken methods
+ HRESULT abandon(AutoCaller &aAutoCaller);
+ HRESULT dummy();
+
+ // data
+ struct Data
+ {
+ Data()
+ {
+ }
+
+ ComObjPtr<SessionMachine> pSessionMachine;
+ };
+
+ Data m;
+};
+
+
+class Medium;
+
+/**
+ * The MediumLockToken class automates cleanup of a Medium lock.
+ */
+class ATL_NO_VTABLE MediumLockToken :
+ public TokenWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(MediumLockToken)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(const ComObjPtr<Medium> &pMedium, bool fWrite);
+ void uninit();
+
+private:
+
+ // wrapped IToken methods
+ HRESULT abandon(AutoCaller &aAutoCaller);
+ HRESULT dummy();
+
+ // data
+ struct Data
+ {
+ Data() :
+ fWrite(false)
+ {
+ }
+
+ ComObjPtr<Medium> pMedium;
+ bool fWrite;
+ };
+
+ Data m;
+};
+
+
+#endif /* !MAIN_INCLUDED_TokenImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/TrustAnchorsAndCerts.h b/src/VBox/Main/include/TrustAnchorsAndCerts.h
new file mode 100644
index 00000000..b828c179
--- /dev/null
+++ b/src/VBox/Main/include/TrustAnchorsAndCerts.h
@@ -0,0 +1,53 @@
+/* $Id: TrustAnchorsAndCerts.h $ */
+/** @file
+ * Main - Collection of trust anchors and certificates included in VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_TrustAnchorsAndCerts_h
+#define MAIN_INCLUDED_TrustAnchorsAndCerts_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+
+RT_C_DECLS_BEGIN
+
+extern const unsigned char g_abUefiMicrosoftKek[];
+extern const unsigned g_cbUefiMicrosoftKek;
+
+extern const unsigned char g_abUefiMicrosoftCa[];
+extern const unsigned g_cbUefiMicrosoftCa;
+
+extern const unsigned char g_abUefiMicrosoftProPca[];
+extern const unsigned g_cbUefiMicrosoftProPca;
+
+extern const unsigned char g_abUefiOracleDefPk[];
+extern const unsigned g_cbUefiOracleDefPk;
+
+RT_C_DECLS_END
+
+#endif /* !MAIN_INCLUDED_TrustAnchorsAndCerts_h */
+
diff --git a/src/VBox/Main/include/TrustedPlatformModuleImpl.h b/src/VBox/Main/include/TrustedPlatformModuleImpl.h
new file mode 100644
index 00000000..dbe8b9a3
--- /dev/null
+++ b/src/VBox/Main/include/TrustedPlatformModuleImpl.h
@@ -0,0 +1,84 @@
+/* $Id: TrustedPlatformModuleImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation - Machine Trusted Platform Module settings.
+ */
+
+/*
+ * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_TrustedPlatformModuleImpl_h
+#define MAIN_INCLUDED_TrustedPlatformModuleImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "TrustedPlatformModuleWrap.h"
+
+class GuestOSType;
+
+namespace settings
+{
+ struct TpmSettings;
+}
+
+class ATL_NO_VTABLE TrustedPlatformModule :
+ public TrustedPlatformModuleWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(TrustedPlatformModule)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *parent);
+ HRESULT init(Machine *parent, TrustedPlatformModule *that);
+ HRESULT initCopy(Machine *parent, TrustedPlatformModule *that);
+ void uninit();
+
+ // public methods for internal purposes only
+ HRESULT i_loadSettings(const settings::TpmSettings &data);
+ HRESULT i_saveSettings(settings::TpmSettings &data);
+
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(TrustedPlatformModule *aThat);
+ void i_applyDefaults(GuestOSType *aOsType);
+
+private:
+
+ // wrapped ITrustedPlatformModule properties
+ HRESULT getType(TpmType_T *aType);
+ HRESULT setType(TpmType_T aType);
+ HRESULT getLocation(com::Utf8Str &location);
+ HRESULT setLocation(const com::Utf8Str &location);
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_TrustedPlatformModuleImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/USBControllerImpl.h b/src/VBox/Main/include/USBControllerImpl.h
new file mode 100644
index 00000000..85ad14b6
--- /dev/null
+++ b/src/VBox/Main/include/USBControllerImpl.h
@@ -0,0 +1,88 @@
+/* $Id: USBControllerImpl.h $ */
+
+/** @file
+ *
+ * VBox USBController COM Class declaration.
+ */
+
+/*
+ * Copyright (C) 2005-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBControllerImpl_h
+#define MAIN_INCLUDED_USBControllerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "USBControllerWrap.h"
+
+class HostUSBDevice;
+class USBDeviceFilter;
+
+namespace settings
+{
+ struct USBController;
+}
+
+class ATL_NO_VTABLE USBController :
+ public USBControllerWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(USBController)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent, const com::Utf8Str &aName, USBControllerType_T enmType);
+ HRESULT init(Machine *aParent, USBController *aThat, bool fReshare = false);
+ HRESULT initCopy(Machine *aParent, USBController *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(USBController *aThat);
+ void i_unshare();
+
+ ComObjPtr<USBController> i_getPeer();
+ const Utf8Str &i_getName() const;
+ const USBControllerType_T &i_getControllerType() const;
+
+private:
+
+ // wrapped IUSBController properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getType(USBControllerType_T *aType);
+ HRESULT setType(USBControllerType_T aType);
+ HRESULT getUSBStandard(USHORT *aUSBStandard);
+
+ void printList();
+
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_USBControllerImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/USBDeviceFilterImpl.h b/src/VBox/Main/include/USBDeviceFilterImpl.h
new file mode 100644
index 00000000..7514b480
--- /dev/null
+++ b/src/VBox/Main/include/USBDeviceFilterImpl.h
@@ -0,0 +1,240 @@
+/* $Id: USBDeviceFilterImpl.h $ */
+/** @file
+ * Declaration of USBDeviceFilter and HostUSBDeviceFilter.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBDeviceFilterImpl_h
+#define MAIN_INCLUDED_USBDeviceFilterImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/settings.h>
+#include "Matching.h"
+#include <VBox/usbfilter.h>
+#include "USBDeviceFilterWrap.h"
+
+class USBDeviceFilters;
+class Host;
+namespace settings
+{
+ struct USBDeviceFilter;
+}
+
+// USBDeviceFilter
+////////////////////////////////////////////////////////////////////////////////
+
+class ATL_NO_VTABLE USBDeviceFilter :
+ public USBDeviceFilterWrap
+{
+public:
+
+ struct BackupableUSBDeviceFilterData
+ {
+ typedef matching::Matchable <matching::ParsedBoolFilter> BOOLFilter;
+
+ BackupableUSBDeviceFilterData() : mId (NULL) {}
+ BackupableUSBDeviceFilterData(const BackupableUSBDeviceFilterData &aThat) :
+ mRemote(aThat.mRemote), mId(aThat.mId)
+ {
+ mData.strName = aThat.mData.strName;
+ mData.fActive = aThat.mData.fActive;
+ mData.ulMaskedInterfaces = aThat.mData.ulMaskedInterfaces;
+ USBFilterClone(&mUSBFilter, &aThat.mUSBFilter);
+ }
+
+ /** Remote or local matching criterion. */
+ BOOLFilter mRemote;
+
+ /** The filter data blob. */
+ USBFILTER mUSBFilter;
+
+ /** Arbitrary ID field (not used by the class itself) */
+ void *mId;
+
+ settings::USBDeviceFilter mData;
+ };
+
+ DECLARE_COMMON_CLASS_METHODS(USBDeviceFilter)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(USBDeviceFilters *aParent,
+ const settings::USBDeviceFilter &data);
+ HRESULT init(USBDeviceFilters *aParent, IN_BSTR aName);
+ HRESULT init(USBDeviceFilters *aParent, USBDeviceFilter *aThat,
+ bool aReshare = false);
+ HRESULT initCopy(USBDeviceFilters *aParent, USBDeviceFilter *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ bool i_isModified();
+ void i_rollback();
+ void i_commit();
+
+ void unshare();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+ void *& i_getId() { return bd->mId; }
+ const BackupableUSBDeviceFilterData& i_getData() { return *bd.data(); }
+ ComObjPtr<USBDeviceFilter> i_peer() { return mPeer; }
+
+ // tr() wants to belong to a class it seems, thus this one here.
+ static HRESULT i_usbFilterFieldFromString(PUSBFILTER aFilter,
+ USBFILTERIDX aIdx,
+ const Utf8Str &aValue,
+ Utf8Str &aErrStr);
+
+ static const char* i_describeUSBFilterIdx(USBFILTERIDX aIdx);
+
+private:
+
+ // wrapped IUSBDeviceFilter properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getActive(BOOL *aActive);
+ HRESULT setActive(BOOL aActive);
+ HRESULT getVendorId(com::Utf8Str &aVendorId);
+ HRESULT setVendorId(const com::Utf8Str &aVendorId);
+ HRESULT getProductId(com::Utf8Str &aProductId);
+ HRESULT setProductId(const com::Utf8Str &aProductId);
+ HRESULT getRevision(com::Utf8Str &aRevision);
+ HRESULT setRevision(const com::Utf8Str &aRevision);
+ HRESULT getManufacturer(com::Utf8Str &aManufacturer);
+ HRESULT setManufacturer(const com::Utf8Str &aManufacturer);
+ HRESULT getProduct(com::Utf8Str &aProduct);
+ HRESULT setProduct(const com::Utf8Str &aProduct);
+ HRESULT getSerialNumber(com::Utf8Str &aSerialNumber);
+ HRESULT setSerialNumber(const com::Utf8Str &aSerialNumber);
+ HRESULT getPort(com::Utf8Str &aPort);
+ HRESULT setPort(const com::Utf8Str &aPort);
+ HRESULT getRemote(com::Utf8Str &aRemote);
+ HRESULT setRemote(const com::Utf8Str &aRemote);
+ HRESULT getMaskedInterfaces(ULONG *aMaskedInterfaces);
+ HRESULT setMaskedInterfaces(ULONG aMaskedInterfaces);
+
+ // wrapped IUSBDeviceFilter methods
+ HRESULT i_usbFilterFieldGetter(USBFILTERIDX aIdx, com::Utf8Str &aStr);
+ HRESULT i_usbFilterFieldSetter(USBFILTERIDX aIdx, const com::Utf8Str &strNew);
+
+ USBDeviceFilters * const mParent;
+ USBDeviceFilter * const mPeer;
+
+ Backupable<BackupableUSBDeviceFilterData> bd;
+
+ bool m_fModified;
+
+ /** Used externally to indicate this filter is in the list
+ (not touched by the class itself except that in init()/uninit()) */
+ bool mInList;
+
+ friend class USBDeviceFilters;
+};
+#include "HostUSBDeviceFilterWrap.h"
+
+// HostUSBDeviceFilter
+////////////////////////////////////////////////////////////////////////////////
+
+class ATL_NO_VTABLE HostUSBDeviceFilter :
+ public HostUSBDeviceFilterWrap
+{
+public:
+
+ struct BackupableUSBDeviceFilterData : public USBDeviceFilter::BackupableUSBDeviceFilterData
+ {
+ BackupableUSBDeviceFilterData() {}
+ };
+
+ DECLARE_COMMON_CLASS_METHODS (HostUSBDeviceFilter)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Host *aParent,
+ const settings::USBDeviceFilter &data);
+ HRESULT init(Host *aParent, IN_BSTR aName);
+ void uninit();
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+ void i_saveSettings(settings::USBDeviceFilter &data);
+
+ void*& i_getId() { return bd.data()->mId; }
+
+ const BackupableUSBDeviceFilterData& i_getData() { return *bd.data(); }
+
+ // util::Lockable interface
+ RWLockHandle *lockHandle() const;
+
+private:
+
+ // wrapped IHostUSBDeviceFilter properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT setName(const com::Utf8Str &aName);
+ HRESULT getActive(BOOL *aActive);
+ HRESULT setActive(BOOL aActive);
+ HRESULT getVendorId(com::Utf8Str &aVendorId);
+ HRESULT setVendorId(const com::Utf8Str &aVendorId);
+ HRESULT getProductId(com::Utf8Str &aProductId);
+ HRESULT setProductId(const com::Utf8Str &aProductId);
+ HRESULT getRevision(com::Utf8Str &aRevision);
+ HRESULT setRevision(const com::Utf8Str &aRevision);
+ HRESULT getManufacturer(com::Utf8Str &aManufacturer);
+ HRESULT setManufacturer(const com::Utf8Str &aManufacturer);
+ HRESULT getProduct(com::Utf8Str &aProduct);
+ HRESULT setProduct(const com::Utf8Str &aProduct);
+ HRESULT getSerialNumber(com::Utf8Str &aSerialNumber);
+ HRESULT setSerialNumber(const com::Utf8Str &aSerialNumber);
+ HRESULT getPort(com::Utf8Str &aPort);
+ HRESULT setPort(const com::Utf8Str &aPort);
+ HRESULT getRemote(com::Utf8Str &aRemote);
+ HRESULT setRemote(const com::Utf8Str &aRemote);
+ HRESULT getMaskedInterfaces(ULONG *aMaskedInterfaces);
+ HRESULT setMaskedInterfaces(ULONG aMaskedInterfaces);
+
+ // wrapped IHostUSBDeviceFilter properties
+ HRESULT getAction(USBDeviceFilterAction_T *aAction);
+ HRESULT setAction(USBDeviceFilterAction_T aAction);
+
+ HRESULT i_usbFilterFieldGetter(USBFILTERIDX aIdx, com::Utf8Str &aStr);
+ HRESULT i_usbFilterFieldSetter(USBFILTERIDX aIdx, const com::Utf8Str &aStr);
+
+ Host * const mParent;
+
+ Backupable<BackupableUSBDeviceFilterData> bd;
+
+ /** Used externally to indicate this filter is in the list
+ (not touched by the class itself except that in init()/uninit()) */
+ bool mInList;
+
+ friend class Host;
+};
+
+#endif /* !MAIN_INCLUDED_USBDeviceFilterImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/USBDeviceFiltersImpl.h b/src/VBox/Main/include/USBDeviceFiltersImpl.h
new file mode 100644
index 00000000..b82c7523
--- /dev/null
+++ b/src/VBox/Main/include/USBDeviceFiltersImpl.h
@@ -0,0 +1,97 @@
+/* $Id: USBDeviceFiltersImpl.h $ */
+/** @file
+ * VBox USBDeviceFilters COM Class declaration.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBDeviceFiltersImpl_h
+#define MAIN_INCLUDED_USBDeviceFiltersImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "USBDeviceFiltersWrap.h"
+
+class HostUSBDevice;
+class USBDeviceFilter;
+
+namespace settings
+{
+ struct USB;
+}
+
+class ATL_NO_VTABLE USBDeviceFilters :
+ public USBDeviceFiltersWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(USBDeviceFilters)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent);
+ HRESULT init(Machine *aParent, USBDeviceFilters *aThat);
+ HRESULT initCopy(Machine *aParent, USBDeviceFilters *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::USB &data);
+ HRESULT i_saveSettings(settings::USB &data);
+
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(USBDeviceFilters *aThat);
+
+#ifdef VBOX_WITH_USB
+ HRESULT i_onDeviceFilterChange(USBDeviceFilter *aFilter,
+ BOOL aActiveChanged = FALSE);
+ bool i_hasMatchingFilter(const ComObjPtr<HostUSBDevice> &aDevice, ULONG *aMaskedIfs);
+ bool i_hasMatchingFilter(IUSBDevice *aUSBDevice, ULONG *aMaskedIfs);
+ HRESULT i_notifyProxy(bool aInsertFilters);
+#endif /* VBOX_WITH_USB */
+
+ // public methods for internal purposes only
+ // (ensure there is a caller and a read lock before calling them!)
+ Machine* i_getMachine();
+
+private:
+
+ // Wrapped IUSBDeviceFilters attributes
+ HRESULT getDeviceFilters(std::vector<ComPtr<IUSBDeviceFilter> > &aDeviceFilters);
+
+ // wrapped IUSBDeviceFilters methods
+ HRESULT createDeviceFilter(const com::Utf8Str &aName,
+ ComPtr<IUSBDeviceFilter> &aFilter);
+ HRESULT insertDeviceFilter(ULONG aPosition,
+ const ComPtr<IUSBDeviceFilter> &aFilter);
+ HRESULT removeDeviceFilter(ULONG aPosition,
+ ComPtr<IUSBDeviceFilter> &aFilter);
+ struct Data;
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_USBDeviceFiltersImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/USBDeviceImpl.h b/src/VBox/Main/include/USBDeviceImpl.h
new file mode 100644
index 00000000..84e378ca
--- /dev/null
+++ b/src/VBox/Main/include/USBDeviceImpl.h
@@ -0,0 +1,118 @@
+/* $Id: USBDeviceImpl.h $ */
+/** @file
+ * Header file for the OUSBDevice (IUSBDevice) class, VBoxC.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBDeviceImpl_h
+#define MAIN_INCLUDED_USBDeviceImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "USBDeviceWrap.h"
+
+/**
+ * Object class used for maintaining devices attached to a USB controller.
+ * Generally this contains much less information.
+ */
+class ATL_NO_VTABLE OUSBDevice :
+ public USBDeviceWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(OUSBDevice)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(IUSBDevice *a_pUSBDevice);
+ void uninit();
+
+ // public methods only for internal purposes
+ const Guid &i_id() const { return mData.id; }
+
+private:
+
+ // Wrapped IUSBDevice properties
+ HRESULT getId(com::Guid &aId);
+ HRESULT getVendorId(USHORT *aVendorId);
+ HRESULT getProductId(USHORT *aProductId);
+ HRESULT getRevision(USHORT *aRevision);
+ HRESULT getManufacturer(com::Utf8Str &aManufacturer);
+ HRESULT getProduct(com::Utf8Str &aProduct);
+ HRESULT getSerialNumber(com::Utf8Str &aSerialNumber);
+ HRESULT getAddress(com::Utf8Str &aAddress);
+ HRESULT getPort(USHORT *aPort);
+ HRESULT getPortPath(com::Utf8Str &aPortPath);
+ HRESULT getVersion(USHORT *aVersion);
+ HRESULT getSpeed(USBConnectionSpeed_T *aSpeed);
+ HRESULT getRemote(BOOL *aRemote);
+ HRESULT getBackend(com::Utf8Str &aBackend);
+ HRESULT getDeviceInfo(std::vector<com::Utf8Str> &aInfo);
+
+ struct Data
+ {
+ Data() : vendorId(0), productId(0), revision(0), port(0),
+ version(1), speed(USBConnectionSpeed_Null),
+ remote(FALSE) {}
+
+ /** The UUID of this device. */
+ const Guid id;
+
+ /** The vendor id of this USB device. */
+ const USHORT vendorId;
+ /** The product id of this USB device. */
+ const USHORT productId;
+ /** The product revision number of this USB device.
+ * (high byte = integer; low byte = decimal) */
+ const USHORT revision;
+ /** The Manufacturer string. (Quite possibly NULL.) */
+ const com::Utf8Str manufacturer;
+ /** The Product string. (Quite possibly NULL.) */
+ const com::Utf8Str product;
+ /** The SerialNumber string. (Quite possibly NULL.) */
+ const com::Utf8Str serialNumber;
+ /** The host specific address of the device. */
+ const com::Utf8Str address;
+ /** The device specific backend. */
+ const com::Utf8Str backend;
+ /** The host port number. */
+ const USHORT port;
+ /** The host port path. */
+ const com::Utf8Str portPath;
+ /** The major USB version number of the device. */
+ const USHORT version;
+ /** The speed at which the device is communicating. */
+ const USBConnectionSpeed_T speed;
+ /** Remote (VRDP) or local device. */
+ const BOOL remote;
+ };
+
+ Data mData;
+};
+
+#endif /* !MAIN_INCLUDED_USBDeviceImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/USBGetDevices.h b/src/VBox/Main/include/USBGetDevices.h
new file mode 100644
index 00000000..d4bcfbdc
--- /dev/null
+++ b/src/VBox/Main/include/USBGetDevices.h
@@ -0,0 +1,114 @@
+/* $Id: USBGetDevices.h $ */
+/** @file
+ * VirtualBox Linux host USB device enumeration.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBGetDevices_h
+#define MAIN_INCLUDED_USBGetDevices_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/usb.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+
+/**
+ * Free all the members of a USB device created by the Linux enumeration code.
+ *
+ * @note This duplicates a USBProxyService method which we needed access too
+ * without pulling in the rest of the proxy service code.
+ *
+ * @param pDevice Pointer to the device.
+ */
+DECLINLINE(void) deviceFreeMembers(PUSBDEVICE pDevice)
+{
+ RTStrFree((char *)pDevice->pszManufacturer);
+ pDevice->pszManufacturer = NULL;
+ RTStrFree((char *)pDevice->pszProduct);
+ pDevice->pszProduct = NULL;
+ RTStrFree((char *)pDevice->pszSerialNumber);
+ pDevice->pszSerialNumber = NULL;
+
+ RTStrFree((char *)pDevice->pszAddress);
+ pDevice->pszAddress = NULL;
+}
+
+/**
+ * Free one USB device created by the Linux enumeration code.
+ *
+ * @note This duplicates a USBProxyService method which we needed access too
+ * without pulling in the rest of the proxy service code.
+ *
+ * @param pDevice Pointer to the device. NULL is OK.
+ */
+DECLINLINE(void) deviceFree(PUSBDEVICE pDevice)
+{
+ if (pDevice)
+ {
+ deviceFreeMembers(pDevice);
+ RTMemFree(pDevice);
+ }
+}
+
+/**
+ * Free a linked list of USB devices created by the Linux enumeration code.
+ * @param ppHead Pointer to the first device in the linked list
+ */
+DECLINLINE(void) deviceListFree(PUSBDEVICE *ppHead)
+{
+ PUSBDEVICE pHead = *ppHead;
+ while (pHead)
+ {
+ PUSBDEVICE pNext = pHead->pNext;
+ deviceFree(pHead);
+ pHead = pNext;
+ }
+ *ppHead = NULL;
+}
+
+RT_C_DECLS_BEGIN
+
+extern bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot, bool fIsDeviceNodes);
+
+#ifdef UNIT_TEST
+void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,
+ const char *pcszDevicesRoot, bool fDevicesAccessible,
+ int vrcMethodInitResult);
+void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot);
+#endif
+
+extern int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices, const char **ppcszDevicesRoot);
+#ifdef UNIT_TEST
+extern void TestUSBSetAvailableUsbfsDevices(const char **pacszDeviceAddresses);
+extern void TestUSBSetAccessibleFiles(const char **pacszAccessibleFiles);
+#endif
+
+extern PUSBDEVICE USBProxyLinuxGetDevices(const char *pcszDevicesRoot, bool fUseSysfs);
+
+RT_C_DECLS_END
+
+#endif /* !MAIN_INCLUDED_USBGetDevices_h */
+
diff --git a/src/VBox/Main/include/USBIdDatabase.h b/src/VBox/Main/include/USBIdDatabase.h
new file mode 100644
index 00000000..b739a017
--- /dev/null
+++ b/src/VBox/Main/include/USBIdDatabase.h
@@ -0,0 +1,226 @@
+/* $Id: USBIdDatabase.h $ */
+/** @file
+ * USB device vendor and product ID database.
+ */
+
+/*
+ * Copyright (C) 2015-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBIdDatabase_h
+#define MAIN_INCLUDED_USBIdDatabase_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/assert.h>
+#include <iprt/stdint.h>
+#include <iprt/cpp/ministring.h>
+#include <iprt/bldprog-strtab.h>
+
+
+/** Saves a few bytes (~25%) on strings. */
+#define USB_ID_DATABASE_WITH_COMPRESSION
+
+/** Max string length. */
+#define USB_ID_DATABASE_MAX_STRING _1K
+
+
+AssertCompileSize(RTBLDPROGSTRREF, sizeof(uint32_t));
+
+
+/**
+ * Elements of product table.
+ */
+typedef struct USBIDDBPROD
+{
+ /** Product ID. */
+ uint16_t idProduct;
+} USBIDDBPROD;
+AssertCompileSize(USBIDDBPROD, sizeof(uint16_t));
+
+
+/**
+ * Element of vendor table.
+ */
+typedef struct USBIDDBVENDOR
+{
+ /** Vendor ID. */
+ uint16_t idVendor;
+ /** Index of the first product. */
+ uint16_t iProduct;
+ /** Number of products. */
+ uint16_t cProducts;
+} USBIDDBVENDOR;
+AssertCompileSize(USBIDDBVENDOR, sizeof(uint16_t) * 3);
+
+
+/**
+ * Wrapper for static array of Aliases.
+ */
+class USBIdDatabase
+{
+public: // For assertions and statis in the generator.
+ /** The compressed string table. */
+ static RTBLDPROGSTRTAB const s_StrTab;
+
+ /** Number of vendors in the two parallel arrays. */
+ static const size_t s_cVendors;
+ /** Vendor IDs lookup table. */
+ static const USBIDDBVENDOR s_aVendors[];
+ /** Vendor names table running parallel to s_aVendors. */
+ static const RTBLDPROGSTRREF s_aVendorNames[];
+
+ /** Number of products in the two parallel arrays. */
+ static const size_t s_cProducts;
+ /** Vendor+Product keys for lookup purposes. */
+ static const USBIDDBPROD s_aProducts[];
+ /** Product names table running parallel to s_aProducts. */
+ static const RTBLDPROGSTRREF s_aProductNames[];
+
+public:
+ static RTCString returnString(PCRTBLDPROGSTRREF pStr)
+ {
+ char szTmp[USB_ID_DATABASE_MAX_STRING * 2];
+ ssize_t cchTmp = RTBldProgStrTabQueryString(&s_StrTab, pStr->off, pStr->cch, szTmp, sizeof(szTmp));
+ return RTCString(szTmp, (size_t)RT_MAX(cchTmp, 0));
+ }
+
+private:
+ /**
+ * Performs a binary lookup of @a idVendor.
+ *
+ * @returns The index in the vendor tables, UINT32_MAX if not found.
+ * @param idVendor The vendor ID.
+ */
+ static uint32_t lookupVendor(uint16_t idVendor)
+ {
+ size_t iEnd = s_cVendors;
+ if (iEnd)
+ {
+ size_t iStart = 0;
+ for (;;)
+ {
+ size_t idx = iStart + (iEnd - iStart) / 2;
+ if (s_aVendors[idx].idVendor < idVendor)
+ {
+ idx++;
+ if (idx < iEnd)
+ iStart = idx;
+ else
+ break;
+ }
+ else if (s_aVendors[idx].idVendor > idVendor)
+ {
+ if (idx != iStart)
+ iEnd = idx;
+ else
+ break;
+ }
+ else
+ return (uint32_t)idx;
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ /**
+ * Performs a binary lookup of @a idProduct.
+ *
+ * @returns The index in the product tables, UINT32_MAX if not found.
+ * @param idProduct The product ID.
+ * @param iStart The index of the first entry for the vendor.
+ * @param iEnd The index of after the last entry.
+ */
+ static uint32_t lookupProduct(uint16_t idProduct, size_t iStart, size_t iEnd)
+ {
+ if (iStart < iEnd)
+ {
+ for (;;)
+ {
+ size_t idx = iStart + (iEnd - iStart) / 2;
+ if (s_aProducts[idx].idProduct < idProduct)
+ {
+ idx++;
+ if (idx < iEnd)
+ iStart = idx;
+ else
+ break;
+ }
+ else if (s_aProducts[idx].idProduct > idProduct)
+ {
+ if (idx != iStart)
+ iEnd = idx;
+ else
+ break;
+ }
+ else
+ return (uint32_t)idx;
+ }
+ }
+ return UINT32_MAX;
+ }
+
+
+public:
+ static RTCString findProduct(uint16_t idVendor, uint16_t idProduct)
+ {
+ uint32_t idxVendor = lookupVendor(idVendor);
+ if (idxVendor != UINT32_MAX)
+ {
+ uint32_t idxProduct = lookupProduct(idProduct, s_aVendors[idxVendor].iProduct,
+ s_aVendors[idxVendor].iProduct + s_aVendors[idxVendor].cProducts);
+ if (idxProduct != UINT32_MAX)
+ return returnString(&s_aProductNames[idxProduct]);
+ }
+ return RTCString();
+ }
+
+ static RTCString findVendor(uint16_t idVendor)
+ {
+ uint32_t idxVendor = lookupVendor(idVendor);
+ if (idxVendor != UINT32_MAX)
+ return returnString(&s_aVendorNames[idxVendor]);
+ return RTCString();
+ }
+
+ static RTCString findVendorAndProduct(uint16_t idVendor, uint16_t idProduct, RTCString *pstrProduct)
+ {
+ uint32_t idxVendor = lookupVendor(idVendor);
+ if (idxVendor != UINT32_MAX)
+ {
+ uint32_t idxProduct = lookupProduct(idProduct, s_aVendors[idxVendor].iProduct,
+ s_aVendors[idxVendor].iProduct + s_aVendors[idxVendor].cProducts);
+ if (idxProduct != UINT32_MAX)
+ *pstrProduct = returnString(&s_aProductNames[idxProduct]);
+ else
+ pstrProduct->setNull();
+ return returnString(&s_aVendorNames[idxVendor]);
+ }
+ pstrProduct->setNull();
+ return RTCString();
+ }
+
+};
+
+
+#endif /* !MAIN_INCLUDED_USBIdDatabase_h */
+
diff --git a/src/VBox/Main/include/USBProxyBackend.h b/src/VBox/Main/include/USBProxyBackend.h
new file mode 100644
index 00000000..540f4d14
--- /dev/null
+++ b/src/VBox/Main/include/USBProxyBackend.h
@@ -0,0 +1,448 @@
+/* $Id: USBProxyBackend.h $ */
+/** @file
+ * VirtualBox USB Proxy Backend (base) class.
+ */
+
+/*
+ * Copyright (C) 2005-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBProxyBackend_h
+#define MAIN_INCLUDED_USBProxyBackend_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/usb.h>
+#include <VBox/usbfilter.h>
+
+#include <iprt/socket.h>
+#include <iprt/poll.h>
+#include <iprt/semaphore.h>
+#include <iprt/cpp/utils.h>
+
+#include "VirtualBoxBase.h"
+#include "VirtualBoxImpl.h"
+#include "HostUSBDeviceImpl.h"
+#include "USBProxyBackendWrap.h"
+class USBProxyService;
+
+/**
+ * Base class for the USB Proxy Backend.
+ */
+class ATL_NO_VTABLE USBProxyBackend
+ : public USBProxyBackendWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackend)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ virtual int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ virtual void uninit();
+
+ bool isActive(void);
+ const com::Utf8Str &i_getId();
+ const com::Utf8Str &i_getAddress();
+ virtual const com::Utf8Str &i_getBackend();
+ uint32_t i_getRefCount();
+
+ virtual bool i_isDevReEnumerationRequired();
+
+ /** @name Interface for the USBController and the Host object.
+ * @{ */
+ virtual void *insertFilter(PCUSBFILTER aFilter);
+ virtual void removeFilter(void *aId);
+ /** @} */
+
+ /** @name Interfaces for the HostUSBDevice
+ * @{ */
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+ virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
+ /** @} */
+
+ static void freeDevice(PUSBDEVICE pDevice);
+
+protected:
+ int start(void);
+ int stop(void);
+ virtual void serviceThreadInit(void);
+ virtual void serviceThreadTerm(void);
+
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+ uint32_t incRef();
+ uint32_t decRef();
+
+ static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
+
+ static void initFilterFromDevice(PUSBFILTER aFilter, HostUSBDevice *aDevice);
+ static void freeDeviceMembers(PUSBDEVICE pDevice);
+
+ /**
+ * Backend specific callback when a device was added.
+ * (Currently only Linux uses it to adjust the udev polling).
+ */
+ virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, PUSBDEVICE pDev);
+ virtual bool isFakeUpdateRequired();
+
+private:
+
+ // wrapped IUSBProxyBackend properties
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getType(com::Utf8Str &aType);
+
+ static DECLCALLBACK(int) serviceThread(RTTHREAD Thread, void *pvUser);
+
+ void updateDeviceList(PUSBDEVICE pDevices);
+
+protected:
+ /** Pointer to the owning USB Proxy Service object. */
+ USBProxyService *m_pUsbProxyService;
+ /** Thread handle of the service thread. */
+ RTTHREAD mThread;
+ /** Flag which stop() sets to cause serviceThread to return. */
+ bool volatile mTerminate;
+ /** Id of the instance. */
+ const com::Utf8Str m_strId;
+ /** Address of the instance. */
+ const com::Utf8Str m_strAddress;
+ /** Backend identifier as used in the settings. */
+ const com::Utf8Str m_strBackend;
+ /** Reference counter which prevents the backend instance from being removed. */
+ uint32_t m_cRefs;
+ /** List of smart HostUSBDevice pointers. */
+ typedef std::list<ComObjPtr<HostUSBDevice> > HostUSBDeviceList;
+ /** List of the known USB devices for this backend. */
+ HostUSBDeviceList m_llDevices;
+};
+
+
+# if defined(RT_OS_DARWIN) || defined(DOXYGEN_RUNNING)
+# include <VBox/param.h>
+# undef PAGE_SHIFT
+# undef PAGE_SIZE
+# define OSType Carbon_OSType
+# include <Carbon/Carbon.h>
+# undef OSType
+# undef PVM
+
+/**
+ * The Darwin hosted USB Proxy Backend.
+ */
+class USBProxyBackendDarwin : public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendDarwin)
+
+ int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ void uninit();
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+
+protected:
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait (void);
+ virtual PUSBDEVICE getDevices (void);
+ virtual void serviceThreadInit (void);
+ virtual void serviceThreadTerm (void);
+ virtual bool isFakeUpdateRequired();
+
+private:
+ /** Reference to the runloop of the service thread.
+ * This is NULL if the service thread isn't running. */
+ CFRunLoopRef mServiceRunLoopRef;
+ /** The opaque value returned by DarwinSubscribeUSBNotifications. */
+ void *mNotifyOpaque;
+ /** A hack to work around the problem with the usb device enumeration
+ * not including newly attached devices. */
+ bool mWaitABitNextTime;
+};
+# endif /* RT_OS_DARWIN */
+
+
+# if defined(RT_OS_LINUX) || defined(DOXYGEN_RUNNING)
+# include <stdio.h>
+# ifdef VBOX_USB_WITH_SYSFS
+# include <HostHardwareLinux.h>
+# endif
+
+/**
+ * The Linux hosted USB Proxy Backend.
+ */
+class USBProxyBackendLinux: public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendLinux)
+
+ int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ void uninit();
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+
+protected:
+ int initUsbfs(void);
+ int initSysfs(void);
+ void doUsbfsCleanupAsNeeded(void);
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+ virtual void deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, PUSBDEVICE aUSBDevice);
+ virtual bool isFakeUpdateRequired();
+
+private:
+ int waitUsbfs(RTMSINTERVAL aMillies);
+ int waitSysfs(RTMSINTERVAL aMillies);
+
+private:
+ /** File handle to the '/proc/bus/usb/devices' file. */
+ RTFILE mhFile;
+ /** Pipe used to interrupt wait(), the read end. */
+ RTPIPE mhWakeupPipeR;
+ /** Pipe used to interrupt wait(), the write end. */
+ RTPIPE mhWakeupPipeW;
+ /** The root of usbfs. */
+ Utf8Str mDevicesRoot;
+ /** Whether we're using \<mUsbfsRoot\>/devices or /sys/whatever. */
+ bool mUsingUsbfsDevices;
+ /** Number of 500ms polls left to do. See usbDeterminState for details. */
+ unsigned mUdevPolls;
+# ifdef VBOX_USB_WITH_SYSFS
+ /** Object used for polling for hotplug events from hal. */
+ VBoxMainHotplugWaiter *mpWaiter;
+# endif
+};
+# endif /* RT_OS_LINUX */
+
+
+# if defined(RT_OS_OS2) || defined(DOXYGEN_RUNNING)
+# include <usbcalls.h>
+
+/**
+ * The Linux hosted USB Proxy Backend.
+ */
+class USBProxyBackendOs2 : public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendOs2)
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+
+protected:
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+ int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
+
+private:
+ /** The notification event semaphore */
+ HEV mhev;
+ /** The notification id. */
+ USBNOTIFY mNotifyId;
+ /** The usbcalls.dll handle. */
+ HMODULE mhmod;
+ /** UsbRegisterChangeNotification */
+ APIRET (APIENTRY *mpfnUsbRegisterChangeNotification)(PUSBNOTIFY, HEV, HEV);
+ /** UsbDeregisterNotification */
+ APIRET (APIENTRY *mpfnUsbDeregisterNotification)(USBNOTIFY);
+ /** UsbQueryNumberDevices */
+ APIRET (APIENTRY *mpfnUsbQueryNumberDevices)(PULONG);
+ /** UsbQueryDeviceReport */
+ APIRET (APIENTRY *mpfnUsbQueryDeviceReport)(ULONG, PULONG, PVOID);
+};
+# endif /* RT_OS_OS2 */
+
+
+# if defined(RT_OS_SOLARIS) || defined(DOXYGEN_RUNNING)
+# include <libdevinfo.h>
+
+/**
+ * The Solaris hosted USB Proxy Backend.
+ */
+class USBProxyBackendSolaris : public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendSolaris)
+
+ int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ void uninit();
+
+ virtual void *insertFilter (PCUSBFILTER aFilter);
+ virtual void removeFilter (void *aID);
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+ virtual void captureDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
+ virtual void releaseDeviceCompleted(HostUSBDevice *aDevice, bool aSuccess);
+
+ virtual bool i_isDevReEnumerationRequired();
+
+protected:
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+
+private:
+ RTSEMEVENT mNotifyEventSem;
+ /** Whether we've successfully initialized the USBLib and should call USBLibTerm in the destructor. */
+ bool mUSBLibInitialized;
+};
+#endif /* RT_OS_SOLARIS */
+
+
+# if defined(RT_OS_WINDOWS) || defined(DOXYGEN_RUNNING)
+/**
+ * The Windows hosted USB Proxy Backend.
+ */
+class USBProxyBackendWindows : public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendWindows)
+
+ int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ void uninit();
+
+ virtual void *insertFilter (PCUSBFILTER aFilter);
+ virtual void removeFilter (void *aID);
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+
+ virtual bool i_isDevReEnumerationRequired();
+
+protected:
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+
+private:
+
+ HANDLE mhEventInterrupt;
+};
+# endif /* RT_OS_WINDOWS */
+
+# if defined(RT_OS_FREEBSD) || defined(DOXYGEN_RUNNING)
+/**
+ * The FreeBSD hosted USB Proxy Backend.
+ */
+class USBProxyBackendFreeBSD : public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendFreeBSD)
+
+ int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ void uninit();
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+
+protected:
+ int initUsbfs(void);
+ int initSysfs(void);
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+ int addDeviceToChain(PUSBDEVICE pDev, PUSBDEVICE *ppFirst, PUSBDEVICE **pppNext, int rc);
+ virtual bool isFakeUpdateRequired();
+
+private:
+ RTSEMEVENT mNotifyEventSem;
+};
+# endif /* RT_OS_FREEBSD */
+
+/**
+ * USB/IP Proxy receive state.
+ */
+typedef enum USBIPRECVSTATE
+{
+ /** Invalid state. */
+ kUsbIpRecvState_Invalid = 0,
+ /** There is no request waiting for an answer. */
+ kUsbIpRecvState_None,
+ /** Waiting for the complete reception of UsbIpRetDevList. */
+ kUsbIpRecvState_Hdr,
+ /** Waiting for the complete reception of a UsbIpExportedDevice structure. */
+ kUsbIpRecvState_ExportedDevice,
+ /** Waiting for a complete reception of a UsbIpDeviceInterface structure to skip. */
+ kUsbIpRecvState_DeviceInterface,
+ /** 32bit hack. */
+ kUsbIpRecvState_32Bit_Hack = 0x7fffffff
+} USBIPRECVSTATE;
+/** Pointer to a USB/IP receive state enum. */
+typedef USBIPRECVSTATE *PUSBIPRECVSTATE;
+
+struct UsbIpExportedDevice;
+
+/**
+ * The USB/IP Proxy Backend.
+ */
+class USBProxyBackendUsbIp: public USBProxyBackend
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(USBProxyBackendUsbIp)
+
+ int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId,
+ const com::Utf8Str &strAddress, bool fLoadingSettings);
+ void uninit();
+
+ virtual int captureDevice(HostUSBDevice *aDevice);
+ virtual int releaseDevice(HostUSBDevice *aDevice);
+
+protected:
+ virtual int wait(RTMSINTERVAL aMillies);
+ virtual int interruptWait(void);
+ virtual PUSBDEVICE getDevices(void);
+ virtual bool isFakeUpdateRequired();
+
+private:
+ int updateDeviceList(bool *pfDeviceListChanged);
+ bool hasDevListChanged(PUSBDEVICE pDevices);
+ void freeDeviceList(PUSBDEVICE pHead);
+ void resetRecvState();
+ int reconnect();
+ void disconnect();
+ int startListExportedDevicesReq();
+ void advanceState(USBIPRECVSTATE enmRecvState);
+ int receiveData();
+ int processData();
+ int addDeviceToList(UsbIpExportedDevice *pDev);
+
+ struct Data; // opaque data struct, defined in USBProxyBackendUsbIp.cpp
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_USBProxyBackend_h */
+
diff --git a/src/VBox/Main/include/USBProxyService.h b/src/VBox/Main/include/USBProxyService.h
new file mode 100644
index 00000000..f73bec85
--- /dev/null
+++ b/src/VBox/Main/include/USBProxyService.h
@@ -0,0 +1,147 @@
+/* $Id: USBProxyService.h $ */
+/** @file
+ * VirtualBox USB Proxy Service (base) class.
+ */
+
+/*
+ * Copyright (C) 2005-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_USBProxyService_h
+#define MAIN_INCLUDED_USBProxyService_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/usb.h>
+#include <VBox/usbfilter.h>
+
+#include "VirtualBoxBase.h"
+#include "VirtualBoxImpl.h"
+#include "HostUSBDeviceImpl.h"
+#include "USBProxyBackend.h"
+
+class Host;
+
+namespace settings
+{
+ struct USBDeviceSource;
+ typedef std::list<USBDeviceSource> USBDeviceSourcesList;
+}
+
+
+/**
+ * Base class for the USB Proxy service.
+ */
+class USBProxyService
+ : public Lockable
+{
+public:
+ DECLARE_TRANSLATE_METHODS(USBProxyService)
+
+ USBProxyService(Host *aHost);
+ virtual HRESULT init(void);
+ virtual ~USBProxyService();
+
+ /**
+ * Override of the default locking class to be used for validating lock
+ * order with the standard member lock handle.
+ */
+ virtual VBoxLockingClass getLockingClass() const
+ {
+ // the USB proxy service uses the Host object lock, so return the
+ // same locking class as the host
+ return LOCKCLASS_HOSTOBJECT;
+ }
+
+ void uninit(void);
+
+ bool isActive(void);
+ int getLastError(void);
+
+ RWLockHandle *lockHandle() const;
+
+ /** @name Interface for the USBController and the Host object.
+ * @{ */
+ void *insertFilter(PCUSBFILTER aFilter);
+ void removeFilter(void *aId);
+ /** @} */
+
+ /** @name Host Interfaces
+ * @{ */
+ HRESULT getDeviceCollection(std::vector<ComPtr<IHostUSBDevice> > &aUSBDevices);
+ HRESULT addUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId, const com::Utf8Str &aAddress,
+ const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues);
+ HRESULT removeUSBDeviceSource(const com::Utf8Str &aId);
+ /** @} */
+
+ /** @name SessionMachine Interfaces
+ * @{ */
+ HRESULT captureDeviceForVM(SessionMachine *aMachine, IN_GUID aId, const com::Utf8Str &aCaptureFilename);
+ HRESULT detachDeviceFromVM(SessionMachine *aMachine, IN_GUID aId, bool aDone);
+ HRESULT autoCaptureDevicesForVM(SessionMachine *aMachine);
+ HRESULT detachAllDevicesFromVM(SessionMachine *aMachine, bool aDone, bool aAbnormal);
+ /** @} */
+
+ typedef std::list< ComObjPtr<HostUSBDeviceFilter> > USBDeviceFilterList;
+
+ HRESULT i_loadSettings(const settings::USBDeviceSourcesList &llUSBDeviceSources);
+ HRESULT i_saveSettings(settings::USBDeviceSourcesList &llUSBDeviceSources);
+
+ void i_deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, PUSBDEVICE aUSBDevice);
+ void i_deviceRemoved(ComObjPtr<HostUSBDevice> &aDevice);
+ void i_updateDeviceState(ComObjPtr<HostUSBDevice> &aDevice, PUSBDEVICE aUSBDevice, bool fFakeUpdate);
+
+protected:
+ ComObjPtr<HostUSBDevice> findDeviceById(IN_GUID aId);
+
+ static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
+
+ USBProxyBackend *findUsbProxyBackendById(const com::Utf8Str &strId);
+
+ HRESULT createUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId,
+ const com::Utf8Str &aAddress, const std::vector<com::Utf8Str> &aPropertyNames,
+ const std::vector<com::Utf8Str> &aPropertyValues, bool fLoadingSettings);
+
+private:
+
+ HRESULT runAllFiltersOnDevice(ComObjPtr<HostUSBDevice> &aDevice,
+ SessionMachinesList &llOpenedMachines,
+ SessionMachine *aIgnoreMachine);
+ bool runMachineFilters(SessionMachine *aMachine, ComObjPtr<HostUSBDevice> &aDevice);
+
+ void deviceChanged(ComObjPtr<HostUSBDevice> &aDevice, bool fRunFilters, SessionMachine *aIgnoreMachine);
+
+ /** Pointer to the Host object. */
+ Host *mHost;
+ /** List of smart HostUSBDevice pointers. */
+ typedef std::list<ComObjPtr<HostUSBDevice> > HostUSBDeviceList;
+ /** List of the known USB devices. */
+ HostUSBDeviceList mDevices;
+ /** List of USBProxyBackend pointers. */
+ typedef std::list<ComObjPtr<USBProxyBackend> > USBProxyBackendList;
+ /** List of active USB backends. */
+ USBProxyBackendList mBackends;
+ int mLastError;
+};
+
+#endif /* !MAIN_INCLUDED_USBProxyService_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/UefiVariableStoreImpl.h b/src/VBox/Main/include/UefiVariableStoreImpl.h
new file mode 100644
index 00000000..a77bdfa0
--- /dev/null
+++ b/src/VBox/Main/include/UefiVariableStoreImpl.h
@@ -0,0 +1,105 @@
+/* $Id: UefiVariableStoreImpl.h $ */
+/** @file
+ * VirtualBox COM UEFI variable store class implementation
+ */
+
+/*
+ * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UefiVariableStoreImpl_h
+#define MAIN_INCLUDED_UefiVariableStoreImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "UefiVariableStoreWrap.h"
+#include <iprt/types.h>
+
+#include <iprt/formats/efi-common.h>
+
+class NvramStore;
+class Machine;
+
+class ATL_NO_VTABLE UefiVariableStore :
+ public UefiVariableStoreWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(UefiVariableStore)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(NvramStore *aParent, Machine *pMachine);
+ void uninit();
+
+ // public methods for internal purposes only
+
+private:
+
+ // Wrapped NVRAM store properties
+ HRESULT getSecureBootEnabled(BOOL *pfEnabled);
+ HRESULT setSecureBootEnabled(BOOL fEnabled);
+
+ // Wrapped NVRAM store members
+ HRESULT addVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid, const std::vector<UefiVariableAttributes_T> &aAttributes,
+ const std::vector<BYTE> &aData);
+ HRESULT deleteVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid);
+ HRESULT changeVariable(const com::Utf8Str &aName, const std::vector<BYTE> &aData);
+ HRESULT queryVariableByName(const com::Utf8Str &aName, com::Guid &aOwnerUuid, std::vector<UefiVariableAttributes_T> &aAttributes,
+ std::vector<BYTE> &aData);
+ HRESULT queryVariables(std::vector<com::Utf8Str> &aNames, std::vector<com::Guid> &aOwnerUuids);
+ HRESULT enrollOraclePlatformKey(void);
+ HRESULT enrollPlatformKey(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid);
+ HRESULT addKek(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+ HRESULT addSignatureToDb(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+ HRESULT addSignatureToDbx(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+ HRESULT enrollDefaultMsSignatures(void);
+ HRESULT addSignatureToMok(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+
+ int i_uefiVarStoreSetVarAttr(const char *pszVar, uint32_t fAttr);
+ int i_uefiVarStoreQueryVarAttr(const char *pszVar, uint32_t *pfAttr);
+ int i_uefiVarStoreQueryVarSz(const char *pszVar, uint64_t *pcbVar);
+ int i_uefiVarStoreQueryVarOwnerUuid(const char *pszVar, PRTUUID pUuid);
+ uint32_t i_uefiVarAttrToMask(const std::vector<UefiVariableAttributes_T> &aAttributes);
+ void i_uefiAttrMaskToVec(uint32_t fAttr, std::vector<UefiVariableAttributes_T> &aAttributes);
+
+ HRESULT i_retainUefiVariableStore(bool fReadonly);
+ HRESULT i_releaseUefiVariableStore(void);
+
+ HRESULT i_uefiVarStoreAddVar(PCEFI_GUID pGuid, const char *pszVar, uint32_t fAttr, PRTVFSFILE phVfsFile);
+ HRESULT i_uefiVarStoreOpenVar(const char *pszVar, PRTVFSFILE phVfsFile);
+ HRESULT i_uefiVarStoreSetVar(PCEFI_GUID pGuid, const char *pszVar, uint32_t fAttr, const void *pvData, size_t cbData);
+ HRESULT i_uefiVarStoreQueryVar(const char *pszVar, void *pvData, size_t cbData);
+ HRESULT i_uefiSigDbAddSig(RTEFISIGDB hEfiSigDb, const void *pvData, size_t cbData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+ HRESULT i_uefiVarStoreAddSignatureToDbVec(PCEFI_GUID pGuid, const char *pszDb, const std::vector<BYTE> &aData,
+ const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType, bool fRuntime = true);
+ HRESULT i_uefiVarStoreAddSignatureToDb(PCEFI_GUID pGuid, const char *pszDb, const void *pvData, size_t cbData,
+ const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType, bool fRuntime = true);
+
+ struct Data; // opaque data struct, defined in UefiVariableStoreImpl.cpp
+ Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_UefiVariableStoreImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/UnattendedImpl.h b/src/VBox/Main/include/UnattendedImpl.h
new file mode 100644
index 00000000..de78c2bf
--- /dev/null
+++ b/src/VBox/Main/include/UnattendedImpl.h
@@ -0,0 +1,318 @@
+/* $Id: UnattendedImpl.h $ */
+/** @file
+ * Unattended class header
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UnattendedImpl_h
+#define MAIN_INCLUDED_UnattendedImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/ostypes.h>
+#include <iprt/time.h>
+#include "UnattendedWrap.h"
+
+/* Forward declarations. */
+class UnattendedInstaller;
+struct UnattendedInstallationDisk;
+struct ControllerSlot;
+
+/**
+ * A data type to store image data which is read from intall.wim file.
+ * Currently relevant only for Windows OSs.
+ */
+struct WIMImage
+{
+ Utf8Str mName;
+ Utf8Str mVersion;
+ Utf8Str mArch;
+ Utf8Str mFlavor;
+ RTCList<RTCString, RTCString *> mLanguages;
+ Utf8Str mDefaultLanguage;
+ uint32_t mImageIndex;
+ VBOXOSTYPE mOSType;
+ WIMImage() : mImageIndex(0), mOSType(VBOXOSTYPE_Unknown) { }
+ const Utf8Str &formatName(Utf8Str &r_strName) const;
+ VBOXOSTYPE mEnmOsType;
+};
+
+/**
+ * Class implementing the IUnattended interface.
+ *
+ * This class is instantiated on the request by IMachine::getUnattended.
+ */
+class ATL_NO_VTABLE Unattended
+ : public UnattendedWrap
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(Unattended)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT initUnattended(VirtualBox *aParent);
+ void uninit();
+
+ // public methods for internal purposes
+ Utf8Str const &i_getIsoPath() const;
+ Utf8Str const &i_getUser() const;
+ Utf8Str const &i_getPassword() const;
+ Utf8Str const &i_getFullUserName() const;
+ Utf8Str const &i_getProductKey() const;
+ Utf8Str const &i_getProxy() const;
+ Utf8Str const &i_getAdditionsIsoPath() const;
+ bool i_getInstallGuestAdditions() const;
+ Utf8Str const &i_getValidationKitIsoPath() const;
+ bool i_getInstallTestExecService() const;
+ Utf8Str const &i_getTimeZone() const;
+ PCRTTIMEZONEINFO i_getTimeZoneInfo() const;
+ Utf8Str const &i_getLocale() const;
+ Utf8Str const &i_getLanguage() const;
+ Utf8Str const &i_getCountry() const;
+ bool i_isMinimalInstallation() const;
+ Utf8Str const &i_getHostname() const;
+ Utf8Str const &i_getAuxiliaryBasePath() const;
+ ULONG i_getImageIndex() const;
+ Utf8Str const &i_getScriptTemplatePath() const;
+ Utf8Str const &i_getPostInstallScriptTemplatePath() const;
+ Utf8Str const &i_getPostInstallCommand() const;
+ /** The directory where the unattended install config and script is
+ * located, from the perspective of the running unattended install. */
+ Utf8Str const &i_getAuxiliaryInstallDir() const;
+ Utf8Str const &i_getExtraInstallKernelParameters() const;
+
+ bool i_isRtcUsingUtc() const;
+ bool i_isGuestOs64Bit() const;
+ bool i_isFirmwareEFI() const;
+ Utf8Str const &i_getDetectedOSVersion();
+ bool i_getAvoidUpdatesOverNetwork() const;
+
+private:
+ ComPtr<VirtualBox> const mParent; /**< Strong reference to the parent object (VirtualBox/IMachine). */
+ ComPtr<Machine> mMachine; /**< Strong reference to the machine object (Machine/IMachine). */
+ Guid mMachineUuid; /**< The machine UUID. */
+ RTNATIVETHREAD mhThreadReconfigureVM; /**< Set when reconfigureVM is running. */
+ Utf8Str mStrGuestOsTypeId; /**< Guest OS type ID (set by prepare). */
+ bool mfRtcUseUtc; /**< Copy of IMachine::RTCUseUTC (locking reasons). */
+ bool mfGuestOs64Bit; /**< 64-bit (true) or 32-bit guest OS (set by prepare). */
+ FirmwareType_T menmFirmwareType; /**< Firmware type BIOS/EFI (set by prepare). */
+ UnattendedInstaller *mpInstaller; /**< The installer instance (set by prepare, deleted by done). */
+
+ /** @name Values of the IUnattended attributes.
+ * @{ */
+ Utf8Str mStrUser;
+ Utf8Str mStrPassword;
+ Utf8Str mStrFullUserName;
+ Utf8Str mStrProductKey;
+ Utf8Str mStrIsoPath;
+ Utf8Str mStrAdditionsIsoPath;
+ bool mfInstallGuestAdditions;
+ bool mfInstallTestExecService;
+ Utf8Str mStrValidationKitIsoPath;
+ Utf8Str mStrTimeZone;
+ PCRTTIMEZONEINFO mpTimeZoneInfo;
+ Utf8Str mStrLocale;
+ Utf8Str mStrLanguage; /**< (only relevant for windows at the moment) */
+ Utf8Str mStrCountry;
+ RTCList<RTCString, RTCString *> mPackageSelectionAdjustments;
+ Utf8Str mStrHostname;
+ Utf8Str mStrAuxiliaryBasePath;
+ bool mfIsDefaultAuxiliaryBasePath;
+ ULONG midxImage;
+ Utf8Str mStrScriptTemplatePath;
+ Utf8Str mStrPostInstallScriptTemplatePath;
+ Utf8Str mStrPostInstallCommand;
+ Utf8Str mStrExtraInstallKernelParameters;
+ Utf8Str mStrProxy;
+
+ bool mfDoneDetectIsoOS; /**< Set by detectIsoOS(), cleared by setIsoPath(). */
+ Utf8Str mStrDetectedOSTypeId;
+ Utf8Str mStrDetectedOSVersion;
+ Utf8Str mStrDetectedOSFlavor;
+ VBOXOSTYPE mEnmOsType;
+ RTCList<RTCString, RTCString *> mDetectedOSLanguages; /**< (only relevant for windows at the moment) */
+ Utf8Str mStrDetectedOSHints;
+ RTCList<WIMImage> mDetectedImages;
+ bool mfAvoidUpdatesOverNetwork;
+ /** @} */
+
+ // wrapped IUnattended functions:
+
+ /**
+ * Checks what mStrIsoPath points to and sets the detectedOS* properties.
+ */
+ HRESULT detectIsoOS();
+
+ /**
+ * Prepare any data, environment, etc.
+ */
+ HRESULT prepare();
+
+ /**
+ * Prepare installation ISO/floppy.
+ */
+ HRESULT constructMedia();
+
+ /**
+ * Prepare a VM to run an unattended installation
+ */
+ HRESULT reconfigureVM();
+
+ /**
+ * Done with all media construction and VM configuration and stuff.
+ */
+ HRESULT done();
+
+ // wrapped IUnattended attributes:
+ HRESULT getIsoPath(com::Utf8Str &isoPath);
+ HRESULT setIsoPath(const com::Utf8Str &isoPath);
+ HRESULT getUser(com::Utf8Str &user);
+ HRESULT setUser(const com::Utf8Str &user);
+ HRESULT getPassword(com::Utf8Str &password);
+ HRESULT setPassword(const com::Utf8Str &password);
+ HRESULT getFullUserName(com::Utf8Str &user);
+ HRESULT setFullUserName(const com::Utf8Str &user);
+ HRESULT getProductKey(com::Utf8Str &productKey);
+ HRESULT setProductKey(const com::Utf8Str &productKey);
+ HRESULT getAdditionsIsoPath(com::Utf8Str &additionsIsoPath);
+ HRESULT setAdditionsIsoPath(const com::Utf8Str &additionsIsoPath);
+ HRESULT getInstallGuestAdditions(BOOL *installGuestAdditions);
+ HRESULT setInstallGuestAdditions(BOOL installGuestAdditions);
+ HRESULT getValidationKitIsoPath(com::Utf8Str &aValidationKitIsoPath);
+ HRESULT setValidationKitIsoPath(const com::Utf8Str &aValidationKitIsoPath);
+ HRESULT getInstallTestExecService(BOOL *aInstallTestExecService);
+ HRESULT setInstallTestExecService(BOOL aInstallTestExecService);
+ HRESULT getTimeZone(com::Utf8Str &aTimezone);
+ HRESULT setTimeZone(const com::Utf8Str &aTimezone);
+ HRESULT getLocale(com::Utf8Str &aLocale);
+ HRESULT setLocale(const com::Utf8Str &aLocale);
+ HRESULT getLanguage(com::Utf8Str &aLanguage);
+ HRESULT setLanguage(const com::Utf8Str &aLanguage);
+ HRESULT getCountry(com::Utf8Str &aCountry);
+ HRESULT setCountry(const com::Utf8Str &aCountry);
+ HRESULT getProxy(com::Utf8Str &aProxy);
+ HRESULT setProxy(const com::Utf8Str &aProxy);
+ HRESULT getPackageSelectionAdjustments(com::Utf8Str &aPackageSelectionAdjustments);
+ HRESULT setPackageSelectionAdjustments(const com::Utf8Str &aPackageSelectionAdjustments);
+ HRESULT getHostname(com::Utf8Str &aHostname);
+ HRESULT setHostname(const com::Utf8Str &aHostname);
+ HRESULT getAuxiliaryBasePath(com::Utf8Str &aAuxiliaryBasePath);
+ HRESULT setAuxiliaryBasePath(const com::Utf8Str &aAuxiliaryBasePath);
+ HRESULT getImageIndex(ULONG *index);
+ HRESULT setImageIndex(ULONG index);
+ HRESULT getMachine(ComPtr<IMachine> &aMachine);
+ HRESULT setMachine(const ComPtr<IMachine> &aMachine);
+ HRESULT getScriptTemplatePath(com::Utf8Str &aScriptTemplatePath);
+ HRESULT setScriptTemplatePath(const com::Utf8Str &aScriptTemplatePath);
+ HRESULT getPostInstallScriptTemplatePath(com::Utf8Str &aPostInstallScriptTemplatePath);
+ HRESULT setPostInstallScriptTemplatePath(const com::Utf8Str &aPostInstallScriptTemplatePath);
+ HRESULT getPostInstallCommand(com::Utf8Str &aPostInstallCommand);
+ HRESULT setPostInstallCommand(const com::Utf8Str &aPostInstallCommand);
+ HRESULT getExtraInstallKernelParameters(com::Utf8Str &aExtraInstallKernelParameters);
+ HRESULT setExtraInstallKernelParameters(const com::Utf8Str &aExtraInstallKernelParameters);
+ HRESULT getDetectedOSTypeId(com::Utf8Str &aDetectedOSTypeId);
+ HRESULT getDetectedOSVersion(com::Utf8Str &aDetectedOSVersion);
+ HRESULT getDetectedOSLanguages(com::Utf8Str &aDetectedOSLanguages);
+ HRESULT getDetectedOSFlavor(com::Utf8Str &aDetectedOSFlavor);
+ HRESULT getDetectedOSHints(com::Utf8Str &aDetectedOSHints);
+ HRESULT getDetectedImageNames(std::vector<com::Utf8Str> &aDetectedImageNames);
+ HRESULT getDetectedImageIndices(std::vector<ULONG> &aDetectedImageIndices);
+ HRESULT getIsUnattendedInstallSupported(BOOL *aIsUnattendedInstallSupported);
+ HRESULT getAvoidUpdatesOverNetwork(BOOL *aAvoidUpdatesOverNetwork);
+ HRESULT setAvoidUpdatesOverNetwork(BOOL aAvoidUpdatesOverNetwork);
+ //internal functions
+
+ /**
+ * Worker for detectIsoOs().
+ *
+ * @returns COM status code.
+ * @retval S_OK if detected.
+ * @retval S_FALSE if not detected.
+ *
+ * @param hVfsIso The ISO file system handle.
+ */
+ HRESULT i_innerDetectIsoOS(RTVFS hVfsIso);
+ typedef union DETECTBUFFER
+ {
+ char sz[4096];
+ char ach[4096];
+ uint8_t ab[4096];
+ uint32_t au32[1024];
+ } DETECTBUFFER;
+ HRESULT i_innerDetectIsoOSWindows(RTVFS hVfsIso, DETECTBUFFER *puBuf);
+ HRESULT i_innerDetectIsoOSLinux(RTVFS hVfsIso, DETECTBUFFER *puBuf);
+ HRESULT i_innerDetectIsoOSLinuxFedora(RTVFS hVfsIso, DETECTBUFFER *puBuf, char *pszVolId);
+ HRESULT i_innerDetectIsoOSOs2(RTVFS hVfsIso, DETECTBUFFER *puBuf);
+ HRESULT i_innerDetectIsoOSFreeBsd(RTVFS hVfsIso, DETECTBUFFER *puBuf);
+
+ /**
+ * Worker for reconfigureVM().
+ * The caller makes sure to close the session whatever happens.
+ */
+ HRESULT i_innerReconfigureVM(AutoMultiWriteLock2 &rAutoLock, StorageBus_T enmRecommendedStorageBus,
+ ComPtr<IMachine> const &rPtrSessionMachine);
+ HRESULT i_reconfigureFloppy(com::SafeIfaceArray<IStorageController> &rControllers,
+ std::vector<UnattendedInstallationDisk> &rVecInstallatationDisks,
+ ComPtr<IMachine> const &rPtrSessionMachine,
+ AutoMultiWriteLock2 &rAutoLock);
+ HRESULT i_reconfigureIsos(com::SafeIfaceArray<IStorageController> &rControllers,
+ std::vector<UnattendedInstallationDisk> &rVecInstallatationDisks,
+ ComPtr<IMachine> const &rPtrSessionMachine,
+ AutoMultiWriteLock2 &rAutoLock, StorageBus_T enmRecommendedStorageBus);
+
+ /**
+ * Adds all free slots on the controller to @a rOutput.
+ */
+ HRESULT i_findOrCreateNeededFreeSlots(const Utf8Str &rStrControllerName, StorageBus_T enmStorageBus,
+ ComPtr<IMachine> const &rPtrSessionMachine, uint32_t cSlotsNeeded,
+ std::list<ControllerSlot> &rDvdSlots);
+
+ /**
+ * Attach to VM a disk
+ */
+ HRESULT i_attachImage(UnattendedInstallationDisk const *pImage, ComPtr<IMachine> const &rPtrSessionMachine,
+ AutoMultiWriteLock2 &rLock);
+
+ /*
+ * Wrapper functions
+ */
+
+ /**
+ * Check whether guest is 64bit platform or not
+ */
+ bool i_isGuestOSArchX64(Utf8Str const &rStrGuestOsTypeId);
+
+ /**
+ * Updates the detected attributes when the image index or image list changes.
+ *
+ * @returns true if we've got all necessary stuff for a successful detection.
+ */
+ bool i_updateDetectedAttributeForImage(WIMImage const &rImage);
+
+};
+
+#endif /* !MAIN_INCLUDED_UnattendedImpl_h */
diff --git a/src/VBox/Main/include/UnattendedInstaller.h b/src/VBox/Main/include/UnattendedInstaller.h
new file mode 100644
index 00000000..536bdcc9
--- /dev/null
+++ b/src/VBox/Main/include/UnattendedInstaller.h
@@ -0,0 +1,932 @@
+/* $Id: UnattendedInstaller.h $ */
+/** @file
+ * UnattendedInstaller class header
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UnattendedInstaller_h
+#define MAIN_INCLUDED_UnattendedInstaller_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "UnattendedScript.h"
+
+/* Forward declarations */
+class Unattended;
+class UnattendedInstaller;
+class BaseTextScript;
+
+
+/**
+ * The abstract UnattendedInstaller class declaration
+ *
+ * The class is intended to service a new VM that this VM will be able to
+ * execute an unattended installation
+ */
+class UnattendedInstaller : public RTCNonCopyable
+{
+/*data*/
+protected:
+ /** Main unattended installation script. */
+ UnattendedScriptTemplate mMainScript;
+ /** Full path to the main template file (set by initInstaller). */
+ Utf8Str mStrMainScriptTemplate;
+
+ /** Post installation (shell) script. */
+ UnattendedScriptTemplate mPostScript;
+ /** Full path to the post template file (set by initInstaller). */
+ Utf8Str mStrPostScriptTemplate;
+
+ /** Pointer to the parent object.
+ * We use this for setting errors and querying attributes. */
+ Unattended *mpParent;
+ /** The path of the extra ISO image we create (set by initInstaller).
+ * This is only valid when isAdditionsIsoNeeded() returns true. */
+ Utf8Str mStrAuxiliaryIsoFilePath;
+ /** The path of the extra floppy image we create (set by initInstaller)
+ * This is only valid when isAdditionsFloppyNeeded() returns true. */
+ Utf8Str mStrAuxiliaryFloppyFilePath;
+ /** The boot device. */
+ DeviceType_T const meBootDevice;
+ /** Default extra install kernel parameters (set by constructor).
+ * This can be overridden by the extraInstallKernelParameters attribute of
+ * IUnattended. */
+ Utf8Str mStrDefaultExtraInstallKernelParameters;
+ /** The directory of the post install script in the unattended install
+ * environment, i.e. when it gets started by the unattended installer
+ * of the respective guest OS. */
+ Utf8Str mStrAuxiliaryInstallDir;
+
+private:
+ UnattendedInstaller(); /* no default constructors */
+
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedInstaller)
+
+ /**
+ * Regular constructor.
+ *
+ * @param pParent The parent object. Used for setting
+ * errors and querying attributes.
+ * @param pszMainScriptTemplateName The name of the template file (no path)
+ * for the main unattended installer
+ * script.
+ * @param pszPostScriptTemplateName The name of the template file (no path)
+ * for the post installation script.
+ * @param pszMainScriptFilename The main unattended installer script
+ * filename (on aux media).
+ * @param pszPostScriptFilename The post installation script filename
+ * (on aux media).
+ * @param enmBootDevice The boot device type.
+ */
+ UnattendedInstaller(Unattended *pParent,
+ const char *pszMainScriptTemplateName, const char *pszPostScriptTemplateName,
+ const char *pszMainScriptFilename, const char *pszPostScriptFilename,
+ DeviceType_T enmBootDevice = DeviceType_DVD);
+ virtual ~UnattendedInstaller();
+
+ /**
+ * Instantiates the appropriate child class.
+ *
+ * @returns Pointer to the new instance, NULL if no appropriate installer.
+ * @param enmDetectedOSType The detected guest OS type value.
+ * @param strDetectedOSType The detected guest OS type string
+ * @param strDetectedOSVersion The detected guest OS version.
+ * @param strDetectedOSFlavor The detected guest OS flavor.
+ * @param strDetectedOSHints Hints about the detected guest OS.
+ * @param pParent The parent object. Used for setting errors
+ * and querying attributes.
+ * @throws std::bad_alloc
+ */
+ static UnattendedInstaller *createInstance(VBOXOSTYPE enmDetectedOSType, const Utf8Str &strDetectedOSType,
+ const Utf8Str &strDetectedOSVersion, const Utf8Str &strDetectedOSFlavor,
+ const Utf8Str &strDetectedOSHints, Unattended *pParent);
+
+ /**
+ * Initialize the installer.
+ *
+ * @note This is called immediately after instantiation and the caller will
+ * always destroy the unattended installer instance on failure, so it
+ * is not necessary to keep track of whether this succeeded or not.
+ */
+ virtual HRESULT initInstaller();
+
+#if 0 /* These are now in the AUX VISO. */
+ /**
+ * Whether the VBox Guest Additions ISO is needed or not.
+ *
+ * The default implementation always returns false when a VISO is used, see
+ * UnattendedInstaller::addFilesToAuxVisoVectors.
+ */
+ virtual bool isAdditionsIsoNeeded() const;
+
+ /**
+ * Whether the VBox validation kit ISO is needed or not.
+ *
+ * The default implementation always returns false when a VISO is used, see
+ * UnattendedInstaller::addFilesToAuxVisoVectors.
+ */
+ virtual bool isValidationKitIsoNeeded() const;
+#endif
+
+ /**
+ * Indicates whether an original installation ISO is needed or not.
+ */
+ virtual bool isOriginalIsoNeeded() const { return true; }
+
+ /**
+ * Indicates whether a floppy image is needed or not.
+ */
+ virtual bool isAuxiliaryFloppyNeeded() const { return false; }
+
+ /**
+ * Indicates whether an additional or replacement ISO image is needed or not.
+ */
+ virtual bool isAuxiliaryIsoNeeded() const;
+
+ /**
+ * Indicates whether we should boot from the auxiliary ISO image.
+ *
+ * Will boot from installation ISO if false.
+ */
+ virtual bool bootFromAuxiliaryIso() const { return isAuxiliaryIsoNeeded(); }
+
+ /**
+ * Indicates whether a the auxiliary ISO is a .viso-file rather than an
+ * .iso-file.
+ *
+ * Different worker methods are used depending on the return value. A
+ * .viso-file is generally only used when the installation media needs to
+ * be remastered with small changes and additions.
+ */
+ virtual bool isAuxiliaryIsoIsVISO() const { return true; }
+
+ /*
+ * Getters
+ */
+ DeviceType_T getBootableDeviceType() const { return meBootDevice; }
+ const Utf8Str &getTemplateFilePath() const { return mStrMainScriptTemplate; }
+ const Utf8Str &getPostTemplateFilePath() const { return mStrPostScriptTemplate; }
+ const Utf8Str &getAuxiliaryIsoFilePath() const { return mStrAuxiliaryIsoFilePath; }
+ const Utf8Str &getAuxiliaryFloppyFilePath() const { return mStrAuxiliaryFloppyFilePath; }
+ const Utf8Str &getDefaultExtraInstallKernelParameters() const { return mStrDefaultExtraInstallKernelParameters; }
+ const Utf8Str &getAuxiliaryInstallDir() const { return mStrAuxiliaryInstallDir; }
+
+ /*
+ * Setters
+ */
+ void setTemplatePath(const Utf8Str& data); /**< @todo r=bird: This is confusing as heck. Dir for a while, then it's a file. Not a comment about it. Brilliant. */
+
+ /**
+ * Prepares the unattended scripts, does all but write them to the installation
+ * media.
+ */
+ HRESULT prepareUnattendedScripts();
+
+ /**
+ * Prepares the media - floppy image, ISO image.
+ *
+ * This method calls prepareAuxFloppyImage() and prepareAuxIsoImage(), child
+ * classes may override these methods or methods they call.
+ *
+ * @returns COM status code.
+ * @param fOverwrite Whether to overwrite media files or fail if they
+ * already exist.
+ */
+ HRESULT prepareMedia(bool fOverwrite = true);
+
+protected:
+ /**
+ * Prepares (creates) the auxiliary floppy image.
+ *
+ * This is called by the base class prepareMedia() when
+ * isAuxiliaryFloppyNeeded() is true. The base class implementation puts the
+ * edited unattended script onto it.
+ */
+ HRESULT prepareAuxFloppyImage(bool fOverwrite);
+
+ /**
+ * Creates and formats (FAT12) a floppy image.
+ *
+ * This can be overridden to do more preparation work or/and create a different
+ * sized floppy.
+ *
+ * @returns COM status code.
+ * @param pszFilename The path to the image file.
+ * @param fOverwrite Whether to overwrite the file.
+ * @param phVfsFile Where to return a read-writable handle to the newly
+ * created image.
+ */
+ virtual HRESULT newAuxFloppyImage(const char *pszFilename, bool fOverwrite, PRTVFSFILE phVfsFile);
+
+ /**
+ * Copies files to the auxiliary floppy image.
+ *
+ * The base class implementation copies the main and post scripts to the root of
+ * the floppy using the default script names. Child classes may override this
+ * to add additional or different files.
+ *
+ * @returns COM status code.
+ * @param hVfs The floppy image VFS handle.
+ */
+ virtual HRESULT copyFilesToAuxFloppyImage(RTVFS hVfs);
+
+ /**
+ * Adds the given script to the root of the floppy image under the default
+ * script filename.
+ *
+ * @returns COM status code.
+ * @param pEditor The script to add.
+ * @param hVfs The VFS to add it to.
+ */
+ HRESULT addScriptToFloppyImage(BaseTextScript *pEditor, RTVFS hVfs);
+
+ /**
+ * Copy an arbritrary file onto the floopy image.
+ *
+ * @returns COM status code.
+ * @param hVfs The VFS to add it to.
+ * @param pszSrc The source filename.
+ * @param pszDst The destination filename (on @a hVfs).
+ */
+ HRESULT addFileToFloppyImage(RTVFS hVfs, const char *pszSrc, const char *pszDst);
+
+ /**
+ * Prepares (creates) the auxiliary ISO image.
+ *
+ * This is called by the base class prepareMedia() when isAuxiliaryIsoNeeded()
+ * is true. The base class implementation puts the edited unattended script
+ * onto it.
+ */
+ virtual HRESULT prepareAuxIsoImage(bool fOverwrite);
+
+ /**
+ * Opens the installation ISO image.
+ *
+ * @returns COM status code.
+ * @param phVfsIso Where to return the VFS handle for the ISO.
+ * @param fFlags RTFSISO9660_F_XXX flags to pass to the
+ * RTFsIso9660VolOpen API.
+ */
+ virtual HRESULT openInstallIsoImage(PRTVFS phVfsIso, uint32_t fFlags = 0);
+
+ /**
+ * Creates and configures the ISO maker instance.
+ *
+ * This can be overridden to set configure options.
+ *
+ * @returns COM status code.
+ * @param phIsoMaker Where to return the ISO maker.
+ */
+ virtual HRESULT newAuxIsoImageMaker(PRTFSISOMAKER phIsoMaker);
+
+ /**
+ * Adds files to the auxiliary ISO image maker.
+ *
+ * The base class implementation copies just the mMainScript and mPostScript
+ * files to root directory using the default filenames.
+ *
+ * @returns COM status code.
+ * @param hIsoMaker The ISO maker handle.
+ * @param hVfsOrgIso The VFS handle to the original ISO in case files
+ * needs to be added from it.
+ */
+ virtual HRESULT addFilesToAuxIsoImageMaker(RTFSISOMAKER hIsoMaker, RTVFS hVfsOrgIso);
+
+ /**
+ * Adds the given script to the ISO maker.
+ *
+ * @returns COM status code.
+ * @param pEditor The script to add.
+ * @param hIsoMaker The ISO maker to add it to.
+ * @param pszDstFilename The file name (w/ path) to add it under. If NULL,
+ * the default script filename is used to add it to the
+ * root.
+ */
+ HRESULT addScriptToIsoMaker(BaseTextScript *pEditor, RTFSISOMAKER hIsoMaker, const char *pszDstFilename = NULL);
+
+ /**
+ * Writes the ISO image to disk.
+ *
+ * @returns COM status code.
+ * @param hIsoMaker The ISO maker handle.
+ * @param pszFilename The filename.
+ * @param fOverwrite Whether to overwrite the destination file or not.
+ */
+ HRESULT finalizeAuxIsoImage(RTFSISOMAKER hIsoMaker, const char *pszFilename, bool fOverwrite);
+
+ /**
+ * Adds files to the .viso-file vectors.
+ *
+ * The base class implementation adds the script from mAlg, additions ISO
+ * content to '/vboxadditions', and validation kit ISO to '/vboxvalidationkit'.
+ *
+ * @returns COM status code.
+ * @param rVecArgs The ISO maker argument list that will be turned into
+ * a .viso-file.
+ * @param rVecFiles The list of files we've created. This is for
+ * cleaning up at the end.
+ * @param hVfsOrgIso The VFS handle to the original ISO in case files
+ * needs to be added from it.
+ * @param fOverwrite Whether to overwrite files or not.
+ */
+ virtual HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
+ RTVFS hVfsOrgIso, bool fOverwrite);
+
+ /**
+ * Saves the given script to disk and adds it to the .viso-file vectors.
+ *
+ * @returns COM status code.
+ * @param pEditor The script to add.
+ * @param rVecArgs The ISO maker argument list that will be turned into
+ * a .viso-file.
+ * @param rVecFiles The list of files we've created. This is for
+ * cleaning up at the end.
+ * @param fOverwrite Whether to overwrite files or not.
+ */
+ HRESULT addScriptToVisoVectors(BaseTextScript *pEditor, RTCList<RTCString> &rVecArgs,
+ RTCList<RTCString> &rVecFiles, bool fOverwrite);
+
+ /**
+ * Writes out the .viso-file to disk.
+ *
+ * @returns COM status code.
+ * @param rVecArgs The ISO maker argument list to write out.
+ * @param pszFilename The filename.
+ * @param fOverwrite Whether to overwrite the destination file or not.
+ */
+ HRESULT finalizeAuxVisoFile(RTCList<RTCString> const &rVecArgs, const char *pszFilename, bool fOverwrite);
+
+ /**
+ * Loads @a pszFilename from @a hVfsOrgIso into @a pEditor and parses it.
+ *
+ * @returns COM status code.
+ * @param hVfsOrgIso The handle to the original installation ISO.
+ * @param pszFilename The filename to open and load from the ISO.
+ * @param pEditor The editor instance to load the file into and
+ * do the parseing with.
+ */
+ HRESULT loadAndParseFileFromIso(RTVFS hVfsOrgIso, const char *pszFilename, AbstractScript *pEditor);
+};
+
+
+/**
+ * Windows installer, for versions up to xp 64 / w2k3.
+ */
+class UnattendedWindowsSifInstaller : public UnattendedInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedWindowsSifInstaller)
+
+ UnattendedWindowsSifInstaller(Unattended *pParent)
+ : UnattendedInstaller(pParent,
+ "win_nt5_unattended.sif", "win_postinstall.cmd",
+ "WINNT.SIF", "VBOXPOST.CMD")
+ {
+ Assert(isOriginalIsoNeeded()); Assert(isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); Assert(!bootFromAuxiliaryIso());
+ mStrAuxiliaryInstallDir = "A:\\";
+ }
+ ~UnattendedWindowsSifInstaller() {}
+
+ bool isAuxiliaryFloppyNeeded() const { return true; }
+ bool bootFromAuxiliaryIso() const { return false; }
+
+};
+
+/**
+ * Windows installer, for versions starting with Vista.
+ */
+class UnattendedWindowsXmlInstaller : public UnattendedInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedWindowsXmlInstaller)
+
+ UnattendedWindowsXmlInstaller(Unattended *pParent)
+ : UnattendedInstaller(pParent,
+ "win_nt6_unattended.xml", "win_postinstall.cmd",
+ "autounattend.xml", "VBOXPOST.CMD")
+ {
+ Assert(isOriginalIsoNeeded()); Assert(isAuxiliaryFloppyNeeded() || isAuxiliaryIsoNeeded()); Assert(isAuxiliaryIsoIsVISO()); Assert(!bootFromAuxiliaryIso());
+ if (isAuxiliaryFloppyNeeded())
+ mStrAuxiliaryInstallDir = "A:\\";
+ else if (bootFromAuxiliaryIso())
+ mStrAuxiliaryInstallDir = "D:\\";
+ else
+ mStrAuxiliaryInstallDir = "E:\\";
+ }
+ ~UnattendedWindowsXmlInstaller() {}
+
+ bool isAuxiliaryFloppyNeeded() const { return !mpParent->i_isFirmwareEFI(); }
+ bool isAuxiliaryIsoNeeded() const { return UnattendedInstaller::isAuxiliaryIsoNeeded() || mpParent->i_isFirmwareEFI(); }
+ bool isAuxiliaryIsoIsVISO() const { return true; }
+ bool bootFromAuxiliaryIso() const { return false; }
+};
+
+
+/**
+ * OS/2 installer.
+ */
+class UnattendedOs2Installer : public UnattendedInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedOs2Installer)
+
+ UnattendedOs2Installer(Unattended *pParent, Utf8Str const &rStrHints);
+ ~UnattendedOs2Installer() {}
+
+ /* Remaster original ISO with auxiliary floppy used for el torito floppy emulation: */
+ bool isOriginalIsoNeeded() const RT_OVERRIDE { return false; }
+ bool isAuxiliaryFloppyNeeded() const RT_OVERRIDE { return true; }
+ bool isAuxiliaryIsoNeeded() const RT_OVERRIDE { return true; }
+
+protected:
+ HRESULT replaceAuxFloppyImageBootSector(RTVFSFILE hVfsFile) RT_NOEXCEPT;
+ HRESULT newAuxFloppyImage(const char *pszFilename, bool fOverwrite, PRTVFSFILE phVfsFile) RT_OVERRIDE;
+ HRESULT copyFilesToAuxFloppyImage(RTVFS hVfs) RT_OVERRIDE;
+ HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
+ RTVFS hVfsOrgIso, bool fOverwrite) RT_OVERRIDE;
+
+ HRESULT splitResponseFile() RT_NOEXCEPT;
+
+ /**
+ * Splits up the given file into sub-files and writes them out with the auxilary
+ * path base as prefix.
+ *
+ * The source file contains @@VBOX_SPLITTER_START[filename]@@ and
+ * @@VBOX_SPLITTER_END[filename]@@ markup that is used to split it up. Any
+ * text between END and START tags are ignored and can be used for comments.
+ *
+ * @returns COM status code (error info set).
+ * @param pszFileToSplit The name of the file to split.
+ * @param rVecSplitFiles Vector where names of the sub-files are appended
+ * (without any path or prefix).
+ */
+ HRESULT splitFile(const char *pszFileToSplit, RTCList<RTCString> &rVecSplitFiles) RT_NOEXCEPT;
+
+ /**
+ * Splits up the given editor output into sub-files and writes them out with the
+ * auxilary path base as prefix.
+ *
+ * The source file contains @@VBOX_SPLITTER_START[filename]@@ and
+ * @@VBOX_SPLITTER_END[filename]@@ markup that is used to split it up. Any
+ * text between END and START tags are ignored and can be used for comments.
+ *
+ * @returns COM status code (error info set).
+ * @param pEditor The editor which output should be split.
+ * @param rVecSplitFiles Vector where names of the sub-files are appended
+ * (without any path or prefix).
+ */
+ HRESULT splitFile(BaseTextScript *pEditor, RTCList<RTCString> &rVecSplitFiles) RT_NOEXCEPT;
+
+ HRESULT splitFileInner(const char *pszFileToSplit, RTCList<RTCString> &rVecSplitFiles,
+ const char *pszSrc, size_t cbLeft) RT_NOEXCEPT;
+
+ static int patchTestCfg(uint8_t *pbFile, size_t cbFile, const char *pszFilename, UnattendedOs2Installer *pThis);
+ static int patchOs2Ldr(uint8_t *pbFile, size_t cbFile, const char *pszFilename, UnattendedOs2Installer *pThis);
+
+ /** The OS2SE20.SRC path ("\\OS2IMAGES"). */
+ Utf8Str mStrOs2Images;
+ /** Files split out from os2_response_files.rsp (bare filenames, no paths). */
+ RTCList<RTCString> mVecSplitFiles;
+};
+
+
+
+/**
+ * Base class for the unattended linux installers.
+ */
+class UnattendedLinuxInstaller : public UnattendedInstaller
+{
+protected:
+ /** Array of linux parameter patterns that should be removed by editIsoLinuxCfg.
+ * The patterns are proceed by RTStrSimplePatternNMatch. */
+ RTCList<RTCString, RTCString *> mArrStrRemoveInstallKernelParameters;
+
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedLinuxInstaller)
+
+ UnattendedLinuxInstaller(Unattended *pParent,
+ const char *pszMainScriptTemplateName, const char *pszPostScriptTemplateName,
+ const char *pszMainScriptFilename, const char *pszPostScriptFilename = "vboxpostinstall.sh")
+ : UnattendedInstaller(pParent,
+ pszMainScriptTemplateName, pszPostScriptTemplateName,
+ pszMainScriptFilename, pszPostScriptFilename) {}
+ ~UnattendedLinuxInstaller() {}
+
+ bool isAuxiliaryIsoNeeded() const { return true; }
+
+protected:
+ /**
+ * Performs basic edits on a isolinux.cfg file.
+ *
+ * @returns COM status code
+ * @param pEditor Editor with the isolinux.cfg file loaded and parsed.
+ */
+ virtual HRESULT editIsoLinuxCfg(GeneralTextScript *pEditor);
+ /**
+ * Performs basic common edits on a isolinux.cfg and menu configuration file(s) (txt.cfg or menu.cfg etc).
+ *
+ * @returns COM status code
+ * @param pEditor Editor with the isolinux.cfg file loaded and parsed.
+ */
+ virtual HRESULT editIsoLinuxCommon(GeneralTextScript *pEditor);
+};
+
+
+/**
+ * Debian installer.
+ *
+ * This will remaster the orignal ISO and therefore be producing a .viso-file.
+ */
+class UnattendedDebianInstaller : public UnattendedLinuxInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedDebianInstaller)
+
+ UnattendedDebianInstaller(Unattended *pParent,
+ const char *pszMainScriptTemplateName = "debian_preseed.cfg",
+ const char *pszPostScriptTemplateName = "debian_postinstall.sh",
+ const char *pszMainScriptFilename = "preseed.cfg")
+ : UnattendedLinuxInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ {
+ Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded());
+ Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO());
+ mStrDefaultExtraInstallKernelParameters.setNull();
+ mStrDefaultExtraInstallKernelParameters += " auto=true";
+ mStrDefaultExtraInstallKernelParameters.append(" preseed/file=/cdrom/").append(pszMainScriptFilename);
+ mStrDefaultExtraInstallKernelParameters += " priority=critical";
+ mStrDefaultExtraInstallKernelParameters += " quiet";
+ mStrDefaultExtraInstallKernelParameters += " splash";
+ mStrDefaultExtraInstallKernelParameters += " noprompt"; /* no questions about things like CD/DVD ejections */
+ mStrDefaultExtraInstallKernelParameters += " noshell"; /* No shells on VT1-3 (debian, not ubuntu). */
+ mStrDefaultExtraInstallKernelParameters += " automatic-ubiquity"; // ubiquity
+ // the following can probably go into the preseed.cfg:
+ mStrDefaultExtraInstallKernelParameters.append(" debian-installer/locale=").append(pParent->i_getLocale());
+ mStrDefaultExtraInstallKernelParameters += " keyboard-configuration/layoutcode=us";
+ mStrDefaultExtraInstallKernelParameters += " languagechooser/language-name=English"; /** @todo fixme */
+ mStrDefaultExtraInstallKernelParameters.append(" localechooser/supported-locales=").append(pParent->i_getLocale()).append(".UTF-8");
+ mStrDefaultExtraInstallKernelParameters.append(" countrychooser/shortlist=").append(pParent->i_getCountry()); // ubiquity?
+ mStrDefaultExtraInstallKernelParameters += " --";
+ }
+ ~UnattendedDebianInstaller() {}
+
+ bool isOriginalIsoNeeded() const { return false; }
+
+protected:
+ HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
+ RTVFS hVfsOrgIso, bool fOverwrite);
+ /**
+ * Performs basic edits on menu configuration file(s) of isolinux (txt.cfg or menu.cfg etc).
+ *
+ * @returns COM status code
+ * @param pEditor Editor with the menu config. file loaded and parsed.
+ */
+ HRESULT editDebianMenuCfg(GeneralTextScript *pEditor);
+ /**
+ * Performs basic edits on grub configuration file (grub.cfg).
+ *
+ * @returns COM status code
+ * @param pEditor Editor with the grub.cfg file loaded and parsed.
+ */
+ HRESULT editDebianGrubCfg(GeneralTextScript *pEditor);
+
+ /**
+ * Performs basic edits on a isolinux.cfg file.
+ *
+ * @returns COM status code
+ * @param pEditor Editor with the isolinux.cfg file loaded and parsed.
+ * @param pszMenuConfigFileName Name of the menu config file to include in isolinux.txt. On Debians (at least)
+ it includes the kernel command line with our preseed file and command line argument.
+ */
+ virtual HRESULT editIsoLinuxCfg(GeneralTextScript *pEditor, const char *pszMenuConfigFileName);
+
+private:
+
+ /**
+ * Tries to set label name of a label line.
+ *
+ * @returns true if label line is found and label name can be set.
+ * @param pEditor Editor with the menu configuration file loaded and parsed.
+ * @param vecLineNumbers Indices of the label lines (within pEditor data).
+ * @param pszKeyWord The keyword searched within the original label name.
+ * @param pszNewLabelName The new name of the label.
+ */
+ bool modifyLabelLine(GeneralTextScript *pEditor, const std::vector<size_t> &vecLineNumbers,
+ const char *pszKeyWord, const char *pszNewLabelName);
+};
+
+
+/**
+ * Ubuntu installer (same as debian, except for the template).
+ */
+class UnattendedUbuntuInstaller : public UnattendedDebianInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedUbuntuInstaller)
+
+ UnattendedUbuntuInstaller(Unattended *pParent)
+ : UnattendedDebianInstaller(pParent, "ubuntu_preseed.cfg")
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedUbuntuInstaller() {}
+};
+
+/**
+ * RHEL installer.
+ *
+ * This serves as a base for the kickstart based installers.
+ */
+class UnattendedRhelInstaller : public UnattendedLinuxInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhelInstaller)
+
+ UnattendedRhelInstaller(Unattended *pParent,
+ const char *pszMainScriptTemplateName,
+ const char *pszPostScriptTemplateName,
+ const char *pszMainScriptFilename)
+ : UnattendedLinuxInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ {}
+ ~UnattendedRhelInstaller() {}
+
+ bool isAuxiliaryIsoIsVISO() { return true; }
+ bool isOriginalIsoNeeded() const { return false; }
+
+protected:
+ HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
+ RTVFS hVfsOrgIso, bool fOverwrite);
+};
+
+/**
+ * RHEL 6 installer.
+ *
+ */
+class UnattendedRhel6Installer : public UnattendedRhelInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhel6Installer)
+
+ UnattendedRhel6Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName = "redhat67_ks.cfg",
+ const char *pszPostScriptTemplateName = "redhat_postinstall.sh",
+ const char *pszMainScriptFilename = "ks.cfg")
+ : UnattendedRhelInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ {
+ Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded());
+ Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO());
+ mStrDefaultExtraInstallKernelParameters.assign(" ks=cdrom:/").append(pszMainScriptFilename).append(' ');
+ mArrStrRemoveInstallKernelParameters.append("rd.live.check"); /* Disables the checkisomd5 step. Required for VISO. */
+ }
+ ~UnattendedRhel6Installer() {}
+};
+
+/**
+ * RHEL 7 installer (same as RHEL 6).
+ * The class was added for better handling any possible subtle difference between RHEL6 and RHEL7.
+ */
+class UnattendedRhel7Installer : public UnattendedRhel6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhel7Installer)
+
+ UnattendedRhel7Installer(Unattended *pParent)
+ : UnattendedRhel6Installer(pParent)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+
+ UnattendedRhel7Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName,
+ const char *pszPostScriptTemplateName,
+ const char *pszMainScriptFilename)
+ : UnattendedRhel6Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedRhel7Installer() {}
+};
+
+
+/**
+ * RHEL 8 installer (same as RHEL 7).
+ * The class was added for better handling any possible subtle difference between RHEL7 and RHEL8.
+ */
+class UnattendedRhel8Installer : public UnattendedRhel7Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhel8Installer)
+
+ UnattendedRhel8Installer(Unattended *pParent)
+ : UnattendedRhel7Installer(pParent)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+
+ UnattendedRhel8Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName,
+ const char *pszPostScriptTemplateName,
+ const char *pszMainScriptFilename)
+ : UnattendedRhel7Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedRhel8Installer() {}
+};
+
+
+/**
+ * RHEL 5 installer (same as RHEL 6, except for the kickstart template).
+ */
+class UnattendedRhel5Installer : public UnattendedRhel6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhel5Installer)
+
+ UnattendedRhel5Installer(Unattended *pParent) : UnattendedRhel6Installer(pParent, "rhel5_ks.cfg") {}
+ ~UnattendedRhel5Installer() {}
+};
+
+
+/**
+ * RHEL 4 installer (same as RHEL 6, except for the kickstart template).
+ */
+class UnattendedRhel4Installer : public UnattendedRhel6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhel4Installer)
+
+ UnattendedRhel4Installer(Unattended *pParent) : UnattendedRhel6Installer(pParent, "rhel4_ks.cfg") {}
+ ~UnattendedRhel4Installer() {}
+};
+
+
+/**
+ * RHEL 3 installer (same as RHEL 6, except for the kickstart template).
+ */
+class UnattendedRhel3Installer : public UnattendedRhel6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedRhel3Installer)
+
+ UnattendedRhel3Installer(Unattended *pParent) : UnattendedRhel6Installer(pParent, "rhel3_ks.cfg") {}
+ ~UnattendedRhel3Installer() {}
+};
+
+
+/**
+ * Fedora installer (same as RHEL 6, except for the template).
+ */
+class UnattendedFedoraInstaller : public UnattendedRhel6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedFedoraInstaller)
+
+ UnattendedFedoraInstaller(Unattended *pParent)
+ : UnattendedRhel6Installer(pParent, "fedora_ks.cfg")
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedFedoraInstaller() {}
+};
+
+
+/**
+ * Oracle Linux 6 installer. Same as RHEL 6, except for the templates.
+ * The reason of adding new class is to sepatate the RHEL from OL.
+ */
+class UnattendedOracleLinux6Installer : public UnattendedRhel6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux6Installer)
+
+ UnattendedOracleLinux6Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName = "ol_ks.cfg",
+ const char *pszPostScriptTemplateName = "ol_postinstall.sh",
+ const char *pszMainScriptFilename = "ks.cfg")
+ : UnattendedRhel6Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedOracleLinux6Installer() {}
+};
+
+
+/**
+ * Oracle Linux 7 installer. Same as OL 6.
+ * The class was added for better handling any possible subtle difference between OL6 and OL7.
+ */
+class UnattendedOracleLinux7Installer : public UnattendedOracleLinux6Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux7Installer)
+
+ UnattendedOracleLinux7Installer(Unattended *pParent)
+ : UnattendedOracleLinux6Installer(pParent)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+
+ UnattendedOracleLinux7Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName,
+ const char *pszPostScriptTemplateName,
+ const char *pszMainScriptFilename)
+ : UnattendedOracleLinux6Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedOracleLinux7Installer() {}
+};
+
+
+/**
+ * Oracle Linux 8 installer. Using a different kickstart file than earlier OL versions.
+ */
+class UnattendedOracleLinux8Installer : public UnattendedOracleLinux7Installer
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux8Installer)
+
+ UnattendedOracleLinux8Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName = "ol8_ks.cfg",
+ const char *pszPostScriptTemplateName = "ol_postinstall.sh",
+ const char *pszMainScriptFilename = "ks.cfg")
+
+ : UnattendedOracleLinux7Installer(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ { Assert(!isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(isAuxiliaryIsoIsVISO()); }
+ ~UnattendedOracleLinux8Installer() {}
+};
+
+/**
+ * Oracle Linux 9 installer.
+ * Uses a different kickstart file since several commands/options are removed in OL9.
+ * See the ol9_ks.cfg file for comments. Also, as of OL9 kernel command argument 'ks' should have
+ * 'inst.' prefix.
+ */
+class UnattendedOracleLinux9Installer : public UnattendedRhelInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedOracleLinux9Installer)
+
+ UnattendedOracleLinux9Installer(Unattended *pParent,
+ const char *pszMainScriptTemplateName = "ol9_ks.cfg",
+ const char *pszPostScriptTemplateName = "ol_postinstall.sh",
+ const char *pszMainScriptFilename = "ks.cfg")
+ : UnattendedRhelInstaller(pParent, pszMainScriptTemplateName, pszPostScriptTemplateName, pszMainScriptFilename)
+ {
+ Assert(!isOriginalIsoNeeded());
+ Assert(isAuxiliaryIsoNeeded());
+ Assert(!isAuxiliaryFloppyNeeded());
+ Assert(isAuxiliaryIsoIsVISO());
+ mStrDefaultExtraInstallKernelParameters.assign(" inst.ks=cdrom:/").append(pszMainScriptFilename).append(' ');
+ mArrStrRemoveInstallKernelParameters.append("rd.live.check"); /* Disables the checkisomd5 step. Required for VISO. */
+ }
+ ~UnattendedOracleLinux9Installer() {}
+};
+
+
+#if 0 /* fixme */
+/**
+ * SUSE linux installer.
+ *
+ * @todo needs fixing.
+ */
+class UnattendedSuseInstaller : public UnattendedLinuxInstaller
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedSuseInstaller)
+
+ UnattendedSuseInstaller(BaseTextScript *pAlg, Unattended *pParent)
+ : UnattendedLinuxInstaller(pAlg, pParent, "suse_autoinstall.xml")
+ { Assert(isOriginalIsoNeeded()); Assert(isAuxiliaryIsoNeeded()); Assert(!isAuxiliaryFloppyNeeded()); Assert(!isAuxiliaryIsoIsVISO()); }
+ ~UnattendedSuseInstaller() {}
+
+ HRESULT setupScriptOnAuxiliaryCD(const Utf8Str &path);
+};
+#endif
+
+/**
+ * Base class for the unattended FreeBSD installers.
+ */
+class UnattendedFreeBsdInstaller : public UnattendedInstaller
+{
+public:
+ UnattendedFreeBsdInstaller(Unattended *pParent)
+ : UnattendedInstaller(pParent,
+ "freebsd_installer.cfg", "freebsd_postinstall.sh",
+ "installerconfig", "vboxpostinstall.sh") {}
+ ~UnattendedFreeBsdInstaller() {}
+
+ bool isAuxiliaryIsoNeeded() const { return true; }
+ bool isOriginalIsoNeeded() const { return false; }
+
+protected:
+ HRESULT addFilesToAuxVisoVectors(RTCList<RTCString> &rVecArgs, RTCList<RTCString> &rVecFiles,
+ RTVFS hVfsOrgIso, bool fOverwrite);
+};
+
+#endif /* !MAIN_INCLUDED_UnattendedInstaller_h */
diff --git a/src/VBox/Main/include/UnattendedScript.h b/src/VBox/Main/include/UnattendedScript.h
new file mode 100644
index 00000000..f61821b8
--- /dev/null
+++ b/src/VBox/Main/include/UnattendedScript.h
@@ -0,0 +1,193 @@
+/* $Id: UnattendedScript.h $ */
+/** @file
+ * Classes for reading/parsing/saving scripts for unattended installation.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UnattendedScript_h
+#define MAIN_INCLUDED_UnattendedScript_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "TextScript.h"
+#include "iprt/expreval.h"
+
+using namespace xml;
+
+class Unattended;
+
+
+/**
+ * Generic unattended text script template editor.
+ *
+ * This just perform variable replacements, no other editing possible.
+ *
+ * Everything happens during saveToString, parse is a noop.
+ */
+class UnattendedScriptTemplate : public BaseTextScript
+{
+protected:
+ /** Where to get the replacement strings from. */
+ Unattended *mpUnattended;
+
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedScriptTemplate)
+
+ UnattendedScriptTemplate(Unattended *pUnattended, const char *pszDefaultTemplateFilename, const char *pszDefaultFilename);
+ virtual ~UnattendedScriptTemplate() {}
+
+ HRESULT parse() { return S_OK; }
+ HRESULT saveToString(Utf8Str &rStrDst);
+
+protected:
+ typedef enum
+ {
+ kValueEscaping_None,
+ kValueEscaping_Bourne,
+ kValueEscaping_XML_Element,
+ kValueEscaping_XML_Attribute_Double_Quotes
+ } kEvalEscaping_T;
+
+ /**
+ * Gets the replacement value for the given placeholder.
+ *
+ * @returns COM status code.
+ * @param pachPlaceholder The placholder string. Not zero terminated.
+ * @param cchPlaceholder The length of the placeholder.
+ * @param fOutputting Indicates whether we actually need the correct value
+ * or is just syntax checking excluded template parts.
+ * @param rValue Where to return the value.
+ */
+ HRESULT getReplacement(const char *pachPlaceholder, size_t cchPlaceholder, bool fOutputting, RTCString &rValue);
+
+ /**
+ * Gets the replacement value for the given expression placeholder
+ * (@@VBOX_INSERT[expr]@@ and friends).
+ *
+ * @returns COM status code.
+ * @param hEvaluator The evaluator to use for the expression.
+ * @param pachPlaceholder The placholder string. Not zero terminated.
+ * @param cchPlaceholder The length of the placeholder.
+ * @param fOutputting Indicates whether we actually need the correct value
+ * or is just syntax checking excluded template parts.
+ * @param ppszValue Where to return the value. Free by calling
+ * RTStrFree. Set to NULL for empty string.
+ */
+ HRESULT getReplacementForExpr(RTEXPREVAL hEvaluator, const char *pachPlaceholder, size_t cchPlaceholder,
+ bool fOutputting, char **ppszValue) RT_NOEXCEPT;
+
+ /**
+ * Resolves a conditional expression.
+ *
+ * @returns COM status code.
+ * @param hEvaluator The evaluator to use for the expression.
+ * @param pachPlaceholder The placholder string. Not zero terminated.
+ * @param cchPlaceholder The length of the placeholder.
+ * @param pfOutputting Where to return the result of the conditional. This
+ * holds the current outputting state on input in case
+ * someone want to sanity check anything.
+ */
+ HRESULT resolveConditionalExpr(RTEXPREVAL hEvaluator, const char *pachPlaceholder, size_t cchPlaceholder,
+ bool *pfOutputting) RT_NOEXCEPT;
+
+ /** @callback_method_impl{FNRTEXPREVALQUERYVARIABLE} */
+ static DECLCALLBACK(int) queryVariableForExpr(const char *pchName, size_t cchName, void *pvUser,
+ char **ppszValue) RT_NOEXCEPT;
+
+ /**
+ * Gets a variable.
+ *
+ * This is used both for getting replacements (@@VBOX_INSERT_XXX@@) and in
+ * expressions (@@VBOX_INSERT[expr]@@, @@VBOX_COND[expr]@@).
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_FOUND if variable does not exist.
+ *
+ * @param pchName The variable name. Not zero terminated.
+ * @param cchName The length of the name.
+ * @param rstrTmp String object that can be used for keeping the
+ * value returned via @a *ppszValue.
+ * @param ppszValue If a value is desired, this is where to return
+ * it. This points to a string that should be
+ * accessible for a little while after the function
+ * returns. Use @a rstrTmp for storage if
+ * necessary.
+ *
+ * This will be NULL when called from the 'defined'
+ * operator. In which case no errors should be
+ * set.
+ * @throws std::bad_alloc
+ * @see FNRTEXPREVALQUERYVARIABLE
+ */
+ virtual int queryVariable(const char *pchName, size_t cchName, Utf8Str &rstrTmp, const char **ppszValue);
+
+ /**
+ * Get the result of a conditional.
+ *
+ * @returns COM status code.
+ * @param pachPlaceholder The placholder string. Not zero terminated.
+ * @param cchPlaceholder The length of the placeholder.
+ * @param pfOutputting Where to return the result of the conditional.
+ * This holds the current outputting state on input
+ * in case someone want to sanity check anything.
+ */
+ virtual HRESULT getConditional(const char *pachPlaceholder, size_t cchPlaceholder, bool *pfOutputting);
+};
+
+#if 0 /* convert when we fix SUSE */
+/**
+ * SUSE unattended XML file editor.
+ */
+class UnattendedSUSEXMLScript : public UnattendedXMLScript
+{
+public:
+ DECLARE_TRANSLATE_METHODS(UnattendedSUSEXMLScript)
+
+ UnattendedSUSEXMLScript(VirtualBoxBase *pSetError, const char *pszDefaultFilename = "autoinst.xml")
+ : UnattendedXMLScript(pSetError, pszDefaultFilename) {}
+ ~UnattendedSUSEXMLScript() {}
+
+ HRESULT parse();
+
+protected:
+ HRESULT setFieldInElement(xml::ElementNode *pElement, const DataId enmDataId, const Utf8Str &rStrValue);
+
+private:
+ //////////////////New functions//////////////////////////////
+ /** @throws std::bad_alloc */
+ HRESULT LoopThruSections(const xml::ElementNode *pelmRoot);
+ /** @throws std::bad_alloc */
+ HRESULT HandleUserAccountsSection(const xml::ElementNode *pelmSection);
+ /** @throws std::bad_alloc */
+ Utf8Str createProbableValue(const DataId enmDataId, const xml::ElementNode *pCurElem);
+ /** @throws std::bad_alloc */
+ Utf8Str createProbableUserHomeDir(const xml::ElementNode *pCurElem);
+ //////////////////New functions//////////////////////////////
+};
+#endif
+
+
+#endif /* !MAIN_INCLUDED_UnattendedScript_h */
+
diff --git a/src/VBox/Main/include/UpdateAgentImpl.h b/src/VBox/Main/include/UpdateAgentImpl.h
new file mode 100644
index 00000000..4381c517
--- /dev/null
+++ b/src/VBox/Main/include/UpdateAgentImpl.h
@@ -0,0 +1,220 @@
+/* $Id: UpdateAgentImpl.h $ */
+/** @file
+ * Update agent COM class implementation - Header
+ */
+
+/*
+ * Copyright (C) 2020-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UpdateAgentImpl_h
+#define MAIN_INCLUDED_UpdateAgentImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/http.h>
+
+#include <VBox/settings.h>
+
+#include "EventImpl.h"
+#include "UpdateAgentWrap.h"
+#include "HostUpdateAgentWrap.h"
+
+class UpdateAgentTask;
+struct UpdateAgentTaskParms;
+
+struct UpdateAgentTaskResult
+{
+ Utf8Str strVer;
+ Utf8Str strWebUrl;
+ Utf8Str strDownloadUrl;
+ UpdateSeverity_T enmSeverity;
+ Utf8Str strReleaseNotes;
+};
+
+class UpdateAgentBase
+{
+protected: /* Not directly instancable. */
+
+ UpdateAgentBase()
+ : m_VirtualBox(NULL)
+ , m(new settings::UpdateAgent) { }
+
+ virtual ~UpdateAgentBase() { delete m; }
+
+public:
+
+ /** @name Pure virtual public methods for internal purposes only
+ * (ensure there is a caller and a read lock before calling them!)
+ * @{ */
+ virtual HRESULT i_loadSettings(const settings::UpdateAgent &data) = 0;
+ virtual HRESULT i_saveSettings(settings::UpdateAgent &data) = 0;
+
+ virtual HRESULT i_setCheckCount(ULONG aCount) = 0;
+ virtual HRESULT i_setLastCheckDate(const com::Utf8Str &aDate) = 0;
+ /** @} */
+
+protected:
+
+ /** @name Pure virtual internal task callbacks.
+ * @{ */
+ friend UpdateAgentTask;
+ virtual DECLCALLBACK(HRESULT) i_checkForUpdateTask(UpdateAgentTask *pTask) = 0;
+ /** @} */
+
+ /** @name Static helper methods.
+ * @{ */
+ static Utf8Str i_getPlatformInfo(void);
+ const char *i_proxyModeToStr(ProxyMode_T enmMode);
+ bool i_urlSchemeIsSupported(const Utf8Str &strUrl) const;
+ /** @} */
+
+protected:
+ /** The update agent's event source. */
+ const ComObjPtr<EventSource> m_EventSource;
+ VirtualBox * const m_VirtualBox;
+
+ /** @name Data members.
+ * @{ */
+ settings::UpdateAgent *m;
+
+ struct Data
+ {
+ UpdateAgentTaskResult m_lastResult;
+ Utf8Str m_strName;
+ /** Vector of update channels this agent supports. */
+ const std::vector<UpdateChannel_T> m_enmChannels;
+ bool m_fHidden;
+ UpdateState_T m_enmState;
+ uint32_t m_uOrder;
+
+ Data(void)
+ {
+ m_fHidden = true;
+ m_enmState = UpdateState_Invalid;
+ m_uOrder = UINT32_MAX;
+ }
+ } mData;
+ /** @} */
+};
+
+class ATL_NO_VTABLE UpdateAgent :
+ public UpdateAgentWrap,
+ public UpdateAgentBase
+{
+public:
+ DECLARE_COMMON_CLASS_METHODS(UpdateAgent)
+
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ HRESULT init(VirtualBox *aVirtualBox);
+ void uninit(void);
+ /** @} */
+
+ /** @name Public methods for internal purposes only
+ * (ensure there is a caller and a read lock before calling them!)
+ * @{ */
+ HRESULT i_loadSettings(const settings::UpdateAgent &data);
+ HRESULT i_saveSettings(settings::UpdateAgent &data);
+
+ virtual HRESULT i_setCheckCount(ULONG aCount);
+ virtual HRESULT i_setLastCheckDate(const com::Utf8Str &aDate);
+ /** @} */
+
+protected:
+
+ /** @name Internal helper methods.
+ * @{ */
+ HRESULT i_getProxyMode(ProxyMode_T *aMode);
+ HRESULT i_getProxyURL(com::Utf8Str &aAddress);
+ HRESULT i_configureProxy(RTHTTP hHttp);
+ HRESULT i_commitSettings(AutoWriteLock &aLock);
+ HRESULT i_reportError(int vrc, const char *pcszMsgFmt, ...);
+ /** @} */
+
+protected:
+ /** @name Wrapped IUpdateAgent attributes and methods.
+ * @{ */
+ HRESULT checkFor(ComPtr<IProgress> &aProgress);
+ HRESULT download(ComPtr<IProgress> &aProgress);
+ HRESULT install(ComPtr<IProgress> &aProgress);
+ HRESULT rollback(void);
+
+ HRESULT getName(com::Utf8Str &aName);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getOrder(ULONG *aOrder);
+ HRESULT getDependsOn(std::vector<com::Utf8Str> &aDeps);
+ HRESULT getVersion(com::Utf8Str &aVer);
+ HRESULT getDownloadUrl(com::Utf8Str &aUrl);
+ HRESULT getWebUrl(com::Utf8Str &aUrl);
+ HRESULT getReleaseNotes(com::Utf8Str &aRelNotes);
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getHidden(BOOL *aHidden);
+ HRESULT getState(UpdateState_T *aState);
+ HRESULT getCheckCount(ULONG *aCount);
+ HRESULT getCheckFrequency(ULONG *aFreqSeconds);
+ HRESULT setCheckFrequency(ULONG aFreqSeconds);
+ HRESULT getChannel(UpdateChannel_T *aChannel);
+ HRESULT setChannel(UpdateChannel_T aChannel);
+ HRESULT getRepositoryURL(com::Utf8Str &aRepo);
+ HRESULT setRepositoryURL(const com::Utf8Str &aRepo);
+ HRESULT getLastCheckDate(com::Utf8Str &aData);
+ HRESULT getIsCheckNeeded(BOOL *aCheckNeeded);
+ HRESULT getSupportedChannels(std::vector<UpdateChannel_T> &aSupportedChannels);
+ /** @} */
+};
+
+/** @todo Put this into an own module, e.g. HostUpdateAgentImpl.[cpp|h]. */
+
+class ATL_NO_VTABLE HostUpdateAgent :
+ public UpdateAgent
+{
+public:
+ /** @name COM and internal init/term/mapping cruft.
+ * @{ */
+ DECLARE_COMMON_CLASS_METHODS(HostUpdateAgent)
+
+ HRESULT init(VirtualBox *aVirtualBox);
+ void uninit(void);
+
+ HRESULT FinalConstruct(void);
+ void FinalRelease(void);
+ /** @} */
+
+private:
+ /** @name Implemented (pure) virtual methods from UpdateAgent.
+ * @{ */
+ HRESULT checkFor(ComPtr<IProgress> &aProgress);
+
+ DECLCALLBACK(HRESULT) i_checkForUpdateTask(UpdateAgentTask *pTask);
+ /** @} */
+
+ HRESULT i_checkForUpdate(void);
+ HRESULT i_checkForUpdateInner(RTHTTP hHttp, com::Utf8Str const &strUrl, com::Utf8Str const &strUserAgent);
+};
+
+#endif /* !MAIN_INCLUDED_UpdateAgentImpl_h */
+
diff --git a/src/VBox/Main/include/UsbCardReader.h b/src/VBox/Main/include/UsbCardReader.h
new file mode 100644
index 00000000..15dc871f
--- /dev/null
+++ b/src/VBox/Main/include/UsbCardReader.h
@@ -0,0 +1,87 @@
+/* $Id: UsbCardReader.h $ */
+
+/** @file
+ * VirtualBox Driver interface to the virtual Usb Card Reader.
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UsbCardReader_h
+#define MAIN_INCLUDED_UsbCardReader_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/vmm/pdmcardreaderinfs.h>
+#include <VBox/vmm/pdmdrv.h>
+
+#define USBCARDREADER_OID "46225eac-10c9-4b57-92b6-e59efd48009f"
+
+class Console;
+typedef struct USBCARDREADER USBCARDREADER;
+typedef struct UCRREMOTE UCRREMOTE;
+
+class UsbCardReader
+{
+ public:
+ UsbCardReader(Console *console);
+ virtual ~UsbCardReader();
+
+ static const PDMDRVREG DrvReg;
+ USBCARDREADER *mpDrv;
+
+ Console *getParent(void) { return mParent; }
+
+ int VRDENotify(uint32_t u32Id, void *pvData, uint32_t cbData);
+ int VRDEResponse(int rcRequest, void *pvUser, uint32_t u32Function, void *pvData, uint32_t cbData);
+
+ int EstablishContext(USBCARDREADER *pDrv);
+ int ReleaseContext(USBCARDREADER *pDrv);
+ int GetStatusChange(USBCARDREADER *pDrv, void *pvUser, uint32_t u32Timeout,
+ PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats);
+ int Connect(USBCARDREADER *pDrv, void *pvUser, const char *pszReaderName,
+ uint32_t u32ShareMode, uint32_t u32PreferredProtocols);
+ int Disconnect(USBCARDREADER *pDrv, void *pvUser, uint32_t u32Mode);
+ int Status(USBCARDREADER *pDrv, void *pvUser);
+ int Transmit(USBCARDREADER *pDrv, void *pvUser, PDMICARDREADER_IO_REQUEST *pioSendRequest,
+ uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer);
+ int Control(USBCARDREADER *pDrv, void *pvUser, uint32_t u32ControlCode,
+ uint8_t *pu8InBuffer, uint32_t cbInBuffer, uint32_t cbOutBuffer);
+ int GetAttrib(USBCARDREADER *pDrv, void *pvUser, uint32_t u32AttrId, uint32_t cbAttrib);
+ int SetAttrib(USBCARDREADER *pDrv, void *pvUser, uint32_t u32AttrId,
+ uint8_t *pu8Attrib, uint32_t cbAttrib);
+
+ private:
+ static DECLCALLBACK(void *) drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+
+ int vrdeSCardRequest(void *pvUser, uint32_t u32Function, const void *pvData, uint32_t cbData);
+
+ Console * const mParent;
+
+ UCRREMOTE *m_pRemote;
+};
+
+#endif /* !MAIN_INCLUDED_UsbCardReader_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/UsbWebcamInterface.h b/src/VBox/Main/include/UsbWebcamInterface.h
new file mode 100644
index 00000000..eb803ba4
--- /dev/null
+++ b/src/VBox/Main/include/UsbWebcamInterface.h
@@ -0,0 +1,79 @@
+/* $Id: UsbWebcamInterface.h $ */
+/** @file
+ * VirtualBox PDM Driver for Emulated USB Webcam
+ */
+
+/*
+ * Copyright (C) 2011-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_UsbWebcamInterface_h
+#define MAIN_INCLUDED_UsbWebcamInterface_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/vmm/pdmdrv.h>
+#define VRDE_VIDEOIN_WITH_VRDEINTERFACE /* Get the VRDE interface definitions. */
+#include <VBox/RemoteDesktop/VRDEVideoIn.h>
+
+class ConsoleVRDPServer;
+typedef struct EMWEBCAMDRV EMWEBCAMDRV;
+typedef struct EMWEBCAMREMOTE EMWEBCAMREMOTE;
+
+class EmWebcam
+{
+ public:
+ EmWebcam(ConsoleVRDPServer *pServer);
+ virtual ~EmWebcam();
+
+ static const PDMDRVREG DrvReg;
+
+ void EmWebcamConstruct(EMWEBCAMDRV *pDrv);
+ void EmWebcamDestruct(EMWEBCAMDRV *pDrv);
+
+ /* Callbacks. */
+ void EmWebcamCbNotify(uint32_t u32Id, const void *pvData, uint32_t cbData);
+ void EmWebcamCbDeviceDesc(int rcRequest, void *pDeviceCtx, void *pvUser,
+ const VRDEVIDEOINDEVICEDESC *pDeviceDesc, uint32_t cbDeviceDesc);
+ void EmWebcamCbControl(int rcRequest, void *pDeviceCtx, void *pvUser,
+ const VRDEVIDEOINCTRLHDR *pControl, uint32_t cbControl);
+ void EmWebcamCbFrame(int rcRequest, void *pDeviceCtx,
+ const VRDEVIDEOINPAYLOADHDR *pFrame, uint32_t cbFrame);
+
+ /* Methods for the PDM driver. */
+ int SendControl(EMWEBCAMDRV *pDrv, void *pvUser, uint64_t u64DeviceId,
+ const VRDEVIDEOINCTRLHDR *pControl, uint32_t cbControl);
+
+ private:
+ static DECLCALLBACK(void *) drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+
+ ConsoleVRDPServer * const mParent;
+
+ EMWEBCAMDRV *mpDrv;
+ EMWEBCAMREMOTE *mpRemote;
+ uint64_t volatile mu64DeviceIdSrc;
+};
+
+#endif /* !MAIN_INCLUDED_UsbWebcamInterface_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/VBoxNls.h b/src/VBox/Main/include/VBoxNls.h
new file mode 100644
index 00000000..19fbc69f
--- /dev/null
+++ b/src/VBox/Main/include/VBoxNls.h
@@ -0,0 +1,65 @@
+/* $Id: VBoxNls.h $ */
+/** @file
+ * VBox NLS.
+ */
+
+/*
+ * Copyright (C) 2020-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+#ifndef MAIN_INCLUDED_VBoxNls_h
+#define MAIN_INCLUDED_VBoxNls_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef VBOX_WITH_MAIN_NLS
+
+#include <VBox/com/defs.h>
+#include <VBox/com/ptr.h>
+#include <VBox/com/string.h>
+#include "VirtualBoxTranslator.h"
+
+
+# define DECLARE_TRANSLATION_CONTEXT(ctx) \
+struct ctx \
+{\
+ static const char *tr(const char *pszSource, const char *pszComment = NULL, const size_t aNum = ~(size_t)0) \
+ { \
+ return VirtualBoxTranslator::translate(NULL, #ctx, pszSource, pszComment, aNum); \
+ } \
+}
+#else
+# define DECLARE_TRANSLATION_CONTEXT(ctx) \
+struct ctx \
+{\
+ static const char *tr(const char *pszSource, const char *pszComment = NULL, const size_t aNum = ~(size_t)0) \
+ { \
+ NOREF(pszComment); \
+ NOREF(aNum); \
+ return pszSource; \
+ } \
+}
+#endif
+
+#endif /* !MAIN_INCLUDED_VBoxNls_h */
+
diff --git a/src/VBox/Main/include/VFSExplorerImpl.h b/src/VBox/Main/include/VFSExplorerImpl.h
new file mode 100644
index 00000000..fb5e4912
--- /dev/null
+++ b/src/VBox/Main/include/VFSExplorerImpl.h
@@ -0,0 +1,101 @@
+/* $Id: VFSExplorerImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2009-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VFSExplorerImpl_h
+#define MAIN_INCLUDED_VFSExplorerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VFSExplorerWrap.h"
+
+class ATL_NO_VTABLE VFSExplorer :
+ public VFSExplorerWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(VFSExplorer)
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT FinalConstruct() { return BaseFinalConstruct(); }
+ void FinalRelease() { uninit(); BaseFinalRelease(); }
+
+ HRESULT init(VFSType_T aType, Utf8Str aFilePath, Utf8Str aHostname, Utf8Str aUsername, Utf8Str aPassword, VirtualBox *aVirtualBox);
+ void uninit();
+
+ /* public methods only for internal purposes */
+ static HRESULT setErrorStatic(HRESULT aResultCode, const char *aText, ...)
+ {
+ va_list va;
+ va_start(va, aText);
+ HRESULT hrc = setErrorInternalV(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, va, false, true);
+ va_end(va);
+ return hrc;
+ }
+
+private:
+
+ // wrapped IVFSExplorer properties
+ HRESULT getPath(com::Utf8Str &aPath);
+ HRESULT getType(VFSType_T *aType);
+
+ // wrapped IVFSExplorer methods
+ HRESULT update(ComPtr<IProgress> &aProgress);
+ HRESULT cd(const com::Utf8Str &aDir, ComPtr<IProgress> &aProgress);
+ HRESULT cdUp(ComPtr<IProgress> &aProgress);
+ HRESULT entryList(std::vector<com::Utf8Str> &aNames,
+ std::vector<ULONG> &aTypes,
+ std::vector<LONG64> &aSizes,
+ std::vector<ULONG> &aModes);
+ HRESULT exists(const std::vector<com::Utf8Str> &aNames,
+ std::vector<com::Utf8Str> &aExists);
+ HRESULT remove(const std::vector<com::Utf8Str> &aNames,
+ ComPtr<IProgress> &aProgress);
+
+ /* Private member vars */
+ VirtualBox * const mVirtualBox;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ ////
+ //// VFSExplorer definitions
+ ////
+ //////////////////////////////////////////////////////////////////////////////////
+ //
+ class TaskVFSExplorer; /* Worker thread helper */
+ struct Data;
+ Data *m;
+
+ /* Private member methods */
+ FsObjType_T i_iprtToVfsObjType(RTFMODE aType) const;
+
+ HRESULT i_updateFS(TaskVFSExplorer *aTask);
+ HRESULT i_deleteFS(TaskVFSExplorer *aTask);
+
+};
+
+#endif /* !MAIN_INCLUDED_VFSExplorerImpl_h */
+
diff --git a/src/VBox/Main/include/VMMDev.h b/src/VBox/Main/include/VMMDev.h
new file mode 100644
index 00000000..a5583d41
--- /dev/null
+++ b/src/VBox/Main/include/VMMDev.h
@@ -0,0 +1,115 @@
+/* $Id: VMMDev.h $ */
+/** @file
+ * VirtualBox Driver interface to VMM device
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VMMDev_h
+#define MAIN_INCLUDED_VMMDev_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/hgcmsvc.h>
+#include <iprt/asm.h>
+
+class Console;
+
+class VMMDevMouseInterface
+{
+public:
+ virtual ~VMMDevMouseInterface() { /* Make VC++ 19.2 happy. */ }
+ virtual PPDMIVMMDEVPORT getVMMDevPort() = 0;
+};
+
+class VMMDev : public VMMDevMouseInterface
+{
+public:
+ VMMDev(Console *console);
+ virtual ~VMMDev();
+ static const PDMDRVREG DrvReg;
+ /** Pointer to the associated VMMDev driver. */
+ struct DRVMAINVMMDEV *mpDrv;
+
+ bool fSharedFolderActive;
+ bool isShFlActive()
+ {
+ return fSharedFolderActive;
+ }
+
+ Console *getParent()
+ {
+ return mParent;
+ }
+
+ int WaitCredentialsJudgement (uint32_t u32Timeout, uint32_t *pu32GuestFlags);
+ int SetCredentialsJudgementResult (uint32_t u32Flags);
+
+ PPDMIVMMDEVPORT getVMMDevPort();
+
+#ifdef VBOX_WITH_HGCM
+ int hgcmLoadService (const char *pszServiceLibrary, const char *pszServiceName);
+ int hgcmHostCall (const char *pszServiceName, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms);
+ void hgcmShutdown(bool fUvmIsInvalid = false);
+
+ bool hgcmIsActive (void) { return ASMAtomicReadBool(&m_fHGCMActive); }
+#endif /* VBOX_WITH_HGCM */
+
+private:
+#ifdef VBOX_WITH_HGCM
+# ifdef VBOX_WITH_GUEST_PROPS
+ void i_guestPropSetMultiple(void *names, void *values, void *timestamps, void *flags);
+ void i_guestPropSet(const char *pszName, const char *pszValue, const char *pszFlags);
+ int i_guestPropSetGlobalPropertyFlags(uint32_t fFlags);
+ int i_guestPropLoadAndConfigure();
+# endif
+#endif
+ static DECLCALLBACK(void *) drvQueryInterface(PPDMIBASE pInterface, const char *pszIID);
+ static DECLCALLBACK(int) drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+ static DECLCALLBACK(void) drvDestruct(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvReset(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvPowerOn(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvPowerOff(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvSuspend(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(void) drvResume(PPDMDRVINS pDrvIns);
+ static DECLCALLBACK(int) hgcmSave(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+ static DECLCALLBACK(int) hgcmLoad(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+
+ Console * const mParent;
+
+ RTSEMEVENT mCredentialsEvent;
+ uint32_t mu32CredentialsFlags;
+
+#ifdef VBOX_WITH_HGCM
+ bool volatile m_fHGCMActive;
+#endif /* VBOX_WITH_HGCM */
+};
+
+/** VMMDev object ID used by Console::i_vmm2User_QueryGenericObject and VMMDev::drvConstruct. */
+#define VMMDEV_OID "e2ff0c7b-c02b-46d0-aa90-b9caf0f60561"
+
+#endif /* !MAIN_INCLUDED_VMMDev_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/VRDEServerImpl.h b/src/VBox/Main/include/VRDEServerImpl.h
new file mode 100644
index 00000000..c8e47273
--- /dev/null
+++ b/src/VBox/Main/include/VRDEServerImpl.h
@@ -0,0 +1,98 @@
+/* $Id: VRDEServerImpl.h $ */
+
+/** @file
+ *
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VRDEServerImpl_h
+#define MAIN_INCLUDED_VRDEServerImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VRDEServerWrap.h"
+
+namespace settings
+{
+ struct VRDESettings;
+}
+
+class ATL_NO_VTABLE VRDEServer :
+ public VRDEServerWrap
+{
+public:
+
+ DECLARE_COMMON_CLASS_METHODS(VRDEServer)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(Machine *aParent);
+ HRESULT init(Machine *aParent, VRDEServer *aThat);
+ HRESULT initCopy(Machine *aParent, VRDEServer *aThat);
+ void uninit();
+
+ // public methods only for internal purposes
+ HRESULT i_loadSettings(const settings::VRDESettings &data);
+ HRESULT i_saveSettings(settings::VRDESettings &data);
+ void i_rollback();
+ void i_commit();
+ void i_copyFrom(VRDEServer *aThat);
+
+private:
+
+ // wrapped IVRDEServer properties
+ HRESULT getEnabled(BOOL *aEnabled);
+ HRESULT setEnabled(BOOL aEnabled);
+ HRESULT getAuthType(AuthType_T *aAuthType);
+ HRESULT setAuthType(AuthType_T aAuthType);
+ HRESULT getAuthTimeout(ULONG *aAuthTimeout);
+ HRESULT setAuthTimeout(ULONG aAuthTimeout);
+ HRESULT getAllowMultiConnection(BOOL *aAllowMultiConnection);
+ HRESULT setAllowMultiConnection(BOOL aAllowMultiConnection);
+ HRESULT getReuseSingleConnection(BOOL *aReuseSingleConnection);
+ HRESULT setReuseSingleConnection(BOOL aReuseSingleConnection);
+ HRESULT getVRDEExtPack(com::Utf8Str &aVRDEExtPack);
+ HRESULT setVRDEExtPack(const com::Utf8Str &aVRDEExtPack);
+ HRESULT getAuthLibrary(com::Utf8Str &aAuthLibrary);
+ HRESULT setAuthLibrary(const com::Utf8Str &aAuthLibrary);
+ HRESULT getVRDEProperties(std::vector<com::Utf8Str> &aVRDEProperties);
+
+ // wrapped IVRDEServer methods
+ HRESULT setVRDEProperty(const com::Utf8Str &aKey,
+ const com::Utf8Str &aValue);
+ HRESULT getVRDEProperty(const com::Utf8Str &aKey,
+ com::Utf8Str &aValue);
+
+ Machine * const mParent;
+ const ComObjPtr<VRDEServer> mPeer;
+
+ Backupable<settings::VRDESettings> mData;
+};
+
+#endif /* !MAIN_INCLUDED_VRDEServerImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/VirtualBoxBase.h b/src/VBox/Main/include/VirtualBoxBase.h
new file mode 100644
index 00000000..2fa10f90
--- /dev/null
+++ b/src/VBox/Main/include/VirtualBoxBase.h
@@ -0,0 +1,1118 @@
+/* $Id: VirtualBoxBase.h $ */
+/** @file
+ * VirtualBox COM base classes definition
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VirtualBoxBase_h
+#define MAIN_INCLUDED_VirtualBoxBase_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/thread.h>
+
+#include <list>
+#include <map>
+
+#include "ObjectState.h"
+
+#include "VBox/com/AutoLock.h"
+#include "VBox/com/string.h"
+#include "VBox/com/Guid.h"
+
+#include "VBox/com/VirtualBox.h"
+
+#include "VirtualBoxTranslator.h"
+
+// avoid including VBox/settings.h and VBox/xml.h; only declare the classes
+namespace xml
+{
+class File;
+}
+
+namespace com
+{
+class ErrorInfo;
+}
+
+using namespace com;
+using namespace util;
+
+class VirtualBox;
+class Machine;
+class Medium;
+class Host;
+typedef std::list<ComObjPtr<Medium> > MediaList;
+typedef std::list<Utf8Str> StringsList;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// COM helpers
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#if !defined(VBOX_WITH_XPCOM)
+
+/* use a special version of the singleton class factory,
+ * see KB811591 in msdn for more info. */
+
+#undef DECLARE_CLASSFACTORY_SINGLETON
+#define DECLARE_CLASSFACTORY_SINGLETON(obj) DECLARE_CLASSFACTORY_EX(CMyComClassFactorySingleton<obj>)
+
+/**
+ * @todo r=bird: This CMyComClassFactorySingleton stuff is probably obsoleted by
+ * microatl.h? Right?
+ */
+
+template <class T>
+class CMyComClassFactorySingleton : public ATL::CComClassFactory
+{
+public:
+ CMyComClassFactorySingleton() :
+ m_hrCreate(S_OK), m_spObj(NULL)
+ {
+ }
+ virtual ~CMyComClassFactorySingleton()
+ {
+ if (m_spObj)
+ m_spObj->Release();
+ }
+ // IClassFactory
+ STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
+ {
+ HRESULT hRes = E_POINTER;
+ if (ppvObj != NULL)
+ {
+ *ppvObj = NULL;
+ // no aggregation for singletons
+ AssertReturn(pUnkOuter == NULL, CLASS_E_NOAGGREGATION);
+ if (m_hrCreate == S_OK && m_spObj == NULL)
+ {
+ Lock();
+ __try
+ {
+ // Fix: The following If statement was moved inside the __try statement.
+ // Did another thread arrive here first?
+ if (m_hrCreate == S_OK && m_spObj == NULL)
+ {
+ // lock the module to indicate activity
+ // (necessary for the monitor shutdown thread to correctly
+ // terminate the module in case when CreateInstance() fails)
+ ATL::_pAtlModule->Lock();
+ ATL::CComObjectCached<T> *p;
+ m_hrCreate = ATL::CComObjectCached<T>::CreateInstance(&p);
+ if (SUCCEEDED(m_hrCreate))
+ {
+ m_hrCreate = p->QueryInterface(IID_IUnknown, (void **)&m_spObj);
+ if (FAILED(m_hrCreate))
+ {
+ delete p;
+ }
+ }
+ ATL::_pAtlModule->Unlock();
+ }
+ }
+ __finally
+ {
+ Unlock();
+ }
+ }
+ if (m_hrCreate == S_OK)
+ {
+ hRes = m_spObj->QueryInterface(riid, ppvObj);
+ }
+ else
+ {
+ hRes = m_hrCreate;
+ }
+ }
+ return hRes;
+ }
+ HRESULT m_hrCreate;
+ IUnknown *m_spObj;
+};
+
+#endif /* !defined(VBOX_WITH_XPCOM) */
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Macros
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Special version of the Assert macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * In the debug build, this macro is equivalent to Assert.
+ * In the release build, this macro uses |setError(E_FAIL, ...)| to set the
+ * error info from the asserted expression.
+ *
+ * @see VirtualBoxBase::setError
+ *
+ * @param expr Expression which should be true.
+ */
+#define ComAssert(expr) \
+ do { \
+ if (RT_LIKELY(!!(expr))) \
+ { /* likely */ } \
+ else \
+ { \
+ AssertMsgFailed(("%s\n", #expr)); \
+ setError(E_FAIL, \
+ VirtualBoxBase::tr("Assertion failed: [%s] at '%s' (%d) in %s.\nPlease contact the product vendor!"), \
+ #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
+ } \
+ } while (0)
+
+/**
+ * Special version of the AssertFailed macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * In the debug build, this macro is equivalent to AssertFailed.
+ * In the release build, this macro uses |setError(E_FAIL, ...)| to set the
+ * error info from the asserted expression.
+ *
+ * @see VirtualBoxBase::setError
+ *
+ */
+#define ComAssertFailed() \
+ do { \
+ AssertFailed(); \
+ setError(E_FAIL, \
+ VirtualBoxBase::tr("Assertion failed: at '%s' (%d) in %s.\nPlease contact the product vendor!"), \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__); \
+ } while (0)
+
+/**
+ * Special version of the AssertMsg macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * See ComAssert for more info.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define ComAssertMsg(expr, a) \
+ do { \
+ if (RT_LIKELY(!!(expr))) \
+ { /* likely */ } \
+ else \
+ { \
+ Utf8StrFmt MyAssertMsg a; /* may throw bad_alloc */ \
+ AssertMsgFailed(("%s\n", MyAssertMsg.c_str())); \
+ setError(E_FAIL, \
+ VirtualBoxBase::tr("Assertion failed: [%s] at '%s' (%d) in %s.\n%s.\nPlease contact the product vendor!"), \
+ #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, MyAssertMsg.c_str()); \
+ } \
+ } while (0)
+
+/**
+ * Special version of the AssertMsgFailed macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * See ComAssert for more info.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define ComAssertMsgFailed(a) \
+ do { \
+ Utf8StrFmt MyAssertMsg a; /* may throw bad_alloc */ \
+ AssertMsgFailed(("%s\n", MyAssertMsg.c_str())); \
+ setError(E_FAIL, \
+ VirtualBoxBase::tr("Assertion failed: at '%s' (%d) in %s.\n%s.\nPlease contact the product vendor!"), \
+ __FILE__, __LINE__, __PRETTY_FUNCTION__, MyAssertMsg.c_str()); \
+ } while (0)
+
+/**
+ * Special version of the AssertRC macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * See ComAssert for more info.
+ *
+ * @param vrc VBox status code.
+ */
+#define ComAssertRC(vrc) ComAssertMsgRC(vrc, ("%Rra", vrc))
+
+/**
+ * Special version of the AssertMsgRC macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * See ComAssert for more info.
+ *
+ * @param vrc VBox status code.
+ * @param msg printf argument list (in parenthesis).
+ */
+#define ComAssertMsgRC(vrc, msg) ComAssertMsg(RT_SUCCESS(vrc), msg)
+
+/**
+ * Special version of the AssertComRC macro to be used within VirtualBoxBase
+ * subclasses.
+ *
+ * See ComAssert for more info.
+ *
+ * @param hrc COM result code
+ */
+#define ComAssertComRC(hrc) ComAssertMsg(SUCCEEDED(hrc), ("COM RC=%Rhrc (0x%08X)", (hrc), (hrc)))
+
+
+/** Special version of ComAssert that returns ret if expr fails */
+#define ComAssertRet(expr, ret) \
+ do { ComAssert(expr); if (!(expr)) return (ret); } while (0)
+/** Special version of ComAssertMsg that returns ret if expr fails */
+#define ComAssertMsgRet(expr, a, ret) \
+ do { ComAssertMsg(expr, a); if (!(expr)) return (ret); } while (0)
+/** Special version of ComAssertRC that returns ret if vrc does not succeed */
+#define ComAssertRCRet(vrc, ret) \
+ do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) return (ret); } while (0)
+/** Special version of ComAssertComRC that returns ret if rc does not succeed */
+#define ComAssertComRCRet(rc, ret) \
+ do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (ret); } while (0)
+/** Special version of ComAssertComRC that returns rc if rc does not succeed */
+#define ComAssertComRCRetRC(rc) \
+ do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (rc); } while (0)
+/** Special version of ComAssertFailed that returns ret */
+#define ComAssertFailedRet(ret) \
+ do { ComAssertFailed(); return (ret); } while (0)
+/** Special version of ComAssertMsgFailed that returns ret */
+#define ComAssertMsgFailedRet(msg, ret) \
+ do { ComAssertMsgFailed(msg); return (ret); } while (0)
+
+
+/** Special version of ComAssert that returns void if expr fails */
+#define ComAssertRetVoid(expr) \
+ do { ComAssert(expr); if (!(expr)) return; } while (0)
+/** Special version of ComAssertMsg that returns void if expr fails */
+#define ComAssertMsgRetVoid(expr, a) \
+ do { ComAssertMsg(expr, a); if (!(expr)) return; } while (0)
+/** Special version of ComAssertRC that returns void if vrc does not succeed */
+#define ComAssertRCRetVoid(vrc) \
+ do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) return; } while (0)
+/** Special version of ComAssertComRC that returns void if rc does not succeed */
+#define ComAssertComRCRetVoid(rc) \
+ do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return; } while (0)
+/** Special version of ComAssertFailed that returns void */
+#define ComAssertFailedRetVoid() \
+ do { ComAssertFailed(); return; } while (0)
+/** Special version of ComAssertMsgFailed that returns void */
+#define ComAssertMsgFailedRetVoid(msg) \
+ do { ComAssertMsgFailed(msg); return; } while (0)
+
+
+/** Special version of ComAssert that evaluates eval and breaks if expr fails */
+#define ComAssertBreak(expr, eval) \
+ if (1) { ComAssert(expr); if (!(expr)) { eval; break; } } else do {} while (0)
+/** Special version of ComAssertMsg that evaluates eval and breaks if expr fails */
+#define ComAssertMsgBreak(expr, a, eval) \
+ if (1) { ComAssertMsg(expr, a); if (!(expr)) { eval; break; } } else do {} while (0)
+/** Special version of ComAssertRC that evaluates eval and breaks if vrc does not succeed */
+#define ComAssertRCBreak(vrc, eval) \
+ if (1) { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) { eval; break; } } else do {} while (0)
+/** Special version of ComAssertFailed that evaluates eval and breaks */
+#define ComAssertFailedBreak(eval) \
+ if (1) { ComAssertFailed(); { eval; break; } } else do {} while (0)
+/** Special version of ComAssertMsgFailed that evaluates eval and breaks */
+#define ComAssertMsgFailedBreak(msg, eval) \
+ if (1) { ComAssertMsgFailed (msg); { eval; break; } } else do {} while (0)
+/** Special version of ComAssertComRC that evaluates eval and breaks if rc does not succeed */
+#define ComAssertComRCBreak(rc, eval) \
+ if (1) { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { eval; break; } } else do {} while (0)
+/** Special version of ComAssertComRC that just breaks if rc does not succeed */
+#define ComAssertComRCBreakRC(rc) \
+ if (1) { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { break; } } else do {} while (0)
+
+
+/** Special version of ComAssert that evaluates eval and throws it if expr fails */
+#define ComAssertThrow(expr, eval) \
+ do { ComAssert(expr); if (!(expr)) { throw (eval); } } while (0)
+/** Special version of ComAssertRC that evaluates eval and throws it if vrc does not succeed */
+#define ComAssertRCThrow(vrc, eval) \
+ do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) { throw (eval); } } while (0)
+/** Special version of ComAssertComRC that evaluates eval and throws it if rc does not succeed */
+#define ComAssertComRCThrow(rc, eval) \
+ do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { throw (eval); } } while (0)
+/** Special version of ComAssertComRC that just throws rc if rc does not succeed */
+#define ComAssertComRCThrowRC(rc) \
+ do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { throw rc; } } while (0)
+/** Special version of ComAssert that throws eval */
+#define ComAssertFailedThrow(eval) \
+ do { ComAssertFailed(); { throw (eval); } } while (0)
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Checks that the pointer argument is not NULL and returns E_INVALIDARG +
+ * extended error info on failure.
+ * @param arg Input pointer-type argument (strings, interface pointers...)
+ */
+#define CheckComArgNotNull(arg) \
+ do { \
+ if (RT_LIKELY((arg) != NULL)) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, VirtualBoxBase::tr("Argument %s is NULL"), #arg); \
+ } while (0)
+
+/**
+ * Checks that the pointer argument is a valid pointer or NULL and returns
+ * E_INVALIDARG + extended error info on failure.
+ * @param arg Input pointer-type argument (strings, interface pointers...)
+ */
+#define CheckComArgMaybeNull(arg) \
+ do { \
+ if (RT_LIKELY(RT_VALID_PTR(arg) || (arg) == NULL)) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, \
+ VirtualBoxBase::tr("Argument %s is an invalid pointer"), #arg); \
+ } while (0)
+
+/**
+ * Checks that the given pointer to an argument is valid and returns
+ * E_POINTER + extended error info otherwise.
+ * @param arg Pointer argument.
+ */
+#define CheckComArgPointerValid(arg) \
+ do { \
+ if (RT_LIKELY(RT_VALID_PTR(arg))) \
+ { /* likely */ }\
+ else \
+ return setError(E_POINTER, \
+ VirtualBoxBase::tr("Argument %s points to invalid memory location (%p)"), \
+ #arg, (void *)(arg)); \
+ } while (0)
+
+/**
+ * Checks that safe array argument is not NULL and returns E_INVALIDARG +
+ * extended error info on failure.
+ * @param arg Input safe array argument (strings, interface pointers...)
+ */
+#define CheckComArgSafeArrayNotNull(arg) \
+ do { \
+ if (RT_LIKELY(!ComSafeArrayInIsNull(arg))) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, \
+ VirtualBoxBase::tr("Argument %s is NULL"), #arg); \
+ } while (0)
+
+/**
+ * Checks that a string input argument is valid (not NULL or obviously invalid
+ * pointer), returning E_INVALIDARG + extended error info if invalid.
+ * @param a_bstrIn Input string argument (IN_BSTR).
+ */
+#define CheckComArgStr(a_bstrIn) \
+ do { \
+ IN_BSTR const bstrInCheck = (a_bstrIn); /* type check */ \
+ if (RT_LIKELY(RT_VALID_PTR(bstrInCheck))) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, \
+ VirtualBoxBase::tr("Argument %s is an invalid pointer"), #a_bstrIn); \
+ } while (0)
+/**
+ * Checks that the string argument is not a NULL, a invalid pointer or an empty
+ * string, returning E_INVALIDARG + extended error info on failure.
+ * @param a_bstrIn Input string argument (BSTR etc.).
+ */
+#define CheckComArgStrNotEmptyOrNull(a_bstrIn) \
+ do { \
+ IN_BSTR const bstrInCheck = (a_bstrIn); /* type check */ \
+ if (RT_LIKELY(RT_VALID_PTR(bstrInCheck) && *(bstrInCheck) != '\0')) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, \
+ VirtualBoxBase::tr("Argument %s is empty or an invalid pointer"), \
+ #a_bstrIn); \
+ } while (0)
+
+/**
+ * Converts the Guid input argument (string) to a Guid object, returns with
+ * E_INVALIDARG and error message on failure.
+ *
+ * @param a_Arg Argument.
+ * @param a_GuidVar The Guid variable name.
+ */
+#define CheckComArgGuid(a_Arg, a_GuidVar) \
+ do { \
+ Guid tmpGuid(a_Arg); \
+ (a_GuidVar) = tmpGuid; \
+ if (RT_LIKELY((a_GuidVar).isValid())) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, \
+ VirtualBoxBase::tr("GUID argument %s is not valid (\"%ls\")"), \
+ #a_Arg, Bstr(a_Arg).raw()); \
+ } while (0)
+
+/**
+ * Checks that the given expression (that must involve the argument) is true and
+ * returns E_INVALIDARG + extended error info on failure.
+ * @param arg Argument.
+ * @param expr Expression to evaluate.
+ */
+#define CheckComArgExpr(arg, expr) \
+ do { \
+ if (RT_LIKELY(!!(expr))) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, \
+ VirtualBoxBase::tr("Argument %s is invalid (must be %s)"), \
+ #arg, #expr); \
+ } while (0)
+
+/**
+ * Checks that the given expression (that must involve the argument) is true and
+ * returns E_INVALIDARG + extended error info on failure. The error message must
+ * be customized.
+ * @param arg Argument.
+ * @param expr Expression to evaluate.
+ * @param msg Parenthesized printf-like expression (must start with a verb,
+ * like "must be one of...", "is not within...").
+ */
+#define CheckComArgExprMsg(arg, expr, msg) \
+ do { \
+ if (RT_LIKELY(!!(expr))) \
+ { /* likely */ }\
+ else \
+ return setError(E_INVALIDARG, VirtualBoxBase::tr("Argument %s %s"), \
+ #arg, Utf8StrFmt msg .c_str()); \
+ } while (0)
+
+/**
+ * Checks that the given pointer to an output argument is valid and returns
+ * E_POINTER + extended error info otherwise.
+ * @param arg Pointer argument.
+ */
+#define CheckComArgOutPointerValid(arg) \
+ do { \
+ if (RT_LIKELY(RT_VALID_PTR(arg))) \
+ { /* likely */ }\
+ else \
+ return setError(E_POINTER, \
+ VirtualBoxBase::tr("Output argument %s points to invalid memory location (%p)"), \
+ #arg, (void *)(arg)); \
+ } while (0)
+
+/**
+ * Checks that the given pointer to an output safe array argument is valid and
+ * returns E_POINTER + extended error info otherwise.
+ * @param arg Safe array argument.
+ */
+#define CheckComArgOutSafeArrayPointerValid(arg) \
+ do { \
+ if (RT_LIKELY(!ComSafeArrayOutIsNull(arg))) \
+ { /* likely */ }\
+ else \
+ return setError(E_POINTER, \
+ VirtualBoxBase::tr("Output argument %s points to invalid memory location (%p)"), \
+ #arg, (void*)(arg)); \
+ } while (0)
+
+/**
+ * Sets the extended error info and returns E_NOTIMPL.
+ */
+#define ReturnComNotImplemented() \
+ do { \
+ return setError(E_NOTIMPL, VirtualBoxBase::tr("Method %s is not implemented"), __FUNCTION__); \
+ } while (0)
+
+/**
+ * Declares an empty constructor and destructor for the given class.
+ * This is useful to prevent the compiler from generating the default
+ * ctor and dtor, which in turn allows to use forward class statements
+ * (instead of including their header files) when declaring data members of
+ * non-fundamental types with constructors (which are always called implicitly
+ * by constructors and by the destructor of the class).
+ *
+ * This macro is to be placed within (the public section of) the class
+ * declaration. Its counterpart, DEFINE_EMPTY_CTOR_DTOR, must be placed
+ * somewhere in one of the translation units (usually .cpp source files).
+ *
+ * @param cls class to declare a ctor and dtor for
+ */
+#define DECLARE_EMPTY_CTOR_DTOR(cls) cls(); virtual ~cls();
+
+/**
+ * Defines an empty constructor and destructor for the given class.
+ * See DECLARE_EMPTY_CTOR_DTOR for more info.
+ */
+#define DEFINE_EMPTY_CTOR_DTOR(cls) \
+ cls::cls() { /*empty*/ } \
+ cls::~cls() { /*empty*/ }
+
+/**
+ * A variant of 'throw' that hits a debug breakpoint first to make
+ * finding the actual thrower possible.
+ */
+#ifdef DEBUG
+# define DebugBreakThrow(a) \
+ do { \
+ RTAssertDebugBreak(); \
+ throw (a); \
+ } while (0)
+#else
+# define DebugBreakThrow(a) throw (a)
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualBoxBase
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef VBOX_WITH_MAIN_NLS
+# define DECLARE_TRANSLATE_METHODS(cls) \
+ static inline const char *tr(const char *aSourceText, \
+ const char *aComment = NULL, \
+ const size_t aNum = ~(size_t)0) \
+ { \
+ return VirtualBoxTranslator::translate(NULL, #cls, aSourceText, aComment, aNum); \
+ }
+#else
+# define DECLARE_TRANSLATE_METHODS(cls) \
+ static inline const char *tr(const char *aSourceText, \
+ const char *aComment = NULL, \
+ const size_t aNum = ~(size_t)0) \
+ { \
+ RT_NOREF(aComment, aNum); \
+ return aSourceText; \
+ }
+#endif
+
+#define DECLARE_COMMON_CLASS_METHODS(cls) \
+ DECLARE_EMPTY_CTOR_DTOR(cls) \
+ DECLARE_TRANSLATE_METHODS(cls)
+
+#define VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) \
+ virtual const IID& getClassIID() const \
+ { \
+ return cls::getStaticClassIID(); \
+ } \
+ static const IID& getStaticClassIID() \
+ { \
+ return COM_IIDOF(iface); \
+ } \
+ virtual const char* getComponentName() const \
+ { \
+ return cls::getStaticComponentName(); \
+ } \
+ static const char* getStaticComponentName() \
+ { \
+ return #cls; \
+ }
+
+/**
+ * VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT:
+ * This macro must be used once in the declaration of any class derived
+ * from VirtualBoxBase. It implements the pure virtual getClassIID() and
+ * getComponentName() methods. If this macro is not present, instances
+ * of a class derived from VirtualBoxBase cannot be instantiated.
+ *
+ * @param cls The class name, e.g. "Class".
+ * @param iface The interface name which this class implements, e.g. "IClass".
+ */
+#ifdef VBOX_WITH_XPCOM
+ #define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(cls, iface) \
+ VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface)
+#else // !VBOX_WITH_XPCOM
+ #define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(cls, iface) \
+ VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) \
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) \
+ { \
+ const ATL::_ATL_INTMAP_ENTRY* pEntries = cls::_GetEntries(); \
+ Assert(pEntries); \
+ if (!pEntries) \
+ return S_FALSE; \
+ BOOL bSupports = FALSE; \
+ BOOL bISupportErrorInfoFound = FALSE; \
+ while (pEntries->pFunc != NULL && !bSupports) \
+ { \
+ if (!bISupportErrorInfoFound) \
+ bISupportErrorInfoFound = InlineIsEqualGUID(*(pEntries->piid), IID_ISupportErrorInfo); \
+ else \
+ bSupports = InlineIsEqualGUID(*(pEntries->piid), riid); \
+ pEntries++; \
+ } \
+ Assert(bISupportErrorInfoFound); \
+ return bSupports ? S_OK : S_FALSE; \
+ }
+#endif // !VBOX_WITH_XPCOM
+
+/**
+ * VBOX_TWEAK_INTERFACE_ENTRY:
+ * Macro for defining magic interface entries needed for all interfaces
+ * implemented by any subclass of VirtualBoxBase.
+ */
+#ifdef VBOX_WITH_XPCOM
+#define VBOX_TWEAK_INTERFACE_ENTRY(iface)
+#else // !VBOX_WITH_XPCOM
+#define VBOX_TWEAK_INTERFACE_ENTRY(iface) \
+ COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.m_p)
+#endif // !VBOX_WITH_XPCOM
+
+
+/**
+ * Abstract base class for all component classes implementing COM
+ * interfaces of the VirtualBox COM library.
+ *
+ * Declares functionality that should be available in all components.
+ *
+ * The object state logic is documented in ObjectState.h.
+ */
+class ATL_NO_VTABLE VirtualBoxBase
+ : public Lockable
+ , public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>
+#if !defined (VBOX_WITH_XPCOM)
+ , public ISupportErrorInfo
+#endif
+{
+protected:
+#ifdef RT_OS_WINDOWS
+ ComPtr<IUnknown> m_pUnkMarshaler;
+#endif
+
+ HRESULT BaseFinalConstruct();
+ void BaseFinalRelease();
+
+public:
+ DECLARE_COMMON_CLASS_METHODS(VirtualBoxBase)
+
+ /**
+ * Uninitialization method.
+ *
+ * Must be called by all final implementations (component classes) when the
+ * last reference to the object is released, before calling the destructor.
+ *
+ * @note Never call this method the AutoCaller scope or after the
+ * ObjectState::addCaller() call not paired by
+ * ObjectState::releaseCaller() because it is a guaranteed deadlock.
+ * See AutoUninitSpan and AutoCaller.h/ObjectState.h for details.
+ */
+ virtual void uninit()
+ { }
+
+ /**
+ */
+ ObjectState &getObjectState()
+ {
+ return mState;
+ }
+
+ /**
+ * Pure virtual method for simple run-time type identification without
+ * having to enable C++ RTTI.
+ *
+ * This *must* be implemented by every subclass deriving from VirtualBoxBase;
+ * use the VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT macro to do that most easily.
+ */
+ virtual const IID& getClassIID() const = 0;
+
+ /**
+ * Pure virtual method for simple run-time type identification without
+ * having to enable C++ RTTI.
+ *
+ * This *must* be implemented by every subclass deriving from VirtualBoxBase;
+ * use the VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT macro to do that most easily.
+ */
+ virtual const char* getComponentName() const = 0;
+
+ /**
+ * Virtual method which determines the locking class to be used for validating
+ * lock order with the standard member lock handle. This method is overridden
+ * in a number of subclasses.
+ */
+ virtual VBoxLockingClass getLockingClass() const
+ {
+ return LOCKCLASS_OTHEROBJECT;
+ }
+
+ virtual RWLockHandle *lockHandle() const;
+
+ static HRESULT handleUnexpectedExceptions(VirtualBoxBase *const aThis, RT_SRC_POS_DECL);
+
+ static HRESULT setErrorInternalF(HRESULT aResultCode,
+ const GUID &aIID,
+ const char *aComponent,
+ bool aWarning,
+ bool aLogIt,
+ LONG aResultDetail,
+ const char *aText, ...);
+ static HRESULT setErrorInternalV(HRESULT aResultCode,
+ const GUID &aIID,
+ const char *aComponent,
+ const char *aText,
+ va_list aArgs,
+ bool aWarning,
+ bool aLogIt,
+ LONG aResultDetail = 0);
+ static void clearError(void);
+
+ HRESULT setError(HRESULT aResultCode);
+ HRESULT setError(HRESULT aResultCode, const char *pcsz, ...);
+ HRESULT setError(const ErrorInfo &ei);
+ HRESULT setErrorVrcV(int vrc, const char *pcszMsgFmt, va_list va_args);
+ HRESULT setErrorVrc(int vrc);
+ HRESULT setErrorVrc(int vrc, const char *pcszMsgFmt, ...);
+ HRESULT setErrorBoth(HRESULT hrc, int vrc);
+ HRESULT setErrorBoth(HRESULT hrc, int vrc, const char *pcszMsgFmt, ...);
+ HRESULT setWarning(HRESULT aResultCode, const char *pcsz, ...);
+ HRESULT setErrorNoLog(HRESULT aResultCode, const char *pcsz, ...);
+
+
+ /** Initialize COM for a new thread. */
+ static HRESULT initializeComForThread(void)
+ {
+#ifndef VBOX_WITH_XPCOM
+ HRESULT hrc = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY);
+ AssertComRCReturn(hrc, hrc);
+#endif
+ return S_OK;
+ }
+
+ /** Uninitializes COM for a dying thread. */
+ static void uninitializeComForThread(void)
+ {
+#ifndef VBOX_WITH_XPCOM
+ CoUninitialize();
+#endif
+ }
+
+
+private:
+ /** Object for representing object state */
+ ObjectState mState;
+
+ /** User-level object lock for subclasses */
+ RWLockHandle *mObjectLock;
+
+ /** Slot of this object in the g_aClassFactoryStats array */
+ uint32_t iFactoryStat;
+
+private:
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(VirtualBoxBase); /* Shuts up MSC warning C4625. */
+};
+
+/** Structure for counting the currently existing and ever created objects
+ * for each component name. */
+typedef struct CLASSFACTORY_STAT
+{
+ const char *psz;
+ uint64_t current;
+ uint64_t overall;
+} CLASSFACTORY_STAT;
+
+/** Maximum number of component names to deal with. There will be debug
+ * assertions if the value is too low. Since the table is global and its
+ * entries are reasonably small, it's not worth squeezing out the last bit. */
+#define CLASSFACTORYSTATS_MAX 128
+
+/* global variables (defined in VirtualBoxBase.cpp) */
+extern CLASSFACTORY_STAT g_aClassFactoryStats[CLASSFACTORYSTATS_MAX];
+extern RWLockHandle *g_pClassFactoryStatsLock;
+
+extern void APIDumpComponentFactoryStats();
+
+/**
+ * Dummy macro that is used to shut down Qt's lupdate tool warnings in some
+ * situations. This macro needs to be present inside (better at the very
+ * beginning) of the declaration of the class that uses translation, to make
+ * lupdate happy.
+ */
+#define Q_OBJECT
+
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Simple template that manages data structure allocation/deallocation
+ * and supports data pointer sharing (the instance that shares the pointer is
+ * not responsible for memory deallocation as opposed to the instance that
+ * owns it).
+ */
+template <class D>
+class Shareable
+{
+public:
+
+ Shareable() : mData(NULL), mIsShared(FALSE) {}
+ virtual ~Shareable() { free(); }
+
+ void allocate() { attach(new D); }
+
+ virtual void free() {
+ if (mData) {
+ if (!mIsShared)
+ delete mData;
+ mData = NULL;
+ mIsShared = false;
+ }
+ }
+
+ void attach(D *d) {
+ AssertMsg(d, ("new data must not be NULL"));
+ if (d && mData != d) {
+ if (mData && !mIsShared)
+ delete mData;
+ mData = d;
+ mIsShared = false;
+ }
+ }
+
+ void attach(Shareable &d) {
+ AssertMsg(
+ d.mData == mData || !d.mIsShared,
+ ("new data must not be shared")
+ );
+ if (this != &d && !d.mIsShared) {
+ attach(d.mData);
+ d.mIsShared = true;
+ }
+ }
+
+ void share(D *d) {
+ AssertMsg(d, ("new data must not be NULL"));
+ if (mData != d) {
+ if (mData && !mIsShared)
+ delete mData;
+ mData = d;
+ mIsShared = true;
+ }
+ }
+
+ void share(const Shareable &d) { share(d.mData); }
+
+ void attachCopy(const D *d) {
+ AssertMsg(d, ("data to copy must not be NULL"));
+ if (d)
+ attach(new D(*d));
+ }
+
+ void attachCopy(const Shareable &d) {
+ attachCopy(d.mData);
+ }
+
+ virtual D *detach() {
+ D *d = mData;
+ mData = NULL;
+ mIsShared = false;
+ return d;
+ }
+
+ D *data() const {
+ return mData;
+ }
+
+ D *operator->() const {
+ AssertMsg(mData, ("data must not be NULL"));
+ return mData;
+ }
+
+ bool isNull() const { return mData == NULL; }
+ bool operator!() const { return isNull(); }
+
+ bool isShared() const { return mIsShared; }
+
+protected:
+
+ D *mData;
+ bool mIsShared;
+};
+
+/**
+ * Simple template that enhances Shareable<> and supports data
+ * backup/rollback/commit (using the copy constructor of the managed data
+ * structure).
+ */
+template<class D>
+class Backupable : public Shareable<D>
+{
+public:
+
+ Backupable() : Shareable<D>(), mBackupData(NULL) {}
+
+ void free()
+ {
+ AssertMsg(this->mData || !mBackupData, ("backup must be NULL if data is NULL"));
+ rollback();
+ Shareable<D>::free();
+ }
+
+ D *detach()
+ {
+ AssertMsg(this->mData || !mBackupData, ("backup must be NULL if data is NULL"));
+ rollback();
+ return Shareable<D>::detach();
+ }
+
+ void share(const Backupable &d)
+ {
+ AssertMsg(!d.isBackedUp(), ("data to share must not be backed up"));
+ if (!d.isBackedUp())
+ Shareable<D>::share(d.mData);
+ }
+
+ /**
+ * Stores the current data pointer in the backup area, allocates new data
+ * using the copy constructor on current data and makes new data active.
+ *
+ * @deprecated Use backupEx to avoid throwing wild out-of-memory exceptions.
+ */
+ void backup()
+ {
+ AssertMsg(this->mData, ("data must not be NULL"));
+ if (this->mData && !mBackupData)
+ {
+ D *pNewData = new D(*this->mData);
+ mBackupData = this->mData;
+ this->mData = pNewData;
+ }
+ }
+
+ /**
+ * Stores the current data pointer in the backup area, allocates new data
+ * using the copy constructor on current data and makes new data active.
+ *
+ * @returns S_OK, E_OUTOFMEMORY or E_FAIL (internal error).
+ */
+ HRESULT backupEx()
+ {
+ AssertMsgReturn(this->mData, ("data must not be NULL"), E_FAIL);
+ if (this->mData && !mBackupData)
+ {
+ try
+ {
+ D *pNewData = new D(*this->mData);
+ mBackupData = this->mData;
+ this->mData = pNewData;
+ }
+ catch (std::bad_alloc &)
+ {
+ return E_OUTOFMEMORY;
+ }
+ }
+ return S_OK;
+ }
+
+ /**
+ * Deletes new data created by #backup() and restores previous data pointer
+ * stored in the backup area, making it active again.
+ */
+ void rollback()
+ {
+ if (this->mData && mBackupData)
+ {
+ delete this->mData;
+ this->mData = mBackupData;
+ mBackupData = NULL;
+ }
+ }
+
+ /**
+ * Commits current changes by deleting backed up data and clearing up the
+ * backup area. The new data pointer created by #backup() remains active
+ * and becomes the only managed pointer.
+ *
+ * This method is much faster than #commitCopy() (just a single pointer
+ * assignment operation), but makes the previous data pointer invalid
+ * (because it is freed). For this reason, this method must not be
+ * used if it's possible that data managed by this instance is shared with
+ * some other Shareable instance. See #commitCopy().
+ */
+ void commit()
+ {
+ if (this->mData && mBackupData)
+ {
+ if (!this->mIsShared)
+ delete mBackupData;
+ mBackupData = NULL;
+ this->mIsShared = false;
+ }
+ }
+
+ /**
+ * Commits current changes by assigning new data to the previous data
+ * pointer stored in the backup area using the assignment operator.
+ * New data is deleted, the backup area is cleared and the previous data
+ * pointer becomes active and the only managed pointer.
+ *
+ * This method is slower than #commit(), but it keeps the previous data
+ * pointer valid (i.e. new data is copied to the same memory location).
+ * For that reason it's safe to use this method on instances that share
+ * managed data with other Shareable instances.
+ */
+ void commitCopy()
+ {
+ if (this->mData && mBackupData)
+ {
+ *mBackupData = *(this->mData);
+ delete this->mData;
+ this->mData = mBackupData;
+ mBackupData = NULL;
+ }
+ }
+
+ void assignCopy(const D *pData)
+ {
+ AssertMsg(this->mData, ("data must not be NULL"));
+ AssertMsg(pData, ("data to copy must not be NULL"));
+ if (this->mData && pData)
+ {
+ if (!mBackupData)
+ {
+ D *pNewData = new D(*pData);
+ mBackupData = this->mData;
+ this->mData = pNewData;
+ }
+ else
+ *this->mData = *pData;
+ }
+ }
+
+ void assignCopy(const Backupable &d)
+ {
+ assignCopy(d.mData);
+ }
+
+ bool isBackedUp() const
+ {
+ return mBackupData != NULL;
+ }
+
+ D *backedUpData() const
+ {
+ return mBackupData;
+ }
+
+protected:
+
+ D *mBackupData;
+};
+
+#endif /* !MAIN_INCLUDED_VirtualBoxBase_h */
+
diff --git a/src/VBox/Main/include/VirtualBoxClientImpl.h b/src/VBox/Main/include/VirtualBoxClientImpl.h
new file mode 100644
index 00000000..f7e40a69
--- /dev/null
+++ b/src/VBox/Main/include/VirtualBoxClientImpl.h
@@ -0,0 +1,144 @@
+/* $Id: VirtualBoxClientImpl.h $ */
+/** @file
+ * Header file for the VirtualBoxClient (IVirtualBoxClient) class, VBoxC.
+ */
+
+/*
+ * Copyright (C) 2010-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VirtualBoxClientImpl_h
+#define MAIN_INCLUDED_VirtualBoxClientImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxClientWrap.h"
+#include "EventImpl.h"
+#include "VirtualBoxTranslator.h"
+
+#ifdef RT_OS_WINDOWS
+# include "win/resource.h"
+#endif
+
+class ATL_NO_VTABLE VirtualBoxClient :
+ public VirtualBoxClientWrap
+#ifdef RT_OS_WINDOWS
+ , public ATL::CComCoClass<VirtualBoxClient, &CLSID_VirtualBoxClient>
+#endif
+{
+public:
+ DECLARE_CLASSFACTORY_SINGLETON(VirtualBoxClient)
+
+ // Do not use any ATL registry support.
+ //DECLARE_REGISTRY_RESOURCEID(IDR_VIRTUALBOX)
+
+ DECLARE_NOT_AGGREGATABLE(VirtualBoxClient)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init();
+ void uninit();
+
+#ifdef RT_OS_WINDOWS
+ /* HACK ALERT! Implemented in dllmain.cpp. */
+ ULONG InternalRelease();
+#endif
+
+private:
+ // wrapped IVirtualBoxClient properties
+ virtual HRESULT getVirtualBox(ComPtr<IVirtualBox> &aVirtualBox);
+ virtual HRESULT getSession(ComPtr<ISession> &aSession);
+ virtual HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+
+ // wrapped IVirtualBoxClient methods
+ virtual HRESULT checkMachineError(const ComPtr<IMachine> &aMachine);
+
+ /** Instance counter for simulating something similar to a singleton.
+ * Only the first instance will be a usable object, all additional
+ * instances will return a failure at creation time and will not work. */
+ static uint32_t g_cInstances;
+
+#ifdef RT_OS_WINDOWS
+ virtual HRESULT i_investigateVirtualBoxObjectCreationFailure(HRESULT hrc);
+#endif
+
+#ifdef VBOX_WITH_SDS
+ int i_getServiceAccountAndStartType(const wchar_t *pwszServiceName,
+ wchar_t *pwszAccountName, size_t cwcAccountName, uint32_t *puStartType);
+#endif
+
+ static DECLCALLBACK(int) SVCWatcherThread(RTTHREAD ThreadSelf, void *pvUser);
+
+ struct Data
+ {
+ Data()
+ : m_ThreadWatcher(NIL_RTTHREAD)
+ , m_SemEvWatcher(NIL_RTSEMEVENT)
+#ifdef VBOX_WITH_MAIN_NLS
+ , m_pVBoxTranslator(NULL)
+ , m_pTrComponent(NULL)
+#endif
+ {}
+
+ ~Data()
+ {
+ /* HACK ALERT! This is for DllCanUnloadNow(). */
+ if (m_pEventSource.isNotNull())
+ {
+ s_cUnnecessaryAtlModuleLocks--;
+ AssertMsg(s_cUnnecessaryAtlModuleLocks == 0, ("%d\n", s_cUnnecessaryAtlModuleLocks));
+ }
+ }
+
+ ComPtr<IVirtualBox> m_pVirtualBox;
+ ComPtr<IToken> m_pToken;
+ const ComObjPtr<EventSource> m_pEventSource;
+ ComPtr<IEventSource> m_pVBoxEventSource;
+ ComPtr<IEventListener> m_pVBoxEventListener;
+
+ RTTHREAD m_ThreadWatcher;
+ RTSEMEVENT m_SemEvWatcher;
+#ifdef VBOX_WITH_MAIN_NLS
+ VirtualBoxTranslator *m_pVBoxTranslator;
+ PTRCOMPONENT m_pTrComponent;
+#endif
+ };
+
+ Data mData;
+
+public:
+ /** Hack for discounting the AtlModule lock held by Data::m_pEventSource during
+ * DllCanUnloadNow(). This is incremented to 1 when init() initialized
+ * m_pEventSource and is decremented by the Data destructor (above). */
+ static LONG s_cUnnecessaryAtlModuleLocks;
+
+#ifdef VBOX_WITH_MAIN_NLS
+ HRESULT i_reloadApiLanguage();
+ HRESULT i_registerEventListener();
+ void i_unregisterEventListener();
+#endif
+};
+
+#endif /* !MAIN_INCLUDED_VirtualBoxClientImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h b/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h
new file mode 100644
index 00000000..6f6e9ef5
--- /dev/null
+++ b/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h
@@ -0,0 +1,175 @@
+/* $Id: VirtualBoxErrorInfoImpl.h $ */
+/** @file
+ * VirtualBoxErrorInfo COM class definition.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VirtualBoxErrorInfoImpl_h
+#define MAIN_INCLUDED_VirtualBoxErrorInfoImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+
+using namespace com;
+
+class ATL_NO_VTABLE VirtualBoxErrorInfo
+ : public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>
+ , VBOX_SCRIPTABLE_IMPL(IVirtualBoxErrorInfo)
+#ifndef VBOX_WITH_XPCOM /* IErrorInfo doesn't inherit from IDispatch, ugly 3am hack: */
+ , public IDispatch
+#endif
+{
+public:
+
+ DECLARE_NOT_AGGREGATABLE(VirtualBoxErrorInfo)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(VirtualBoxErrorInfo)
+ COM_INTERFACE_ENTRY(IErrorInfo)
+ COM_INTERFACE_ENTRY(IVirtualBoxErrorInfo)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler)
+ END_COM_MAP()
+
+ DECLARE_TRANSLATE_METHODS(VirtualBoxErrorInfo)
+
+ HRESULT FinalConstruct()
+ {
+#ifndef VBOX_WITH_XPCOM
+ return CoCreateFreeThreadedMarshaler((IUnknown *)(void *)this, &m_pUnkMarshaler);
+#else
+ return S_OK;
+#endif
+ }
+
+ void FinalRelease()
+ {
+#ifndef VBOX_WITH_XPCOM
+ if (m_pUnkMarshaler)
+ {
+ m_pUnkMarshaler->Release();
+ m_pUnkMarshaler = NULL;
+ }
+#endif
+ }
+
+#ifndef VBOX_WITH_XPCOM
+
+ HRESULT init(IErrorInfo *aInfo);
+
+ STDMETHOD(GetGUID)(GUID *guid);
+ STDMETHOD(GetSource)(BSTR *pBstrSource);
+ STDMETHOD(GetDescription)(BSTR *description);
+ STDMETHOD(GetHelpFile)(BSTR *pBstrHelpFile);
+ STDMETHOD(GetHelpContext)(DWORD *pdwHelpContext);
+
+ // IDispatch forwarding - 3am hack.
+ typedef IDispatchImpl<IVirtualBoxErrorInfo, &IID_IVirtualBoxErrorInfo, &LIBID_VirtualBox, kTypeLibraryMajorVersion, kTypeLibraryMinorVersion> idi;
+
+ STDMETHOD(GetTypeInfoCount)(UINT *pcInfo)
+ {
+ return idi::GetTypeInfoCount(pcInfo);
+ }
+
+ STDMETHOD(GetTypeInfo)(UINT iInfo, LCID Lcid, ITypeInfo **ppTypeInfo)
+ {
+ return idi::GetTypeInfo(iInfo, Lcid, ppTypeInfo);
+ }
+
+ STDMETHOD(GetIDsOfNames)(REFIID rIID, LPOLESTR *papwszNames, UINT cNames, LCID Lcid, DISPID *paDispIDs)
+ {
+ return idi::GetIDsOfNames(rIID, papwszNames, cNames, Lcid, paDispIDs);
+ }
+
+ STDMETHOD(Invoke)(DISPID idDispMember, REFIID rIID, LCID Lcid, WORD fw, DISPPARAMS *pDispParams,
+ VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *piErrArg)
+ {
+ return idi::Invoke(idDispMember, rIID, Lcid, fw, pDispParams, pVarResult, pExcepInfo, piErrArg);
+ }
+
+#else // defined(VBOX_WITH_XPCOM)
+
+ HRESULT init(nsIException *aInfo);
+
+ NS_DECL_NSIEXCEPTION
+
+#endif
+
+ VirtualBoxErrorInfo()
+ : m_resultCode(S_OK),
+ m_resultDetail(0)
+ {}
+ virtual ~VirtualBoxErrorInfo() {}
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init(HRESULT aResultCode,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const Utf8Str &strText,
+ IVirtualBoxErrorInfo *aNext = NULL);
+
+ HRESULT initEx(HRESULT aResultCode,
+ LONG aResultDetail,
+ const GUID &aIID,
+ const char *pcszComponent,
+ const Utf8Str &strText,
+ IVirtualBoxErrorInfo *aNext = NULL);
+
+ HRESULT init(const com::ErrorInfo &ei,
+ IVirtualBoxErrorInfo *aNext = NULL);
+
+ // IVirtualBoxErrorInfo properties
+ STDMETHOD(COMGETTER(ResultCode))(LONG *aResultCode);
+ STDMETHOD(COMGETTER(ResultDetail))(LONG *aResultDetail);
+ STDMETHOD(COMGETTER(InterfaceID))(BSTR *aIID);
+ STDMETHOD(COMGETTER(Component))(BSTR *aComponent);
+ STDMETHOD(COMGETTER(Text))(BSTR *aText);
+ STDMETHOD(COMGETTER(Next))(IVirtualBoxErrorInfo **aNext);
+
+ const char* getComponentName() const { return "VirtualBoxErrorInfo"; }
+
+private:
+ static HRESULT setError(HRESULT rc,
+ const char * /* a */,
+ const char * /* b */,
+ void * /* c */) { return rc; }
+
+ HRESULT m_resultCode;
+ LONG m_resultDetail;
+ Utf8Str m_strText;
+ Guid m_IID;
+ Utf8Str m_strComponent;
+ ComPtr<IVirtualBoxErrorInfo> mNext;
+
+#ifndef VBOX_WITH_XPCOM
+ IUnknown *m_pUnkMarshaler;
+#endif
+};
+
+#endif /* !MAIN_INCLUDED_VirtualBoxErrorInfoImpl_h */
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/VirtualBoxImpl.h b/src/VBox/Main/include/VirtualBoxImpl.h
new file mode 100644
index 00000000..e75f11f0
--- /dev/null
+++ b/src/VBox/Main/include/VirtualBoxImpl.h
@@ -0,0 +1,502 @@
+/* $Id: VirtualBoxImpl.h $ */
+/** @file
+ * VirtualBox COM class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VirtualBoxImpl_h
+#define MAIN_INCLUDED_VirtualBoxImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <VBox/VBoxCryptoIf.h>
+
+#include "VirtualBoxBase.h"
+#include "objectslist.h"
+#include "VirtualBoxWrap.h"
+
+#ifdef RT_OS_WINDOWS
+# include "win/resource.h"
+#endif
+
+//#ifdef DEBUG_bird
+//# define VBOXSVC_WITH_CLIENT_WATCHER
+//#endif
+
+namespace com
+{
+ class Event;
+ class EventQueue;
+}
+
+class SessionMachine;
+class GuestOSType;
+class Progress;
+class Host;
+class SystemProperties;
+class DHCPServer;
+class PerformanceCollector;
+class CloudProviderManager;
+#ifdef VBOX_WITH_EXTPACK
+class ExtPackManager;
+#endif
+class AutostartDb;
+class NATNetwork;
+#ifdef VBOX_WITH_CLOUD_NET
+class CloudNetwork;
+#endif /* VBOX_WITH_CLOUD_NET */
+
+
+typedef std::list<ComObjPtr<SessionMachine> > SessionMachinesList;
+
+#ifdef RT_OS_WINDOWS
+class SVCHlpClient;
+#endif
+
+namespace settings
+{
+ class MainConfigFile;
+ struct MediaRegistry;
+}
+
+
+#if defined(VBOX_WITH_SDS) && !defined(VBOX_WITH_XPCOM)
+class VirtualBoxClassFactory; /* See ../src-server/win/svcmain.cpp */
+#endif
+
+class ATL_NO_VTABLE VirtualBox :
+ public VirtualBoxWrap
+#ifdef RT_OS_WINDOWS
+ , public ATL::CComCoClass<VirtualBox, &CLSID_VirtualBox>
+#endif
+{
+
+public:
+
+ typedef std::list<ComPtr<IInternalSessionControl> > InternalControlList;
+ typedef ObjectsList<Machine> MachinesOList;
+
+#if 0 /* obsoleted by AsyncEvent */
+ class CallbackEvent;
+ friend class CallbackEvent;
+#endif
+ class AsyncEvent;
+ friend class AsyncEvent;
+
+#ifndef VBOX_WITH_XPCOM
+# ifdef VBOX_WITH_SDS
+ DECLARE_CLASSFACTORY_EX(VirtualBoxClassFactory)
+# else
+ DECLARE_CLASSFACTORY_SINGLETON(VirtualBox)
+# endif
+#endif
+
+ // Do not use any ATL registry support.
+ //DECLARE_REGISTRY_RESOURCEID(IDR_VIRTUALBOX)
+
+ // Kind of redundant (VirtualBoxWrap declares itself not aggregatable and
+ // CComCoClass<VirtualBox, &CLSID_VirtualBox> as aggregatable, the former
+ // is the first inheritance), but the C++ multiple inheritance rules and
+ // the class factory in svcmain.cpp needs this to disambiguate.
+ DECLARE_NOT_AGGREGATABLE(VirtualBox)
+
+ // to postpone generation of the default ctor/dtor
+ DECLARE_COMMON_CLASS_METHODS(VirtualBox)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+ // public initializer/uninitializer for internal purposes only
+ HRESULT init();
+ HRESULT initMachines();
+ HRESULT initMedia(const Guid &uuidMachineRegistry,
+ const settings::MediaRegistry &mediaRegistry,
+ const Utf8Str &strMachineFolder);
+ void uninit();
+
+ // public methods only for internal purposes
+
+ /**
+ * Override of the default locking class to be used for validating lock
+ * order with the standard member lock handle.
+ */
+ virtual VBoxLockingClass getLockingClass() const
+ {
+ return LOCKCLASS_VIRTUALBOXOBJECT;
+ }
+
+#ifdef DEBUG
+ void i_dumpAllBackRefs();
+#endif
+
+ HRESULT i_postEvent(Event *event);
+
+ HRESULT i_addProgress(IProgress *aProgress);
+ HRESULT i_removeProgress(IN_GUID aId);
+
+#ifdef RT_OS_WINDOWS
+ typedef HRESULT (*PFN_SVC_HELPER_CLIENT_T)(SVCHlpClient *aClient, Progress *aProgress, void *aUser, int *aVrc);
+ HRESULT i_startSVCHelperClient(bool aPrivileged,
+ PFN_SVC_HELPER_CLIENT_T aFunc,
+ void *aUser, Progress *aProgress);
+#endif
+
+ void i_addProcessToReap(RTPROCESS pid);
+ void i_updateClientWatcher();
+
+ int i_loadVDPlugin(const char *pszPluginLibrary);
+ int i_unloadVDPlugin(const char *pszPluginLibrary);
+
+ void i_onMediumRegistered(const Guid &aMediumId, const DeviceType_T aDevType, BOOL aRegistered);
+ void i_onMediumConfigChanged(IMedium *aMedium);
+ void i_onMediumChanged(IMediumAttachment* aMediumAttachment);
+ void i_onStorageControllerChanged(const Guid &aMachineId, const com::Utf8Str &aControllerName);
+ void i_onStorageDeviceChanged(IMediumAttachment* aStorageDevice, BOOL fRemoved, BOOL fSilent);
+ void i_onMachineStateChanged(const Guid &aId, MachineState_T aState);
+ void i_onMachineDataChanged(const Guid &aId, BOOL aTemporary = FALSE);
+ void i_onMachineGroupsChanged(const Guid &aId);
+ BOOL i_onExtraDataCanChange(const Guid &aId, const Utf8Str &aKey, const Utf8Str &aValue, Bstr &aError);
+ void i_onExtraDataChanged(const Guid &aId, const Utf8Str &aKey, const Utf8Str &aValue);
+ void i_onMachineRegistered(const Guid &aId, BOOL aRegistered);
+ void i_onSessionStateChanged(const Guid &aId, SessionState_T aState);
+
+ void i_onSnapshotTaken(const Guid &aMachineId, const Guid &aSnapshotId);
+ void i_onSnapshotDeleted(const Guid &aMachineId, const Guid &aSnapshotId);
+ void i_onSnapshotRestored(const Guid &aMachineId, const Guid &aSnapshotId);
+ void i_onSnapshotChanged(const Guid &aMachineId, const Guid &aSnapshotId);
+
+ void i_onGuestPropertyChanged(const Guid &aMachineId, const Utf8Str &aName, const Utf8Str &aValue, const Utf8Str &aFlags,
+ const BOOL fWasDeleted);
+ void i_onNatRedirectChanged(const Guid &aMachineId, ULONG ulSlot, bool fRemove, const Utf8Str &aName,
+ NATProtocol_T aProto, const Utf8Str &aHostIp, uint16_t aHostPort,
+ const Utf8Str &aGuestIp, uint16_t aGuestPort);
+ void i_onNATNetworkChanged(const Utf8Str &aNetworkName);
+ void i_onNATNetworkStartStop(const Utf8Str &aNetworkName, BOOL aStart);
+ void i_onNATNetworkSetting(const Utf8Str &aNetworkName, BOOL aEnabled, const Utf8Str &aNetwork,
+ const Utf8Str &aGateway, BOOL aAdvertiseDefaultIpv6RouteEnabled,
+ BOOL fNeedDhcpServer);
+ void i_onNATNetworkPortForward(const Utf8Str &aNetworkName, BOOL create, BOOL fIpv6,
+ const Utf8Str &aRuleName, NATProtocol_T proto,
+ const Utf8Str &aHostIp, LONG aHostPort,
+ const Utf8Str &aGuestIp, LONG aGuestPort);
+ void i_onHostNameResolutionConfigurationChange();
+
+ int i_natNetworkRefInc(const Utf8Str &aNetworkName);
+ int i_natNetworkRefDec(const Utf8Str &aNetworkName);
+
+ RWLockHandle *i_getNatNetLock() const;
+ bool i_isNatNetStarted(const Utf8Str &aNetworkName) const;
+
+ void i_onCloudProviderListChanged(BOOL aRegistered);
+ void i_onCloudProviderRegistered(const Utf8Str &aProviderId, BOOL aRegistered);
+ void i_onCloudProviderUninstall(const Utf8Str &aProviderId);
+
+ void i_onProgressCreated(const Guid &aId, BOOL aCreated);
+
+ void i_onLanguageChanged(const Utf8Str &aLanguageId);
+
+#ifdef VBOX_WITH_UPDATE_AGENT
+ void i_onUpdateAgentAvailable(IUpdateAgent *aAgent,
+ const Utf8Str &aVer, UpdateChannel_T aChannel, UpdateSeverity_T aSev,
+ const Utf8Str &aDownloadURL, const Utf8Str &aWebURL, const Utf8Str &aReleaseNotes);
+ void i_onUpdateAgentError(IUpdateAgent *aAgent, const Utf8Str &aErrMsg, LONG aRc);
+ void i_onUpdateAgentStateChanged(IUpdateAgent *aAgent, UpdateState_T aState);
+ void i_onUpdateAgentSettingsChanged(IUpdateAgent *aAgent, const Utf8Str &aAttributeHint);
+#endif /* VBOX_WITH_UPDATE_AGENT */
+
+#ifdef VBOX_WITH_CLOUD_NET
+ HRESULT i_findCloudNetworkByName(const com::Utf8Str &aNetworkName,
+ ComObjPtr<CloudNetwork> *aNetwork = NULL);
+ HRESULT i_getEventSource(ComPtr<IEventSource>& aSource);
+#endif /* VBOX_WITH_CLOUD_NET */
+
+ ComObjPtr<GuestOSType> i_getUnknownOSType();
+
+ void i_getOpenedMachines(SessionMachinesList &aMachines,
+ InternalControlList *aControls = NULL);
+ MachinesOList &i_getMachinesList();
+
+ HRESULT i_findMachine(const Guid &aId,
+ bool fPermitInaccessible,
+ bool aSetError,
+ ComObjPtr<Machine> *aMachine = NULL);
+
+ HRESULT i_findMachineByName(const Utf8Str &aName,
+ bool aSetError,
+ ComObjPtr<Machine> *aMachine = NULL);
+
+ HRESULT i_validateMachineGroup(const com::Utf8Str &aGroup, bool fPrimary);
+ HRESULT i_convertMachineGroups(const std::vector<com::Utf8Str> aMachineGroups, StringsList *pllMachineGroups);
+
+ HRESULT i_findHardDiskById(const Guid &id,
+ bool aSetError,
+ ComObjPtr<Medium> *aHardDisk = NULL);
+ HRESULT i_findHardDiskByLocation(const Utf8Str &strLocation,
+ bool aSetError,
+ ComObjPtr<Medium> *aHardDisk = NULL);
+ HRESULT i_findDVDOrFloppyImage(DeviceType_T mediumType,
+ const Guid *aId,
+ const Utf8Str &aLocation,
+ bool aSetError,
+ ComObjPtr<Medium> *aImage = NULL);
+ HRESULT i_findRemoveableMedium(DeviceType_T mediumType,
+ const Guid &uuid,
+ bool fRefresh,
+ bool aSetError,
+ ComObjPtr<Medium> &pMedium);
+
+ HRESULT i_findGuestOSType(const Utf8Str &strOSType,
+ ComObjPtr<GuestOSType> &guestOSType);
+
+ const Guid &i_getGlobalRegistryId() const;
+
+ const ComObjPtr<Host> &i_host() const;
+ SystemProperties *i_getSystemProperties() const;
+ CloudProviderManager *i_getCloudProviderManager() const;
+#ifdef VBOX_WITH_EXTPACK
+ ExtPackManager *i_getExtPackManager() const;
+#endif
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+ const ComObjPtr<PerformanceCollector> &i_performanceCollector() const;
+#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+
+ void i_getDefaultMachineFolder(Utf8Str &str) const;
+ void i_getDefaultHardDiskFormat(Utf8Str &str) const;
+
+ /** Returns the VirtualBox home directory */
+ const Utf8Str &i_homeDir() const;
+ int i_calculateFullPath(const Utf8Str &strPath, Utf8Str &aResult);
+ void i_copyPathRelativeToConfig(const Utf8Str &strSource, Utf8Str &strTarget);
+ HRESULT i_registerMedium(const ComObjPtr<Medium> &pMedium, ComObjPtr<Medium> *ppMedium,
+ AutoWriteLock &mediaTreeLock, bool fCalledFromMediumInit = false);
+ HRESULT i_unregisterMedium(Medium *pMedium);
+ HRESULT i_unregisterMachineMedia(const Guid &id);
+ HRESULT i_unregisterMachine(Machine *pMachine, CleanupMode_T aCleanupMode, const Guid &id);
+ void i_rememberMachineNameChangeForMedia(const Utf8Str &strOldConfigDir,
+ const Utf8Str &strNewConfigDir);
+ void i_saveMediaRegistry(settings::MediaRegistry &mediaRegistry,
+ const Guid &uuidRegistry,
+ const Utf8Str &strMachineFolder);
+ HRESULT i_saveSettings();
+ void i_markRegistryModified(const Guid &uuid);
+ void i_unmarkRegistryModified(const Guid &uuid);
+ void i_saveModifiedRegistries();
+ static const com::Utf8Str &i_getVersionNormalized();
+ static HRESULT i_ensureFilePathExists(const Utf8Str &strFileName, bool fCreate);
+ const Utf8Str& i_settingsFilePath();
+ AutostartDb* i_getAutostartDb() const;
+ RWLockHandle& i_getMachinesListLockHandle();
+ RWLockHandle& i_getMediaTreeLockHandle();
+ int i_encryptSetting(const Utf8Str &aPlaintext, Utf8Str *aCiphertext);
+ int i_decryptSetting(Utf8Str *aPlaintext, const Utf8Str &aCiphertext);
+ void i_storeSettingsKey(const Utf8Str &aKey);
+ bool i_isMediaUuidInUse(const Guid &aId, DeviceType_T deviceType);
+ HRESULT i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf);
+ HRESULT i_releaseCryptoIf(PCVBOXCRYPTOIF pCryptoIf);
+ HRESULT i_unloadCryptoIfModule(void);
+
+
+
+private:
+ class ClientWatcher;
+
+ // wrapped IVirtualBox properties
+ HRESULT getVersion(com::Utf8Str &aVersion);
+ HRESULT getVersionNormalized(com::Utf8Str &aVersionNormalized);
+ HRESULT getRevision(ULONG *aRevision);
+ HRESULT getPackageType(com::Utf8Str &aPackageType);
+ HRESULT getAPIVersion(com::Utf8Str &aAPIVersion);
+ HRESULT getAPIRevision(LONG64 *aAPIRevision);
+ HRESULT getHomeFolder(com::Utf8Str &aHomeFolder);
+ HRESULT getSettingsFilePath(com::Utf8Str &aSettingsFilePath);
+ HRESULT getHost(ComPtr<IHost> &aHost);
+ HRESULT getSystemProperties(ComPtr<ISystemProperties> &aSystemProperties);
+ HRESULT getMachines(std::vector<ComPtr<IMachine> > &aMachines);
+ HRESULT getMachineGroups(std::vector<com::Utf8Str> &aMachineGroups);
+ HRESULT getHardDisks(std::vector<ComPtr<IMedium> > &aHardDisks);
+ HRESULT getDVDImages(std::vector<ComPtr<IMedium> > &aDVDImages);
+ HRESULT getFloppyImages(std::vector<ComPtr<IMedium> > &aFloppyImages);
+ HRESULT getProgressOperations(std::vector<ComPtr<IProgress> > &aProgressOperations);
+ HRESULT getGuestOSTypes(std::vector<ComPtr<IGuestOSType> > &aGuestOSTypes);
+ HRESULT getSharedFolders(std::vector<ComPtr<ISharedFolder> > &aSharedFolders);
+ HRESULT getPerformanceCollector(ComPtr<IPerformanceCollector> &aPerformanceCollector);
+ HRESULT getDHCPServers(std::vector<ComPtr<IDHCPServer> > &aDHCPServers);
+ HRESULT getNATNetworks(std::vector<ComPtr<INATNetwork> > &aNATNetworks);
+ HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
+ HRESULT getExtensionPackManager(ComPtr<IExtPackManager> &aExtensionPackManager);
+ HRESULT getHostOnlyNetworks(std::vector<ComPtr<IHostOnlyNetwork> > &aHostOnlyNetworks);
+ HRESULT getInternalNetworks(std::vector<com::Utf8Str> &aInternalNetworks);
+ HRESULT getGenericNetworkDrivers(std::vector<com::Utf8Str> &aGenericNetworkDrivers);
+ HRESULT getCloudNetworks(std::vector<ComPtr<ICloudNetwork> > &aCloudNetworks);
+ HRESULT getCloudProviderManager(ComPtr<ICloudProviderManager> &aCloudProviderManager);
+
+ // wrapped IVirtualBox methods
+ HRESULT composeMachineFilename(const com::Utf8Str &aName,
+ const com::Utf8Str &aGroup,
+ const com::Utf8Str &aCreateFlags,
+ const com::Utf8Str &aBaseFolder,
+ com::Utf8Str &aFile);
+ HRESULT createMachine(const com::Utf8Str &aSettingsFile,
+ const com::Utf8Str &aName,
+ const std::vector<com::Utf8Str> &aGroups,
+ const com::Utf8Str &aOsTypeId,
+ const com::Utf8Str &aFlags,
+ const com::Utf8Str &aCipher,
+ const com::Utf8Str &aPasswordId,
+ const com::Utf8Str &aPassword,
+ ComPtr<IMachine> &aMachine);
+ HRESULT openMachine(const com::Utf8Str &aSettingsFile,
+ const com::Utf8Str &aPassword,
+ ComPtr<IMachine> &aMachine);
+ HRESULT registerMachine(const ComPtr<IMachine> &aMachine);
+ HRESULT findMachine(const com::Utf8Str &aNameOrId,
+ ComPtr<IMachine> &aMachine);
+ HRESULT getMachinesByGroups(const std::vector<com::Utf8Str> &aGroups,
+ std::vector<ComPtr<IMachine> > &aMachines);
+ HRESULT getMachineStates(const std::vector<ComPtr<IMachine> > &aMachines,
+ std::vector<MachineState_T> &aStates);
+ HRESULT createAppliance(ComPtr<IAppliance> &aAppliance);
+ HRESULT createUnattendedInstaller(ComPtr<IUnattended> &aUnattended);
+ HRESULT createMedium(const com::Utf8Str &aFormat,
+ const com::Utf8Str &aLocation,
+ AccessMode_T aAccessMode,
+ DeviceType_T aDeviceType,
+ ComPtr<IMedium> &aMedium);
+ HRESULT openMedium(const com::Utf8Str &aLocation,
+ DeviceType_T aDeviceType,
+ AccessMode_T aAccessMode,
+ BOOL aForceNewUuid,
+ ComPtr<IMedium> &aMedium);
+ HRESULT getGuestOSType(const com::Utf8Str &aId,
+ ComPtr<IGuestOSType> &aType);
+ HRESULT createSharedFolder(const com::Utf8Str &aName,
+ const com::Utf8Str &aHostPath,
+ BOOL aWritable,
+ BOOL aAutomount,
+ const com::Utf8Str &aAutoMountPoint);
+ HRESULT removeSharedFolder(const com::Utf8Str &aName);
+ HRESULT getExtraDataKeys(std::vector<com::Utf8Str> &aKeys);
+ HRESULT getExtraData(const com::Utf8Str &aKey,
+ com::Utf8Str &aValue);
+ HRESULT setExtraData(const com::Utf8Str &aKey,
+ const com::Utf8Str &aValue);
+ HRESULT setSettingsSecret(const com::Utf8Str &aPassword);
+ HRESULT createDHCPServer(const com::Utf8Str &aName,
+ ComPtr<IDHCPServer> &aServer);
+ HRESULT findDHCPServerByNetworkName(const com::Utf8Str &aName,
+ ComPtr<IDHCPServer> &aServer);
+ HRESULT removeDHCPServer(const ComPtr<IDHCPServer> &aServer);
+ HRESULT createNATNetwork(const com::Utf8Str &aNetworkName,
+ ComPtr<INATNetwork> &aNetwork);
+ HRESULT findNATNetworkByName(const com::Utf8Str &aNetworkName,
+ ComPtr<INATNetwork> &aNetwork);
+ HRESULT removeNATNetwork(const ComPtr<INATNetwork> &aNetwork);
+ HRESULT createHostOnlyNetwork(const com::Utf8Str &aNetworkName,
+ ComPtr<IHostOnlyNetwork> &aNetwork);
+ HRESULT findHostOnlyNetworkByName(const com::Utf8Str &aNetworkName,
+ ComPtr<IHostOnlyNetwork> &aNetwork);
+ HRESULT findHostOnlyNetworkById(const com::Guid &aId,
+ ComPtr<IHostOnlyNetwork> &aNetwork);
+ HRESULT removeHostOnlyNetwork(const ComPtr<IHostOnlyNetwork> &aNetwork);
+ HRESULT createCloudNetwork(const com::Utf8Str &aNetworkName,
+ ComPtr<ICloudNetwork> &aNetwork);
+ HRESULT findCloudNetworkByName(const com::Utf8Str &aNetworkName,
+ ComPtr<ICloudNetwork> &aNetwork);
+ HRESULT removeCloudNetwork(const ComPtr<ICloudNetwork> &aNetwork);
+ HRESULT checkFirmwarePresent(FirmwareType_T aFirmwareType,
+ const com::Utf8Str &aVersion,
+ com::Utf8Str &aUrl,
+ com::Utf8Str &aFile,
+ BOOL *aResult);
+ HRESULT findProgressById(const com::Guid &aId,
+ ComPtr<IProgress> &aProgressObject);
+
+ static HRESULT i_setErrorStaticBoth(HRESULT aResultCode, int vrc, const char *aText, ...)
+ {
+ va_list va;
+ va_start (va, aText);
+ HRESULT hrc = setErrorInternalV(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, va, false, true, vrc);
+ va_end(va);
+ return hrc;
+ }
+
+ HRESULT i_registerMachine(Machine *aMachine);
+ HRESULT i_registerDHCPServer(DHCPServer *aDHCPServer,
+ bool aSaveRegistry = true);
+ HRESULT i_unregisterDHCPServer(DHCPServer *aDHCPServer);
+ HRESULT i_registerNATNetwork(NATNetwork *aNATNetwork,
+ bool aSaveRegistry = true);
+ HRESULT i_unregisterNATNetwork(NATNetwork *aNATNetwork,
+ bool aSaveRegistry = true);
+ HRESULT i_checkMediaForConflicts(const Guid &aId,
+ const Utf8Str &aLocation,
+ Utf8Str &aConflictType,
+ ComObjPtr<Medium> *pDupMedium);
+ int i_decryptSettings();
+ int i_decryptMediumSettings(Medium *pMedium);
+ int i_decryptSettingBytes(uint8_t *aPlaintext,
+ const uint8_t *aCiphertext,
+ size_t aCiphertextSize) const;
+ int i_encryptSettingBytes(const uint8_t *aPlaintext,
+ uint8_t *aCiphertext,
+ size_t aPlaintextSize,
+ size_t aCiphertextSize) const;
+ void i_reportDriverVersions(void);
+
+ struct Data; // opaque data structure, defined in VirtualBoxImpl.cpp
+
+ Data *m;
+
+ /* static variables (defined in VirtualBoxImpl.cpp) */
+ static com::Utf8Str sVersion;
+ static com::Utf8Str sVersionNormalized;
+ static ULONG sRevision;
+ static com::Utf8Str sPackageType;
+ static com::Utf8Str sAPIVersion;
+ static std::map<com::Utf8Str, int> sNatNetworkNameToRefCount;
+ static RWLockHandle* spMtxNatNetworkNameToRefCountLock;
+
+ static DECLCALLBACK(int) AsyncEventHandler(RTTHREAD thread, void *pvUser);
+
+#ifdef RT_OS_WINDOWS
+ friend class StartSVCHelperClientData;
+ static void i_SVCHelperClientThreadTask(StartSVCHelperClientData *pTask);
+#endif
+
+#if defined(RT_OS_WINDOWS) && defined(VBOXSVC_WITH_CLIENT_WATCHER)
+protected:
+ void i_callHook(const char *a_pszFunction) RT_OVERRIDE;
+ bool i_watchClientProcess(RTPROCESS a_pidClient, const char *a_pszFunction);
+public:
+ static void i_logCaller(const char *a_pszFormat, ...);
+private:
+
+#endif
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+#endif /* !MAIN_INCLUDED_VirtualBoxImpl_h */
+
diff --git a/src/VBox/Main/include/VirtualBoxSDSImpl.h b/src/VBox/Main/include/VirtualBoxSDSImpl.h
new file mode 100644
index 00000000..0b5c2ad9
--- /dev/null
+++ b/src/VBox/Main/include/VirtualBoxSDSImpl.h
@@ -0,0 +1,161 @@
+/* $Id: VirtualBoxSDSImpl.h $ */
+/** @file
+ * VBox Global COM Class definition
+ */
+
+/*
+ * Copyright (C) 2017-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VirtualBoxSDSImpl_h
+#define MAIN_INCLUDED_VirtualBoxSDSImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "VirtualBoxBase.h"
+
+/* Enable the watcher code in debug builds. */
+#ifdef DEBUG
+# define WITH_WATCHER
+#endif
+
+
+class VBoxSDSPerUserData; /* See VirtualBoxSDSImpl.cpp. */
+struct VBoxSDSWatcher; /* See VirtualBoxSDSImpl.cpp. */
+
+/**
+ * The IVirtualBoxSDS implementation.
+ *
+ * This class helps different VBoxSVC processes make sure a user only have a
+ * single VirtualBox instance.
+ *
+ * @note This is a simple internal class living in a privileged process. So, we
+ * do not use the API wrappers as they add complexity. In particular,
+ * they add the auto caller logic, which is an excellent tool to create
+ * unkillable processes. If an API method during development or product
+ * for instance triggers an NT exception like STATUS_ACCESS_VIOLATION, the
+ * caller will be unwound without releasing the caller. When uninit is
+ * called during COM shutdown/whatever, the thread gets stuck waiting for
+ * the long gone caller and cannot be killed (Windows 10, build 16299),
+ * requiring a reboot to continue.
+ *
+ * @todo Would be very nice to get rid of the ATL cruft too here.
+ */
+class VirtualBoxSDS
+ : public IVirtualBoxSDS
+ , public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>
+ , public ATL::CComCoClass<VirtualBoxSDS, &CLSID_VirtualBoxSDS>
+{
+private:
+ typedef std::map<com::Utf8Str, VBoxSDSPerUserData *> UserDataMap_T;
+ /** Per user data map (key is SID string).
+ * This is an insert-only map! */
+ UserDataMap_T m_UserDataMap;
+ /** Number of registered+watched VBoxSVC processes. */
+ uint32_t m_cVBoxSvcProcesses;
+#ifdef WITH_WATCHER
+ /** Number of watcher threads. */
+ uint32_t m_cWatchers;
+ /** Pointer to an array of watcher pointers. */
+ VBoxSDSWatcher **m_papWatchers;
+ /** Lock protecting m_papWatchers and associated structures. */
+ RTCRITSECT m_WatcherCritSect;
+#endif
+ /** Lock protecting m_UserDataMap . */
+ RTCRITSECTRW m_MapCritSect;
+
+public:
+ DECLARE_CLASSFACTORY_SINGLETON(VirtualBoxSDS)
+ DECLARE_NOT_AGGREGATABLE(VirtualBoxSDS)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(VirtualBoxSDS)
+ COM_INTERFACE_ENTRY(IVirtualBoxSDS)
+ END_COM_MAP()
+
+ DECLARE_COMMON_CLASS_METHODS(VirtualBoxSDS)
+
+ HRESULT FinalConstruct();
+ void FinalRelease();
+
+private:
+
+ /** @name IVirtualBoxSDS methods
+ * @{ */
+ STDMETHOD(RegisterVBoxSVC)(IVBoxSVCRegistration *aVBoxSVC, LONG aPid, IUnknown **aExistingVirtualBox);
+ STDMETHOD(DeregisterVBoxSVC)(IVBoxSVCRegistration *aVBoxSVC, LONG aPid);
+ STDMETHOD(LaunchVMProcess)(IN_BSTR aMachine, IN_BSTR aComment, IN_BSTR aFrontend,
+ ComSafeArrayIn(IN_BSTR, aEnvironmentChanges), IN_BSTR aCmdOptions,
+ ULONG aSessionId, ULONG *aPid);
+ /** @} */
+
+
+ /** @name Private methods
+ * @{ */
+ /**
+ * Gets the client user SID of the
+ */
+ static bool i_getClientUserSid(com::Utf8Str *a_pStrSid, com::Utf8Str *a_pStrUsername);
+
+ /**
+ * Returns whether a VBoxSDS feature is enabled or not.
+ *
+ * @returns \c true if enabled, \c false if not.
+ * @param a_pwszFeature Feature to check enabled status for.
+ */
+ static bool i_isFeatureEnabled(wchar_t const *a_pwszFeature);
+
+ /**
+ * Looks up the given user.
+ *
+ * @returns Pointer to the LOCKED per user data. NULL if not found.
+ * @param a_rStrUserSid The user SID.
+ */
+ VBoxSDSPerUserData *i_lookupPerUserData(com::Utf8Str const &a_rStrUserSid);
+
+ /**
+ * Looks up the given user, creating it if not found
+ *
+ * @returns Pointer to the LOCKED per user data. NULL on allocation error.
+ * @param a_rStrUserSid The user SID.
+ * @param a_rStrUsername The user name if available.
+ */
+ VBoxSDSPerUserData *i_lookupOrCreatePerUserData(com::Utf8Str const &a_rStrUserSid, com::Utf8Str const &a_rStrUsername);
+
+#ifdef WITH_WATCHER
+ static DECLCALLBACK(int) i_watcherThreadProc(RTTHREAD hSelf, void *pvUser);
+ bool i_watchIt(VBoxSDSPerUserData *pProcess, HANDLE hProcess, RTPROCESS pid);
+ void i_stopWatching(VBoxSDSPerUserData *pProcess, RTPROCESS pid);
+ void i_shutdownAllWatchers(void);
+
+ void i_decrementClientCount();
+ void i_incrementClientCount();
+#endif
+ /** @} */
+};
+
+#ifdef WITH_WATCHER
+void VBoxSDSNotifyClientCount(uint32_t cClients);
+#endif
+
+#endif /* !MAIN_INCLUDED_VirtualBoxSDSImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/VirtualBoxTranslator.h b/src/VBox/Main/include/VirtualBoxTranslator.h
new file mode 100644
index 00000000..ef87ff4e
--- /dev/null
+++ b/src/VBox/Main/include/VirtualBoxTranslator.h
@@ -0,0 +1,165 @@
+/* $Id: VirtualBoxTranslator.h $ */
+/** @file
+ * VirtualBox Translator.
+ */
+
+/*
+ * Copyright (C) 2005-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_VirtualBoxTranslator_h
+#define MAIN_INCLUDED_VirtualBoxTranslator_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <list>
+
+#include <iprt/cpp/lock.h>
+#include <VBox/com/AutoLock.h>
+
+COM_STRUCT_OR_CLASS(IVirtualBox);
+class QMTranslator;
+
+class VirtualBoxTranslator
+ : public util::RWLockHandle
+{
+public:
+ virtual ~VirtualBoxTranslator();
+
+ static VirtualBoxTranslator *instance();
+ /* Returns instance if exists, returns NULL otherwise. */
+ static VirtualBoxTranslator *tryInstance() RT_NOEXCEPT;
+ void release();
+
+ /* Load language based on settings in the VirtualBox config */
+ HRESULT loadLanguage(ComPtr<IVirtualBox> aVirtualBox);
+
+private:
+ /** Translator component. */
+ struct TranslatorComponent
+ {
+ QMTranslator *pTranslator;
+ /** Path to translation files. It includes file prefix, i.e '/path/to/folder/file_prefix'. */
+ com::Utf8Str strPath;
+
+ TranslatorComponent() : pTranslator(NULL) {}
+ };
+public:
+ /** Pointer to a translator component. */
+ typedef TranslatorComponent *PTRCOMPONENT;
+
+ /**
+ * Registers the translation for a component.
+ *
+ * @returns VBox status code
+ * @param aTranslationPath Path to the translation files, this includes the
+ * base filename prefix.
+ * @param aDefault Use this as the default translation component, i.e.
+ * when translate() is called with NULL for @a
+ * aComponent.
+ * @param aComponent Pointer to where is the component handle should be
+ * returned on success. The return value must be used
+ * for all subsequent calls to translate().
+ */
+ static int registerTranslation(const char *aTranslationPath,
+ bool aDefault,
+ PTRCOMPONENT *aComponent);
+
+ /**
+ * Removes translations for a component.
+ *
+ * @returns VBox status code
+ * @param aComponent The component. NULL is quietly (VWRN_NOT_FOUND)
+ * ignored .
+ */
+ static int unregisterTranslation(PTRCOMPONENT aComponent);
+
+ /**
+ * Translates @a aSourceText to user language.
+ * Uses component marked as default if @a aTranslationComponent is NULL
+ *
+ * @returns Translated string or @a aSourceText. The returned string is
+ * valid only during lifetime of the translator instance.
+ */
+ static const char *translate(PTRCOMPONENT aComponent,
+ const char *aContext,
+ const char *aSourceText,
+ const char *aComment = NULL,
+ const size_t aNum = ~(size_t)0) RT_NOEXCEPT;
+
+ /**
+ * Returns source text stored in the cache if exists.
+ * Otherwise, the pszTranslation itself returned.
+ */
+ static const char *trSource(const char *aTranslation) RT_NOEXCEPT;
+
+ /* Convenience function used by VirtualBox::init */
+ int i_loadLanguage(const char *pszLang);
+
+ static int32_t initCritSect();
+
+ com::Utf8Str language();
+
+private:
+ static RTCRITSECTRW s_instanceRwLock;
+ static VirtualBoxTranslator *s_pInstance;
+
+ uint32_t m_cInstanceRefs;
+
+ typedef std::list<TranslatorComponent> TranslatorList;
+ TranslatorList m_lTranslators;
+ TranslatorComponent *m_pDefaultComponent;
+
+ /* keep the language code for registration */
+ com::Utf8Str m_strLanguage;
+
+ /** String cache that all translation strings are stored in.
+ * This is a add-only cache, which allows translate() to return C-strings w/o
+ * needing to think about racing loadLanguage() wrt string lifetime. */
+ RTSTRCACHE m_hStrCache;
+ /** RTStrCacheCreate status code. */
+ int m_rcCache;
+
+ VirtualBoxTranslator();
+
+ int i_loadLanguageForComponent(TranslatorComponent *aComponent, const char *aLang);
+
+ int i_setLanguageFile(TranslatorComponent *aComponent, const char *aFileName);
+
+ int i_registerTranslation(const char *aTranslationPath,
+ bool aDefault,
+ PTRCOMPONENT *aComponent);
+
+ int i_unregisterTranslation(PTRCOMPONENT aComponent);
+
+ const char *i_translate(PTRCOMPONENT aComponent,
+ const char *aContext,
+ const char *aSourceText,
+ const char *aComment = NULL,
+ const size_t aNum = ~(size_t)0) RT_NOEXCEPT;
+};
+
+/** Pointer to a translator component. */
+typedef VirtualBoxTranslator::PTRCOMPONENT PTRCOMPONENT;
+
+#endif /* !MAIN_INCLUDED_VirtualBoxTranslator_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/WebMWriter.h b/src/VBox/Main/include/WebMWriter.h
new file mode 100644
index 00000000..67d4b128
--- /dev/null
+++ b/src/VBox/Main/include/WebMWriter.h
@@ -0,0 +1,579 @@
+/* $Id: WebMWriter.h $ */
+/** @file
+ * WebMWriter.h - WebM container handling.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_WebMWriter_h
+#define MAIN_INCLUDED_WebMWriter_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/buildconfig.h>
+#include <iprt/mem.h>
+#include <iprt/rand.h>
+#include <iprt/string.h>
+
+#include "VBox/com/VirtualBox.h"
+#include <VBox/version.h>
+
+#include "EBMLWriter.h"
+#include "EBML_MKV.h"
+
+#include <queue>
+#include <map>
+#include <list>
+
+#ifdef VBOX_WITH_LIBVPX
+# ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4668) /* vpx_codec.h(64) : warning C4668: '__GNUC__' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */
+# include <vpx/vpx_encoder.h>
+# pragma warning(pop)
+# else
+# include <vpx/vpx_encoder.h>
+# endif
+#endif /* VBOX_WITH_LIBVPX */
+
+/** No flags specified. */
+#define VBOX_WEBM_BLOCK_FLAG_NONE 0
+/** Invisible block which can be skipped. */
+#define VBOX_WEBM_BLOCK_FLAG_INVISIBLE 0x08
+/** The block marks a key frame. */
+#define VBOX_WEBM_BLOCK_FLAG_KEY_FRAME 0x80
+
+/** The default timecode scale factor for WebM -- all timecodes in the segments are expressed in ms.
+ * This allows every cluster to have blocks with positive values up to 32.767 seconds. */
+#define VBOX_WEBM_TIMECODESCALE_FACTOR_MS 1000000
+
+/** Maximum time (in ms) a cluster can store. */
+#define VBOX_WEBM_CLUSTER_MAX_LEN_MS INT16_MAX
+
+/** Maximum time a block can store.
+ * With signed 16-bit timecodes and a default timecode scale of 1ms per unit this makes 65536ms. */
+#define VBOX_WEBM_BLOCK_MAX_LEN_MS UINT16_MAX
+
+#ifdef VBOX_WITH_LIBVORBIS
+# pragma pack(push)
+# pragma pack(1)
+ /** Ogg Vorbis codec private data within the MKV (WEBM) container.
+ * Taken from: https://www.matroska.org/technical/codec_specs.html */
+ typedef struct WEBMOGGVORBISPRIVDATA
+ {
+ WEBMOGGVORBISPRIVDATA(uint32_t a_cbHdrIdent, uint32_t a_cbHdrComments, uint32_t a_cbHdrSetup)
+ : cbHdrIdent(a_cbHdrIdent)
+ , cbHdrComments(a_cbHdrComments)
+ {
+ RT_NOREF(a_cbHdrSetup);
+
+ /* We supply 3 headers total: The "real" header, comments header + setup header. */
+ cHeaders = 3 /* Headers */ - 1; /* Note: Always "minus one" here. */
+
+ Assert(a_cbHdrIdent <= UINT8_MAX);
+ Assert(a_cbHdrComments <= UINT8_MAX);
+ Assert(a_cbHdrSetup <= _8K);
+ Assert(a_cbHdrIdent + a_cbHdrComments + a_cbHdrSetup <= sizeof(abHdr));
+ }
+
+ /** Number of private headers - 1. */
+ uint8_t cHeaders;
+ /** Size of identification header (in bytes). */
+ uint8_t cbHdrIdent;
+ /** < Size of comments header (in bytes). */
+ uint8_t cbHdrComments;
+ /** < Header code area. */
+ uint8_t abHdr[UINT8_MAX /* Header */ + UINT8_MAX /* Comments header */ + _8K /* Setup header */];
+
+ } WEBMOGGVORBISPRIVDATA, *PWEBMOGGVORBISPRIVDATA;
+# pragma pack(pop)
+#endif
+
+class WebMWriter : public EBMLWriter
+{
+
+public:
+
+ /** Defines an absolute WebM timecode (Block + Cluster). */
+ typedef uint64_t WebMTimecodeAbs;
+
+ /** Defines a relative WebM timecode (Block). */
+ typedef uint16_t WebMTimecodeRel;
+
+ /** Defines the WebM block flags data type. */
+ typedef uint8_t WebMBlockFlags;
+
+ /**
+ * Track type enumeration.
+ */
+ enum WebMTrackType
+ {
+ /** Unknown / invalid type. */
+ WebMTrackType_Invalid = 0,
+ /** Only writes audio. */
+ WebMTrackType_Audio = 1,
+ /** Only writes video. */
+ WebMTrackType_Video = 2
+ };
+
+ struct WebMTrack;
+
+ /**
+ * Structure for defining a WebM simple block.
+ */
+ struct WebMSimpleBlock
+ {
+ WebMSimpleBlock(WebMTrack *a_pTrack,
+ WebMTimecodeAbs a_tcAbsPTSMs, const void *a_pvData, size_t a_cbData, WebMBlockFlags a_fFlags)
+ : pTrack(a_pTrack)
+ {
+ Data.tcAbsPTSMs = a_tcAbsPTSMs;
+ Data.cb = a_cbData;
+ Data.fFlags = a_fFlags;
+
+ if (Data.cb)
+ {
+ Data.pv = RTMemDup(a_pvData, a_cbData);
+ if (!Data.pv)
+ throw;
+ }
+ }
+
+ virtual ~WebMSimpleBlock()
+ {
+ if (Data.pv)
+ {
+ Assert(Data.cb);
+ RTMemFree(Data.pv);
+ }
+ }
+
+ WebMTrack *pTrack;
+
+ /** Actual simple block data. */
+ struct
+ {
+ WebMTimecodeAbs tcAbsPTSMs;
+ WebMTimecodeRel tcRelToClusterMs;
+ void *pv;
+ size_t cb;
+ WebMBlockFlags fFlags;
+ } Data;
+ };
+
+ /** A simple block queue.*/
+ typedef std::queue<WebMSimpleBlock *> WebMSimpleBlockQueue;
+
+ /** Structure for queuing all simple blocks bound to a single timecode.
+ * This can happen if multiple tracks are being involved. */
+ struct WebMTimecodeBlocks
+ {
+ WebMTimecodeBlocks(void)
+ : fClusterNeeded(false)
+ , fClusterStarted(false) { }
+
+ /** The actual block queue for this timecode. */
+ WebMSimpleBlockQueue Queue;
+ /** Whether a new cluster is needed for this timecode or not. */
+ bool fClusterNeeded;
+ /** Whether a new cluster already has been started for this timecode or not. */
+ bool fClusterStarted;
+
+ /**
+ * Enqueues a simple block into the internal queue.
+ *
+ * @param a_pBlock Block to enqueue and take ownership of.
+ */
+ void Enqueue(WebMSimpleBlock *a_pBlock)
+ {
+ Queue.push(a_pBlock);
+
+ if (a_pBlock->Data.fFlags & VBOX_WEBM_BLOCK_FLAG_KEY_FRAME)
+ fClusterNeeded = true;
+ }
+ };
+
+ /** A block map containing all currently queued blocks.
+ * The key specifies a unique timecode, whereas the value
+ * is a queue of blocks which all correlate to the key (timecode). */
+ typedef std::map<WebMTimecodeAbs, WebMTimecodeBlocks> WebMBlockMap;
+
+ /**
+ * Structure for defining a WebM (encoding) queue.
+ */
+ struct WebMQueue
+ {
+ WebMQueue(void)
+ : tcAbsLastBlockWrittenMs(0)
+ , tsLastProcessedMs(0) { }
+
+ /** Blocks as FIFO (queue). */
+ WebMBlockMap Map;
+ /** Absolute timecode (in ms) of last written block to queue. */
+ WebMTimecodeAbs tcAbsLastBlockWrittenMs;
+ /** Time stamp (in ms) of when the queue was processed last. */
+ uint64_t tsLastProcessedMs;
+ };
+
+ /**
+ * Structure for keeping a WebM track entry.
+ */
+ struct WebMTrack
+ {
+ WebMTrack(WebMTrackType a_enmType, PRECORDINGCODEC pTheCodec, uint8_t a_uTrack, uint64_t a_offID)
+ : enmType(a_enmType)
+ , pCodec(pTheCodec)
+ , uTrack(a_uTrack)
+ , offUUID(a_offID)
+ , cTotalBlocks(0)
+ , tcAbsLastWrittenMs(0)
+ {
+ uUUID = RTRandU32();
+ }
+
+ /** The type of this track. */
+ WebMTrackType enmType;
+ /** Pointer to codec data to use. */
+ PRECORDINGCODEC pCodec;
+ /** Track parameters. */
+ union
+ {
+ struct
+ {
+ /** Sample rate of input data. */
+ uint32_t uHz;
+ /** Duration of the frame in samples (per channel).
+ * Valid frame size are:
+ *
+ * ms Frame size
+ * 2.5 120
+ * 5 240
+ * 10 480
+ * 20 (Default) 960
+ * 40 1920
+ * 60 2880
+ */
+ uint16_t framesPerBlock;
+ /** How many milliseconds (ms) one written (simple) block represents. */
+ uint16_t msPerBlock;
+ } Audio;
+ };
+ /** This track's track number. Also used as key in track map. */
+ uint8_t uTrack;
+ /** The track's "UUID".
+ * Needed in case this track gets mux'ed with tracks from other files. Not really unique though. */
+ uint32_t uUUID;
+ /** Absolute offset in file of track UUID.
+ * Needed to write the hash sum within the footer. */
+ uint64_t offUUID;
+ /** Total number of blocks. */
+ uint64_t cTotalBlocks;
+ /** Absoute timecode (in ms) of last write. */
+ WebMTimecodeAbs tcAbsLastWrittenMs;
+ };
+
+ /**
+ * Structure for a single cue point track position entry.
+ */
+ struct WebMCueTrackPosEntry
+ {
+ WebMCueTrackPosEntry(uint64_t a_offCluster)
+ : offCluster(a_offCluster) { }
+
+ /** Offset (in bytes) of the related cluster containing the given position. */
+ uint64_t offCluster;
+ };
+
+ /** Map for keeping track position entries for a single cue point.
+ * The key is the track number (*not* UUID!). */
+ typedef std::map<uint8_t, WebMCueTrackPosEntry *> WebMCueTrackPosMap;
+
+ /**
+ * Structure for keeping a cue point.
+ */
+ struct WebMCuePoint
+ {
+ WebMCuePoint(WebMTimecodeAbs a_tcAbs)
+ : tcAbs(a_tcAbs) { }
+
+ virtual ~WebMCuePoint()
+ {
+ Clear();
+ }
+
+ void Clear(void)
+ {
+ WebMCueTrackPosMap::iterator itTrackPos = Pos.begin();
+ while (itTrackPos != Pos.end())
+ {
+ WebMCueTrackPosEntry *pTrackPos = itTrackPos->second;
+ AssertPtr(pTrackPos);
+ delete pTrackPos;
+
+ Pos.erase(itTrackPos);
+ itTrackPos = Pos.begin();
+ }
+
+ Assert(Pos.empty());
+ }
+
+ /** Map containing all track positions for this specific cue point. */
+ WebMCueTrackPosMap Pos;
+ /** Absolute time code according to the segment time base. */
+ WebMTimecodeAbs tcAbs;
+ };
+
+ /** List of cue points. */
+ typedef std::list<WebMCuePoint *> WebMCuePointList;
+
+ /**
+ * Structure for keeping a WebM cluster entry.
+ */
+ struct WebMCluster
+ {
+ WebMCluster(void)
+ : uID(0)
+ , offStart(0)
+ , fOpen(false)
+ , tcAbsStartMs(0)
+ , cBlocks(0) { }
+
+ /** This cluster's ID. */
+ uint64_t uID;
+ /** Absolute offset (in bytes) of this cluster.
+ * Needed for seeking info table. */
+ uint64_t offStart;
+ /** Whether this cluster element is opened currently. */
+ bool fOpen;
+ /** Absolute timecode (in ms) when this cluster starts. */
+ WebMTimecodeAbs tcAbsStartMs;
+ /** Absolute timecode (in ms) of when last written to this cluster. */
+ WebMTimecodeAbs tcAbsLastWrittenMs;
+ /** Number of (simple) blocks in this cluster. */
+ uint64_t cBlocks;
+ };
+
+ /**
+ * Structure for keeping a WebM segment entry.
+ *
+ * Current we're only using one segment.
+ */
+ struct WebMSegment
+ {
+ WebMSegment(void)
+ : m_tcAbsStartMs(0)
+ , m_tcAbsLastWrittenMs(0)
+ , m_offStart(0)
+ , m_offInfo(0)
+ , m_offSeekInfo(0)
+ , m_offTracks(0)
+ , m_offCues(0)
+ , m_cClusters(0)
+ {
+ m_uTimecodeScaleFactor = VBOX_WEBM_TIMECODESCALE_FACTOR_MS;
+
+ LogFunc(("Default timecode scale is: %RU64ns\n", m_uTimecodeScaleFactor));
+ }
+
+ virtual ~WebMSegment()
+ {
+ uninit();
+ }
+
+ /**
+ * Initializes a segment.
+ *
+ * @returns VBox status code.
+ */
+ int init(void)
+ {
+ return RTCritSectInit(&m_CritSect);
+ }
+
+ /**
+ * Uninitializes a segment.
+ */
+ void uninit(void)
+ {
+ clear();
+
+ RTCritSectDelete(&m_CritSect);
+ }
+
+ /**
+ * Clear the segment's data by removing (and freeing) all data.
+ */
+ void clear(void)
+ {
+ WebMCuePointList::iterator itCuePoint = m_lstCuePoints.begin();
+ while (itCuePoint != m_lstCuePoints.end())
+ {
+ WebMCuePoint *pCuePoint = (*itCuePoint);
+ AssertPtr(pCuePoint);
+ delete pCuePoint;
+
+ m_lstCuePoints.erase(itCuePoint);
+ itCuePoint = m_lstCuePoints.begin();
+ }
+
+ Assert(m_lstCuePoints.empty());
+ }
+
+ /** Critical section for serializing access to this segment. */
+ RTCRITSECT m_CritSect;
+
+ /** The timecode scale factor of this segment. */
+ uint64_t m_uTimecodeScaleFactor;
+
+ /** Absolute timecode (in ms) when starting this segment. */
+ WebMTimecodeAbs m_tcAbsStartMs;
+ /** Absolute timecode (in ms) of last write. */
+ WebMTimecodeAbs m_tcAbsLastWrittenMs;
+
+ /** Absolute offset (in bytes) of CurSeg. */
+ uint64_t m_offStart;
+ /** Absolute offset (in bytes) of general info. */
+ uint64_t m_offInfo;
+ /** Absolute offset (in bytes) of seeking info. */
+ uint64_t m_offSeekInfo;
+ /** Absolute offset (in bytes) of tracks. */
+ uint64_t m_offTracks;
+ /** Absolute offset (in bytes) of cues table. */
+ uint64_t m_offCues;
+ /** List of cue points. Needed for seeking table. */
+ WebMCuePointList m_lstCuePoints;
+
+ /** Total number of clusters. */
+ uint64_t m_cClusters;
+
+ /** Map of tracks.
+ * The key marks the track number (*not* the UUID!). */
+ std::map <uint8_t, WebMTrack *> m_mapTracks;
+
+ /** Current cluster which is being handled.
+ *
+ * Note that we don't need (and shouldn't need, as this can be a *lot* of data!) a
+ * list of all clusters. */
+ WebMCluster m_CurCluster;
+
+ WebMQueue m_queueBlocks;
+
+ } m_CurSeg;
+
+ /** Audio codec to use. */
+ RecordingAudioCodec_T m_enmAudioCodec;
+ /** Video codec to use. */
+ RecordingVideoCodec_T m_enmVideoCodec;
+
+ /** Whether we're currently in the tracks section. */
+ bool m_fInTracksSection;
+
+ /** Size of timecodes (in bytes). */
+ size_t m_cbTimecode;
+ /** Maximum value a timecode can have. */
+ uint32_t m_uTimecodeMax;
+
+#ifdef VBOX_WITH_LIBVPX
+ /**
+ * Block data for VP8-encoded video data.
+ */
+ struct BlockData_VP8
+ {
+ const vpx_codec_enc_cfg_t *pCfg;
+ const vpx_codec_cx_pkt_t *pPkt;
+ };
+#endif /* VBOX_WITH_LIBVPX */
+
+ /**
+ * Block data for encoded audio data.
+ */
+ struct BlockData_Audio
+ {
+ /** Pointer to encoded audio data. */
+ const void *pvData;
+ /** Size (in bytes) of encoded audio data. */
+ size_t cbData;
+ /** PTS (in ms) of encoded audio data. */
+ uint64_t uPTSMs;
+ };
+
+public:
+
+ WebMWriter();
+
+ virtual ~WebMWriter();
+
+public:
+
+ int OpenEx(const char *a_pszFilename, PRTFILE a_phFile,
+ RecordingAudioCodec_T a_enmAudioCodec, RecordingVideoCodec_T a_enmVideoCodec);
+
+ int Open(const char *a_pszFilename, uint64_t a_fOpen,
+ RecordingAudioCodec_T a_enmAudioCodec, RecordingVideoCodec_T a_enmVideoCodec);
+
+ int Close(void);
+
+ int AddAudioTrack(PRECORDINGCODEC pCodec, uint16_t uHz, uint8_t cChannels, uint8_t cBits, uint8_t *puTrack);
+
+ int AddVideoTrack(PRECORDINGCODEC pCodec, uint16_t uWidth, uint16_t uHeight, uint32_t uFPS, uint8_t *puTrack);
+
+ int WriteBlock(uint8_t uTrack, const void *pvData, size_t cbData, WebMTimecodeAbs tcAbsPTSMs, WebMBlockFlags uFlags);
+
+ const com::Utf8Str& GetFileName(void);
+
+ uint64_t GetFileSize(void);
+
+ uint64_t GetAvailableSpace(void);
+
+ /**
+ * Returns the number of written WebM clusters.
+ *
+ * @returns Number of written WebM clusters; 0 when no clusters written (empty file).
+ */
+ uint64_t GetClusters(void) const { return m_CurSeg.m_cClusters; }
+
+protected:
+
+ int init(RecordingAudioCodec_T a_enmAudioCodec, RecordingVideoCodec_T a_enmVideoCodec);
+
+ void destroy(void);
+
+ int writeHeader(void);
+
+ void writeSeekHeader(void);
+
+ int writeFooter(void);
+
+ int writeSimpleBlockEBML(WebMTrack *a_pTrack, WebMSimpleBlock *a_pBlock);
+
+ int writeSimpleBlockQueued(WebMTrack *a_pTrack, WebMSimpleBlock *a_pBlock);
+
+ int processQueue(WebMQueue *pQueue, bool fForce);
+
+protected:
+
+ typedef std::map <uint8_t, WebMTrack *> WebMTracks;
+};
+
+#endif /* !MAIN_INCLUDED_WebMWriter_h */
diff --git a/src/VBox/Main/include/Wrapper.h b/src/VBox/Main/include/Wrapper.h
new file mode 100644
index 00000000..bb2f5550
--- /dev/null
+++ b/src/VBox/Main/include/Wrapper.h
@@ -0,0 +1,504 @@
+/* $Id: Wrapper.h $ */
+/** @file
+ * VirtualBox COM - API wrapper helpers.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_Wrapper_h
+#define MAIN_INCLUDED_Wrapper_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <vector>
+#include <VBox/com/ptr.h>
+#include <VBox/com/array.h>
+
+#include "AutoCaller.h"
+
+
+/**
+ * Checks that the given pointer to an output argument is valid and throws
+ * E_POINTER + extended error info otherwise.
+ * @param arg Pointer argument.
+ */
+#define CheckComArgOutPointerValidThrow(arg) \
+ do { \
+ if (RT_LIKELY(RT_VALID_PTR(arg))) \
+ { /* likely */ }\
+ /* Have to use use VirtualBoxBase::tr here or lupdate won't be able to figure out the context, \
+ as it is picking it up right here rather than in the places where the macro is actually used. */ \
+ else throw setError(E_POINTER, VirtualBoxBase::tr("Output argument %s points to invalid memory location (%p)"), \
+ #arg, (void *)(arg)); \
+ } while (0)
+
+
+class BSTROutConverter
+{
+public:
+ BSTROutConverter() : mDst(NULL)
+ {
+ }
+
+ BSTROutConverter(BSTR *aDst) : mDst(aDst)
+ {
+ }
+
+ ~BSTROutConverter()
+ {
+ if (mDst)
+ Bstr(mStr).detachTo(mDst);
+ }
+
+ com::Utf8Str &str()
+ {
+ return mStr;
+ }
+
+private:
+ com::Utf8Str mStr;
+ BSTR *mDst;
+};
+
+class BSTRInConverter
+{
+public:
+ BSTRInConverter() : mSrc()
+ {
+ }
+
+ BSTRInConverter(CBSTR aSrc) : mSrc(aSrc)
+ {
+ }
+
+ ~BSTRInConverter()
+ {
+ }
+
+ const com::Utf8Str &str()
+ {
+ return mSrc;
+ }
+
+private:
+ const com::Utf8Str mSrc;
+};
+
+class ArrayBSTROutConverter
+{
+public:
+ ArrayBSTROutConverter() :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(NULL),
+ mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+ mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ArrayBSTROutConverter(ComSafeArrayOut(BSTR, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(aDstSize),
+ mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+ mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ~ArrayBSTROutConverter()
+ {
+ if (mDst)
+ {
+ com::SafeArray<BSTR> outArray(mArray.size());
+ for (size_t i = 0; i < mArray.size(); i++)
+ Bstr(mArray[i]).detachTo(&outArray[i]);
+ outArray.detachTo(ComSafeArrayOutArg(mDst));
+ }
+ }
+
+ std::vector<com::Utf8Str> &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<com::Utf8Str> mArray;
+#ifdef VBOX_WITH_XPCOM
+ PRUint32 *mDstSize;
+ BSTR **mDst;
+#else // !VBOX_WITH_XPCOM
+ SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+class ArrayBSTRInConverter
+{
+public:
+ ArrayBSTRInConverter()
+ {
+ }
+
+ ArrayBSTRInConverter(ComSafeArrayIn(IN_BSTR, aSrc))
+ {
+ if (!ComSafeArrayInIsNull(aSrc))
+ {
+ com::SafeArray<IN_BSTR> inArray(ComSafeArrayInArg(aSrc));
+ mArray.resize(inArray.size());
+ for (size_t i = 0; i < inArray.size(); i++)
+ mArray[i] = inArray[i];
+ }
+ }
+
+ ~ArrayBSTRInConverter()
+ {
+ }
+
+ const std::vector<com::Utf8Str> &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<com::Utf8Str> mArray;
+};
+
+class UuidOutConverter
+{
+public:
+ UuidOutConverter() : mDst(NULL)
+ {
+ }
+
+ UuidOutConverter(BSTR *aDst) : mDst(aDst)
+ {
+ }
+
+ ~UuidOutConverter()
+ {
+ if (mDst)
+ mUuid.toUtf16().detachTo(mDst);
+ }
+
+ com::Guid &uuid()
+ {
+ return mUuid;
+ }
+
+private:
+ com::Guid mUuid;
+ BSTR *mDst;
+};
+
+class UuidInConverter
+{
+public:
+ UuidInConverter() : mSrc()
+ {
+ }
+
+ UuidInConverter(CBSTR aSrc) : mSrc(aSrc)
+ {
+ }
+
+ ~UuidInConverter()
+ {
+ }
+
+ const com::Guid &uuid()
+ {
+ return mSrc;
+ }
+
+private:
+ const com::Guid mSrc;
+};
+
+class ArrayUuidOutConverter
+{
+public:
+ ArrayUuidOutConverter() :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(NULL),
+ mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+ mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ArrayUuidOutConverter(ComSafeArrayOut(BSTR, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(aDstSize),
+ mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+ mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ~ArrayUuidOutConverter()
+ {
+ if (mDst)
+ {
+ com::SafeArray<BSTR> outArray(mArray.size());
+ for (size_t i = 0; i < mArray.size(); i++)
+ mArray[i].toUtf16().detachTo(&outArray[i]);
+ outArray.detachTo(ComSafeArrayOutArg(mDst));
+ }
+ }
+
+ std::vector<com::Guid> &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<com::Guid> mArray;
+#ifdef VBOX_WITH_XPCOM
+ PRUint32 *mDstSize;
+ BSTR **mDst;
+#else // !VBOX_WITH_XPCOM
+ SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+template <class A>
+class ComTypeOutConverter
+{
+public:
+ ComTypeOutConverter() : mDst(NULL)
+ {
+ }
+
+ ComTypeOutConverter(A **aDst) : mDst(aDst)
+ {
+ }
+
+ ~ComTypeOutConverter()
+ {
+ if (mDst)
+ mPtr.queryInterfaceTo(mDst);
+ }
+
+ ComPtr<A> &ptr()
+ {
+ return mPtr;
+ }
+
+private:
+ ComPtr<A> mPtr;
+ A **mDst;
+};
+
+template <class A>
+class ComTypeInConverter
+{
+public:
+ ComTypeInConverter() : mSrc(NULL)
+ {
+ }
+
+ ComTypeInConverter(A *aSrc) : mSrc(aSrc)
+ {
+ }
+
+ ~ComTypeInConverter()
+ {
+ }
+
+ const ComPtr<A> &ptr()
+ {
+ return mSrc;
+ }
+
+private:
+ const ComPtr<A> mSrc;
+};
+
+template <class A>
+class ArrayComTypeOutConverter
+{
+public:
+ ArrayComTypeOutConverter() :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(NULL),
+ mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+ mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ArrayComTypeOutConverter(ComSafeArrayOut(A *, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(aDstSize),
+ mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+ mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ~ArrayComTypeOutConverter()
+ {
+ if (mDst)
+ {
+ com::SafeIfaceArray<A> outArray(mArray);
+ outArray.detachTo(ComSafeArrayOutArg(mDst));
+ }
+ }
+
+ std::vector<ComPtr<A> > &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<ComPtr<A> > mArray;
+#ifdef VBOX_WITH_XPCOM
+ PRUint32 *mDstSize;
+ A ***mDst;
+#else // !VBOX_WITH_XPCOM
+ SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+template <class A>
+class ArrayComTypeInConverter
+{
+public:
+ ArrayComTypeInConverter()
+ {
+ }
+
+ ArrayComTypeInConverter(ComSafeArrayIn(A *, aSrc))
+ {
+ if (!ComSafeArrayInIsNull(aSrc))
+ {
+ com::SafeIfaceArray<A> inArray(ComSafeArrayInArg(aSrc));
+ mArray.resize(inArray.size());
+ for (size_t i = 0; i < inArray.size(); i++)
+ mArray[i] = inArray[i];
+ }
+ }
+
+ ~ArrayComTypeInConverter()
+ {
+ }
+
+ const std::vector<ComPtr<A> > &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<ComPtr<A> > mArray;
+};
+
+template <typename A>
+class ArrayOutConverter
+{
+public:
+ ArrayOutConverter() :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(NULL),
+ mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+ mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ArrayOutConverter(ComSafeArrayOut(A, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+ mDstSize(aDstSize),
+ mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+ mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+ {
+ }
+
+ ~ArrayOutConverter()
+ {
+ if (mDst)
+ {
+ com::SafeArray<A> outArray(mArray.size());
+ for (size_t i = 0; i < mArray.size(); i++)
+ outArray[i] = mArray[i];
+ outArray.detachTo(ComSafeArrayOutArg(mDst));
+ }
+ }
+
+ std::vector<A> &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<A> mArray;
+#ifdef VBOX_WITH_XPCOM
+ PRUint32 *mDstSize;
+ A **mDst;
+#else // !VBOX_WITH_XPCOM
+ SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+template <typename A>
+class ArrayInConverter
+{
+public:
+ ArrayInConverter()
+ {
+ }
+
+ ArrayInConverter(ComSafeArrayIn(A, aSrc))
+ {
+ if (!ComSafeArrayInIsNull(aSrc))
+ {
+ com::SafeArray<A> inArray(ComSafeArrayInArg(aSrc));
+ mArray.resize(inArray.size());
+ for (size_t i = 0; i < inArray.size(); i++)
+ mArray[i] = inArray[i];
+ }
+ }
+
+ ~ArrayInConverter()
+ {
+ }
+
+ const std::vector<A> &array()
+ {
+ return mArray;
+ }
+
+private:
+ std::vector<A> mArray;
+};
+
+#endif /* !MAIN_INCLUDED_Wrapper_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/netif.h b/src/VBox/Main/include/netif.h
new file mode 100644
index 00000000..3d344914
--- /dev/null
+++ b/src/VBox/Main/include/netif.h
@@ -0,0 +1,145 @@
+/* $Id: netif.h $ */
+/** @file
+ * Main - Network Interfaces.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_netif_h
+#define MAIN_INCLUDED_netif_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/net.h>
+/** @todo r=bird: The inlined code below that drags in asm.h here. I doubt
+ * speed is very important here, so move it into a .cpp file, please. */
+#include <iprt/asm.h>
+
+#ifndef RT_OS_WINDOWS
+# include <arpa/inet.h>
+# include <stdio.h>
+#endif /* !RT_OS_WINDOWS */
+
+#define VBOXNET_IPV4ADDR_DEFAULT 0x0138A8C0 /* 192.168.56.1 */
+#define VBOXNET_IPV4MASK_DEFAULT "255.255.255.0"
+
+#define VBOXNET_MAX_SHORT_NAME 50
+
+#if 1
+/**
+ * Encapsulation type.
+ * @note Must match HostNetworkInterfaceMediumType_T exactly.
+ * @todo r=bird: Why are we duplicating HostNetworkInterfaceMediumType_T here?!?
+ */
+typedef enum NETIFTYPE
+{
+ NETIF_T_UNKNOWN,
+ NETIF_T_ETHERNET,
+ NETIF_T_PPP,
+ NETIF_T_SLIP
+} NETIFTYPE;
+
+/**
+ * Current state of the interface.
+ * @note Must match HostNetworkInterfaceStatus_T exactly.
+ * @todo r=bird: Why are we duplicating HostNetworkInterfaceStatus_T here?!?
+ */
+typedef enum NETIFSTATUS
+{
+ NETIF_S_UNKNOWN,
+ NETIF_S_UP,
+ NETIF_S_DOWN
+} NETIFSTATUS;
+
+/**
+ * Host Network Interface Information.
+ */
+typedef struct NETIFINFO
+{
+ NETIFINFO *pNext;
+ RTNETADDRIPV4 IPAddress;
+ RTNETADDRIPV4 IPNetMask;
+ RTNETADDRIPV6 IPv6Address;
+ RTNETADDRIPV6 IPv6NetMask;
+ BOOL fDhcpEnabled;
+ BOOL fIsDefault;
+ BOOL fWireless;
+ RTMAC MACAddress;
+ NETIFTYPE enmMediumType;
+ NETIFSTATUS enmStatus;
+ uint32_t uSpeedMbits;
+ RTUUID Uuid;
+ char szShortName[VBOXNET_MAX_SHORT_NAME];
+ char szName[1];
+} NETIFINFO;
+
+/** Pointer to a network interface info. */
+typedef NETIFINFO *PNETIFINFO;
+/** Pointer to a const network interface info. */
+typedef NETIFINFO const *PCNETIFINFO;
+#endif
+
+int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list);
+int NetIfEnableStaticIpConfig(VirtualBox *pVBox, HostNetworkInterface * pIf, ULONG aOldIp, ULONG aNewIp, ULONG aMask);
+int NetIfEnableStaticIpConfigV6(VirtualBox *pVBox, HostNetworkInterface *pIf, const Utf8Str &aOldIPV6Address, const Utf8Str &aIPV6Address, ULONG aIPV6MaskPrefixLength);
+int NetIfEnableDynamicIpConfig(VirtualBox *pVBox, HostNetworkInterface * pIf);
+#ifdef RT_OS_WINDOWS
+int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress,
+ IN_BSTR bstrName = NULL);
+#else
+int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVBox, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress,
+ const char *pszName = NULL);
+#endif
+int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVBox, const Guid &aId, IProgress **aProgress);
+int NetIfGetConfig(HostNetworkInterface * pIf, NETIFINFO *);
+int NetIfGetConfigByName(PNETIFINFO pInfo);
+int NetIfGetState(const char *pcszIfName, NETIFSTATUS *penmState);
+int NetIfGetLinkSpeed(const char *pcszIfName, uint32_t *puMbits);
+int NetIfDhcpRediscover(VirtualBox *pVBox, HostNetworkInterface * pIf);
+int NetIfAdpCtlOut(const char *pszName, const char *pszCmd, char *pszBuffer, size_t cBufSize);
+
+DECLINLINE(Bstr) getDefaultIPv4Address(Bstr bstrIfName)
+{
+ /* Get the index from the name */
+ Utf8Str strTmp = bstrIfName;
+ const char *pcszIfName = strTmp.c_str();
+ size_t iPos = strcspn(pcszIfName, "0123456789");
+ uint32_t uInstance = 0;
+ if (pcszIfName[iPos])
+ uInstance = RTStrToUInt32(pcszIfName + iPos);
+
+ in_addr tmp;
+#if defined(RT_OS_WINDOWS)
+ tmp.S_un.S_addr = VBOXNET_IPV4ADDR_DEFAULT + (uInstance << 16);
+#else
+ tmp.s_addr = VBOXNET_IPV4ADDR_DEFAULT + (uInstance << 16);
+#endif
+ char *addr = inet_ntoa(tmp);
+ return Bstr(addr);
+}
+
+#endif /* !MAIN_INCLUDED_netif_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/objectslist.h b/src/VBox/Main/include/objectslist.h
new file mode 100644
index 00000000..fad5a20b
--- /dev/null
+++ b/src/VBox/Main/include/objectslist.h
@@ -0,0 +1,224 @@
+/* $Id: objectslist.h $ */
+/** @file
+ *
+ * List of COM objects
+ */
+
+/*
+ * Copyright (C) 2009-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_objectslist_h
+#define MAIN_INCLUDED_objectslist_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <list>
+#include <VBox/com/ptr.h>
+
+/**
+ * Implements a "flat" objects list with a lock. Since each such list
+ * has its own lock it is not a good idea to implement trees with this.
+ *
+ * ObjectList<T> is designed to behave as if it were a std::list of
+ * COM pointers of class T; in other words,
+ * ObjectList<Medium> behaves like std::list< ComObjPtr<Medium> > but
+ * it's less typing. Iterators, front(), size(), begin() and end()
+ * are implemented.
+ *
+ * In addition it automatically includes an RWLockHandle which can be
+ * accessed with getLockHandle().
+ *
+ * If you need the raw std::list for some reason you can access it with
+ * getList().
+ *
+ * The destructor automatically calls uninit() on every contained
+ * COM object. If this is not desired, clear the member list before
+ * deleting the list object.
+ */
+template<typename T>
+class ObjectsList
+{
+public:
+ typedef ComObjPtr<T> MyType;
+ typedef std::list<MyType> MyList;
+
+ typedef typename MyList::iterator iterator;
+ typedef typename MyList::const_iterator const_iterator;
+ // typename is necessary to disambiguate "::iterator" in templates; see
+ // the "this might hurt your head" part in
+ // http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18
+
+ ObjectsList(RWLockHandle &lockHandle)
+ : m_lock(lockHandle)
+ { }
+
+ ~ObjectsList()
+ {
+ uninitAll();
+ }
+
+private:
+ // prohibit copying and assignment
+ ObjectsList(const ObjectsList &d);
+ ObjectsList& operator=(const ObjectsList &d);
+
+public:
+
+ /**
+ * Returns the lock handle which protects this list, for use with
+ * AutoReadLock or AutoWriteLock.
+ */
+ RWLockHandle& getLockHandle()
+ {
+ return m_lock;
+ }
+
+ /**
+ * Calls m_ll.push_back(p) with locking.
+ * @param p
+ */
+ void addChild(MyType p)
+ {
+ AutoWriteLock al(m_lock COMMA_LOCKVAL_SRC_POS);
+ m_ll.push_back(p);
+ }
+
+ /**
+ * Calls m_ll.remove(p) with locking. Does NOT call uninit()
+ * on the contained object.
+ * @param p
+ */
+ void removeChild(MyType p)
+ {
+ AutoWriteLock al(m_lock COMMA_LOCKVAL_SRC_POS);
+ m_ll.remove(p);
+ }
+
+ /**
+ * Appends all objects from another list to the member list.
+ * Locks the other list for reading but does not lock "this"
+ * (because it might be on the caller's stack and needs no
+ * locking).
+ * @param ll
+ */
+ void appendOtherList(ObjectsList<T> &ll)
+ {
+ AutoReadLock alr(ll.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+ for (const_iterator it = ll.begin();
+ it != ll.end();
+ ++it)
+ {
+ m_ll.push_back(*it);
+ }
+ }
+
+ /**
+ * Calls uninit() on every COM object on the list and then
+ * clears the list, with locking.
+ */
+ void uninitAll()
+ {
+ /* The implementation differs from the high level description, because
+ * it isn't safe to hold any locks when invoking uninit() methods. It
+ * leads to incorrect lock order (first lock, then the Caller related
+ * event semaphore) and thus deadlocks. Dropping the lock is vital,
+ * and means we can't rely on iterators while not holding the lock. */
+ AutoWriteLock al(m_lock COMMA_LOCKVAL_SRC_POS);
+ while (!m_ll.empty())
+ {
+ /* Need a copy of the element, have to delete the entry before
+ * dropping the lock, otherwise someone else might mess with the
+ * list in the mean time, leading to erratic behavior. */
+ MyType q = m_ll.front();
+ m_ll.pop_front();
+ al.release();
+ q->uninit();
+ al.acquire();
+ }
+ }
+
+ /**
+ * Returns the no. of objects on the list (std::list compatibility)
+ * with locking.
+ */
+ size_t size()
+ {
+ AutoReadLock al(m_lock COMMA_LOCKVAL_SRC_POS);
+ return m_ll.size();
+ }
+
+ /**
+ * Returns a raw pointer to the member list of objects.
+ * Does not lock!
+ * @return
+ */
+ MyList& getList()
+ {
+ return m_ll;
+ }
+
+ /**
+ * Returns the first object on the list (std::list compatibility)
+ * with locking.
+ */
+ MyType front()
+ {
+ AutoReadLock al(m_lock COMMA_LOCKVAL_SRC_POS);
+ return m_ll.front();
+ }
+
+ /**
+ * Returns the begin iterator from the list (std::list compatibility).
+ * Does not lock!
+ * @return
+ */
+ iterator begin()
+ {
+ return m_ll.begin();
+ }
+
+ /**
+ * Returns the end iterator from the list (std::list compatibility).
+ * Does not lock!
+ */
+ iterator end()
+ {
+ return m_ll.end();
+ }
+
+ void insert(iterator it, MyType &p)
+ {
+ m_ll.insert(it, p);
+ }
+
+ void erase(iterator it)
+ {
+ m_ll.erase(it);
+ }
+
+private:
+ MyList m_ll;
+ RWLockHandle &m_lock;
+};
+
+#endif /* !MAIN_INCLUDED_objectslist_h */
diff --git a/src/VBox/Main/include/ovfreader.h b/src/VBox/Main/include/ovfreader.h
new file mode 100644
index 00000000..8cdb3906
--- /dev/null
+++ b/src/VBox/Main/include/ovfreader.h
@@ -0,0 +1,732 @@
+/* $Id: ovfreader.h $ */
+/** @file
+ * VirtualBox Main - OVF reader declarations.
+ *
+ * Depends only on IPRT, including the RTCString and IPRT XML classes.
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_ovfreader_h
+#define MAIN_INCLUDED_ovfreader_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "iprt/cpp/xml.h"
+#include <map>
+#include <vector>
+
+namespace ovf
+{
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Errors
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Thrown by OVFReader for any kind of error that is not an XML error but
+ * still makes the OVF impossible to parse. Based on xml::LogicError so
+ * that one catch() for all xml::LogicError can handle all possible errors.
+ */
+class OVFLogicError : public xml::LogicError
+{
+public:
+ OVFLogicError(const char *aFormat, ...);
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Enumerations
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * CIM OS values.
+ *
+ * The OVF 1.10 spec refers to some CIM_OperatingSystem.mof doc. Could this be it:
+ * http://cvs.opengroup.org/cgi-bin/cvsweb.cgi/pegasus/Schemas/CIM231/DMTF/System/CIM_OperatingSystem.mof
+ *
+ * @todo r=bird: Why are the values are repeating 'CIMOS'. CIMOSType_T is also
+ * repeating it self, 'Type' and '_T'. Why not call it kCIOMOpSys,
+ * easier to read as well.
+ * Then also apply: s/CIMOSType_CIMOS_/kCIMOpSys_/g
+ */
+enum CIMOSType_T
+{
+ CIMOSType_CIMOS_Unknown = 0,
+ CIMOSType_CIMOS_Other = 1,
+ CIMOSType_CIMOS_MACOS = 2,
+ CIMOSType_CIMOS_ATTUNIX = 3,
+ CIMOSType_CIMOS_DGUX = 4,
+ CIMOSType_CIMOS_DECNT = 5,
+ CIMOSType_CIMOS_Tru64UNIX = 6,
+ CIMOSType_CIMOS_OpenVMS = 7,
+ CIMOSType_CIMOS_HPUX = 8,
+ CIMOSType_CIMOS_AIX = 9,
+ CIMOSType_CIMOS_MVS = 10,
+ CIMOSType_CIMOS_OS400 = 11,
+ CIMOSType_CIMOS_OS2 = 12,
+ CIMOSType_CIMOS_JavaVM = 13,
+ CIMOSType_CIMOS_MSDOS = 14,
+ CIMOSType_CIMOS_WIN3x = 15,
+ CIMOSType_CIMOS_WIN95 = 16,
+ CIMOSType_CIMOS_WIN98 = 17,
+ CIMOSType_CIMOS_WINNT = 18,
+ CIMOSType_CIMOS_WINCE = 19,
+ CIMOSType_CIMOS_NCR3000 = 20,
+ CIMOSType_CIMOS_NetWare = 21,
+ CIMOSType_CIMOS_OSF = 22,
+ CIMOSType_CIMOS_DCOS = 23,
+ CIMOSType_CIMOS_ReliantUNIX = 24,
+ CIMOSType_CIMOS_SCOUnixWare = 25,
+ CIMOSType_CIMOS_SCOOpenServer = 26,
+ CIMOSType_CIMOS_Sequent = 27,
+ CIMOSType_CIMOS_IRIX = 28,
+ CIMOSType_CIMOS_Solaris = 29,
+ CIMOSType_CIMOS_SunOS = 30,
+ CIMOSType_CIMOS_U6000 = 31,
+ CIMOSType_CIMOS_ASERIES = 32,
+ CIMOSType_CIMOS_HPNonStopOS = 33,
+ CIMOSType_CIMOS_HPNonStopOSS = 34,
+ CIMOSType_CIMOS_BS2000 = 35,
+ CIMOSType_CIMOS_LINUX = 36,
+ CIMOSType_CIMOS_Lynx = 37,
+ CIMOSType_CIMOS_XENIX = 38,
+ CIMOSType_CIMOS_VM = 39,
+ CIMOSType_CIMOS_InteractiveUNIX = 40,
+ CIMOSType_CIMOS_BSDUNIX = 41,
+ CIMOSType_CIMOS_FreeBSD = 42,
+ CIMOSType_CIMOS_NetBSD = 43,
+ CIMOSType_CIMOS_GNUHurd = 44,
+ CIMOSType_CIMOS_OS9 = 45,
+ CIMOSType_CIMOS_MACHKernel = 46,
+ CIMOSType_CIMOS_Inferno = 47,
+ CIMOSType_CIMOS_QNX = 48,
+ CIMOSType_CIMOS_EPOC = 49,
+ CIMOSType_CIMOS_IxWorks = 50,
+ CIMOSType_CIMOS_VxWorks = 51,
+ CIMOSType_CIMOS_MiNT = 52,
+ CIMOSType_CIMOS_BeOS = 53,
+ CIMOSType_CIMOS_HPMPE = 54,
+ CIMOSType_CIMOS_NextStep = 55,
+ CIMOSType_CIMOS_PalmPilot = 56,
+ CIMOSType_CIMOS_Rhapsody = 57,
+ CIMOSType_CIMOS_Windows2000 = 58,
+ CIMOSType_CIMOS_Dedicated = 59,
+ CIMOSType_CIMOS_OS390 = 60,
+ CIMOSType_CIMOS_VSE = 61,
+ CIMOSType_CIMOS_TPF = 62,
+ CIMOSType_CIMOS_WindowsMe = 63,
+ CIMOSType_CIMOS_CalderaOpenUNIX = 64,
+ CIMOSType_CIMOS_OpenBSD = 65,
+ CIMOSType_CIMOS_NotApplicable = 66,
+ CIMOSType_CIMOS_WindowsXP = 67,
+ CIMOSType_CIMOS_zOS = 68,
+ CIMOSType_CIMOS_MicrosoftWindowsServer2003 = 69,
+ CIMOSType_CIMOS_MicrosoftWindowsServer2003_64 = 70,
+ CIMOSType_CIMOS_WindowsXP_64 = 71,
+ CIMOSType_CIMOS_WindowsXPEmbedded = 72,
+ CIMOSType_CIMOS_WindowsVista = 73,
+ CIMOSType_CIMOS_WindowsVista_64 = 74,
+ CIMOSType_CIMOS_WindowsEmbeddedforPointofService = 75,
+ CIMOSType_CIMOS_MicrosoftWindowsServer2008 = 76,
+ CIMOSType_CIMOS_MicrosoftWindowsServer2008_64 = 77,
+ CIMOSType_CIMOS_FreeBSD_64 = 78,
+ CIMOSType_CIMOS_RedHatEnterpriseLinux = 79,
+ CIMOSType_CIMOS_RedHatEnterpriseLinux_64 = 80,
+ CIMOSType_CIMOS_Solaris_64 = 81,
+ CIMOSType_CIMOS_SUSE = 82,
+ CIMOSType_CIMOS_SUSE_64 = 83,
+ CIMOSType_CIMOS_SLES = 84,
+ CIMOSType_CIMOS_SLES_64 = 85,
+ CIMOSType_CIMOS_NovellOES = 86,
+ CIMOSType_CIMOS_NovellLinuxDesktop = 87,
+ CIMOSType_CIMOS_SunJavaDesktopSystem = 88,
+ CIMOSType_CIMOS_Mandriva = 89,
+ CIMOSType_CIMOS_Mandriva_64 = 90,
+ CIMOSType_CIMOS_TurboLinux = 91,
+ CIMOSType_CIMOS_TurboLinux_64 = 92,
+ CIMOSType_CIMOS_Ubuntu = 93,
+ CIMOSType_CIMOS_Ubuntu_64 = 94,
+ CIMOSType_CIMOS_Debian = 95,
+ CIMOSType_CIMOS_Debian_64 = 96,
+ CIMOSType_CIMOS_Linux_2_4_x = 97,
+ CIMOSType_CIMOS_Linux_2_4_x_64 = 98,
+ CIMOSType_CIMOS_Linux_2_6_x = 99,
+ CIMOSType_CIMOS_Linux_2_6_x_64 = 100,
+ CIMOSType_CIMOS_Linux_64 = 101,
+ CIMOSType_CIMOS_Other_64 = 102,
+ // types added with CIM 2.25.0 follow:
+ CIMOSType_CIMOS_WindowsServer2008R2 = 103,
+ CIMOSType_CIMOS_VMwareESXi = 104,
+ CIMOSType_CIMOS_Windows7 = 105,
+ CIMOSType_CIMOS_CentOS = 106,
+ CIMOSType_CIMOS_CentOS_64 = 107,
+ CIMOSType_CIMOS_OracleLinux = 108,
+ CIMOSType_CIMOS_OracleLinux_64 = 109,
+ CIMOSType_CIMOS_eComStation = 110,
+ // no new types added with CIM 2.26.0
+ CIMOSType_CIMOS_WindowsServer2011 = 111,
+ CIMOSType_CIMOS_WindowsServer2012 = 112,
+ CIMOSType_CIMOS_Windows8 = 113,
+ CIMOSType_CIMOS_Windows8_64 = 114,
+ CIMOSType_CIMOS_WindowsServer2012R2 = 115,
+ CIMOSType_CIMOS_Windows8_1 = 116,
+ CIMOSType_CIMOS_Windows8_1_64 = 117,
+ CIMOSType_CIMOS_WindowsServer2016 = 118,
+ CIMOSType_CIMOS_Windows10 = 119,
+ CIMOSType_CIMOS_Windows10_64 = 120,
+ // the above covers up to CIM 2.52.0, without checking when it was added
+};
+
+enum OVFVersion_T
+{
+ OVFVersion_unknown,
+ OVFVersion_0_9,
+ OVFVersion_1_0,
+ OVFVersion_2_0
+};
+
+const char* const OVF09_URI_string = "http://www.vmware.com/schema/ovf/1/envelope";
+const char* const OVF10_URI_string = "http://schemas.dmtf.org/ovf/envelope/1";
+const char* const OVF20_URI_string = "http://schemas.dmtf.org/ovf/envelope/2";
+
+const char* const DTMF_SPECS_URI = "http://schemas.dmtf.org/wbem/cim-html/2/";
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Envelope data
+//
+////////////////////////////////////////////////////////////////////////////////
+struct EnvelopeData
+{
+ OVFVersion_T version;//OVF standard version, it is used internally only by VirtualBox
+ RTCString lang;//language
+
+ OVFVersion_T getOVFVersion() const
+ {
+ return version;
+ }
+
+
+ RTCString getStringOVFVersion() const
+ {
+ if (version == OVFVersion_0_9)
+ return "0.9";
+ else if (version == OVFVersion_1_0)
+ return "1.0";
+ else if (version == OVFVersion_2_0)
+ return "2.0";
+ else
+ return "";
+ }
+
+ void setOVFVersion(OVFVersion_T v)
+ {
+ version = v;
+ }
+};
+
+
+struct FileReference
+{
+ RTCString strHref; // value from /References/File/@href (filename)
+ RTCString strDiskId; // value from /References/File/@id ()
+};
+
+typedef std::map<uint32_t, FileReference> FileReferenceMap;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Hardware definition structs
+//
+////////////////////////////////////////////////////////////////////////////////
+
+struct DiskImage
+{
+ // fields from /DiskSection/Disk
+ RTCString strDiskId; // value from DiskSection/Disk/@diskId
+ int64_t iCapacity; // value from DiskSection/Disk/@capacity;
+ // (maximum size for dynamic images, I guess; we always translate this to bytes)
+ int64_t iPopulatedSize; // optional value from DiskSection/Disk/@populatedSize
+ // (actual used size of disk, always in bytes; can be an estimate of used disk
+ // space, but cannot be larger than iCapacity; -1 if not set)
+ RTCString strFormat; // value from DiskSection/Disk/@format
+ // typically http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized
+ RTCString uuidVBox; // optional; if the file was exported by VirtualBox >= 3.2,
+ // then this has the UUID with which the disk was registered
+
+ // fields from /References/File; the spec says the file reference from disk can be empty,
+ // so in that case, strFilename will be empty, then a new disk should be created
+ RTCString strHref; // value from /References/File/@href (filename); if empty, then the remaining fields are ignored
+ int64_t iSize; // value from /References/File/@size (optional according to spec; then we set -1 here)
+ int64_t iChunkSize; // value from /References/File/@chunkSize (optional, unsupported)
+ RTCString strCompression; // value from /References/File/@compression (optional, can be "gzip" according to spec)
+
+ // additional field which has a descriptive size in megabytes derived from the above; this can be used for progress reports
+ uint32_t ulSuggestedSizeMB;
+};
+
+enum ResourceType_T
+{
+ ResourceType_Other = 1,
+ ResourceType_ComputerSystem = 2,
+ ResourceType_Processor = 3,
+ ResourceType_Memory = 4,
+ ResourceType_IDEController = 5,
+ ResourceType_ParallelSCSIHBA = 6,
+ ResourceType_FCHBA = 7,
+ ResourceType_iSCSIHBA = 8,
+ ResourceType_IBHCA = 9,
+ ResourceType_EthernetAdapter = 10,
+ ResourceType_OtherNetworkAdapter = 11,
+ ResourceType_IOSlot = 12,
+ ResourceType_IODevice = 13,
+ ResourceType_FloppyDrive = 14,
+ ResourceType_CDDrive = 15,
+ ResourceType_DVDDrive = 16,
+ ResourceType_HardDisk = 17,
+ ResourceType_TapeDrive = 18,
+ ResourceType_StorageExtent = 19,
+ ResourceType_OtherStorageDevice = 20,
+ ResourceType_SerialPort = 21,
+ ResourceType_ParallelPort = 22,
+ ResourceType_USBController = 23,
+ ResourceType_GraphicsController = 24,
+ ResourceType_IEEE1394Controller = 25,
+ ResourceType_PartitionableUnit = 26,
+ ResourceType_BasePartitionableUnit = 27,
+ ResourceType_Power = 28,
+ ResourceType_CoolingCapacity = 29,
+ ResourceType_EthernetSwitchPort = 30,
+ ResourceType_LogicalDisk = 31,
+ ResourceType_StorageVolume = 32,
+ ResourceType_EthernetConnection = 33,
+ ResourceType_SoundCard = 35 /**< @todo r=klaus: Not part of OVF/CIM spec, should use "Other" or some value from 0x8000..0xffff. */
+};
+
+
+enum StorageAccessType_T
+{ StorageAccessType_Unknown = 0,
+ StorageAccessType_Readable = 1,
+ StorageAccessType_Writeable = 2,
+ StorageAccessType_ReadWrite = 3
+};
+
+enum ComplianceType_T
+{ ComplianceType_No = 0,
+ ComplianceType_Soft = 1,
+ ComplianceType_Medium = 2,
+ ComplianceType_Strong = 3
+};
+
+class VirtualHardwareItem
+{
+public:
+ RTCString strDescription;
+ RTCString strCaption;
+ RTCString strElementName;
+
+ RTCString strInstanceID;
+ RTCString strParent;
+
+ ResourceType_T resourceType;
+ RTCString strOtherResourceType;
+ RTCString strResourceSubType;
+ bool fResourceRequired;
+
+ RTCString strHostResource; ///< "Abstractly specifies how a device shall connect to a resource on the deployment platform.
+ /// Not all devices need a backing." Used with disk items, for which this
+ /// references a virtual disk from the Disks section.
+ bool fAutomaticAllocation;
+ bool fAutomaticDeallocation;
+ RTCString strConnection; ///< "All Ethernet adapters that specify the same abstract network connection name within an OVF
+ /// package shall be deployed on the same network. The abstract network connection name shall be
+ /// listed in the NetworkSection at the outermost envelope level." We ignore this and only set up
+ /// a network adapter depending on the network name.
+ RTCString strAddress; ///< "Device-specific. For an Ethernet adapter, this specifies the MAC address."
+ int32_t lAddress; ///< strAddress as an integer, if applicable.
+ RTCString strAddressOnParent;///< "For a device, this specifies its location on the controller."
+ RTCString strAllocationUnits;///< "Specifies the units of allocation used. For example, “byte * 2^20”."
+ uint64_t ullVirtualQuantity; ///< "Specifies the quantity of resources presented. For example, “256”."
+ uint64_t ullReservation; ///< "Specifies the minimum quantity of resources guaranteed to be available."
+ uint64_t ullLimit; ///< "Specifies the maximum quantity of resources that will be granted."
+ uint64_t ullWeight; ///< "Specifies a relative priority for this allocation in relation to other allocations."
+
+ RTCString strConsumerVisibility;
+ RTCString strMappingBehavior;
+ RTCString strPoolID;
+ uint32_t ulBusNumber; ///< seen with IDE controllers, but not listed in OVF spec
+
+ int m_iLineNumber; ///< line number of \<Item\> element in XML source; cached for error messages
+
+ VirtualHardwareItem()
+ : fResourceRequired(false)
+ , fAutomaticAllocation(false)
+ , fAutomaticDeallocation(false)
+ , ullVirtualQuantity(0)
+ , ullReservation(0)
+ , ullLimit(0)
+ , ullWeight(0)
+ , ulBusNumber(0)
+ , m_iLineNumber(0)
+ , fDefault(false)
+ {
+ itemName = "Item";
+ }
+
+ virtual ~VirtualHardwareItem() { /* Makes MSC happy. */ }
+
+ void fillItem(const xml::ElementNode *item);
+
+ void setDefaultFlag()
+ {
+ fDefault = true;
+ }
+
+ bool isThereDefaultValues() const
+ {
+ return fDefault;
+ }
+
+ void checkConsistencyAndCompliance() RT_THROW(OVFLogicError)
+ {
+ _checkConsistencyAndCompliance();
+ }
+
+protected:
+ virtual void _checkConsistencyAndCompliance() RT_THROW(OVFLogicError);
+ virtual const RTCString& getItemName()
+ {
+ return _getItemName();
+ }
+
+private:
+ RTCString itemName;
+ bool fDefault;//true means that some fields were absent in the XML and some default values were assigned to.
+
+ virtual const RTCString& _getItemName()
+ {
+ return itemName;
+ }
+};
+
+class StorageItem: public VirtualHardwareItem
+{
+ //see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/
+ StorageAccessType_T accessType;
+ RTCString strHostExtentName;
+#if 0 /* unused */
+ int16_t hostExtentNameFormat;
+ int16_t hostExtentNameNamespace;
+ int64_t hostExtentStartingAddress;
+#endif
+ int64_t hostResourceBlockSize;
+ int64_t limit;
+ RTCString strOtherHostExtentNameFormat;
+ RTCString strOtherHostExtentNameNamespace;
+ int64_t reservation;
+ int64_t virtualQuantity;
+ RTCString strVirtualQuantityUnits;
+ int64_t virtualResourceBlockSize;
+
+public:
+ StorageItem()
+ : VirtualHardwareItem()
+ , accessType(StorageAccessType_Unknown)
+#if 0 /* unused */
+ , hostExtentNameFormat(-1)
+ , hostExtentNameNamespace(-1)
+ , hostExtentStartingAddress(-1)
+#endif
+ , hostResourceBlockSize(-1)
+ , limit(-1)
+ , reservation(-1)
+ , virtualQuantity(-1)
+ , virtualResourceBlockSize(-1)
+ {
+ itemName = "StorageItem";
+ };
+
+ void fillItem(const xml::ElementNode *item);
+
+protected:
+ virtual void _checkConsistencyAndCompliance() RT_THROW(OVFLogicError);
+private:
+ RTCString itemName;
+
+ virtual const RTCString& _getItemName()
+ {
+ return itemName;
+ }
+};
+
+
+class EthernetPortItem: public VirtualHardwareItem
+{
+ //see DMTF Schema Documentation http://schemas.dmtf.org/wbem/cim-html/2/
+#if 0 /* unused */
+ uint16_t DefaultPortVID;
+ uint16_t DefaultPriority;
+ uint16_t DesiredVLANEndpointMode;
+ uint32_t GroupID;
+ uint32_t ManagerID;
+ uint16_t NetworkPortProfileIDType;
+#endif
+ RTCString strNetworkPortProfileID;
+ RTCString strOtherEndpointMode;
+ RTCString strOtherNetworkPortProfileIDTypeInfo;
+ RTCString strPortCorrelationID;
+#if 0 /* unused */
+ uint16_t PortVID;
+ bool Promiscuous;
+ uint64_t ReceiveBandwidthLimit;
+ uint16_t ReceiveBandwidthReservation;
+ bool SourceMACFilteringEnabled;
+ uint32_t VSITypeID;
+ uint8_t VSITypeIDVersion;
+ uint16_t AllowedPriorities[256];
+ uint16_t AllowedToReceiveVLANs[256];
+ uint16_t AllowedToTransmitVLANs[256];
+#endif
+ RTCString strAllowedToReceiveMACAddresses;
+ RTCString strAllowedToTransmitMACAddresses;
+
+public:
+ EthernetPortItem() : VirtualHardwareItem()
+ {
+ itemName = "EthernetPortItem";
+ };
+
+ void fillItem(const xml::ElementNode *item);
+
+protected:
+ virtual void _checkConsistencyAndCompliance() RT_THROW(OVFLogicError);
+private:
+ RTCString itemName;
+
+ virtual const RTCString& _getItemName()
+ {
+ return itemName;
+ }
+};
+
+typedef std::map<RTCString, DiskImage> DiskImagesMap;
+
+struct VirtualSystem;
+
+
+/**
+ * VirtualHardwareItem pointer vector with safe cleanup.
+ *
+ * We need to use object pointers because we also want EthernetPortItem and
+ * StorageItems to go into the container.
+ */
+class HardwareItemVector : public std::vector<VirtualHardwareItem *>
+{
+public:
+ HardwareItemVector() : std::vector<VirtualHardwareItem *>() { }
+ ~HardwareItemVector()
+ {
+ for (iterator it = begin(); it != end(); ++it)
+ delete(*it);
+ clear();
+ }
+
+ /* There is no copying of this vector. We'd need something like shared_ptr for that. */
+private:
+ HardwareItemVector(const VirtualSystem &);
+
+};
+
+struct HardDiskController
+{
+ RTCString strIdController; // instance ID (Item/InstanceId); this gets referenced from VirtualDisk
+
+ enum ControllerSystemType { IDE, SATA, SCSI, VIRTIOSCSI, NVMe };
+ ControllerSystemType system; // one of IDE, SATA, SCSI, VIRTIOSCSI, NVMe
+
+ RTCString strControllerType;
+ // controller subtype (Item/ResourceSubType); e.g. "LsiLogic"; can be empty (esp. for IDE)
+ // note that we treat LsiLogicSAS as a SCSI controller (system == SCSI) even though VirtualBox
+ // treats it as a fourth class besides IDE, SATA, SCSI
+
+ int32_t lAddress; // value from OVF "Address" element
+ bool fPrimary; // controller index; this is determined heuristically by the OVF reader and will
+ // be true for the first controller of this type (e.g. IDE primary ctler) or
+ // false for the next (e.g. IDE secondary ctler)
+
+ HardDiskController()
+ : lAddress(0),
+ fPrimary(true)
+ { }
+};
+
+typedef std::map<RTCString, HardDiskController> ControllersMap;
+
+struct VirtualDisk
+{
+ RTCString strIdController; // SCSI (or IDE) controller this disk is connected to;
+ // this must match HardDiskController.strIdController and
+ // points into VirtualSystem.mapControllers
+ uint32_t ulAddressOnParent; // parsed strAddressOnParent of hardware item; will be 0 or 1 for IDE
+ // and possibly higher for disks attached to SCSI controllers (untested)
+ RTCString strDiskId; // if the hard disk has an ovf:/disk/<id> reference,
+ // this receives the <id> component; points to one of the
+ // references in Appliance::Data.mapDisks
+ bool fEmpty; //true - empty disk, e.g. the component <rasd:HostResource>...</rasd:HostResource> is absent.
+};
+
+typedef std::map<RTCString, VirtualDisk> VirtualDisksMap;
+
+/**
+ * A list of EthernetAdapters is contained in VirtualSystem, representing the
+ * ethernet adapters in the virtual system.
+ */
+struct EthernetAdapter
+{
+ RTCString strAdapterType; // "PCNet32" or "E1000" or whatever; from <rasd:ResourceSubType>
+ RTCString strNetworkName; // from <rasd:Connection>
+};
+
+typedef std::list<EthernetAdapter> EthernetAdaptersList;
+
+/**
+ * A list of VirtualSystem structs is created by OVFReader::read(). Each refers to
+ * a \<VirtualSystem\> block in the OVF file.
+ */
+struct VirtualSystem
+{
+ RTCString strName; // copy of VirtualSystem/@id
+
+ RTCString strDescription; // copy of VirtualSystem/AnnotationSection content, if any
+
+ CIMOSType_T cimos;
+ RTCString strCimosDesc; // readable description of the cimos type in the case of cimos = 0/1/102
+ RTCString strTypeVBox; // optional type from @vbox:ostype attribute (VirtualBox 4.0 or higher)
+
+ RTCString strVirtualSystemType; // generic hardware description; OVF says this can be something like "vmx-4" or "xen";
+ // VMware Workstation 6.5 is "vmx-07"
+
+ HardwareItemVector vecHardwareItems; //< vector containing all virtual hardware items in parsing order.
+
+ uint64_t ullMemorySize; // always in bytes, copied from llHardwareItems; default = 0 (unspecified)
+ uint16_t cCPUs; // no. of CPUs, copied from llHardwareItems; default = 1
+
+ EthernetAdaptersList llEthernetAdapters; // (one for each VirtualSystem/Item[@ResourceType=10]element)
+
+ ControllersMap mapControllers;
+ // list of hard disk controllers
+ // (one for each VirtualSystem/Item[@ResourceType=6] element with accumulated data from children)
+
+ VirtualDisksMap mapVirtualDisks;
+ // (one for each VirtualSystem/Item[@ResourceType=17] element with accumulated data from children)
+
+ bool fHasFloppyDrive; // true if there's a floppy item in mapHardwareItems
+ bool fHasCdromDrive; // true if there's a CD-ROM item in mapHardwareItems; ISO images are not yet supported by OVFtool
+ bool fHasUsbController; // true if there's a USB controller item in mapHardwareItems
+
+ RTCString strSoundCardType; // if not empty, then the system wants a soundcard; this then specifies the hardware;
+ // VMware Workstation 6.5 uses "ensoniq1371" for example
+
+ RTCString strLicenseText; // license info if any; receives contents of VirtualSystem/EulaSection/License
+
+ RTCString strProduct; // product info if any; receives contents of VirtualSystem/ProductSection/Product
+ RTCString strVendor; // product info if any; receives contents of VirtualSystem/ProductSection/Vendor
+ RTCString strVersion; // product info if any; receives contents of VirtualSystem/ProductSection/Version
+ RTCString strProductUrl; // product info if any; receives contents of VirtualSystem/ProductSection/ProductUrl
+ RTCString strVendorUrl; // product info if any; receives contents of VirtualSystem/ProductSection/VendorUrl
+
+ const xml::ElementNode *pelmVBoxMachine; // pointer to <vbox:Machine> element under <VirtualSystem> element or NULL if not present
+
+ VirtualSystem()
+ : cimos(CIMOSType_CIMOS_Unknown),
+ ullMemorySize(0),
+ cCPUs(1),
+ fHasFloppyDrive(false),
+ fHasCdromDrive(false),
+ fHasUsbController(false),
+ pelmVBoxMachine(NULL)
+ {
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Class OVFReader
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * OVFReader attempts to open, read in and parse an OVF XML file. This is all done
+ * in the constructor; if there is any kind of error in the file -- filesystem error
+ * from IPRT, XML parsing errors from libxml, or OVF logical errors --, exceptions
+ * are thrown. These are all based on xml::Error.
+ *
+ * Hence, use this class as follows:
+<code>
+ OVFReader *pReader = NULL;
+ try
+ {
+ pReader = new("/path/to/file.ovf");
+ }
+ catch (xml::Error &e)
+ {
+ printf("A terrible thing happened: %s", e.what());
+ }
+ // now go look at pReader->m_llVirtualSystem and what's in there
+ if (pReader)
+ delete pReader;
+</code>
+ */
+class OVFReader
+{
+public:
+ OVFReader();
+ OVFReader(const void *pvBuf, size_t cbSize, const RTCString &path);
+ OVFReader(const RTCString &path);
+
+ // Data fields
+ EnvelopeData m_envelopeData; //data of root element "Envelope"
+ RTCString m_strPath; // file name given to constructor
+ DiskImagesMap m_mapDisks; // map of DiskImage structs, sorted by DiskImage.strDiskId
+ std::list<VirtualSystem> m_llVirtualSystems; // list of virtual systems, created by and valid after read()
+
+private:
+ xml::Document m_doc;
+
+ void parse();
+ void LoopThruSections(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pCurElem);
+ void HandleDiskSection(const xml::ElementNode *pReferencesElem, const xml::ElementNode *pSectionElem);
+ void HandleNetworkSection(const xml::ElementNode *pSectionElem);
+ void HandleVirtualSystemContent(const xml::ElementNode *pContentElem);
+};
+
+} // end namespace ovf
+
+#endif /* !MAIN_INCLUDED_ovfreader_h */
+
diff --git a/src/VBox/Main/include/vbox-libhal.h b/src/VBox/Main/include/vbox-libhal.h
new file mode 100644
index 00000000..6e0d0a82
--- /dev/null
+++ b/src/VBox/Main/include/vbox-libhal.h
@@ -0,0 +1,80 @@
+/* $Id: vbox-libhal.h $ */
+/** @file
+ *
+ * Module to dynamically load libhal and libdbus and load all symbols
+ * which are needed by VirtualBox.
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_vbox_libhal_h
+#define MAIN_INCLUDED_vbox_libhal_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <stdint.h>
+
+#define LIB_HAL "libhal.so.1"
+
+/** Types from the dbus and hal header files which we need. These are taken more or less
+ verbatim from the DBus and Hal public interface header files. */
+struct DBusError
+{
+ const char *name;
+ const char *message;
+ unsigned int dummy1 : 1; /**< placeholder */
+ unsigned int dummy2 : 1; /**< placeholder */
+ unsigned int dummy3 : 1; /**< placeholder */
+ unsigned int dummy4 : 1; /**< placeholder */
+ unsigned int dummy5 : 1; /**< placeholder */
+ void *padding1; /**< placeholder */
+};
+struct DBusConnection;
+typedef struct DBusConnection DBusConnection;
+typedef uint32_t dbus_bool_t;
+typedef enum { DBUS_BUS_SESSON, DBUS_BUS_SYSTEM, DBUS_BUS_STARTER } DBusBusType;
+struct LibHalContext_s;
+typedef struct LibHalContext_s LibHalContext;
+
+/** The following are the symbols which we need from libdbus and libhal. */
+extern void (*gDBusErrorInit)(DBusError *);
+extern DBusConnection *(*gDBusBusGet)(DBusBusType, DBusError *);
+extern void (*gDBusErrorFree)(DBusError *);
+extern void (*gDBusConnectionUnref)(DBusConnection *);
+extern LibHalContext *(*gLibHalCtxNew)(void);
+extern dbus_bool_t (*gLibHalCtxSetDBusConnection)(LibHalContext *, DBusConnection *);
+extern dbus_bool_t (*gLibHalCtxInit)(LibHalContext *, DBusError *);
+extern char **(*gLibHalFindDeviceStringMatch)(LibHalContext *, const char *, const char *, int *,
+ DBusError *);
+extern char *(*gLibHalDeviceGetPropertyString)(LibHalContext *, const char *, const char *,
+ DBusError *);
+extern void (*gLibHalFreeString)(char *);
+extern void (*gLibHalFreeStringArray)(char **);
+extern dbus_bool_t (*gLibHalCtxShutdown)(LibHalContext *, DBusError *);
+extern dbus_bool_t (*gLibHalCtxFree)(LibHalContext *);
+
+extern bool gLibHalCheckPresence(void);
+
+#endif /* !MAIN_INCLUDED_vbox_libhal_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/vector.h b/src/VBox/Main/include/vector.h
new file mode 100644
index 00000000..08671457
--- /dev/null
+++ b/src/VBox/Main/include/vector.h
@@ -0,0 +1,372 @@
+/* $Id: vector.h $ */
+/** @file
+ * STL-inspired vector implementation in C
+ * @note functions in this file are inline to prevent warnings about
+ * unused static functions. I assume that in this day and age a
+ * compiler makes its own decisions about whether to actually
+ * inline a function.
+ * @note as this header is included in rdesktop-vrdp, we do not include other
+ * required header files here (to wit assert.h, err.h, mem.h and
+ * types.h). These must be included first. If this moves to iprt, we
+ * should write a wrapper around it doing that.
+ * @todo can we do more of the type checking at compile time somehow?
+ */
+
+/*
+ * Copyright (C) 2008-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_vector_h
+#define MAIN_INCLUDED_vector_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <stdlib.h>
+
+
+/*********************************************************************************************************************************
+* Helper macros and definitions *
+*********************************************************************************************************************************/
+
+/** The unit by which the vector capacity is increased */
+#define VECTOR_ALLOC_UNIT 16
+
+/** Calculate a hash of a string of tokens for sanity type checking */
+#define VECTOR_TOKEN_HASH(token) \
+ ((unsigned) \
+ ( VECTOR_TOKEN_HASH4(token, 0) \
+ ^ VECTOR_TOKEN_HASH4(token, 4) \
+ ^ VECTOR_TOKEN_HASH4(token, 8) \
+ ^ VECTOR_TOKEN_HASH4(token, 12)))
+
+/** Helper macro for @a VECTOR_TOKEN_HASH */
+#define VECTOR_TOKEN_HASH_VALUE(token, place, mul) \
+ (sizeof(#token) > place ? #token[place] * mul : 0)
+
+/** Helper macro for @a VECTOR_TOKEN_HASH */
+#define VECTOR_TOKEN_HASH4(token, place) \
+ VECTOR_TOKEN_HASH_VALUE(token, place, 0x1) \
+ ^ VECTOR_TOKEN_HASH_VALUE(token, place + 1, 0x100) \
+ ^ VECTOR_TOKEN_HASH_VALUE(token, place + 2, 0x10000) \
+ ^ VECTOR_TOKEN_HASH_VALUE(token, place + 3, 0x1000000)
+
+/** Generic vector structure, used by @a VECTOR_OBJ and @a VECTOR_PTR */
+#define VECTOR_STRUCT \
+{ \
+ /** The number of elements in the vector */ \
+ size_t mcElements; \
+ /** The current capacity of the vector */ \
+ size_t mcCapacity; \
+ /** The size of an element */ \
+ size_t mcbElement; \
+ /** Hash value of the element type */ \
+ unsigned muTypeHash; \
+ /** The elements themselves */ \
+ void *mpvaElements; \
+ /** Destructor for elements - takes a pointer to an element. */ \
+ void (*mpfnCleanup)(void *); \
+}
+
+/*** Structure definitions ***/
+
+/** A vector of values or objects */
+typedef struct VECTOR_OBJ VECTOR_STRUCT VECTOR_OBJ;
+
+/** A vector of pointer values. (A handy special case.) */
+typedef struct VECTOR_PTR VECTOR_STRUCT VECTOR_PTR;
+
+/** Convenience macro for annotating the type of the vector. Unfortunately the
+ * type name is only cosmetic. */
+/** @todo can we do something useful with the type? */
+#define VECTOR_OBJ(type) VECTOR_OBJ
+
+/** Convenience macro for annotating the type of the vector. Unfortunately the
+ * type name is only cosmetic. */
+#define VECTOR_PTR(type) VECTOR_PTR
+
+/*** Private helper functions and macros ***/
+
+#define VEC_GET_ELEMENT_OBJ(pvaElements, cbElement, cElement) \
+ ((void *)((char *)(pvaElements) + (cElement) * (cbElement)))
+
+#define VEC_GET_ELEMENT_PTR(pvaElements, cElement) \
+ (*(void **)VEC_GET_ELEMENT_OBJ(pvaElements, sizeof(void *), cElement))
+
+/** Default cleanup function that does nothing. */
+DECLINLINE(void) vecNoCleanup(void *pvElement)
+{
+ (void) pvElement;
+}
+
+/** Expand an existing vector, implementation */
+DECLINLINE(int) vecExpand(size_t *pcCapacity, void **ppvaElements,
+ size_t cbElement)
+{
+ size_t cOldCap, cNewCap;
+ void *pRealloc;
+
+ cOldCap = *pcCapacity;
+ cNewCap = cOldCap + VECTOR_ALLOC_UNIT;
+ pRealloc = RTMemRealloc(*ppvaElements, cNewCap * cbElement);
+ if (!pRealloc)
+ return VERR_NO_MEMORY;
+ *pcCapacity = cNewCap;
+ *ppvaElements = pRealloc;
+ return VINF_SUCCESS;
+}
+
+/** Expand an existing vector */
+#define VEC_EXPAND(pvec) vecExpand(&(pvec)->mcCapacity, &(pvec)->mpvaElements, \
+ (pvec)->mcbElement)
+
+/** Reset a vector, cleaning up all its elements. */
+DECLINLINE(void) vecClearObj(VECTOR_OBJ *pvec)
+{
+ unsigned i;
+
+ for (i = 0; i < pvec->mcElements; ++i)
+ pvec->mpfnCleanup(VEC_GET_ELEMENT_OBJ(pvec->mpvaElements,
+ pvec->mcbElement, i));
+ pvec->mcElements = 0;
+}
+
+/** Reset a pointer vector, cleaning up all its elements. */
+DECLINLINE(void) vecClearPtr(VECTOR_PTR *pvec)
+{
+ unsigned i;
+
+ for (i = 0; i < pvec->mcElements; ++i)
+ pvec->mpfnCleanup(VEC_GET_ELEMENT_PTR(pvec->mpvaElements, i));
+ pvec->mcElements = 0;
+}
+
+/** Clean up a vector */
+DECLINLINE(void) vecCleanupObj(VECTOR_OBJ *pvec)
+{
+ vecClearObj(pvec);
+ RTMemFree(pvec->mpvaElements);
+ pvec->mpvaElements = NULL;
+}
+
+/** Clean up a pointer vector */
+DECLINLINE(void) vecCleanupPtr(VECTOR_PTR *pvec)
+{
+ vecClearPtr(pvec);
+ RTMemFree(pvec->mpvaElements);
+ pvec->mpvaElements = NULL;
+}
+
+/** Initialise a vector structure, implementation */
+#define VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup) \
+ pvec->mcElements = pvec->mcCapacity = 0; \
+ pvec->mcbElement = cbElement; \
+ pvec->muTypeHash = uTypeHash; \
+ pvec->mpfnCleanup = pfnCleanup ? pfnCleanup : vecNoCleanup; \
+ pvec->mpvaElements = NULL;
+
+/** Initialise a vector. */
+DECLINLINE(void) vecInitObj(VECTOR_OBJ *pvec, size_t cbElement,
+ unsigned uTypeHash, void (*pfnCleanup)(void *))
+{
+ VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup)
+}
+
+/** Initialise a pointer vector. */
+DECLINLINE(void) vecInitPtr(VECTOR_PTR *pvec, size_t cbElement,
+ unsigned uTypeHash, void (*pfnCleanup)(void *))
+{
+ VEC_INIT(pvec, cbElement, uTypeHash, pfnCleanup)
+}
+
+/** Add an element onto the end of a vector */
+DECLINLINE(int) vecPushBackObj(VECTOR_OBJ *pvec, unsigned uTypeHash,
+ void *pvElement)
+{
+ AssertReturn(pvec->muTypeHash == uTypeHash, VERR_INVALID_PARAMETER);
+ if (pvec->mcElements == pvec->mcCapacity)
+ {
+ int vrc2 = VEC_EXPAND(pvec);
+ if (RT_FAILURE(vrc2))
+ return vrc2;
+ }
+ memcpy(VEC_GET_ELEMENT_OBJ(pvec->mpvaElements, pvec->mcbElement,
+ pvec->mcElements), pvElement, pvec->mcbElement);
+ ++pvec->mcElements;
+ return VINF_SUCCESS;
+}
+
+/** Add a pointer onto the end of a pointer vector */
+DECLINLINE(int) vecPushBackPtr(VECTOR_PTR *pvec, unsigned uTypeHash,
+ void *pv)
+{
+ AssertReturn(pvec->muTypeHash == uTypeHash, VERR_INVALID_PARAMETER);
+ if (pvec->mcElements == pvec->mcCapacity)
+ {
+ int vrc2 = VEC_EXPAND(pvec);
+ if (RT_FAILURE(vrc2))
+ return vrc2;
+ }
+ VEC_GET_ELEMENT_PTR(pvec->mpvaElements, pvec->mcElements) = pv;
+ ++pvec->mcElements;
+ return VINF_SUCCESS;
+}
+
+
+/*********************************************************************************************************************************
+* Public interface macros *
+*********************************************************************************************************************************/
+
+/**
+ * Initialise a vector structure. Always succeeds.
+ * @param pvec pointer to an uninitialised vector structure
+ * @param type the type of the objects in the vector. As this is
+ * hashed by the preprocessor use of space etc is
+ * important.
+ * @param pfnCleanup cleanup function (void (*pfn)(void *)) that is called
+ * on a pointer to a vector element when that element is
+ * dropped
+ */
+#define VEC_INIT_OBJ(pvec, type, pfnCleanup) \
+ vecInitObj(pvec, sizeof(type), VECTOR_TOKEN_HASH(type), \
+ (void (*)(void*)) pfnCleanup)
+
+/**
+ * Initialise a vector-of-pointers structure. Always succeeds.
+ * @param pvec pointer to an uninitialised vector structure
+ * @param type the type of the pointers in the vector, including the
+ * final "*". As this is hashed by the preprocessor use
+ * of space etc is important.
+ * @param pfnCleanup cleanup function (void (*pfn)(void *)) that is called
+ * directly on a vector element when that element is
+ * dropped
+ */
+#define VEC_INIT_PTR(pvec, type, pfnCleanup) \
+ vecInitPtr(pvec, sizeof(type), VECTOR_TOKEN_HASH(type), \
+ (void (*)(void*)) pfnCleanup)
+
+/**
+ * Clean up a vector.
+ * @param pvec pointer to the vector to clean up. The clean up function
+ * specified at initialisation (if any) is called for each element
+ * in the vector. After clean up, the vector structure is invalid
+ * until it is re-initialised
+ */
+#define VEC_CLEANUP_OBJ vecCleanupObj
+
+/**
+ * Clean up a vector-of-pointers.
+ * @param pvec pointer to the vector to clean up. The clean up function
+ * specified at initialisation (if any) is called for each element
+ * in the vector. After clean up, the vector structure is invalid
+ * until it is re-initialised
+ */
+#define VEC_CLEANUP_PTR vecCleanupPtr
+
+/**
+ * Reinitialises a vector structure to empty.
+ * @param pvec pointer to the vector to re-initialise. The clean up function
+ * specified at initialisation (if any) is called for each element
+ * in the vector.
+ */
+#define VEC_CLEAR_OBJ vecClearObj
+
+/**
+ * Reinitialises a vector-of-pointers structure to empty.
+ * @param pvec pointer to the vector to re-initialise. The clean up function
+ * specified at initialisation (if any) is called for each element
+ * in the vector.
+ */
+#define VEC_CLEAR_PTR vecClearPtr
+
+/**
+ * Adds an element to the back of a vector. The element will be byte-copied
+ * and become owned by the vector, to be cleaned up by the vector's clean-up
+ * routine when the element is dropped.
+ * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY)
+ * @returns VERR_INVALID_PARAMETER if the type does not match the type given
+ * when the vector was initialised (asserted)
+ * @param pvec pointer to the vector on to which the element should be
+ * added
+ * @param type the type of the vector as specified at initialisation.
+ * Spacing etc is important.
+ * @param pvElement void pointer to the element to be added
+ */
+#define VEC_PUSH_BACK_OBJ(pvec, type, pvElement) \
+ vecPushBackObj(pvec, VECTOR_TOKEN_HASH(type), \
+ (pvElement) + ((pvElement) - (type *)(pvElement)))
+
+/**
+ * Adds a pointer to the back of a vector-of-pointers. The pointer will become
+ * owned by the vector, to be cleaned up by the vector's clean-up routine when
+ * it is dropped.
+ * @returns iprt status code (VINF_SUCCESS or VERR_NO_MEMORY)
+ * @returns VERR_INVALID_PARAMETER if the type does not match the type given
+ * when the vector was initialised (asserted)
+ * @param pvec pointer to the vector on to which the element should be
+ * added
+ * @param type the type of the vector as specified at initialisation.
+ * Spacing etc is important.
+ * @param pvElement the pointer to be added, typecast to pointer-to-void
+ */
+#define VEC_PUSH_BACK_PTR(pvec, type, pvElement) \
+ vecPushBackPtr(pvec, VECTOR_TOKEN_HASH(type), \
+ (pvElement) + ((pvElement) - (type)(pvElement)))
+
+/**
+ * Returns the count of elements in a vector.
+ * @param pvec pointer to the vector.
+ */
+#define VEC_SIZE_OBJ(pvec) (pvec)->mcElements
+
+/**
+ * Returns the count of elements in a vector-of-pointers.
+ * @param pvec pointer to the vector.
+ */
+#define VEC_SIZE_PTR VEC_SIZE_OBJ
+
+/**
+ * Iterates over a vector.
+ *
+ * Iterates over the vector elements from first to last and execute the
+ * following instruction or block on each iteration with @a pIterator set to
+ * point to the current element (that is, a pointer to the pointer element for
+ * a vector-of-pointers). Use in the same way as a "for" statement.
+ *
+ * @param pvec Pointer to the vector to be iterated over.
+ * @param type The type of the vector, must match the type specified at
+ * vector initialisation (including whitespace etc).
+ * @param pIterator A pointer to @a type which will be set to point to the
+ * current vector element on each iteration.
+ *
+ * @todo can we assert the correctness of the type in some way?
+ */
+#define VEC_FOR_EACH(pvec, type, pIterator) \
+ for (pIterator = (type *) (pvec)->mpvaElements; \
+ (pvec)->muTypeHash == VECTOR_TOKEN_HASH(type) \
+ && pIterator < (type *) (pvec)->mpvaElements + (pvec)->mcElements; \
+ ++pIterator)
+
+#endif /* !MAIN_INCLUDED_vector_h */
diff --git a/src/VBox/Main/include/win/resource.h b/src/VBox/Main/include/win/resource.h
new file mode 100644
index 00000000..d6aeecdc
--- /dev/null
+++ b/src/VBox/Main/include/win/resource.h
@@ -0,0 +1,43 @@
+/* $Id: resource.h $ */
+/** @file
+ *
+ * Resource definitions
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef MAIN_INCLUDED_win_resource_h
+#define MAIN_INCLUDED_win_resource_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+// registry script resource ID
+#define IDR_VIRTUALBOX 101
+
+// service name string resource ID
+#define IDS_SERVICENAME 102
+
+
+#endif /* !MAIN_INCLUDED_win_resource_h */