summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/VBox/Additions/3D/Config.kmk5
-rw-r--r--src/VBox/Additions/darwin/VBoxClient/VBoxClientClipboardGuestToHost.cpp2
-rw-r--r--src/VBox/Additions/linux/drm/vbox_drv.c2
-rw-r--r--src/VBox/Additions/linux/drm/vbox_fb.c4
-rw-r--r--src/VBox/Devices/Audio/AudioMixer.cpp14
-rw-r--r--src/VBox/Devices/Audio/DevHdaCodec.cpp54
-rw-r--r--src/VBox/Devices/Audio/DevHdaCodec.h3
-rw-r--r--src/VBox/Devices/Config.kmk12
-rw-r--r--src/VBox/Devices/EFI/DevEFI.cpp12
-rw-r--r--src/VBox/Devices/EFI/DevEFI.h1
-rw-r--r--src/VBox/Devices/EFI/Firmware/Makefile.kmk6
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c46
-rw-r--r--src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fdbin4194304 -> 4194304 bytes
-rw-r--r--src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fdbin4194304 -> 4194304 bytes
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm6
-rw-r--r--src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum2
-rw-r--r--src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp21
-rw-r--r--src/VBox/Devices/Graphics/DevVGA-SVGA.cpp38
-rw-r--r--src/VBox/Devices/Makefile.kmk1
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum2
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum2
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm4
-rw-r--r--src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum2
-rw-r--r--src/VBox/Devices/PC/vbox-tpm.dsl269
-rw-r--r--src/VBox/Devices/Security/DevTpmPpi.cpp453
-rw-r--r--src/VBox/Devices/USB/DevEHCI.cpp41
-rw-r--r--src/VBox/Devices/USB/DrvVUSBRootHub.cpp13
-rw-r--r--src/VBox/Devices/USB/VUSBInternal.h2
-rw-r--r--src/VBox/Devices/USB/VUSBUrb.cpp2
-rw-r--r--src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp37
-rw-r--r--src/VBox/Devices/VirtIO/VirtioCore.cpp9
-rw-r--r--src/VBox/Devices/build/VBoxDD.cpp4
-rw-r--r--src/VBox/Devices/build/VBoxDD.h1
-rw-r--r--src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp90
-rw-r--r--src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardGH-X11.cpp6
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c50
-rw-r--r--src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp2
-rw-r--r--src/VBox/Installer/darwin/Makefile.kmk4
-rw-r--r--src/VBox/Installer/linux/distributions_deb1
-rw-r--r--src/VBox/Installer/win/UserInterface.wxi7
-rw-r--r--src/VBox/Main/Certificates/microsoft_corporation_kek_2k_ca_2023.crtbin0 -> 1462 bytes
-rw-r--r--src/VBox/Main/Certificates/microsoft_uefi_ca_2023.crtbin0 -> 1448 bytes
-rw-r--r--src/VBox/Main/Certificates/windows_uefi_ca_2023.crtbin0 -> 1454 bytes
-rw-r--r--src/VBox/Main/Makefile.kmk16
-rw-r--r--src/VBox/Main/include/GuestSessionImplTasks.h2
-rw-r--r--src/VBox/Main/include/TrustAnchorsAndCerts.h17
-rw-r--r--src/VBox/Main/include/netif.h7
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl.cpp17
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl2.cpp114
-rw-r--r--src/VBox/Main/src-client/GuestSessionImplTasks.cpp190
-rw-r--r--src/VBox/Main/src-client/RecordingStream.cpp10
-rw-r--r--src/VBox/Main/src-server/UefiVariableStoreImpl.cpp19
-rw-r--r--src/VBox/Main/src-server/linux/NetIf-linux.cpp21
-rw-r--r--src/VBox/Runtime/common/efi/efisignaturedb.cpp54
-rw-r--r--src/VBox/Runtime/common/vfs/vfsmemory.cpp31
-rw-r--r--src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c14
-rw-r--r--src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp19
-rw-r--r--src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp4
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp14
-rw-r--r--src/VBox/VMM/VMMAll/TMAll.cpp14
-rw-r--r--src/VBox/VMM/VMMR3/PDM.cpp8
-rw-r--r--src/VBox/ValidationKit/Config.kmk9
-rw-r--r--src/bldprogs/VBoxPeSetVersion.cpp201
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp90
71 files changed, 1743 insertions, 384 deletions
diff --git a/src/VBox/Additions/3D/Config.kmk b/src/VBox/Additions/3D/Config.kmk
index 1f6fc5c3..1392a884 100644
--- a/src/VBox/Additions/3D/Config.kmk
+++ b/src/VBox/Additions/3D/Config.kmk
@@ -132,10 +132,9 @@ TEMPLATE_VBoxMesa3DGuestR3DllMinVista = VBox Mesa 3D Guest U
TEMPLATE_VBoxMesa3DGuestR3DllMinVista_EXTENDS = VBoxMesa3DGuestR3Dll
TEMPLATE_VBoxMesa3DGuestR3DllMinVista_VBOX_IMPORT_CHECKER.win.x86 := vista
TEMPLATE_VBoxMesa3DGuestR3DllMinVista_VBOX_IMPORT_CHECKER.win.amd64 := vista
+TEMPLATE_VBoxMesa3DGuestR3DllMinVista_VBOX_SET_PE_VERSION.win.x86 := vista
+TEMPLATE_VBoxMesa3DGuestR3DllMinVista_VBOX_SET_PE_VERSION.win.amd64 := vista
ifeq ($(KBUILD_TARGET),win)
TEMPLATE_VBoxMesa3DGuestR3DllMinVista_LDFLAGS.win.x86 = $(filter-out -Section:.bss$(COMMA)RW!K,$(TEMPLATE_VBoxMesa3DGuestR3Dll_LDFLAGS.win.x86))
- TEMPLATE_VBoxMesa3DGuestR3DllMinVista_POST_CMDS.win.x86 = $(subst $(VBOX_PE_SET_VERSION), $(VBOX_PE_SET_VERSION) --vista,$(TEMPLATE_VBoxMesa3DGuestR3Dll_POST_CMDS.win.x86))
- TEMPLATE_VBoxMesa3DGuestR3DllMinVista_POST_CMDS.win.amd64 = $(if $(eq $(tool_do),LINK_LIBRARY),,$(VBOX_PE_SET_VERSION) --vista $(out)$$(NLTAB)$(TEMPLATE_VBoxMesa3DGuestR3Dll_POST_CMDS.win.amd64))
- TEMPLATE_VBoxMesa3DGuestR3DllMinVista_LNK_DEPS.win.amd64 = $(if $(eq $(tool_do),LINK_LIBRARY),,$(VBOX_PE_SET_VERSION)) $(TEMPLATE_VBoxMesa3DGuestR3Dll_LNK_DEPS.win.amd64)
endif
diff --git a/src/VBox/Additions/darwin/VBoxClient/VBoxClientClipboardGuestToHost.cpp b/src/VBox/Additions/darwin/VBoxClient/VBoxClientClipboardGuestToHost.cpp
index 2cef7257..c04ddddb 100644
--- a/src/VBox/Additions/darwin/VBoxClient/VBoxClientClipboardGuestToHost.cpp
+++ b/src/VBox/Additions/darwin/VBoxClient/VBoxClientClipboardGuestToHost.cpp
@@ -231,7 +231,7 @@ static int vbclClipboardHostPasteText(uint32_t u32ClientId, PRTUTF16 pwszData, u
AssertPtrReturn(pwszData, VERR_INVALID_POINTER);
size_t cwcTmp; /* (includes a schwarzenegger character) */
- int rc = ShClUtf16LFLenUtf8(pwszData, cbData / sizeof(RTUTF16), &cwcTmp);
+ int rc = ShClUtf16CalcNormalizedEolToCRLFLength(pwszData, cbData / sizeof(RTUTF16), &cwcTmp);
AssertRCReturn(rc, rc);
cwcTmp++; /* Add space for terminator. */
diff --git a/src/VBox/Additions/linux/drm/vbox_drv.c b/src/VBox/Additions/linux/drm/vbox_drv.c
index 7d2561dd..1712c2b7 100644
--- a/src/VBox/Additions/linux/drm/vbox_drv.c
+++ b/src/VBox/Additions/linux/drm/vbox_drv.c
@@ -395,7 +395,7 @@ static struct drm_driver driver = {
#endif
.gem_prime_import = drm_gem_prime_import,
.gem_prime_import_sg_table = vbox_gem_prime_import_sg_table,
-#if RTLNX_VER_MAX(6,6,0) && !RTLNX_RHEL_RANGE(9,4, 9,99)
+#if RTLNX_VER_MAX(6,6,0) && !RTLNX_RHEL_RANGE(9,4, 9,99) && !RTLNX_SUSE_MAJ_PREREQ(15, 6)
.gem_prime_mmap = vbox_gem_prime_mmap,
#endif
diff --git a/src/VBox/Additions/linux/drm/vbox_fb.c b/src/VBox/Additions/linux/drm/vbox_fb.c
index 37cf7ef1..d484163e 100644
--- a/src/VBox/Additions/linux/drm/vbox_fb.c
+++ b/src/VBox/Additions/linux/drm/vbox_fb.c
@@ -196,7 +196,7 @@ static struct fb_ops vboxfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
-#if RTLNX_VER_MIN(6,5,0) || RTLNX_RHEL_RANGE(9,4, 9,99)
+#if RTLNX_VER_MIN(6,5,0) || RTLNX_RHEL_RANGE(9,4, 9,99) || RTLNX_SUSE_MAJ_PREREQ(15, 6)
.fb_read = fb_sys_read,
.fb_write = fb_sys_write,
.fb_fillrect = sys_fillrect,
@@ -351,7 +351,7 @@ static int vboxfb_create(struct drm_fb_helper *helper,
* The last flag forces a mode set on VT switches even if the kernel
* does not think it is needed.
*/
-#if RTLNX_VER_MIN(6,6,0)
+#if RTLNX_VER_MIN(6,6,0) || RTLNX_SUSE_MAJ_PREREQ(15, 6)
info->flags = FBINFO_MISC_ALWAYS_SETPAR;
#else
info->flags = FBINFO_DEFAULT | FBINFO_MISC_ALWAYS_SETPAR;
diff --git a/src/VBox/Devices/Audio/AudioMixer.cpp b/src/VBox/Devices/Audio/AudioMixer.cpp
index 899154eb..071e997f 100644
--- a/src/VBox/Devices/Audio/AudioMixer.cpp
+++ b/src/VBox/Devices/Audio/AudioMixer.cpp
@@ -311,9 +311,13 @@ int AudioMixerSetMasterVolume(PAUDIOMIXER pMixer, PCPDMAUDIOVOLUME pVol)
*/
LogFlowFunc(("[%s] fMuted=%RTbool auChannels=%.*Rhxs => fMuted=%RTbool auChannels=%.*Rhxs\n", pMixer->pszName,
pMixer->VolMaster.fMuted, sizeof(pMixer->VolMaster.auChannels), pMixer->VolMaster.auChannels,
- pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels ));
+ pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
memcpy(&pMixer->VolMaster, pVol, sizeof(PDMAUDIOVOLUME));
+ LogRelMax(256, ("Audio Mixer: %s master volume of '%s' -- channel volumes: %.*Rhxs\n",
+ pMixer->VolMaster.fMuted ? "MUTING" : "Setting",
+ pMixer->pszName, sizeof(pMixer->VolMaster.auChannels), pMixer->VolMaster.auChannels));
+
/*
* Propagate new master volume to all sinks.
*/
@@ -1108,6 +1112,11 @@ static int audioMixerSinkUpdateVolume(PAUDMIXSINK pSink, PCPDMAUDIOVOLUME pVolMa
pSink->Volume.fMuted, sizeof(pSink->Volume.auChannels), pSink->Volume.auChannels,
pSink->VolumeCombined.fMuted, sizeof(pSink->VolumeCombined.auChannels), pSink->VolumeCombined.auChannels ));
+ LogRelMax(256, ("Audio Mixer: %s sink '%s/%s' -- channel volumes: %.*Rhxs\n",
+ pSink->VolumeCombined.fMuted ? "MUTING" : "Setting",
+ pSink->pParent->pszName, pSink->pszName,
+ sizeof(pSink->VolumeCombined.auChannels), pSink->VolumeCombined.auChannels));
+
AudioMixBufSetVolume(&pSink->MixBuf, &pSink->VolumeCombined);
return VINF_SUCCESS;
}
@@ -1131,9 +1140,6 @@ int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PCPDMAUDIOVOLUME pVol)
memcpy(&pSink->Volume, pVol, sizeof(PDMAUDIOVOLUME));
- LogRel2(("Audio Mixer: Setting volume of sink '%s' to fMuted=%RTbool auChannels=%.*Rhxs\n",
- pSink->pszName, pVol->fMuted, sizeof(pVol->auChannels), pVol->auChannels));
-
Assert(pSink->pParent);
if (pSink->pParent)
rc = audioMixerSinkUpdateVolume(pSink, &pSink->pParent->VolMaster);
diff --git a/src/VBox/Devices/Audio/DevHdaCodec.cpp b/src/VBox/Devices/Audio/DevHdaCodec.cpp
index 9782ac7f..4ea275fd 100644
--- a/src/VBox/Devices/Audio/DevHdaCodec.cpp
+++ b/src/VBox/Devices/Audio/DevHdaCodec.cpp
@@ -805,7 +805,8 @@ static int stac9220Construct(PHDACODECR3 pThis, HDACODECCFG *pCfg)
AssertCompile(STAC9221_NUM_NODES <= RT_ELEMENTS(pThis->aNodes));
pCfg->cTotalNodes = STAC9221_NUM_NODES;
- pCfg->idxAdcVolsLineIn = STAC9220_NID_AMP_ADC0;
+ pCfg->idxAdcVolsLineIn = STAC9220_NID_AMP_ADC0; /* We treat ADC0 as Line-In. */
+ pCfg->idxAdcVolsMicIn = STAC9220_NID_AMP_ADC1; /* We treat ADC1 as Mic-In. */
pCfg->idxDacLineOut = STAC9220_NID_DAC1;
/* Copy over the node class lists and popuplate afNodeClassifications. */
@@ -2105,25 +2106,42 @@ static DECLCALLBACK(int) vrbProcR3SetAmplifier(PHDACODECR3 pThis, uint32_t uCmd,
if (fIsRight)
hdaCodecSetRegisterU8(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), uCmd, 0);
- /*
- * Check if the node ID is the one we use for controlling the line-in volume;
- * with STAC9220 this is connected to STAC9220_NID_AMP_ADC0 (ID 0x17).
- *
- * If we don't do this check here, some guests like newer Ubuntus mute mic-in
- * afterwards (connected to STAC9220_NID_AMP_ADC1 (ID 0x18)). This then would
- * also mute line-in, which breaks audio recording.
- *
- * See STAC9220 V1.0 01/08, p. 30 + oem2ticketref:53.
- */
- if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsLineIn)
- hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
-
-#ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
-# error "Implement mic-in volume / mute setting."
- else if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsMicIn)
- hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_MIC_IN);
+ switch (pThis->Cfg.enmType)
+ {
+ case CODECTYPE_STAC9220:
+ {
+ /*
+ * Check if the node ID is the one we use for controlling the recording (capturing) volume + mute status.
+ *
+ * The STAC9220 codec is connected to STAC9220_NID_AMP_ADC0 (ID 0x17) and
+ * STAC9220_NID_AMP_ADC0 (ID 0x18).
+ *
+ * If we don't do this check here, some guests like newer Ubuntus mute mic-in
+ * afterwards (connected to STAC9220_NID_AMP_ADC1 (ID 0x18)). This then would
+ * also mute line-in, which breaks audio recording.
+ *
+ * See STAC9220 V1.0 01/08, p. 30 + @oem2ticketref{53}.
+ */
+ if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsLineIn)
+ hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
+
+#ifdef VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN
+ /* Newer Windows 10 versions use STAC9220_NID_AMP_ADC1 (ID 0x18) for microphone
+ * volume control by default. */
+# ifndef VBOX_WITH_AUDIO_HDA_MIC_IN
+ /* If we don't implement dedicated microphone-in support (we then only offer recording via line-in),
+ * make sure to propagate volume control from mic-in to our line-in mixer control. See @oem2ticketref{93}. */
+ else if (CODEC_NID(uCmd) == pThis->Cfg.idxAdcVolsMicIn)
+ hdaR3CodecToAudVolume(pThis, pNode, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN);
+# endif
#endif
+ break;
+ }
+ default:
+ /* Nothing to do here. */
+ break;
+ }
}
if (fIsOut)
{
diff --git a/src/VBox/Devices/Audio/DevHdaCodec.h b/src/VBox/Devices/Audio/DevHdaCodec.h
index 00890922..52e52bf7 100644
--- a/src/VBox/Devices/Audio/DevHdaCodec.h
+++ b/src/VBox/Devices/Audio/DevHdaCodec.h
@@ -836,11 +836,12 @@ typedef struct HDACODECCFG
uint8_t cTotalNodes;
uint8_t idxAdcVolsLineIn;
+ uint8_t idxAdcVolsMicIn;
uint8_t idxDacLineOut;
/** Align the lists below so they don't cross cache lines (assumes
* CODEC_NODES_MAX is 32). */
- uint8_t const abPadding1[CODEC_NODES_MAX - 15];
+ uint8_t const abPadding1[CODEC_NODES_MAX - 16];
/** @name Node classifications.
* @note These are copies of the g_abStac9220Xxxx arrays in DevHdaCodec.cpp.
diff --git a/src/VBox/Devices/Config.kmk b/src/VBox/Devices/Config.kmk
index f24024f8..335a83eb 100644
--- a/src/VBox/Devices/Config.kmk
+++ b/src/VBox/Devices/Config.kmk
@@ -112,7 +112,7 @@ TEMPLATE_VBoxBios32Lib_POST_CMDS = $(NO_SUCH_VARIABLE)
#
VBOX_AUDIO_DEFS :=
if 0 # Not stable yet.
- # Enable microphone-in support for HDA. Otherwise only line-in is supported.
+ # Enable dedicated microphone-in support for HDA. Otherwise only line-in is supported.
VBOX_AUDIO_DEFS += VBOX_WITH_AUDIO_HDA_MIC_IN
# Enable interleavig streams support for HDA. Needed for 5.1 surround support.
@@ -123,6 +123,16 @@ if 0 # Not stable yet.
VBOX_AUDIO_DEFS += VBOX_WITH_AUDIO_HDA_51_SURROUND
endif
+# If dedicated microphone-in support for HDA isn't enabled, treat mic-in as line-in to
+# propagate the volume (+ mute) settings appropriately.
+ifndef VBOX_WITH_AUDIO_HDA_MIC_IN
+ VBOX_AUDIO_DEFS += VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN
+endif
+
+if defined(VBOX_WITH_AUDIO_HDA_MIC_IN) && defined(VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN)
+ $(error Defining VBOX_WITH_AUDIO_HDA_MIC_IN and VBOX_AUDIO_HDA_MIC_IN_AS_LINE_IN at the same time makes no sense!)
+endif
+
# Enable backend-independent device enumeration support.
VBOX_AUDIO_DEFS += VBOX_WITH_AUDIO_ENUM
diff --git a/src/VBox/Devices/EFI/DevEFI.cpp b/src/VBox/Devices/EFI/DevEFI.cpp
index e14f6858..35b6cca7 100644
--- a/src/VBox/Devices/EFI/DevEFI.cpp
+++ b/src/VBox/Devices/EFI/DevEFI.cpp
@@ -201,6 +201,8 @@ typedef struct DEVEFIR3
uint64_t u64McfgBase;
/** Length of PCI config space MMIO region */
uint64_t cbMcfgLength;
+ /** Physical address of the TPM PPI area. */
+ uint64_t u64TpmPpiBase;
/** Size of the configured NVRAM device. */
uint32_t cbNvram;
/** Start address of the NVRAM flash. */
@@ -331,6 +333,7 @@ static uint32_t efiInfoSize(PDEVEFIR3 pThisCC)
case EFI_INFO_INDEX_TSC_FREQUENCY:
case EFI_INFO_INDEX_MCFG_BASE:
case EFI_INFO_INDEX_MCFG_SIZE:
+ case EFI_INFO_INDEX_TPM_PPI_BASE:
return 8;
case EFI_INFO_INDEX_APIC_MODE:
return 1;
@@ -433,6 +436,7 @@ static uint8_t efiInfoNextByte(PDEVEFIR3 pThisCC)
case EFI_INFO_INDEX_MCFG_BASE: return efiInfoNextByteU64(pThisCC, pThisCC->u64McfgBase);
case EFI_INFO_INDEX_MCFG_SIZE: return efiInfoNextByteU64(pThisCC, pThisCC->cbMcfgLength);
case EFI_INFO_INDEX_APIC_MODE: return efiInfoNextByteU8(pThisCC, pThisCC->u8APIC);
+ case EFI_INFO_INDEX_TPM_PPI_BASE: return efiInfoNextByteU64(pThisCC, pThisCC->u64TpmPpiBase);
default:
PDMDevHlpDBGFStop(pThisCC->pDevIns, RT_SRC_POS, "%#x", pThisCC->iInfoSelector);
@@ -1567,7 +1571,8 @@ static DECLCALLBACK(int) efiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
"UgaHorizontalResolution|" // legacy
"UgaVerticalResolution|" // legacy
"GraphicsResolution|"
- "NvramFile", "");
+ "NvramFile|"
+ "TpmPpiBase", "");
/* CPU count (optional). */
rc = pHlp->pfnCFGMQueryU32Def(pCfg, "NumCPUs", &pThisCC->cCpus, 1);
@@ -1765,6 +1770,11 @@ static DECLCALLBACK(int) efiConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMN
return PDMDEV_SET_ERROR(pDevIns, rc,
N_("Configuration error: Querying \"NvramFile\" as a string failed"));
+ rc = pHlp->pfnCFGMQueryU64Def(pCfg, "TpmPpiBase", &pThisCC->u64TpmPpiBase, 0);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Querying \"TpmPpiBase\" as integer failed"));
+
/*
* Load firmware volume and thunk ROM.
*/
diff --git a/src/VBox/Devices/EFI/DevEFI.h b/src/VBox/Devices/EFI/DevEFI.h
index 400f537a..704035d4 100644
--- a/src/VBox/Devices/EFI/DevEFI.h
+++ b/src/VBox/Devices/EFI/DevEFI.h
@@ -84,6 +84,7 @@ typedef enum
EFI_INFO_INDEX_APIC_MODE,
EFI_INFO_INDEX_CPU_COUNT_CURRENT,
EFI_INFO_INDEX_CPU_COUNT_MAX,
+ EFI_INFO_INDEX_TPM_PPI_BASE,
EFI_INFO_INDEX_END
} EfiInfoIndex;
diff --git a/src/VBox/Devices/EFI/Firmware/Makefile.kmk b/src/VBox/Devices/EFI/Firmware/Makefile.kmk
index 02395eb5..7f597026 100644
--- a/src/VBox/Devices/EFI/Firmware/Makefile.kmk
+++ b/src/VBox/Devices/EFI/Firmware/Makefile.kmk
@@ -198,15 +198,15 @@ if1of ($(KBUILD_HOST), win)
VBOX_EFI_REDIRECT_E_EQUAL := $(EQUAL)
VBOX_EFI_BUILD_CMD = $(REDIRECT) \
-E 'PATH=$(VBOX_PATH_STAGE_EFI_BLDPROGS)$(VBOX_SEP)$(PATH);' \
- -E 'INCLUDE=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_SEP)$(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)$(INCLUDE);' \
+ -E 'INCLUDE=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_PATH_EFI_FIRMWARE)/..$(VBOX_SEP)$(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)$(INCLUDE);' \
-E 'COMSPEC=$(firstword $(windir) $(SystemRoot) C:\windows)\system32\cmd.exe' \
-E 'MAKEFLAGS='
else
VBOX_EFI_REDIRECT_E_EQUAL :=
VBOX_EFI_BUILD_CMD = $(REDIRECT) \
-E "PATH=$(VBOX_PATH_STAGE_EFI_BLDPROGS)$(VBOX_SEP)$(PATH)" \
- -E "C_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(C_INCLUDE_PATH)" \
- -E "CPLUS_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(C_INCLUDE_PATH)"
+ -E "C_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_PATH_EFI_FIRMWARE)/..$(VBOX_SEP)$(C_INCLUDE_PATH)" \
+ -E "CPLUS_INCLUDE_PATH=$(PATH_ROOT)/include$(VBOX_SEP)$(PATH_OUT)$(VBOX_SEP)$(VBOX_PATH_EFI_FIRMWARE)/..$(VBOX_SEP)$(CPLUS_INCLUDE_PATH)"
endif
VBOX_EFI_BUILD_CMD += \
-E 'PYTHONPATH=$(VBOX_PATH_EFI_FIRMWARE)/BaseTools/Source/Python' \
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c
index 226743dc..29e53bc9 100644
--- a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.c
@@ -35,6 +35,33 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/Tcg2PhysicalPresenceLib.h>
+#if defined(VBOX)
+# define IN_RING0
+# include "../../../../DevEFI.h"
+# include "iprt/cdefs.h" /* RT_ARCH_XXX */
+
+# if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
+# include "iprt/asm-amd64-x86.h"
+
+/*
+ * Internal Functions
+ */
+static UINT32
+GetVmVariable(UINT32 Variable, CHAR8 *pbBuf, UINT32 cbBuf)
+{
+ UINT32 cbVar, offBuf;
+
+ ASMOutU32(EFI_INFO_PORT, Variable);
+ cbVar = ASMInU32(EFI_INFO_PORT);
+
+ for (offBuf = 0; offBuf < cbVar && offBuf < cbBuf; offBuf++)
+ pbBuf[offBuf] = ASMInU8(EFI_INFO_PORT);
+
+ return cbVar;
+}
+# endif
+#endif
+
#define CONFIRM_BUFFER_SIZE 4096
EFI_HII_HANDLE mTcg2PpStringPackHandle;
@@ -44,6 +71,8 @@ EFI_HII_HANDLE mTcg2PpStringPackHandle;
STATIC volatile QEMU_TPM_PPI *mPpi;
+#if !defined(VBOX) \
+ || (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64))
/**
Reads QEMU PPI config from fw_cfg.
@@ -75,6 +104,7 @@ QemuTpmReadConfig (
QemuFwCfgReadBytes (sizeof (*Config), Config);
return EFI_SUCCESS;
}
+#endif
/**
@@ -90,7 +120,9 @@ QemuTpmInitPPI (
)
{
EFI_STATUS Status;
+#ifndef VBOX
QEMU_FWCFG_TPM_CONFIG Config;
+#endif
EFI_PHYSICAL_ADDRESS PpiAddress64;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINTN Idx;
@@ -99,6 +131,8 @@ QemuTpmInitPPI (
return EFI_SUCCESS;
}
+#if !defined(VBOX) \
+ || (!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64))
Status = QemuTpmReadConfig (&Config);
if (EFI_ERROR (Status)) {
return Status;
@@ -108,6 +142,14 @@ QemuTpmInitPPI (
if (mPpi == NULL) {
return EFI_PROTOCOL_ERROR;
}
+#else
+ uint64_t u64TpmPpiBase = 0;
+ if ( GetVmVariable(EFI_INFO_INDEX_TPM_PPI_BASE, (CHAR8 *)&u64TpmPpiBase, sizeof(u64TpmPpiBase)) != sizeof(u64TpmPpiBase)
+ || u64TpmPpiBase == 0)
+ return EFI_PROTOCOL_ERROR;
+
+ mPpi = (QEMU_TPM_PPI *)(UINTN)u64TpmPpiBase;
+#endif
DEBUG ((DEBUG_INFO, "[TPM2PP] mPpi=%p version=%d\n", mPpi, Config.TpmVersion));
@@ -133,7 +175,9 @@ QemuTpmInitPPI (
for (Idx = 0; Idx < ARRAY_SIZE (mPpi->Func); Idx++) {
mPpi->Func[Idx] = 0;
}
+#ifndef VBOX
if (Config.TpmVersion == QEMU_TPM_VERSION_2) {
+#endif
mPpi->Func[TCG2_PHYSICAL_PRESENCE_NO_ACTION] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_CLEAR] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR] = TPM_PPI_FLAGS;
@@ -144,7 +188,9 @@ QemuTpmInitPPI (
mPpi->Func[TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID] = TPM_PPI_FLAGS;
+#ifndef VBOX
}
+#endif
if (mPpi->In == 0) {
mPpi->In = 1;
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 16789a3b..e63fbd06 100644
--- a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
+++ b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
Binary files differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index a11bbd1b..5711cfdb 100644
--- a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
+++ b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
Binary files differ
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
index 0c156fb2..e5d2f0ef 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.asm
@@ -8281,7 +8281,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.18 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.20 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -9212,7 +9212,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.18', 000h
+ db 'Oracle VM VirtualBox Version 7.0.20', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -9247,4 +9247,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 0dah
+ db 000h, 0e8h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
index 5b04df55..7d578726 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative286.md5sum
@@ -1 +1 @@
-a9f7b007aff3ce32ea3f5295bc1144ed *VBoxVgaBios286.rom
+1ab418acec7c367d0ffd228c5ef63633 *VBoxVgaBios286.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
index b480612b..0d013e8b 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.asm
@@ -7735,7 +7735,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.18 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.20 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -8666,7 +8666,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.18', 000h
+ db 'Oracle VM VirtualBox Version 7.0.20', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -8701,4 +8701,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 04fh
+ db 000h, 05dh
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
index 62bbb895..f4eab9e3 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative386.md5sum
@@ -1 +1 @@
-73c6f655de7140699ff561c5b01f3625 *VBoxVgaBios386.rom
+fc1076be2c8e2edddd08bbfdf33182ff *VBoxVgaBios386.rom
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
index fbfc435c..83e60936 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.asm
@@ -8439,7 +8439,7 @@ vesa_pm_end: ; 0xc4754 LB 0x1
section _DATA progbits vstart=0x4780 align=1 ; size=0x374d class=DATA group=DGROUP
; disGetNextSymbol 0xc4780 LB 0x374d -> off=0x0 cb=000000000000002f uValue=00000000000c0000 '_msg_vga_init'
_msg_vga_init: ; 0xc4780 LB 0x2f
- db 'Oracle VM VirtualBox Version 7.0.18 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 7.0.20 VGA BIOS', 00dh, 00ah, 000h
; disGetNextSymbol 0xc47af LB 0x371e -> off=0x0 cb=0000000000000080 uValue=00000000000c002f 'vga_modes'
vga_modes: ; 0xc47af LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -9370,7 +9370,7 @@ _vbebios_product_name: ; 0xc7e34 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
; disGetNextSymbol 0xc7e55 LB 0x78 -> off=0x0 cb=0000000000000024 uValue=00000000000c36d5 '_vbebios_product_revision'
_vbebios_product_revision: ; 0xc7e55 LB 0x24
- db 'Oracle VM VirtualBox Version 7.0.18', 000h
+ db 'Oracle VM VirtualBox Version 7.0.20', 000h
; disGetNextSymbol 0xc7e79 LB 0x54 -> off=0x0 cb=000000000000002b uValue=00000000000c36f9 '_vbebios_info_string'
_vbebios_info_string: ; 0xc7e79 LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
@@ -9405,4 +9405,4 @@ section CONST2 progbits vstart=0x7ece align=1 ; size=0x0 class=DATA group=DGROUP
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
- db 000h, 019h
+ db 000h, 027h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
index 1940a52f..bf5f9e97 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative8086.md5sum
@@ -1 +1 @@
-0f0564e36ea2319f2e46b42b53b39e81 *VBoxVgaBios8086.rom
+945a23ce7641a719d5917bf389c9dbb4 *VBoxVgaBios8086.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
index cc4f0f1b..c84b93c5 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA-cmd.cpp
@@ -1857,6 +1857,11 @@ static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC
pScreen->offVRAM = 0; /* Not applicable for screen targets, they use either a separate memory buffer or a host window. */
pScreen->cbPitch = pCmd->width * 4;
pScreen->cBpp = 32;
+ pScreen->cDpi = pCmd->dpi;
+
+ /* The screen bitmap must be deallocated after 'vmsvgaR3ChangeMode'. */
+ void *pvOldScreenBitmap = pScreen->pvScreenBitmap;
+ pScreen->pvScreenBitmap = 0;
if (RT_LIKELY(pThis->svga.f3DEnabled))
vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
@@ -1869,6 +1874,8 @@ static void vmsvga3dCmdDefineGBScreenTarget(PVGASTATE pThis, PVGASTATECC pThisCC
pThis->svga.fGFBRegisters = false;
vmsvgaR3ChangeMode(pThis, pThisCC);
+
+ RTMemFree(pvOldScreenBitmap);
}
}
@@ -6757,6 +6764,12 @@ void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDe
VMSVGASCREENOBJECT *pScreen = &pSvgaR3State->aScreens[idScreen];
Assert(pScreen->idScreen == idScreen);
+ pScreen->cDpi = 0; /* SVGAFifoCmdDefineScreen does not support dpi. */
+
+ /* SVGAFifoCmdDefineScreen uses the guest VRAM. The screen bitmap must be deallocated after 'vmsvgaR3ChangeMode'. */
+ void *pvOldScreenBitmap = pScreen->pvScreenBitmap;
+ pScreen->pvScreenBitmap = 0;
+
pScreen->fDefined = true;
pScreen->fModified = true;
pScreen->fuScreen = pCmd->screen.flags;
@@ -6779,13 +6792,15 @@ void vmsvgaR3CmdDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, SVGAFifoCmdDe
/* Screen blanked. Keep old values. */
}
- pThis->svga.fGFBRegisters = false;
- vmsvgaR3ChangeMode(pThis, pThisCC);
-
#ifdef VBOX_WITH_VMSVGA3D
if (RT_LIKELY(pThis->svga.f3DEnabled))
vmsvga3dDefineScreen(pThis, pThisCC, pScreen);
#endif
+
+ pThis->svga.fGFBRegisters = false;
+ vmsvgaR3ChangeMode(pThis, pThisCC);
+
+ RTMemFree(pvOldScreenBitmap);
}
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
index c199b618..ea34efa2 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
@@ -1655,6 +1655,22 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
VMSVGASCREENOBJECT *pScreen = &pSVGAState->aScreens[0];
Assert(pScreen->idScreen == 0);
+
+ if ( pScreen->cWidth == VMSVGA_VAL_UNINITIALIZED
+ || pScreen->cHeight == VMSVGA_VAL_UNINITIALIZED
+ || pScreen->cBpp == VMSVGA_VAL_UNINITIALIZED)
+ {
+ /* Do not apply the change if the guest has not finished updating registers.
+ * This is necessary in order to make a full mode change, including freeing
+ * pvScreenBitmap buffers for screen 0 if necessary.
+ */
+ return VINF_SUCCESS;
+ }
+
+ /* Remember screen bitmap buffers to be freed. */
+ void * apvOldScreenBitmap[RT_ELEMENTS(pSVGAState->aScreens)];
+ RT_ZERO(apvOldScreenBitmap);
+
pScreen->fDefined = true;
pScreen->fModified = true;
pScreen->fuScreen = SVGA_SCREEN_MUST_BE_SET | SVGA_SCREEN_IS_PRIMARY;
@@ -1665,6 +1681,11 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
pScreen->cWidth = pThis->svga.uWidth;
pScreen->cHeight = pThis->svga.uHeight;
pScreen->cBpp = pThis->svga.uBpp;
+ pScreen->cDpi = 0; /* GFB mode does not support dpi. */
+ /* GFB mode uses the guest VRAM. The screen bitmap must be deallocated after 'vmsvgaR3VBVAResize'. */
+ apvOldScreenBitmap[0] = pScreen->pvScreenBitmap;
+ /* Set pvScreenBitmap to zero because if it is not, then vmsvgaR3VBVAResize uses it as VRAM address. */
+ pScreen->pvScreenBitmap = 0;
for (unsigned iScreen = 1; iScreen < RT_ELEMENTS(pSVGAState->aScreens); ++iScreen)
{
@@ -1674,8 +1695,21 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
{
pScreen->fModified = true;
pScreen->fDefined = false;
+
+#ifdef VBOX_WITH_VMSVGA3D
+ if (RT_LIKELY(pThis->svga.f3DEnabled))
+ vmsvga3dDestroyScreen(pThisCC, pScreen);
+#endif
+ apvOldScreenBitmap[iScreen] = pScreen->pvScreenBitmap;
+ pScreen->pvScreenBitmap = 0;
}
}
+
+ vmsvgaR3VBVAResize(pThis, pThisCC);
+
+ /* Deallocate screen bitmaps for all screens because GFB mode uses the guest VRAM. */
+ for (unsigned iScreen = 0; iScreen < RT_ELEMENTS(apvOldScreenBitmap); ++iScreen)
+ RTMemFree(apvOldScreenBitmap[iScreen]);
}
else
{
@@ -1686,9 +1720,9 @@ int vmsvgaR3ChangeMode(PVGASTATE pThis, PVGASTATECC pThisCC)
pThis->svga.uWidth = VMSVGA_VAL_UNINITIALIZED;
pThis->svga.uHeight = VMSVGA_VAL_UNINITIALIZED;
pThis->svga.uBpp = pThis->svga.uHostBpp;
- }
- vmsvgaR3VBVAResize(pThis, pThisCC);
+ vmsvgaR3VBVAResize(pThis, pThisCC);
+ }
/* Last stuff. For the VGA device screenshot. */
pThis->last_bpp = pSVGAState->aScreens[0].cBpp;
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index a17e655f..3e22f141 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -626,6 +626,7 @@ if !defined(VBOX_ONLY_EXTPACKS) && "$(intersects $(KBUILD_TARGET_ARCH),$(VBOX_SU
VBoxDD_DEFS += VBOX_WITH_TPM
VBoxDD_SOURCES += \
Security/DevTpm.cpp \
+ Security/DevTpmPpi.cpp \
Security/DrvTpmEmu.cpp
VBoxDD_SOURCES.linux += \
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
index 96b8e631..b70cd3f5 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.asm
@@ -1621,7 +1621,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xcda class=DATA group=DGROUP
section CONST2 progbits vstart=0xdca align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0dca LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0dca 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0dca LB 0x12
- db 'VirtualBox 7.0.18', 000h
+ db 'VirtualBox 7.0.20', 000h
; disGetNextSymbol 0xf0ddc LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0ddc '_bios_prefix_string'
_bios_prefix_string: ; 0xf0ddc LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19429,4 +19429,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0d4h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 0dbh
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
index 8fb531ac..c546774a 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative286.md5sum
@@ -1 +1 @@
-ad4d1a253850bc31cfa497722faafa3a *VBoxPcBios286.rom
+60aec905c47ddf2c8a658f7fdedf61b6 *VBoxPcBios286.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
index 85af1d40..9e1c4215 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.asm
@@ -1566,7 +1566,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xd14 class=DATA group=DGROUP
section CONST2 progbits vstart=0xe04 align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0e04 LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0e04 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0e04 LB 0x12
- db 'VirtualBox 7.0.18', 000h
+ db 'VirtualBox 7.0.20', 000h
; disGetNextSymbol 0xf0e16 LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0e16 '_bios_prefix_string'
_bios_prefix_string: ; 0xf0e16 LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19195,4 +19195,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 032h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 039h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
index 9cb9bea8..7934d06b 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative386.md5sum
@@ -1 +1 @@
-79eeb980dd6104d8bc534c8c7c4e877a *VBoxPcBios386.rom
+dbb41e6f7bffdc046e70fcc71697c569 *VBoxPcBios386.rom
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
index 80829ed2..44b44449 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.asm
@@ -1621,7 +1621,7 @@ section CONST progbits vstart=0xf0 align=1 ; size=0xcda class=DATA group=DGROUP
section CONST2 progbits vstart=0xdca align=1 ; size=0x3fa class=DATA group=DGROUP
; disGetNextSymbol 0xf0dca LB 0x3fa -> off=0x0 cb=0000000000000012 uValue=00000000000f0dca 'bios_cvs_version_string'
bios_cvs_version_string: ; 0xf0dca LB 0x12
- db 'VirtualBox 7.0.18', 000h
+ db 'VirtualBox 7.0.20', 000h
; disGetNextSymbol 0xf0ddc LB 0x3e8 -> off=0x0 cb=0000000000000008 uValue=00000000000f0ddc '_bios_prefix_string'
_bios_prefix_string: ; 0xf0ddc LB 0x8
db 'BIOS: ', 000h, 000h
@@ -19906,4 +19906,4 @@ biosorg_check_before_or_at_0FFEEh: ; 0xfff80 LB 0x70
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0 ; 0xffff0 orgs.asm:2114
; disGetNextSymbol 0xffff5 LB 0xb -> off=0xb cb=0000000000000000 uValue=0000000000100000 '_dummy_addr_0x100000'
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fbh, 0b9h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fbh, 0c0h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
index fc4dd6b7..9ad9c6d4 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative8086.md5sum
@@ -1 +1 @@
-bd634fab26a7c7e944a845a9415c8623 *VBoxPcBios8086.rom
+c032703c5648215f94b3881f8ea0174a *VBoxPcBios8086.rom
diff --git a/src/VBox/Devices/PC/vbox-tpm.dsl b/src/VBox/Devices/PC/vbox-tpm.dsl
index a24f9f16..889f1515 100644
--- a/src/VBox/Devices/PC/vbox-tpm.dsl
+++ b/src/VBox/Devices/PC/vbox-tpm.dsl
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2021-2023 Oracle and/or its affiliates.
+ * Copyright (C) 2021-2024 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
@@ -27,6 +27,8 @@
DefinitionBlock ("SSDT.aml", "SSDT", 1, "VBOX ", "VBOXTPMT", 2)
{
+ External(DBG, MethodObj, ,)
+
Scope (\_SB)
{
Device (TPM)
@@ -88,6 +90,271 @@ DefinitionBlock ("SSDT.aml", "SSDT", 1, "VBOX ", "VBOXTPMT", 2)
{
Return (RES)
}
+
+ Method (TPFS, 1, Serialized)
+ {
+ If (LGreaterEqual(Arg0, 0x100))
+ {
+ Return (Zero)
+ }
+
+ OperationRegion (TPP1, SystemMemory, Add(0xFED45000, Arg0), One)
+ Field (TPP1, ByteAcc, NoLock, Preserve)
+ {
+ TPPF, 8
+ }
+
+ Return (TPPF)
+ }
+
+ /**
+ * Device-Specific Method
+ */
+ Method (_DSM, 4, Serialized)
+ {
+ /**
+ * The TPM Physical Presence Interface MMIO region.
+ */
+ OperationRegion (TPMP, SystemMemory, 0xFED45100, 0x5A)
+ Field (TPMP, AnyAcc, NoLock, Preserve)
+ {
+ PPIN, 8,
+ PPIP, 32,
+ PPRP, 32,
+ PPRQ, 32,
+ PPRM, 32,
+ LPPR, 32
+ }
+
+ Name (TPB2, Package (0x02)
+ {
+ Zero,
+ Zero
+ })
+
+ Name (TPB3, Package (0x03)
+ {
+ Zero,
+ Zero,
+ Zero
+ })
+
+ /**
+ * Physical Presence Interface Specification PPI.
+ */
+ If (LEqual (Arg0, ToUUID("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
+ {
+ /**
+ * Standard _DSM query function.
+ */
+ If (LEqual (Arg2, Zero))
+ {
+ DBG("_DSM: Query\n")
+ Return (Buffer (0x02) { 0xFF, 0x01 })
+ }
+
+ /**
+ * Query supported PPI revision.
+ *
+ * Result:
+ * 1.3 (string).
+ */
+ If (LEqual (Arg2, One))
+ {
+ DBG("_DSM: PPI Revision\n")
+ Return ("1.3")
+ }
+
+ /**
+ * Submit TPM Operation Request to pre-OS environment.
+ *
+ * Input:
+ * Package[0] - Operation value of the request
+ * Result:
+ * - 0: Success
+ * - 1: Operation value of the request not supported.
+ * - 2: General failure
+ */
+ If (LEqual (Arg2, 0x02))
+ {
+ DBG("_DSM: Submit TPM Operation Request\n")
+
+ Store(DerefOf(Index(Arg3, Zero)), Local0)
+ Store(TPFS(Local0), Local1)
+ If (LEqual(And(Local1, 0x07), Zero))
+ {
+ Return (One)
+ }
+
+ Store(Local0, PPRQ)
+ Store(Zero, PPRM)
+ Return (Zero)
+ }
+
+ /**
+ * Get Pending TPM Operation Requested by the OS.
+ *
+ * Result:
+ * Package[0] - Function Return Code:
+ * - 0: Success
+ * - 1: General Failure
+ * Package[1] - Pending operation requested by the OS:
+ * - 0: None
+ * - >0: Operation value of the pending request
+ * Package[2] - Optional argument to pending operation requested by the OS:
+ * - 0: None
+ * - >0: Argument value of the pending request
+ */
+ If (LEqual (Arg2, 0x03))
+ {
+ DBG("_DSM: Get Pending TPM Operation Request\n")
+
+ if (LEqual(Arg1, One))
+ {
+ Store(PPRQ, Index(TPB2, One))
+ Return (TPB2)
+ }
+
+ if (LEqual(Arg1, 0x02))
+ {
+ Store(PPRQ, Index(TPB3, One))
+ Store(PPRM, Index(TPB3, 0x02))
+ Return (TPB3)
+ }
+
+ Return (TPB3)
+ }
+
+ /**
+ * Get Platform-Specific Action to Transition to Pre-OS Environment.
+ *
+ * Result:
+ * - 0: None
+ * - 1: Shutdown
+ * - 2: Reboot
+ * - 3: OS vendor specific
+ */
+ If (LEqual (Arg2, 0x04))
+ {
+ DBG("_DSM: Get Platform-Specific Action to Transition to Pre-OS Environment\n")
+
+ Return (0x02)
+ }
+
+ /**
+ * Return TPM Operation Response to OS Environment.
+ */
+ If (LEqual (Arg2, 0x05))
+ {
+ DBG("_DSM: Return TPM Operation Response to OS Environment\n")
+
+ Store (LPPR, Index (TPB3, One))
+ Store (PPRP, Index (TPB3, 0x02))
+ Return (TPB3)
+ }
+
+ /**
+ * Submit preferred user language - deprecated
+ *
+ * Result:
+ * - 3: Not implemented
+ */
+ If (LEqual (Arg2, 0x06))
+ {
+ DBG("_DSM: Submit preferred user language\n")
+
+ Return (0x03)
+ }
+
+ /**
+ * Submit TPM Operation Request to Pre-OS Environment 2
+ */
+ If (LEqual (Arg2, 0x07))
+ {
+ DBG("_DSM: Submit TPM Operation Request 2\n")
+
+ Store(DerefOf(Index(Arg3, Zero)), Local0) /* Local0 = *Arg3[0] (Arg3 is a Package) */
+ Store(TPFS(Local0), Local1) /* Local1 = TPFS(Local0) */
+ Store(And(Local1, 0x07), Local1) /* Local1 &= 0x7 */
+ If (LEqual(Local1, Zero))
+ {
+ Return (One) /* Operation not implemented */
+ }
+
+ If (LEqual(Local1, 0x02))
+ {
+ Return (0x03) /* Operation blocked by current firmware settings */
+ }
+
+ If (LEqual(Arg1, One))
+ {
+ Store(Local0, PPRQ)
+ Store(Zero, PPRM)
+ }
+
+ If (LEqual(Arg1, 0x02))
+ {
+ Store(DerefOf(Index(Arg3, One)), Local2) /* Local2 = *Arg3[1] (Arg3 is a Package) */
+
+ Store(Local0, PPRQ)
+ Store(Local2, PPRM)
+ }
+
+ Return (Zero)
+ }
+
+ /**
+ * Get User Confirmation Status for Operation.
+ *
+ * Input is the operation value maybe needing user confirmation
+ * Result:
+ * - 0: Not implemented
+ * - 1: Firmware only
+ * - 2: Blocked for OS by firmware configuration.
+ * - 3: Allowed and physically present user required
+ * - 4: Allowed and physically present user not required.
+ */
+ If (LEqual (Arg2, 0x08))
+ {
+ DBG("_DSM: Get user confirmation status for operation\n")
+
+ Store(DerefOf(Index(Arg3, Zero)), Local0)
+ Store(TPFS(Local0), Local1)
+
+ Return (And(Local1, 0x7))
+ }
+
+ DBG("TPM_DSM: Unknown function\n")
+ Return (Buffer (One) { 0x00 })
+ }
+
+ /**
+ * TCG Platform Reset Attack Mitigation Specification interface.
+ */
+ If (LEqual (Arg0, ToUUID("376054ed-cc13-4675-901c-4756d7f2d45d")))
+ {
+ /**
+ * Standard _DSM query function.
+ */
+ If (LEqual (Arg2, Zero))
+ {
+ Return (Buffer (One) { 0x03 })
+ }
+
+ /**
+ * Set Memory Overwrite Request (MOR) bit to specified value.
+ */
+ If (LEqual (Arg2, One))
+ {
+ /* Memory is always zeroed on reset. */
+ Return (Zero)
+ }
+
+ Return (Buffer (One) { 0x00 })
+ }
+
+ Return (Buffer (One) { 0x00 })
+ }
}
}
}
diff --git a/src/VBox/Devices/Security/DevTpmPpi.cpp b/src/VBox/Devices/Security/DevTpmPpi.cpp
new file mode 100644
index 00000000..03159d88
--- /dev/null
+++ b/src/VBox/Devices/Security/DevTpmPpi.cpp
@@ -0,0 +1,453 @@
+/* $Id: DevTpmPpi.cpp $ */
+/** @file
+ * DevTpmPpi - Guest platform <-> VirtualBox TPM Physical Presence Interface Integration Framework.
+ *
+ * Based on: https://github.com/qemu/qemu/blob/master/docs/specs/tpm.rst (2024-06-26).
+ */
+
+/*
+ * Copyright (C) 2024 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
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_DEV_TPM
+
+#include <VBox/vmm/pdmdev.h>
+#include <VBox/log.h>
+#include <VBox/err.h>
+#include <VBox/param.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/ctype.h>
+
+#include "VBoxDD.h"
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+
+/** The TPM saved state version. */
+#define TPM_PPI_SAVED_STATE_VERSION 1
+
+/** The TPM PPI MMIO base default (compatible with qemu). */
+#define TPM_PPI_MMIO_BASE_DEFAULT UINT64_C(0xfed45000)
+/** The size of the TPM PPI MMIO area. */
+#define TPM_PPI_MMIO_SIZE _4K
+
+/** @name QEMU compatible PPI interface layout.
+ * @{ */
+/**
+ * The PPI structure layout (yes, it really is misaligned).
+ */
+#pragma pack(1)
+typedef union QEMUTPMPPI
+{
+ /** The byte view. */
+ uint8_t ab[0x400];
+ /** The structured view. */
+ struct
+ {
+ /** Supported operation flags set by the firmware for each operation. */
+ uint8_t abFunc[0x100];
+ /** SMI interrupt to use, set by firmware. Not supported. */
+ uint8_t bPpin;
+ /** ACPI function index to pass to SMM code, set by ACPI. Not supported. */
+ uint32_t u32Ppip;
+ /** Result of last executed operation, set by firmware. */
+ uint32_t u32Pprp;
+ /** Operation request number to execute, set by ACPI. */
+ uint32_t u32Pprq;
+ /** Operation request optional parameter, set by ACPI. */
+ uint32_t u32Pprm;
+ /** Last executed operation request number, copied from QEMUTPMPPI::u32PPrq field by firmware. */
+ uint32_t u32Lppr;
+ /** Result code from SMM function, not supported. */
+ uint32_t u32Fret;
+ /** Reserved for future use. */
+ uint8_t abRsvd[0x40];
+ /** Operation to execute after reboot by firmware, used by firmware. */
+ uint8_t bNextStep;
+ /** Memory overwrite variable. */
+ uint8_t bMovv;
+ } s;
+} QEMUTPMPPI;
+#pragma pack()
+AssertCompileSize(QEMUTPMPPI, 0x400);
+/** Pointer to the QEMU PPI structure layout. */
+typedef QEMUTPMPPI *PQEMUTPMPPI;
+/** Pointer to a const QEMU PPI structure layout. */
+typedef const QEMUTPMPPI *PCQEMUTPMPPI;
+/** @} */
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+
+/**
+ * Shared TPM PPI device state.
+ */
+typedef struct DEVTPMPPI
+{
+ /** Base MMIO address of the TPM PPI area. */
+ RTGCPHYS GCPhysMmio;
+ /** The handle of the MMIO region. */
+ IOMMMIOHANDLE hMmio;
+ /** The QEMU PPI state. */
+ QEMUTPMPPI Ppi;
+} DEVTPMPPI;
+/** Pointer to the shared TPM PPI device state. */
+typedef DEVTPMPPI *PDEVTPMPPI;
+
+/**
+ * TPM PPI device state for ring-3.
+ */
+typedef struct DEVTPMPPIR3
+{
+ /** Pointer to the device instance. */
+ PPDMDEVINS pDevIns;
+} DEVTPMPPIR3;
+/** Pointer to the TPM device state for ring-3. */
+typedef DEVTPMPPIR3 *PDEVTPMPPIR3;
+
+
+/**
+ * TPM PPI device state for ring-0.
+ */
+typedef struct DEVTPMPPIR0
+{
+ uint32_t u32Dummy;
+
+} DEVTPMPPIR0;
+/** Pointer to the TPM device state for ring-0. */
+typedef DEVTPMPPIR0 *PDEVTPMPPIR0;
+
+
+/**
+ * TPM PPI device state for raw-mode.
+ */
+typedef struct DEVTPMPPIRC
+{
+ uint32_t u32Dummy;
+} DEVTPMPPIRC;
+/** Pointer to the TPM device state for raw-mode. */
+typedef DEVTPMPPIRC *PDEVTPMPPIRC;
+
+/** The TPM PI device state for the current context. */
+typedef CTX_SUFF(DEVTPMPPI) DEVTPMPPICC;
+/** Pointer to the TPM PPI device state for the current context. */
+typedef CTX_SUFF(PDEVTPMPPI) PDEVTPMPPICC;
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+
+#ifdef IN_RING3
+/**
+ * SSM descriptor table for the TPM PPI structure.
+ */
+static SSMFIELD const g_aTpmPpiFields[] =
+{
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.abFunc),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.bPpin),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Ppip),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprp),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprq),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprm),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Lppr),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Fret),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.bNextStep),
+ SSMFIELD_ENTRY(QEMUTPMPPI, s.bMovv),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+
+/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
+
+/**
+ * @callback_method_impl{FNIOMMMIONEWREAD}
+ */
+static DECLCALLBACK(VBOXSTRICTRC) tpmPpiMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ RT_NOREF(pvUser);
+
+ LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
+ if (off + cb > sizeof(pThis->Ppi))
+ return VINF_IOM_MMIO_UNUSED_FF;
+
+ memcpy(pv, &pThis->Ppi.ab[off], cb);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @callback_method_impl{FNIOMMMIONEWWRITE}
+ */
+static DECLCALLBACK(VBOXSTRICTRC) tpmPpiMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ RT_NOREF(pvUser);
+
+ LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
+ if (off + cb > sizeof(pThis->Ppi))
+ return VINF_SUCCESS;
+
+ memcpy(&pThis->Ppi.ab[off], pv, cb);
+ return VINF_SUCCESS;
+}
+
+
+#ifdef IN_RING3
+
+/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
+
+/**
+ * @callback_method_impl{FNSSMDEVLIVEEXEC}
+ */
+static DECLCALLBACK(int) tpmPpiR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+ RT_NOREF(uPass);
+
+ /* Save the part of the config used for verification purposes when restoring. */
+ pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmio);
+
+ return VINF_SSM_DONT_CALL_AGAIN;
+}
+
+
+/**
+ * @callback_method_impl{FNSSMDEVSAVEEXEC}
+ */
+static DECLCALLBACK(int) tpmPpiR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+
+ tpmPpiR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
+
+ int rc = pHlp->pfnSSMPutStructEx(pSSM, &pThis->Ppi, sizeof(pThis->Ppi), 0 /*fFlags*/, &g_aTpmPpiFields[0], NULL);
+ AssertRCReturn(rc, rc);
+
+ return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
+}
+
+
+/**
+ * @callback_method_impl{FNSSMDEVLOADEXEC}
+ */
+static DECLCALLBACK(int) tpmPpiR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+ RTGCPHYS GCPhysMmio;
+
+ Assert(uPass == SSM_PASS_FINAL); RT_NOREF(uPass);
+ AssertMsgReturn(uVersion == TPM_PPI_SAVED_STATE_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
+
+ /* Verify the config first. */
+ int rc = pHlp->pfnSSMGetGCPhys(pSSM, &GCPhysMmio);
+ AssertRCReturn(rc, rc);
+ if (GCPhysMmio != pThis->GCPhysMmio)
+ return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS,
+ N_("Config mismatch - saved GCPhysMmio=%#RGp; configured GCPhysMmio=%#RGp"),
+ GCPhysMmio, pThis->GCPhysMmio);
+
+ if (uPass == SSM_PASS_FINAL)
+ {
+ rc = pHlp->pfnSSMGetStructEx(pSSM, &pThis->Ppi, sizeof(pThis->Ppi), 0 /*fFlags*/, &g_aTpmPpiFields[0], NULL);
+ AssertRCReturn(rc, rc);
+
+ /* The marker. */
+ uint32_t u32;
+ rc = pHlp->pfnSSMGetU32(pSSM, &u32);
+ AssertRCReturn(rc, rc);
+ AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnDestruct}
+ */
+static DECLCALLBACK(int) tpmPpiR3Destruct(PPDMDEVINS pDevIns)
+{
+ PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnConstruct}
+ */
+static DECLCALLBACK(int) tpmPpiR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+{
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+ PDEVTPMPPICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMPPICC);
+ PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
+ int rc;
+
+ RT_NOREF(iInstance);
+ Assert(iInstance == 0);
+
+ /*
+ * Initalize the basic variables so that the destructor always works.
+ */
+ pThisCC->pDevIns = pDevIns;
+
+ /*
+ * Validate and read the configuration.
+ */
+ PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "MmioBase", "");
+
+ rc = pHlp->pfnCFGMQueryU64Def(pCfg, "MmioBase", &pThis->GCPhysMmio, TPM_PPI_MMIO_BASE_DEFAULT);
+ if (RT_FAILURE(rc))
+ return PDMDEV_SET_ERROR(pDevIns, rc,
+ N_("Configuration error: Failed to get the \"MmioBase\" value"));
+
+ /*
+ * Register the MMIO range, PDM API requests page aligned
+ * addresses and sizes.
+ */
+ rc = PDMDevHlpMmioCreateAndMap(pDevIns, pThis->GCPhysMmio, TPM_PPI_MMIO_SIZE, tpmPpiMmioWrite, tpmPpiMmioRead,
+ IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
+ "TPM PPI MMIO", &pThis->hMmio);
+ AssertRCReturn(rc, rc);
+
+ /*
+ * Saved state.
+ */
+ rc = PDMDevHlpSSMRegister3(pDevIns, TPM_PPI_SAVED_STATE_VERSION, sizeof(*pThis),
+ tpmPpiR3LiveExec, tpmPpiR3SaveExec, tpmPpiR3LoadExec);
+ AssertRCReturn(rc, rc);
+
+ return VINF_SUCCESS;
+}
+
+
+#else /* !IN_RING3 */
+
+/**
+ * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
+ */
+static DECLCALLBACK(int) tpmPpiRZConstruct(PPDMDEVINS pDevIns)
+{
+ PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+ PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
+
+ int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, tpmPpiMmioWrite, tpmPpiMmioRead, NULL /*pvUser*/);
+ AssertRCReturn(rc, rc);
+
+ return VINF_SUCCESS;
+}
+
+#endif /* !IN_RING3 */
+
+
+/**
+ * The device registration structure.
+ */
+const PDMDEVREG g_DeviceTpmPpi =
+{
+ /* .u32Version = */ PDM_DEVREG_VERSION,
+ /* .uReserved0 = */ 0,
+ /* .szName = */ "tpm-ppi",
+ /* .fFlags = */ PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_NEW_STYLE,
+ /* .fClass = */ PDM_DEVREG_CLASS_ARCH_BIOS,
+ /* .cMaxInstances = */ 1,
+ /* .uSharedVersion = */ 42,
+ /* .cbInstanceShared = */ sizeof(DEVTPMPPI),
+ /* .cbInstanceCC = */ sizeof(DEVTPMPPICC),
+ /* .cbInstanceRC = */ sizeof(DEVTPMPPIRC),
+ /* .cMaxPciDevices = */ 0,
+ /* .cMaxMsixVectors = */ 0,
+ /* .pszDescription = */ "Device implementing the TPM Physical Presence Interface (PPI)\n",
+#if defined(IN_RING3)
+ /* .pszRCMod = */ "",
+ /* .pszR0Mod = */ "",
+ /* .pfnConstruct = */ tpmPpiR3Construct,
+ /* .pfnDestruct = */ tpmPpiR3Destruct,
+ /* .pfnRelocate = */ NULL,
+ /* .pfnMemSetup = */ NULL,
+ /* .pfnPowerOn = */ NULL,
+ /* .pfnReset = */ NULL,
+ /* .pfnSuspend = */ NULL,
+ /* .pfnResume = */ NULL,
+ /* .pfnAttach = */ NULL,
+ /* .pfnDetach = */ NULL,
+ /* .pfnQueryInterface = */ NULL,
+ /* .pfnInitComplete = */ NULL,
+ /* .pfnPowerOff = */ NULL,
+ /* .pfnSoftReset = */ NULL,
+ /* .pfnReserved0 = */ NULL,
+ /* .pfnReserved1 = */ NULL,
+ /* .pfnReserved2 = */ NULL,
+ /* .pfnReserved3 = */ NULL,
+ /* .pfnReserved4 = */ NULL,
+ /* .pfnReserved5 = */ NULL,
+ /* .pfnReserved6 = */ NULL,
+ /* .pfnReserved7 = */ NULL,
+#elif defined(IN_RING0)
+ /* .pfnEarlyConstruct = */ NULL,
+ /* .pfnConstruct = */ tpmPpiRZConstruct,
+ /* .pfnDestruct = */ NULL,
+ /* .pfnFinalDestruct = */ NULL,
+ /* .pfnRequest = */ NULL,
+ /* .pfnReserved0 = */ NULL,
+ /* .pfnReserved1 = */ NULL,
+ /* .pfnReserved2 = */ NULL,
+ /* .pfnReserved3 = */ NULL,
+ /* .pfnReserved4 = */ NULL,
+ /* .pfnReserved5 = */ NULL,
+ /* .pfnReserved6 = */ NULL,
+ /* .pfnReserved7 = */ NULL,
+#elif defined(IN_RC)
+ /* .pfnConstruct = */ tpmPpiRZConstruct,
+ /* .pfnReserved0 = */ NULL,
+ /* .pfnReserved1 = */ NULL,
+ /* .pfnReserved2 = */ NULL,
+ /* .pfnReserved3 = */ NULL,
+ /* .pfnReserved4 = */ NULL,
+ /* .pfnReserved5 = */ NULL,
+ /* .pfnReserved6 = */ NULL,
+ /* .pfnReserved7 = */ NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+ /* .u32VersionEnd = */ PDM_DEVREG_VERSION
+};
diff --git a/src/VBox/Devices/USB/DevEHCI.cpp b/src/VBox/Devices/USB/DevEHCI.cpp
index 1ca85af3..48659563 100644
--- a/src/VBox/Devices/USB/DevEHCI.cpp
+++ b/src/VBox/Devices/USB/DevEHCI.cpp
@@ -161,7 +161,7 @@ typedef struct VUSBURBHCITDINT
/** The address of the TD. */
RTGCPHYS TdAddr;
/** A copy of the TD. */
- uint32_t TdCopy[16];
+ uint32_t TdCopy[18];
} VUSBURBHCITDINT;
/**
@@ -526,19 +526,25 @@ typedef const EHCI_ITD *PEHCI_CITD;
AssertCompileSize(EHCI_ITD, 0x40);
/** @} */
-/* ITD with extra padding to add 8th 'Buffer' entry. The PG member of
+/* ITD with extra padding to add 8th and 9th 'Buffer' entry. The PG member of
* EHCI_ITD_TRANSACTION can contain values in the 0-7 range, but only values
* 0-6 are valid. The extra padding is added to avoid cluttering the code
* with range checks; ehciR3ReadItd() initializes the pad with a safe value.
* The EHCI 1.0 specification explicitly says using PG value of 7 yields
- * undefined behavior.
+ * undefined behavior. Two pad entries are needed because initial PG value
+ * of 7 (already 'wrong') can cross to the next page (8).
*/
typedef struct
{
- EHCI_ITD itd;
- EHCI_BUFFER_PTR pad;
+ EHCI_TD_PTR Next;
+ EHCI_ITD_TRANSACTION Transaction[EHCI_NUM_ITD_TRANSACTIONS];
+ union
+ {
+ EHCI_ITD_MISC Misc;
+ EHCI_BUFFER_PTR Buffer[EHCI_NUM_ITD_PAGES + 2];
+ } Buffer;
} EHCI_ITD_PAD, *PEHCI_ITD_PAD;
-AssertCompileSize(EHCI_ITD_PAD, 0x44);
+AssertCompileSize(EHCI_ITD_PAD, 0x48);
/** @name Split Transaction Isochronous Transfer Descriptor (siTD)
* @{ */
@@ -1471,7 +1477,8 @@ DECLINLINE(void) ehciR3ReadTDPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, EHCI_TD_PT
DECLINLINE(void) ehciR3ReadItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD_PAD pPItd)
{
ehciGetDWords(pDevIns, GCPhys, (uint32_t *)pPItd, sizeof(EHCI_ITD) >> 2);
- pPItd->pad.Pointer = 0xFFFFF; /* Direct accesses at the last page under 4GB (ROM). */
+ pPItd->Buffer.Buffer[7].Pointer = 0xFFFFF; /* Direct ill-defined accesses to the last page under 4GB (ROM). */
+ pPItd->Buffer.Buffer[8].Pointer = 0xFFFFF;
}
DECLINLINE(void) ehciR3ReadSitd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_SITD pSitd)
@@ -1479,7 +1486,7 @@ DECLINLINE(void) ehciR3ReadSitd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_SITD
ehciGetDWords(pDevIns, GCPhys, (uint32_t *)pSitd, sizeof(*pSitd) >> 2);
}
-DECLINLINE(void) ehciR3WriteItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD pItd)
+DECLINLINE(void) ehciR3WriteItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD_PAD pItd)
{
/** @todo might need to be careful about write order in async io thread */
/*
@@ -1490,7 +1497,7 @@ DECLINLINE(void) ehciR3WriteItd(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_ITD p
uint32_t offDWordsWrite = offWrite / sizeof(uint32_t);
Assert(!(offWrite % sizeof(uint32_t)));
- ehciPutDWords(pDevIns, GCPhys + offWrite, (uint32_t *)pItd + offDWordsWrite, (sizeof(*pItd) >> 2) - offDWordsWrite);
+ ehciPutDWords(pDevIns, GCPhys + offWrite, (uint32_t *)pItd + offDWordsWrite, (sizeof(EHCI_ITD) >> 2) - offDWordsWrite);
}
DECLINLINE(void) ehciR3ReadQHD(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PEHCI_QHD pQHD)
@@ -1758,7 +1765,7 @@ DECLINLINE(void) ehciR3DumpITD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysHead, bool fLi
/* Read the whole ITD */
EHCI_ITD_PAD PaddedItd;
- PEHCI_ITD pItd = &PaddedItd.itd;
+ PEHCI_ITD_PAD pItd = &PaddedItd;
ehciR3ReadItd(pDevIns, GCPhys, &PaddedItd);
Log2(("Addr=%x EndPt=%x Dir=%s MaxSize=%x Mult=%d}\n", pItd->Buffer.Misc.DeviceAddress, pItd->Buffer.Misc.EndPt, (pItd->Buffer.Misc.DirectionIn) ? "in" : "out", pItd->Buffer.Misc.MaxPacket, pItd->Buffer.Misc.Multi));
@@ -2028,7 +2035,7 @@ static int ehciR3InFlightRemoveUrb(PEHCI pThis, PEHCICC pThisCC, PVUSBURB pUrb)
* @param pUrb The URB in question.
* @param pItd The ITD pointer.
*/
-static bool ehciR3ItdHasUrbBeenCanceled(PEHCICC pThisCC, PVUSBURB pUrb, PEHCI_ITD pItd)
+static bool ehciR3ItdHasUrbBeenCanceled(PEHCICC pThisCC, PVUSBURB pUrb, PEHCI_ITD_PAD pItd)
{
RT_NOREF(pThisCC);
Assert(pItd);
@@ -2252,7 +2259,7 @@ static void ehciR3RhXferCompleteITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pTh
{
/* Read the whole ITD */
EHCI_ITD_PAD PaddedItd;
- PEHCI_ITD pItd = &PaddedItd.itd;
+ PEHCI_ITD_PAD pItd = &PaddedItd;
ehciR3ReadItd(pDevIns, pUrb->paTds[0].TdAddr, &PaddedItd);
/*
@@ -2323,7 +2330,7 @@ static void ehciR3RhXferCompleteITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pTh
ehciPhysWrite(pDevIns, GCPhysBuf, pb, cb1);
if ((pg + 1) >= EHCI_NUM_ITD_PAGES)
- LogRelMax(10, ("EHCI: Crossing to undefined page %d in iTD at %RGp on completion.\n", pg + 1, pUrb->paTds[0].TdAddr));
+ LogRelMax(10, ("EHCI: Crossing to nonstandard page %d in iTD at %RGp on completion.\n", pg + 1, pUrb->paTds[0].TdAddr));
GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
ehciPhysWrite(pDevIns, GCPhysBuf, pb + cb1, cb2);
@@ -2790,7 +2797,7 @@ static bool ehciR3SubmitQTD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC, RT
* @returns false on failure to submit.
*/
static bool ehciR3SubmitITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
- PEHCI_ITD pItd, RTGCPHYS ITdAddr, const unsigned iFrame)
+ PEHCI_ITD_PAD pItd, RTGCPHYS ITdAddr, const unsigned iFrame)
{
/*
* Determine the endpoint direction.
@@ -2875,7 +2882,7 @@ static bool ehciR3SubmitITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
ehciPhysRead(pDevIns, GCPhysBuf, &pUrb->abData[curOffset], cb1);
if ((pg + 1) >= EHCI_NUM_ITD_PAGES)
- LogRelMax(10, ("EHCI: Crossing to undefined page %d in iTD at %RGp on submit.\n", pg + 1, pUrb->paTds[0].TdAddr));
+ LogRelMax(10, ("EHCI: Crossing to nonstandard page %d in iTD at %RGp on submit.\n", pg + 1, pUrb->paTds[0].TdAddr));
GCPhysBuf = (RTGCPHYS)pItd->Buffer.Buffer[pg + 1].Pointer << EHCI_BUFFER_PTR_SHIFT;
ehciPhysRead(pDevIns, GCPhysBuf, &pUrb->abData[curOffset + cb1], cb2);
@@ -2932,7 +2939,7 @@ static void ehciR3ServiceITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
RT_NOREF(enmServiceType);
bool fAnyActive = false;
EHCI_ITD_PAD PaddedItd;
- PEHCI_ITD pItd = &PaddedItd.itd;
+ PEHCI_ITD_PAD pItd = &PaddedItd;
if (ehciR3IsTdInFlight(pThisCC, GCPhys))
return;
@@ -2953,7 +2960,7 @@ static void ehciR3ServiceITD(PPDMDEVINS pDevIns, PEHCI pThis, PEHCICC pThisCC,
/* Using out of range PG value (7) yields undefined behavior. We will attempt
* the last page below 4GB (which is ROM, not writable).
*/
- LogRelMax(10, ("EHCI: Illegal page value %d in iTD at %RGp.\n", pItd->Transaction[i].PG, (RTGCPHYS)GCPhys));
+ LogRelMax(10, ("EHCI: Nonstandard page value %d in iTD at %RGp.\n", pItd->Transaction[i].PG, (RTGCPHYS)GCPhys));
}
Log2((" T%d Len=%x Offset=%x PG=%d IOC=%d Buffer=%x\n", i, pItd->Transaction[i].Length, pItd->Transaction[i].Offset, pItd->Transaction[i].PG, pItd->Transaction[i].IOC,
diff --git a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
index c1d5ab9d..81a4b08d 100644
--- a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
+++ b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
@@ -703,7 +703,8 @@ DECLHIDDEN(uint64_t) vusbRhR3ProcessFrame(PVUSBROOTHUB pThis, bool fCallback)
uint64_t tsNanoStart = RTTimeNanoTS();
/* Don't do anything if we are not supposed to process anything (EHCI and XHCI). */
- if (!pThis->uFrameRateDefault)
+ if ( !pThis->uFrameRateDefault
+ || ASMAtomicReadBool(&pThis->fSavingState))
return 0;
if (ASMAtomicXchgBool(&pThis->fFrameProcessing, true))
@@ -1348,15 +1349,16 @@ static DECLCALLBACK(int) vusbR3RhSavePrep(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
LogFlow(("vusbR3RhSavePrep:\n"));
RT_NOREF(pSSM);
+ ASMAtomicXchgBool(&pThis->fSavingState, true);
+
/*
* Detach all proxied devices.
*/
- RTCritSectEnter(&pThis->CritSectDevices);
/** @todo we a) can't tell which are proxied, and b) this won't work well when continuing after saving! */
for (unsigned i = 0; i < RT_ELEMENTS(pThis->apDevByPort); i++)
{
- PVUSBDEV pDev = pThis->apDevByPort[i];
+ PVUSBDEV pDev = vusbR3RhGetVUsbDevByPortRetain(pThis, i, "SavePrep");
if (pDev)
{
if (!VUSBIDevIsSavedStateSupported(&pDev->IDevice))
@@ -1369,13 +1371,13 @@ static DECLCALLBACK(int) vusbR3RhSavePrep(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
* This will work fine even if the save fails since the Done handler is
* called unconditionally if the Prep handler was called.
*/
+ Assert(!pThis->apDevByPort[i]);
pThis->apDevByPort[i] = pDev;
+ vusbDevRelease(pDev, "SavePrep");
}
}
}
- RTCritSectLeave(&pThis->CritSectDevices);
-
/*
* Kill old load data which might be hanging around.
*/
@@ -1423,6 +1425,7 @@ static DECLCALLBACK(int) vusbR3RhSaveDone(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
vusbHubAttach(pThis, pDev);
}
+ ASMAtomicXchgBool(&pThis->fSavingState, false);
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/USB/VUSBInternal.h b/src/VBox/Devices/USB/VUSBInternal.h
index e82c4ce4..4a482ca5 100644
--- a/src/VBox/Devices/USB/VUSBInternal.h
+++ b/src/VBox/Devices/USB/VUSBInternal.h
@@ -421,6 +421,8 @@ typedef struct VUSBROOTHUB
/** Flag whether a frame is currently being processed. */
volatile bool fFrameProcessing;
+ /** Flag whether we are in the middle of saving the VM state. */
+ volatile bool fSavingState;
#if HC_ARCH_BITS == 32
uint32_t Alignment1;
diff --git a/src/VBox/Devices/USB/VUSBUrb.cpp b/src/VBox/Devices/USB/VUSBUrb.cpp
index 595277f9..f55e8746 100644
--- a/src/VBox/Devices/USB/VUSBUrb.cpp
+++ b/src/VBox/Devices/USB/VUSBUrb.cpp
@@ -231,7 +231,7 @@ static void vusbMsgCompletion(PVUSBURB pUrb)
int vusbUrbErrorRhEx(PVUSBROOTHUB pRh, PVUSBURB pUrb)
{
PVUSBDEV pDev = pUrb->pVUsb->pDev;
- LogFlow(("%s: vusbUrbErrorRh: pDev=%p[%s] rh=%p\n", pUrb->pszDesc, pDev, pDev->pUsbIns ? pDev->pUsbIns->pszName : "", pRh));
+ LogFlow(("%s: vusbUrbErrorRh: pDev=%p[%s] rh=%p\n", pUrb->pszDesc, pDev, pDev && pDev->pUsbIns ? pDev->pUsbIns->pszName : "", pRh));
RT_NOREF(pDev);
return pRh->pIRhPort->pfnXferError(pRh->pIRhPort, pUrb);
}
diff --git a/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp b/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
index e76eb5f8..f3b568f7 100644
--- a/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
+++ b/src/VBox/Devices/USB/darwin/USBProxyDevice-darwin.cpp
@@ -50,6 +50,7 @@
#include <iprt/assert.h>
#include <iprt/critsect.h>
+#include <iprt/ldr.h>
#include <iprt/list.h>
#include <iprt/mem.h>
#include <iprt/once.h>
@@ -74,6 +75,17 @@
typedef struct USBPROXYIFOSX *PUSBPROXYIFOSX;
+/** @name IOKitLib declarations and definitions for IOServiceAuthorize() which is not available in all SDKs.
+ * @{ */
+/** IOServiceAuthorize in IOKit. */
+typedef kern_return_t (* PFNIOSERVICEAUTHORIZE)(io_service_t, uint32_t options);
+
+#ifndef kIOServiceInteractionAllowed
+# define kIOServiceInteractionAllowed 0x00000001
+#endif
+/** @} */
+
+
/**
* A low latency isochronous buffer.
*
@@ -278,6 +290,8 @@ static CFStringRef g_pRunLoopMode = NULL;
/** The IO Master Port.
* Not worth cleaning up. */
static mach_port_t g_MasterPort = MACH_PORT_NULL;
+/** Pointer to the IOServiceAuthorize() method. */
+static PFNIOSERVICEAUTHORIZE g_pfnIOServiceAuthorize = NULL;
/**
@@ -291,7 +305,17 @@ static DECLCALLBACK(int32_t) usbProxyDarwinInitOnce(void *pvUser1)
{
RT_NOREF(pvUser1);
- int rc;
+ RTLDRMOD hMod = NIL_RTLDRMOD;
+ int rc = RTLdrLoadEx("/System/Library/Frameworks/IOKit.framework/Versions/Current/IOKit", &hMod, RTLDRLOAD_FLAGS_NO_SUFFIX | RTLDRLOAD_FLAGS_NO_UNLOAD,
+ NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTLdrGetSymbol(hMod, "IOServiceAuthorize", (void **)&g_pfnIOServiceAuthorize);
+ if (RT_FAILURE(rc))
+ LogRel(("USB: Failed to resolve IOServiceAuthorize(), capturing USB devices might not work (%Rrc)\n", rc));
+ RTLdrClose(hMod);
+ }
+
kern_return_t krc = IOMasterPort(MACH_PORT_NULL, &g_MasterPort);
if (krc == KERN_SUCCESS)
{
@@ -1215,6 +1239,17 @@ static DECLCALLBACK(int) usbProxyDarwinOpen(PUSBPROXYDEV pProxyDev, const char *
}
/*
+ * Ask for authorization (which only works with the com.apple.vm.device-access entitlement).
+ */
+ if (g_pfnIOServiceAuthorize)
+ {
+ irc = g_pfnIOServiceAuthorize(USBDevice, kIOServiceInteractionAllowed);
+ if (irc != kIOReturnSuccess)
+ LogRel(("USB: Failed to get authorization for device '%s', capturing the device might not work: irc=%#x\n",
+ pszAddress, irc));
+ }
+
+ /*
* Create a plugin interface for the device and query its IOUSBDeviceInterface.
*/
SInt32 Score = 0;
diff --git a/src/VBox/Devices/VirtIO/VirtioCore.cpp b/src/VBox/Devices/VirtIO/VirtioCore.cpp
index f0ed6e42..a0deddd6 100644
--- a/src/VBox/Devices/VirtIO/VirtioCore.cpp
+++ b/src/VBox/Devices/VirtIO/VirtioCore.cpp
@@ -1193,7 +1193,10 @@ int virtioCoreR3VirtqUsedBufPut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_
size_t cbCopy = 0, cbTotal = 0, cbRemain = 0;
- if (pSgVirtReturn)
+ /** @todo r=aeichner Check whether VirtIO should return an error if the device wants to return data but
+ * the guest didn't set up an IN buffer. */
+ if ( pSgVirtReturn
+ && pSgPhysReturn)
{
size_t cbTarget = virtioCoreGCPhysChainCalcBufSize(pSgPhysReturn);
cbRemain = cbTotal = RTSgBufCalcTotalLength(pSgVirtReturn);
@@ -1227,7 +1230,9 @@ int virtioCoreR3VirtqUsedBufPut(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, uint16_
virtioWriteUsedElem(pDevIns, pVirtio, pVirtq, pVirtq->uUsedIdxShadow++, pVirtqBuf->uHeadIdx, (uint32_t)cbTotal);
#ifdef LOG_ENABLED
- if (LogIs6Enabled() && pSgVirtReturn)
+ if ( LogIs6Enabled()
+ && pSgVirtReturn
+ && pSgPhysReturn)
{
LogFunc((" ... %d segs, %zu bytes, copied to %u byte buf@offset=%u. Residual: %zu bytes\n",
diff --git a/src/VBox/Devices/build/VBoxDD.cpp b/src/VBox/Devices/build/VBoxDD.cpp
index 36b12c69..1e88822d 100644
--- a/src/VBox/Devices/build/VBoxDD.cpp
+++ b/src/VBox/Devices/build/VBoxDD.cpp
@@ -246,6 +246,10 @@ extern "C" DECLEXPORT(int) VBoxDevicesRegister(PPDMDEVREGCB pCallbacks, uint32_t
rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceTpm);
if (RT_FAILURE(rc))
return rc;
+
+ rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceTpmPpi);
+ if (RT_FAILURE(rc))
+ return rc;
#endif
return VINF_SUCCESS;
diff --git a/src/VBox/Devices/build/VBoxDD.h b/src/VBox/Devices/build/VBoxDD.h
index 9350f428..e451abcd 100644
--- a/src/VBox/Devices/build/VBoxDD.h
+++ b/src/VBox/Devices/build/VBoxDD.h
@@ -115,6 +115,7 @@ extern const PDMDEVREG g_DeviceVirtualKD;
extern const PDMDEVREG g_DeviceQemuFwCfg;
#ifdef VBOX_WITH_TPM
extern const PDMDEVREG g_DeviceTpm;
+extern const PDMDEVREG g_DeviceTpmPpi;
#endif
extern const PDMDRVREG g_DrvMouseQueue;
diff --git a/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp b/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
index c1886d31..98280dae 100644
--- a/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
+++ b/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp
@@ -590,7 +590,7 @@ int ShClConvUtf16LFToCRLFA(PCRTUTF16 pcwszSrc, size_t cwcSrc,
PRTUTF16 pwszDst = NULL;
size_t cchDst;
- int rc = ShClUtf16LFLenUtf8(pcwszSrc, cwcSrc, &cchDst);
+ int rc = ShClUtf16CalcNormalizedEolToCRLFLength(pcwszSrc, cwcSrc, &cchDst);
if (RT_SUCCESS(rc))
{
pwszDst = (PRTUTF16)RTMemAlloc((cchDst + 1 /* Leave space for terminator */) * sizeof(RTUTF16));
@@ -760,7 +760,7 @@ int ShClConvUtf16ToUtf8HTML(PCRTUTF16 pcwszSrc, size_t cwcSrc, char **ppszDst, s
return rc;
}
-int ShClUtf16LFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pchLen)
+int ShClUtf16CalcNormalizedEolToCRLFLength(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pchLen)
{
AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER);
AssertPtrReturn(pchLen, VERR_INVALID_POINTER);
@@ -778,12 +778,18 @@ int ShClUtf16LFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pchLen)
for (; i < cwSrc; ++i, ++cLen)
{
/* Check for a single line feed */
- if (pcwszSrc[i] == VBOX_SHCL_LINEFEED)
+ if ( pcwszSrc[i] == VBOX_SHCL_LINEFEED
+ && (i == 0 || pcwszSrc[i - 1] != VBOX_SHCL_CARRIAGERETURN))
+ {
++cLen;
+ }
#ifdef RT_OS_DARWIN
/* Check for a single carriage return (MacOS) */
- if (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN)
+ if ( pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN
+ && (i + 1 >= cwSrc || pcwszSrc[i + 1] != VBOX_SHCL_LINEFEED))
+ {
++cLen;
+ }
#endif
if (pcwszSrc[i] == 0)
{
@@ -832,79 +838,63 @@ int ShClUtf16CRLFLenUtf8(PCRTUTF16 pcwszSrc, size_t cwSrc, size_t *pchLen)
return VINF_SUCCESS;
}
-int ShClConvUtf16LFToCRLF(PCRTUTF16 pcwszSrc, size_t cwcSrc, PRTUTF16 pu16Dst, size_t cwDst)
+int ShClConvUtf16LFToCRLF(PCRTUTF16 pcwszSrc, size_t cwcSrc, PRTUTF16 pu16Dst, size_t cwcDst)
{
AssertPtrReturn(pcwszSrc, VERR_INVALID_POINTER);
AssertPtrReturn(pu16Dst, VERR_INVALID_POINTER);
- AssertReturn(cwDst, VERR_INVALID_PARAMETER);
+ AssertReturn(cwcDst, VERR_INVALID_PARAMETER);
AssertMsgReturn(pcwszSrc[0] != VBOX_SHCL_UTF16BEMARKER,
("Big endian UTF-16 not supported yet\n"), VERR_NOT_SUPPORTED);
- int rc = VINF_SUCCESS;
-
/* Don't copy the endian marker. */
- size_t i = pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER ? 1 : 0;
- size_t j = 0;
-
- for (; i < cwcSrc; ++i, ++j)
+ size_t offDst = 0;
+ for (size_t offSrc = pcwszSrc[0] == VBOX_SHCL_UTF16LEMARKER ? 1 : 0; offSrc < cwcSrc; ++offSrc, ++offDst)
{
- /* Don't copy the null byte, as we add it below. */
- if (pcwszSrc[i] == 0)
- break;
+ /* Ensure more output space: */
+ if (offDst < cwcDst) { /* likely */ }
+ else return VERR_BUFFER_OVERFLOW;
- /* Not enough space in destination? */
- if (j == cwDst)
- {
- rc = VERR_BUFFER_OVERFLOW;
+ /* Don't copy the null byte, as we add it below. */
+ if (pcwszSrc[offSrc] == 0)
break;
- }
- if (pcwszSrc[i] == VBOX_SHCL_LINEFEED)
+ /* Check for newlines not preceeded by carriage return: "\n" -> "\r\n"; but not "\r\n" to "\r\r\n"! */
+ if ( pcwszSrc[offSrc] == VBOX_SHCL_LINEFEED
+ && (offSrc == 0 || pcwszSrc[offSrc - 1] != VBOX_SHCL_CARRIAGERETURN))
{
- pu16Dst[j] = VBOX_SHCL_CARRIAGERETURN;
- ++j;
+ pu16Dst[offDst++] = VBOX_SHCL_CARRIAGERETURN;
- /* Not enough space in destination? */
- if (j == cwDst)
- {
- rc = VERR_BUFFER_OVERFLOW;
- break;
- }
+ /* Ensure sufficient output space: */
+ if (offDst < cwcDst) { /* likely */ }
+ else return VERR_BUFFER_OVERFLOW;
}
#ifdef RT_OS_DARWIN
- /* Check for a single carriage return (MacOS) */
- else if (pcwszSrc[i] == VBOX_SHCL_CARRIAGERETURN)
+ /* Check for a carriage return not followed by newline (MacOS): "\r" -> "\n\r"; but not "\r\n" to "\r\n\n"! */
+ else if ( pcwszSrc[offSrc] == VBOX_SHCL_CARRIAGERETURN
+ && (offSrc + 1 >= cwcSrc || pcwszSrc[offSrc + 1] != VBOX_SHCL_LINEFEED))
{
- /* Set CR.r */
- pu16Dst[j] = VBOX_SHCL_CARRIAGERETURN;
- ++j;
+ pu16Dst[offDst++] = VBOX_SHCL_CARRIAGERETURN;
- /* Not enough space in destination? */
- if (j == cwDst)
- {
- rc = VERR_BUFFER_OVERFLOW;
- break;
- }
+ /* Ensure more output space: */
+ if (offDst < cwcDst) { /* likely */ }
+ else return VERR_BUFFER_OVERFLOW;
/* Add line feed. */
- pu16Dst[j] = VBOX_SHCL_LINEFEED;
+ pu16Dst[offDst] = VBOX_SHCL_LINEFEED;
continue;
}
#endif
- pu16Dst[j] = pcwszSrc[i];
+ pu16Dst[offDst] = pcwszSrc[offSrc];
}
- if (j == cwDst)
- rc = VERR_BUFFER_OVERFLOW;
-
- if (RT_SUCCESS(rc))
+ /* Add terminator. */
+ if (offDst < cwcDst)
{
- /* Add terminator. */
- pu16Dst[j] = 0;
+ pu16Dst[offDst] = 0;
+ return VINF_SUCCESS;
}
-
- return rc;
+ return VERR_BUFFER_OVERFLOW;
}
int ShClConvUtf16CRLFToLF(PCRTUTF16 pcwszSrc, size_t cwcSrc, PRTUTF16 pu16Dst, size_t cwDst)
diff --git a/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardGH-X11.cpp b/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardGH-X11.cpp
index f9bc19c1..c280c684 100644
--- a/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardGH-X11.cpp
+++ b/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardGH-X11.cpp
@@ -510,9 +510,7 @@ static void tstStringFromX11(RTTEST hTest, PSHCLX11CTX pCtx,
{
if (cbActual != cbExp)
{
- RTTestFailed(hTest, "Returned string is the wrong size, string \"%.*ls\", size %u, expected \"%s\", size %u\n",
- RT_MIN(TESTCASE_MAX_BUF_SIZE, cbActual), pc, cbActual,
- pcszExp, cbExp);
+ RTTestFailed(hTest, "Returned string is the wrong size: got size %u, expected %u\n", cbActual, cbExp);
}
else
{
@@ -710,7 +708,7 @@ int main()
/* With an embedded CRLF */
tstClipSetSelectionValues("text/plain;charset=UTF-8", XA_STRING,
"hello\r\nworld", sizeof("hello\r\nworld"), 8);
- tstStringFromX11(hTest, &X11Ctx, "hello\r\r\nworld", VINF_SUCCESS);
+ tstStringFromX11(hTest, &X11Ctx, "hello\r\nworld", VINF_SUCCESS);
/* With an embedded LFCR */
tstClipSetSelectionValues("text/plain;charset=UTF-8", XA_STRING,
"hello\n\rworld", sizeof("hello\n\rworld"), 8);
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
index 1cff0981..d7c1afb5 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFltInternal.h
@@ -202,6 +202,8 @@ typedef struct VBOXNETFLTINS
struct sk_buff_head XmitQueue;
struct work_struct XmitTask;
# endif
+ /** Unique identifier of network namespace of device to attach to. */
+ uint32_t uNamespaceInode;
/** @} */
# elif defined(RT_OS_SOLARIS)
/** @name Solaris instance data.
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
index 85777fa1..a016cf69 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
@@ -47,7 +47,11 @@
#if RTLNX_VER_MIN(2,6,24)
# include <linux/nsproxy.h>
#endif
-#if RTLNX_VER_MIN(6,4,10) || RTLNX_RHEL_RANGE(9,4, 9,99)
+#if RTLNX_VER_MIN(3,10,0) /* proc_ns introduced */
+# define VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+# include <linux/proc_ns.h>
+#endif
+#if RTLNX_VER_MIN(6,4,10) || RTLNX_RHEL_RANGE(9,4, 9,99) || RTLNX_SUSE_MAJ_PREREQ(15, 6)
# include <net/gso.h>
#endif
#include <linux/netdevice.h>
@@ -1841,6 +1845,7 @@ static void vboxNetFltSetLinkState(PVBOXNETFLTINS pThis, struct net_device *pDev
*/
static int vboxNetFltLinuxAttachToInterface(PVBOXNETFLTINS pThis, struct net_device *pDev)
{
+ bool fAlreadyAttached = false;
LogFlow(("vboxNetFltLinuxAttachToInterface: pThis=%p (%s)\n", pThis, pThis->szName));
/*
@@ -1849,9 +1854,20 @@ static int vboxNetFltLinuxAttachToInterface(PVBOXNETFLTINS pThis, struct net_dev
dev_hold(pDev);
RTSpinlockAcquire(pThis->hSpinlock);
- ASMAtomicUoWritePtr(&pThis->u.s.pDev, pDev);
+ if (ASMAtomicUoReadPtrT(&pThis->u.s.pDev, struct net_device *))
+ fAlreadyAttached = true; /* Do not attach multiple times! */
+ else
+ ASMAtomicUoWritePtr(&pThis->u.s.pDev, pDev);
RTSpinlockRelease(pThis->hSpinlock);
+ if (fAlreadyAttached)
+ {
+ dev_put(pDev);
+ Log(("vboxNetFltLinuxAttachToInterface: Not attaching to %p(%s), already attached to %p(%s).\n",
+ pDev, pDev->name, pThis->u.s.pDev, pThis->u.s.pDev->name));
+ return VINF_ALREADY_INITIALIZED;
+ }
+
Log(("vboxNetFltLinuxAttachToInterface: Device %p(%s) retained. ref=%d\n",
pDev, pDev->name,
#if RTLNX_VER_MIN(2,6,37)
@@ -2062,6 +2078,29 @@ static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned
if (ulEventType == NETDEV_REGISTER)
{
+#ifdef VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+# if RTLNX_VER_MIN(3,19,0) /* ns_common introduced */
+# define VBOX_DEV_NET_NS_INUM(dev) dev_net(dev)->ns.inum
+# else
+# define VBOX_DEV_NET_NS_INUM(dev) dev_net(dev)->proc_inum
+# endif
+ if (pThis->u.s.uNamespaceInode == 0 || pThis->u.s.uNamespaceInode == VBOX_DEV_NET_NS_INUM(pDev))
+ {
+ /* Skip namespace if it is present */
+ const char *pcszIfName = strchr(pThis->szName, '/');
+ if (pcszIfName)
+ ++pcszIfName;
+ else
+ pcszIfName = pThis->szName;
+ if (strcmp(pDev->name, pcszIfName) == 0)
+ vboxNetFltLinuxAttachToInterface(pThis, pDev);
+ else
+ Log(("VBoxNetFlt: not attaching to '%s' as it does not match '%s'\n", pDev->name, pcszIfName));
+ }
+ else
+ Log(("VBoxNetFlt: ignoring '%s' in wrong namespace (%u, expected %u)\n", pDev->name,
+ VBOX_DEV_NET_NS_INUM(pDev), pThis->u.s.uNamespaceInode));
+#else /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
#if RTLNX_VER_MIN(2,6,24) /* cgroups/namespaces introduced */
# if RTLNX_VER_MIN(2,6,26)
# define VBOX_DEV_NET(dev) dev_net(dev)
@@ -2081,6 +2120,7 @@ static int vboxNetFltLinuxNotifierCallback(struct notifier_block *self, unsigned
vboxNetFltLinuxAttachToInterface(pThis, pDev);
}
}
+#endif /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
}
else
{
@@ -2579,6 +2619,12 @@ int vboxNetFltOsPreInitInstance(PVBOXNETFLTINS pThis)
pThis->u.s.fPromiscuousSet = false;
pThis->u.s.fPacketHandler = false;
memset(&pThis->u.s.PacketType, 0, sizeof(pThis->u.s.PacketType));
+#ifdef VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+ /* We should get the interface name in the form <namespace>/<ifname>, parse it. */
+ pThis->u.s.uNamespaceInode = RTStrToUInt32(pThis->szName);
+#else /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
+ pThis->u.s.uNamespaceInode = 0;
+#endif /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
#ifndef VBOXNETFLT_LINUX_NO_XMIT_QUEUE
skb_queue_head_init(&pThis->u.s.XmitQueue);
# if RTLNX_VER_MIN(2,6,20)
diff --git a/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp b/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
index 290763be..41d08be5 100644
--- a/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
+++ b/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
@@ -308,7 +308,7 @@ int readFromPasteboard(PasteboardRef pPasteboard, uint32_t fFormat, void *pv, ui
*/
Assert(cwcSrc == RTUtf16Len(pwszSrc));
size_t cwcDst = 0;
- rc = ShClUtf16LFLenUtf8(pwszSrc, cwcSrc, &cwcDst);
+ rc = ShClUtf16CalcNormalizedEolToCRLFLength(pwszSrc, cwcSrc, &cwcDst);
if (RT_SUCCESS(rc))
{
cwcDst++; /* Add space for terminator. */
diff --git a/src/VBox/Installer/darwin/Makefile.kmk b/src/VBox/Installer/darwin/Makefile.kmk
index 1b7a16f8..beffa086 100644
--- a/src/VBox/Installer/darwin/Makefile.kmk
+++ b/src/VBox/Installer/darwin/Makefile.kmk
@@ -189,7 +189,9 @@ ifdef VBOX_SIGNING_MODE
$(call VBOX_SIGN_DMG_FN,$@,org.virtualbox.dmg)
if $(intersects darwin darwin_notarize all 1,$(VBOX_WITH_CORP_CODE_SIGNING))
@# Notarize the signed dmg (includes stapling).
- $(call VBOX_NOTARIZE_FILE_FN,$@,org.virtualbox.VirtualBox.$(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD).$(VBOX_SVN_REV))
+ $(call VBOX_NOTARIZE_FILE_FN,$@,org.virtualbox.VirtualBox.$(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD).$(VBOX_SVN_REV),$(call VBOX_DIRX,$@).tmp)
+ $(MV) -f $(call VBOX_DIRX,$@).tmp/$(call VBOX_NOTDIRX,$@) $@
+ $(RMDIR) $(call VBOX_DIRX,$@).tmp
endif
endif
endif
diff --git a/src/VBox/Installer/linux/distributions_deb b/src/VBox/Installer/linux/distributions_deb
index 072f3323..3ece6095 100644
--- a/src/VBox/Installer/linux/distributions_deb
+++ b/src/VBox/Installer/linux/distributions_deb
@@ -2,6 +2,7 @@ _Debian_sid = DEBIAN_12_0
_Debian_bookworm = DEBIAN_12_0
_Debian_bullseye = DEBIAN_11_0
_Debian_buster = DEBIAN_10_0
+_Ubuntu_noble = UBUNTU_24_04
_Ubuntu_jammy = UBUNTU_22_04
_Ubuntu_focal = UBUNTU_20_04
_Ubuntu_eoan = UBUNTU_19_10
diff --git a/src/VBox/Installer/win/UserInterface.wxi b/src/VBox/Installer/win/UserInterface.wxi
index cd4c2660..b8fff529 100644
--- a/src/VBox/Installer/win/UserInterface.wxi
+++ b/src/VBox/Installer/win/UserInterface.wxi
@@ -364,7 +364,6 @@
<Control Id="Text" Type="Text" X="25" Y="70" Width="320" Height="20">
<Text>!(loc.Customize2Dlg_Desc)</Text>
</Control>
-<?if $(env.VBOX_WITH_QTGUI) = "yes" ?>
<!-- Note the gray background behind the checkboxes. Unfortunately there's no easy way to
fix this, without fixing it in the WiX source code. Because the control's background
uses the default dialog background color, changing the background image for the dialog to
@@ -388,7 +387,7 @@
Property="VBOX_REGISTERFILEEXTENSIONS" CheckBoxValue="1" Default="no">
<Text>!(loc.Customize2Dlg_RegisterFileExtensions)</Text>
</Control>
-<?endif?> <!-- VBOX_WITH_QTGUI -->
+
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Next)" />
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.ButtonText_Back)" />
@@ -1169,11 +1168,11 @@
<!-- Property which defines whether the installer checks the serial number or not. -->
<Property Id="VBOX_SHOW_SERIAL_CHECK_DLG">1</Property>
<?endif?>
-<?if $(env.VBOX_WITH_QTGUI) = "no" ?>
+<?if $(env.VBOX_WITH_QTGUI) = "yes" ?>
<!-- Property which defines whether to show the second customization dialog. This second customization
dialog only is needed for GUI-based options, so skip if we either don't ship FE/Qt or don't show
the (first) customization dialog. -->
- <Property Id="VBOX_SHOW_CUSTOMIZE2_DLG"><![CDATA[VBOX_SHOW_CUSTOMIZE_DLG]]></Property>
+ <Property Id="VBOX_SHOW_CUSTOMIZE2_DLG">1</Property>
<?endif?>
diff --git a/src/VBox/Main/Certificates/microsoft_corporation_kek_2k_ca_2023.crt b/src/VBox/Main/Certificates/microsoft_corporation_kek_2k_ca_2023.crt
new file mode 100644
index 00000000..e6ffb4f9
--- /dev/null
+++ b/src/VBox/Main/Certificates/microsoft_corporation_kek_2k_ca_2023.crt
Binary files differ
diff --git a/src/VBox/Main/Certificates/microsoft_uefi_ca_2023.crt b/src/VBox/Main/Certificates/microsoft_uefi_ca_2023.crt
new file mode 100644
index 00000000..39a91b31
--- /dev/null
+++ b/src/VBox/Main/Certificates/microsoft_uefi_ca_2023.crt
Binary files differ
diff --git a/src/VBox/Main/Certificates/windows_uefi_ca_2023.crt b/src/VBox/Main/Certificates/windows_uefi_ca_2023.crt
new file mode 100644
index 00000000..4c5430b2
--- /dev/null
+++ b/src/VBox/Main/Certificates/windows_uefi_ca_2023.crt
Binary files differ
diff --git a/src/VBox/Main/Makefile.kmk b/src/VBox/Main/Makefile.kmk
index 5711816d..00bab609 100644
--- a/src/VBox/Main/Makefile.kmk
+++ b/src/VBox/Main/Makefile.kmk
@@ -440,19 +440,23 @@ if !defined(VBOX_ONLY_SDK) && !defined(VBOX_ONLY_EXTPACKS) # Note this goes on f
#
# Trust anchors and certificates -> .cpp
+ # Source for the Microsoft Certificates: https://github.com/microsoft/secureboot_objects
#
VBOX_SVC_CERTS_FILE = $(VBoxSVC_0_OUTDIR)/TrustAnchorsAndCerts.cpp
VBOX_SVC_CERTS := \
UefiMicrosoftKek=MicCorKEKCA2011_2011-06-24.crt \
- UefiMicrosoftCa=MicCorUEFCA2011_2011-06-27.crt \
- UefiMicrosoftProPca=MicWinProPCA2011_2011-10-19.crt \
+ UefiMicrosoftKek2023=microsoft_corporation_kek_2k_ca_2023.crt \
+ UefiMicrosoft3rdCa=MicCorUEFCA2011_2011-06-27.crt \
+ UefiMicrosoft3rdCa2023=microsoft_uefi_ca_2023.crt \
+ UefiMicrosoftWinCa=MicWinProPCA2011_2011-10-19.crt \
+ UefiMicrosoftWinCa2023=windows_uefi_ca_2023.crt \
UefiOracleDefPk=OrclUefiDefPk2021_2021-09-29.crt
- VBOX_SVC_CERT_NAMES := $(foreach cert,$(VBOX_SVC_CERTS),$(firstword $(subst =,$(SPACE) ,$(cert))))
+ VBOX_SVC_CERT_NAMES := $(foreach cert,$(VBOX_SVC_CERTS),$(firstword $(subst =,$(SP),$(cert))))
VBOX_SVC_PATH_CERTIFICATES := $(PATH_SUB_CURRENT)/Certificates
$$(VBOX_SVC_CERTS_FILE): $(MAKEFILE_CURRENT) \
- $(foreach cert,$(VBOX_SVC_CERTS),$(VBOX_SVC_PATH_CERTIFICATES)/$(lastword $(subst =,$(SPACE) ,$(cert)))) \
+ $(foreach cert,$(VBOX_SVC_CERTS),$(VBOX_SVC_PATH_CERTIFICATES)/$(lastword $(subst =,$(SP),$(cert)))) \
$(VBOX_BIN2C) \
| $$(dir $$@)
$(QUIET)$(RM) -f -- $@
@@ -461,8 +465,8 @@ if !defined(VBOX_ONLY_SDK) && !defined(VBOX_ONLY_EXTPACKS) # Note this goes on f
'#include "TrustAnchorsAndCerts.h"' \
''
$(foreach cert,$(VBOX_SVC_CERTS), $(NLTAB)$(VBOX_BIN2C) -ascii --append \
- "$(firstword $(subst =,$(SP) ,$(cert)))" \
- "$(VBOX_SVC_PATH_CERTIFICATES)/$(lastword $(subst =,$(SP) ,$(cert)))" \
+ "$(firstword $(subst =,$(SP),$(cert)))" \
+ "$(VBOX_SVC_PATH_CERTIFICATES)/$(lastword $(subst =,$(SP),$(cert)))" \
"$@")
OTHER_CLEAN += $(VBOX_SVC_CERTS_FILE)
diff --git a/src/VBox/Main/include/GuestSessionImplTasks.h b/src/VBox/Main/include/GuestSessionImplTasks.h
index d32cd8b3..463ad443 100644
--- a/src/VBox/Main/include/GuestSessionImplTasks.h
+++ b/src/VBox/Main/include/GuestSessionImplTasks.h
@@ -419,6 +419,8 @@ protected:
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);
+ HRESULT setUpdateErrorMsg(HRESULT hrc, const Utf8Str &strMsg);
+ HRESULT setUpdateErrorMsg(HRESULT hrc, const Utf8Str &strMsg, const GuestErrorInfo &guestErrorInfo);
int checkGuestAdditionsStatus(GuestSession *pSession, eOSType osType);
int waitForGuestSession(ComObjPtr<Guest> pGuest, eOSType osType);
diff --git a/src/VBox/Main/include/TrustAnchorsAndCerts.h b/src/VBox/Main/include/TrustAnchorsAndCerts.h
index b828c179..9b9e4cf9 100644
--- a/src/VBox/Main/include/TrustAnchorsAndCerts.h
+++ b/src/VBox/Main/include/TrustAnchorsAndCerts.h
@@ -38,11 +38,20 @@ 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_abUefiMicrosoftKek2023[];
+extern const unsigned g_cbUefiMicrosoftKek2023;
-extern const unsigned char g_abUefiMicrosoftProPca[];
-extern const unsigned g_cbUefiMicrosoftProPca;
+extern const unsigned char g_abUefiMicrosoft3rdCa[];
+extern const unsigned g_cbUefiMicrosoft3rdCa;
+
+extern const unsigned char g_abUefiMicrosoft3rdCa2023[];
+extern const unsigned g_cbUefiMicrosoft3rdCa2023;
+
+extern const unsigned char g_abUefiMicrosoftWinCa[];
+extern const unsigned g_cbUefiMicrosoftWinCa;
+
+extern const unsigned char g_abUefiMicrosoftWinCa2023[];
+extern const unsigned g_cbUefiMicrosoftWinCa2023;
extern const unsigned char g_abUefiOracleDefPk[];
extern const unsigned g_cbUefiOracleDefPk;
diff --git a/src/VBox/Main/include/netif.h b/src/VBox/Main/include/netif.h
index 3d344914..cf6a2853 100644
--- a/src/VBox/Main/include/netif.h
+++ b/src/VBox/Main/include/netif.h
@@ -43,6 +43,13 @@
# include <stdio.h>
#endif /* !RT_OS_WINDOWS */
+#ifdef RT_OS_LINUX
+# include <linux/version.h>
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) /* proc_ns introduced */
+# define VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+# endif
+#endif
+
#define VBOXNET_IPV4ADDR_DEFAULT 0x0138A8C0 /* 192.168.56.1 */
#define VBOXNET_IPV4MASK_DEFAULT "255.255.255.0"
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index 6d94eb1f..c28eda2a 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -7500,8 +7500,11 @@ int Console::i_recordingStart(util::AutoWriteLock *pAutoLock /* = NULL */)
/**
* Stops recording. Does nothing if recording is not active.
+ *
+ * Note: This does *not* disable recording for a VM, in other words,
+ * it does not change the VM's recording (enabled) setting.
*/
-int Console::i_recordingStop(util::AutoWriteLock *pAutoLock /* = NULL */)
+int Console::i_recordingStop(util::AutoWriteLock *)
{
if (!mRecording.mCtx.IsStarted())
return VINF_SUCCESS;
@@ -7514,18 +7517,6 @@ int Console::i_recordingStop(util::AutoWriteLock *pAutoLock /* = NULL */)
const size_t cStreams = mRecording.mCtx.GetStreamCount();
for (unsigned uScreen = 0; uScreen < cStreams; ++uScreen)
mDisplay->i_recordingScreenChanged(uScreen);
-
- if (pAutoLock)
- pAutoLock->release();
-
- ComPtr<IRecordingSettings> pRecordSettings;
- HRESULT hrc = mMachine->COMGETTER(RecordingSettings)(pRecordSettings.asOutParam());
- ComAssertComRC(hrc);
- hrc = pRecordSettings->COMSETTER(Enabled)(FALSE);
- ComAssertComRC(hrc);
-
- if (pAutoLock)
- pAutoLock->acquire();
}
LogFlowFuncLeaveRC(vrc);
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index 3576c493..cf57754d 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -145,6 +145,9 @@
# include "ExtPackManagerImpl.h"
#endif
+/** The TPM PPI MMIO base default (compatible with qemu). */
+#define TPM_PPI_MMIO_BASE_DEFAULT UINT64_C(0xfed45000)
+
/*********************************************************************************************************************************
* Internal Functions *
@@ -1928,6 +1931,58 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, Au
N_("Invalid graphics controller type '%d'"), enmGraphicsController);
}
+#if defined(VBOX_WITH_TPM)
+ /*
+ * Configure the Trusted Platform Module.
+ */
+ ComObjPtr<ITrustedPlatformModule> ptrTpm;
+ TpmType_T enmTpmType = TpmType_None;
+
+ hrc = pMachine->COMGETTER(TrustedPlatformModule)(ptrTpm.asOutParam()); H();
+ hrc = ptrTpm->COMGETTER(Type)(&enmTpmType); H();
+ if (enmTpmType != TpmType_None)
+ {
+ InsertConfigNode(pDevices, "tpm", &pDev);
+ InsertConfigNode(pDev, "0", &pInst);
+ InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
+ InsertConfigNode(pInst, "Config", &pCfg);
+ InsertConfigNode(pInst, "LUN#0", &pLunL0);
+
+ switch (enmTpmType)
+ {
+ case TpmType_v1_2:
+ case TpmType_v2_0:
+ InsertConfigString(pLunL0, "Driver", "TpmEmuTpms");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "TpmVersion", enmTpmType == TpmType_v1_2 ? 1 : 2);
+ InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
+ InsertConfigString(pLunL1, "Driver", "NvramStore");
+ break;
+ case TpmType_Host:
+#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
+ InsertConfigString(pLunL0, "Driver", "TpmHost");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+#endif
+ break;
+ case TpmType_Swtpm:
+ hrc = ptrTpm->COMGETTER(Location)(bstr.asOutParam()); H();
+ InsertConfigString(pLunL0, "Driver", "TpmEmu");
+ InsertConfigNode(pLunL0, "Config", &pCfg);
+ InsertConfigString(pCfg, "Location", bstr);
+ break;
+ default:
+ AssertFailedBreak();
+ }
+
+ /* Add the device for the physical presence interface. */
+ InsertConfigNode( pDevices, "tpm-ppi", &pDev);
+ InsertConfigNode( pDev, "0", &pInst);
+ InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
+ InsertConfigNode( pInst, "Config", &pCfg);
+ InsertConfigInteger(pCfg, "MmioBase", TPM_PPI_MMIO_BASE_DEFAULT);
+ }
+#endif
+
/*
* Firmware.
*/
@@ -2116,6 +2171,9 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, Au
InsertConfigInteger(pCfg, "DmiExposeMemoryTable", 1);
}
+ if (enmTpmType != TpmType_None)
+ InsertConfigInteger(pCfg, "TpmPpiBase", TPM_PPI_MMIO_BASE_DEFAULT);
+
/* Attach the NVRAM storage driver. */
InsertConfigNode(pInst, "LUN#0", &pLunL0);
InsertConfigString(pLunL0, "Driver", "NvramStore");
@@ -3540,51 +3598,6 @@ int Console::i_configConstructorInner(PUVM pUVM, PVM pVM, PCVMMR3VTABLE pVMM, Au
}
#endif /* VBOX_WITH_DRAG_AND_DROP */
-#if defined(VBOX_WITH_TPM)
- /*
- * Configure the Trusted Platform Module.
- */
- ComObjPtr<ITrustedPlatformModule> ptrTpm;
- TpmType_T enmTpmType = TpmType_None;
-
- hrc = pMachine->COMGETTER(TrustedPlatformModule)(ptrTpm.asOutParam()); H();
- hrc = ptrTpm->COMGETTER(Type)(&enmTpmType); H();
- if (enmTpmType != TpmType_None)
- {
- InsertConfigNode(pDevices, "tpm", &pDev);
- InsertConfigNode(pDev, "0", &pInst);
- InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
- InsertConfigNode(pInst, "Config", &pCfg);
- InsertConfigNode(pInst, "LUN#0", &pLunL0);
-
- switch (enmTpmType)
- {
- case TpmType_v1_2:
- case TpmType_v2_0:
- InsertConfigString(pLunL0, "Driver", "TpmEmuTpms");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigInteger(pCfg, "TpmVersion", enmTpmType == TpmType_v1_2 ? 1 : 2);
- InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1);
- InsertConfigString(pLunL1, "Driver", "NvramStore");
- break;
- case TpmType_Host:
-#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
- InsertConfigString(pLunL0, "Driver", "TpmHost");
- InsertConfigNode(pLunL0, "Config", &pCfg);
-#endif
- break;
- case TpmType_Swtpm:
- hrc = ptrTpm->COMGETTER(Location)(bstr.asOutParam()); H();
- InsertConfigString(pLunL0, "Driver", "TpmEmu");
- InsertConfigNode(pLunL0, "Config", &pCfg);
- InsertConfigString(pCfg, "Location", bstr);
- break;
- default:
- AssertFailedBreak();
- }
- }
-#endif
-
/*
* ACPI
*/
@@ -6203,6 +6216,17 @@ int Console::i_configNetwork(const char *pszDevice,
close(iSock);
}
}
+# ifdef VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+ RTUUID IfaceUuid;
+ Bstr IfId;
+ hrc = hostInterface->COMGETTER(Id)(IfId.asOutParam()); H();
+ vrc = RTUuidFromUtf16(&IfaceUuid, IfId.raw());
+ AssertRCReturn(vrc, vrc);
+ char szTrunkNameWithNamespace[INTNET_MAX_TRUNK_NAME];
+ RTStrPrintf(szTrunkNameWithNamespace, sizeof(szTrunkNameWithNamespace), "%u/%s",
+ IfaceUuid.au32[0], pszTrunk);
+ pszTrunk = szTrunkNameWithNamespace;
+# endif
# else
# error "PORTME (VBOX_WITH_NETFLT)"
diff --git a/src/VBox/Main/src-client/GuestSessionImplTasks.cpp b/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
index 9a74e050..b8666f20 100644
--- a/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
+++ b/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
@@ -2571,7 +2571,7 @@ int GuestSessionTaskUpdateAdditions::copyFileToGuest(GuestSession *pSession, RTV
vrc = RTVfsFileQuerySize(hVfsFile, &cbSrcSize);
if (RT_SUCCESS(vrc))
{
- LogRel(("Copying Guest Additions installer file \"%s\" to \"%s\" on guest ...\n",
+ LogRel(("Guest Additions Update: Copying installer file \"%s\" to \"%s\" on guest ...\n",
strFileSrc.c_str(), strFileDst.c_str()));
GuestFileOpenInfo dstOpenInfo;
@@ -2588,13 +2588,14 @@ int GuestSessionTaskUpdateAdditions::copyFileToGuest(GuestSession *pSession, RTV
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
- setProgressErrorMsg(VBOX_E_IPRT_ERROR, GuestFile::i_guestErrorToString(vrcGuest, strFileDst.c_str()));
+ setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ GuestFile::i_guestErrorToString(vrcGuest, strFileDst.c_str()));
break;
default:
- setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Guest file \"%s\" could not be opened: %Rrc"),
- strFileDst.c_str(), vrc));
+ setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ Utf8StrFmt(tr("Guest file \"%s\" could not be opened: %Rrc"),
+ strFileDst.c_str(), vrc));
break;
}
}
@@ -2617,6 +2618,34 @@ int GuestSessionTaskUpdateAdditions::copyFileToGuest(GuestSession *pSession, RTV
}
/**
+ * Sets an update error message to the current progress object + logs to release log.
+ *
+ * @returns Returns \a hrc for convenience.
+ * @param hrc Progress operation result to set.
+ * @param strMsg Message to set.
+ */
+HRESULT GuestSessionTaskUpdateAdditions::setUpdateErrorMsg(HRESULT hrc, const Utf8Str &strMsg)
+{
+ Utf8Str const strLog = "Guest Additions Update failed: " + strMsg;
+ LogRel(("%s\n", strLog.c_str()));
+ return GuestSessionTask::setProgressErrorMsg(hrc, strLog);
+}
+
+/**
+ * Sets an update error message to the current progress object + logs to release log.
+ *
+ * @returns Returns \a hrc for convenience.
+ * @param hrc Progress operation result to set.
+ * @param strMsg Message to set.
+ * @param guestErrorInfo Guest error info to use.
+ */
+HRESULT GuestSessionTaskUpdateAdditions::setUpdateErrorMsg(HRESULT hrc, const Utf8Str &strMsg, const GuestErrorInfo &guestErrorInfo)
+{
+ Utf8Str const strLog = strMsg + Utf8Str(": ") + GuestBase::getErrorAsString(guestErrorInfo);
+ return GuestSessionTaskUpdateAdditions::setProgressErrorMsg(hrc, strLog);
+}
+
+/**
* Helper function to run (start) a file on the guest.
*
* @returns VBox status code.
@@ -2628,7 +2657,7 @@ int GuestSessionTaskUpdateAdditions::runFileOnGuest(GuestSession *pSession, Gues
{
AssertPtrReturn(pSession, VERR_INVALID_POINTER);
- LogRel(("Running %s ...\n", procInfo.mName.c_str()));
+ LogRel(("Guest Additions Update: Running \"%s\" ...\n", procInfo.mName.c_str()));
GuestProcessTool procTool;
int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
@@ -2647,26 +2676,26 @@ int GuestSessionTaskUpdateAdditions::runFileOnGuest(GuestSession *pSession, Gues
switch (vrc)
{
case VERR_GSTCTL_PROCESS_EXIT_CODE:
- setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Running update file \"%s\" on guest failed: %Rrc"),
- procInfo.mExecutable.c_str(), procTool.getRc()));
+ setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ Utf8StrFmt(tr("Running update file \"%s\" on guest failed: %Rrc"),
+ procInfo.mExecutable.c_str(), procTool.getRc()));
break;
case VERR_GSTCTL_GUEST_ERROR:
- setProgressErrorMsg(VBOX_E_IPRT_ERROR, tr("Running update file on guest failed"),
- GuestErrorInfo(GuestErrorInfo::Type_Process, vrcGuest, procInfo.mExecutable.c_str()));
+ setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR, tr("Running update file on guest failed"),
+ GuestErrorInfo(GuestErrorInfo::Type_Process, vrcGuest, procInfo.mExecutable.c_str()));
break;
case VERR_INVALID_STATE: /** @todo Special guest control vrc needed! */
- setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Update file \"%s\" reported invalid running state"),
- procInfo.mExecutable.c_str()));
+ setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ Utf8StrFmt(tr("Update file \"%s\" reported invalid running state"),
+ procInfo.mExecutable.c_str()));
break;
default:
- setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Error while running update file \"%s\" on guest: %Rrc"),
- procInfo.mExecutable.c_str(), vrc));
+ setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ Utf8StrFmt(tr("Error while running update file \"%s\" on guest: %Rrc"),
+ procInfo.mExecutable.c_str(), vrc));
break;
}
}
@@ -2708,16 +2737,14 @@ int GuestSessionTaskUpdateAdditions::checkGuestAdditionsStatus(GuestSession *pSe
vrc = runFileOnGuest(pSession, procInfo, true /* fSilent */);
if (RT_FAILURE(vrc))
- hrc = setProgressErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
- Utf8StrFmt(tr("Automatic update of Guest Additions has failed: "
- "files were installed, but user services were not reloaded automatically. "
- "Please consider rebooting the guest")));
+ hrc = setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ Utf8StrFmt(tr("Files were installed, but user services were not reloaded automatically. "
+ "Please consider rebooting the guest")));
}
else
- hrc = setProgressErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
- Utf8StrFmt(tr("Automatic update of Guest Additions has failed: "
- "files were installed, but kernel modules were not reloaded automatically. "
- "Please consider rebooting the guest")));
+ hrc = setUpdateErrorMsg(VBOX_E_GSTCTL_GUEST_ERROR,
+ Utf8StrFmt(tr("Files were installed, but kernel modules were not reloaded automatically. "
+ "Please consider rebooting the guest")));
}
return vrc;
@@ -2768,9 +2795,9 @@ int GuestSessionTaskUpdateAdditions::waitForGuestSession(ComObjPtr<Guest> pGuest
/* Make sure Guest Additions were reloaded on the guest side. */
vrc = checkGuestAdditionsStatus(pSession, osType);
if (RT_SUCCESS(vrc))
- LogRel(("Guest Additions were successfully reloaded after installation\n"));
+ LogRel(("Guest Additions Update: Guest Additions were successfully reloaded after installation\n"));
else
- LogRel(("Guest Additions were failed to reload after installation, please consider rebooting the guest\n"));
+ LogRel(("Guest Additions Update: Guest Additions were failed to reload after installation, please consider rebooting the guest\n"));
vrc = pSession->Close();
vrcRet = VINF_SUCCESS;
@@ -2805,7 +2832,7 @@ int GuestSessionTaskUpdateAdditions::Run(void)
HRESULT hrc = S_OK;
- LogRel(("Automatic update of Guest Additions started, using \"%s\"\n", mSource.c_str()));
+ LogRel(("Guest Additions Update: Automatic update started, using \"%s\"\n", mSource.c_str()));
ComObjPtr<Guest> pGuest(mSession->i_getParent());
#if 0
@@ -2829,8 +2856,8 @@ int GuestSessionTaskUpdateAdditions::Run(void)
if (FAILED(hrc)) vrc = VERR_TIMEOUT;
if (vrc == VERR_TIMEOUT)
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Guest Additions were not ready within time, giving up")));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Guest Additions were not ready within time, giving up")));
#else
/*
* For use with the GUI we don't want to wait, just return so that the manual .ISO mounting
@@ -2842,11 +2869,11 @@ int GuestSessionTaskUpdateAdditions::Run(void)
&& addsRunLevel != AdditionsRunLevelType_Desktop))
{
if (addsRunLevel == AdditionsRunLevelType_System)
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Guest Additions are installed but not fully loaded yet, aborting automatic update")));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Guest Additions are installed but not fully loaded yet, aborting automatic update")));
else
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Guest Additions not installed or ready, aborting automatic update")));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Guest Additions not installed or ready, aborting automatic update")));
vrc = VERR_NOT_SUPPORTED;
}
#endif
@@ -2862,9 +2889,9 @@ int GuestSessionTaskUpdateAdditions::Run(void)
if ( RT_SUCCESS(vrc)
&& RTStrVersionCompare(strAddsVer.c_str(), "4.1") < 0)
{
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Guest has too old Guest Additions (%s) installed for automatic updating, please update manually"),
- strAddsVer.c_str()));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Guest has too old Guest Additions (%s) installed for automatic updating, please update manually"),
+ strAddsVer.c_str()));
vrc = VERR_NOT_SUPPORTED;
}
}
@@ -2891,8 +2918,8 @@ int GuestSessionTaskUpdateAdditions::Run(void)
vrc = getGuestProperty(pGuest, "/VirtualBox/GuestInfo/OS/Release", strOSVer);
if (RT_FAILURE(vrc))
{
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Unable to detected guest OS version, please update manually")));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Unable to detected guest OS version, please update manually")));
vrc = VERR_NOT_SUPPORTED;
}
@@ -2911,17 +2938,17 @@ int GuestSessionTaskUpdateAdditions::Run(void)
* (and the user has to deal with it in the guest). */
if (!(mFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly))
{
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Windows 2000 and XP are not supported for automatic updating due to WHQL interaction, please update manually")));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Windows 2000 and XP are not supported for automatic updating due to WHQL interaction, please update manually")));
vrc = VERR_NOT_SUPPORTED;
}
}
}
else
{
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("%s (%s) not supported for automatic updating, please update manually"),
- strOSType.c_str(), strOSVer.c_str()));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("%s (%s) not supported for automatic updating, please update manually"),
+ strOSType.c_str(), strOSVer.c_str()));
vrc = VERR_NOT_SUPPORTED;
}
}
@@ -2937,9 +2964,9 @@ int GuestSessionTaskUpdateAdditions::Run(void)
&& osType != eOSType_Linux))
/** @todo Support Solaris. */
{
- hrc = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
- Utf8StrFmt(tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
- strOSType.c_str()));
+ hrc = setUpdateErrorMsg(VBOX_E_NOT_SUPPORTED,
+ Utf8StrFmt(tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
+ strOSType.c_str()));
vrc = VERR_NOT_SUPPORTED;
}
}
@@ -2954,9 +2981,9 @@ int GuestSessionTaskUpdateAdditions::Run(void)
vrc = RTVfsFileOpenNormal(mSource.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE, &hVfsFileIso);
if (RT_FAILURE(vrc))
{
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Unable to open Guest Additions .ISO file \"%s\": %Rrc"),
- mSource.c_str(), vrc));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR,
+ Utf8StrFmt(tr("Unable to open Guest Additions .ISO file \"%s\": %Rrc"),
+ mSource.c_str(), vrc));
}
else
{
@@ -2964,8 +2991,8 @@ int GuestSessionTaskUpdateAdditions::Run(void)
vrc = RTFsIso9660VolOpen(hVfsFileIso, 0 /*fFlags*/, &hVfsIso, NULL);
if (RT_FAILURE(vrc))
{
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Unable to open file as ISO 9660 file system volume: %Rrc"), vrc));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR,
+ Utf8StrFmt(tr("Unable to open file as ISO 9660 file system volume: %Rrc"), vrc));
}
else
{
@@ -2990,21 +3017,21 @@ int GuestSessionTaskUpdateAdditions::Run(void)
else
strUpdateDir.append("/");
- LogRel(("Guest Additions update directory is: %s\n", strUpdateDir.c_str()));
+ LogRel(("Guest Additions Update: Update directory is '%s'\n", strUpdateDir.c_str()));
}
else
{
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, tr("Creating update directory on guest failed"),
- GuestErrorInfo(GuestErrorInfo::Type_Directory, vrcGuest, strUpdateDir.c_str()));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR, tr("Creating update directory on guest failed"),
+ GuestErrorInfo(GuestErrorInfo::Type_Directory, vrcGuest, strUpdateDir.c_str()));
break;
default:
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Creating update directory \"%s\" on guest failed: %Rrc"),
- strUpdateDir.c_str(), vrc));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR,
+ Utf8StrFmt(tr("Creating update directory \"%s\" on guest failed: %Rrc"),
+ strUpdateDir.c_str(), vrc));
break;
}
}
@@ -3028,10 +3055,10 @@ int GuestSessionTaskUpdateAdditions::Run(void)
if (RTStrVersionCompare(strOSVer.c_str(), "5.0") >= 0)
{
fInstallCert = true;
- LogRel(("Certificates for auto updating WHQL drivers will be installed\n"));
+ LogRel(("Guest Additions Update: Certificates for auto updating WHQL drivers will be installed\n"));
}
else
- LogRel(("Skipping installation of certificates for WHQL drivers\n"));
+ LogRel(("Guest Additions Update: Skipping installation of certificates for WHQL drivers\n"));
if (fInstallCert)
{
@@ -3176,7 +3203,7 @@ int GuestSessionTaskUpdateAdditions::Run(void)
uint8_t uOffset = 20; /* Start at 20%. */
uint8_t uStep = 40 / (uint8_t)mFiles.size(); Assert(mFiles.size() <= 10);
- LogRel(("Copying over Guest Additions update files to the guest ...\n"));
+ LogRel(("Guest Additions Update: Copying over update files to the guest ...\n"));
std::vector<ISOFile>::const_iterator itFiles = mFiles.begin();
while (itFiles != mFiles.end())
@@ -3189,9 +3216,9 @@ int GuestSessionTaskUpdateAdditions::Run(void)
vrc = copyFileToGuest(pSession, hVfsIso, itFiles->strSource, itFiles->strDest, fOptional);
if (RT_FAILURE(vrc))
{
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Error while copying file \"%s\" to \"%s\" on the guest: %Rrc"),
- itFiles->strSource.c_str(), itFiles->strDest.c_str(), vrc));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR,
+ Utf8StrFmt(tr("Error while copying file \"%s\" to \"%s\" on the guest: %Rrc"),
+ itFiles->strSource.c_str(), itFiles->strDest.c_str(), vrc));
break;
}
}
@@ -3215,7 +3242,7 @@ int GuestSessionTaskUpdateAdditions::Run(void)
uint8_t uOffset = 60; /* Start at 60%. */
uint8_t uStep = 35 / (uint8_t)mFiles.size(); Assert(mFiles.size() <= 10);
- LogRel(("Executing Guest Additions update files ...\n"));
+ LogRel(("Guest Additions Update: Executing update files ...\n"));
std::vector<ISOFile>::iterator itFiles = mFiles.begin();
while (itFiles != mFiles.end())
@@ -3247,27 +3274,26 @@ int GuestSessionTaskUpdateAdditions::Run(void)
{
if (pSession->i_isTerminated())
{
- LogRel(("Old guest session has terminated, waiting updated guest services to start\n"));
+ LogRel(("Guest Additions Update: Old guest session has terminated, waiting updated guest services to start\n"));
/* Wait for VBoxService to restart. */
vrc = waitForGuestSession(pSession->i_getParent(), osType);
if (RT_FAILURE(vrc))
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Automatic update of Guest Additions has failed: "
- "guest services were not restarted, please reinstall Guest Additions manually")));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR,
+ Utf8StrFmt(tr("Guest services were not restarted, please reinstall Guest Additions manually")));
}
else
{
vrc = VERR_TRY_AGAIN;
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Old guest session is still active, guest services were not restarted "
- "after installation, please reinstall Guest Additions manually")));
+ hrc = setUpdateErrorMsg(VBOX_E_IPRT_ERROR,
+ Utf8StrFmt(tr("Old guest session is still active, guest services were not restarted "
+ "after installation, please reinstall Guest Additions manually")));
}
}
if (RT_SUCCESS(vrc))
{
- LogRel(("Automatic update of Guest Additions succeeded\n"));
+ LogRel(("Guest Additions Update: Automatic update succeeded\n"));
hrc = setProgressSuccess();
}
}
@@ -3281,17 +3307,17 @@ int GuestSessionTaskUpdateAdditions::Run(void)
{
if (vrc == VERR_CANCELLED)
{
- LogRel(("Automatic update of Guest Additions was canceled\n"));
+ LogRel(("Guest Additions Update: Automatic update was canceled\n"));
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Installation was canceled")));
+ hrc = setUpdateErrorMsg(E_ABORT,
+ Utf8StrFmt(tr("Operation was canceled")));
}
else if (vrc == VERR_TIMEOUT)
{
- LogRel(("Automatic update of Guest Additions has timed out\n"));
+ LogRel(("Guest Additions Update: Automatic update has timed out\n"));
- hrc = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
- Utf8StrFmt(tr("Installation has timed out")));
+ hrc = setUpdateErrorMsg(E_FAIL,
+ Utf8StrFmt(tr("Operation has timed out")));
}
else
{
@@ -3313,11 +3339,11 @@ int GuestSessionTaskUpdateAdditions::Run(void)
}
}
- LogRel(("Automatic update of Guest Additions failed: %s (%Rhrc)\n",
- strError.c_str(), hrc));
+ LogRel(("Guest Additions Update: Automatic update failed: %s (vrc=%Rrc, hrc=%Rhrc)\n",
+ strError.c_str(), vrc, hrc));
}
- LogRel(("Please install Guest Additions manually\n"));
+ LogRel(("Guest Additions Update: An error has occurred (see above). Please install Guest Additions manually\n"));
}
/** @todo Clean up copied / left over installation files. */
diff --git a/src/VBox/Main/src-client/RecordingStream.cpp b/src/VBox/Main/src-client/RecordingStream.cpp
index dad3e5c5..63ddb86f 100644
--- a/src/VBox/Main/src-client/RecordingStream.cpp
+++ b/src/VBox/Main/src-client/RecordingStream.cpp
@@ -418,9 +418,9 @@ int RecordingStream::SendAudioFrame(const void *pvData, size_t cbData, uint64_t
/**
* Sends a raw (e.g. not yet encoded) video frame to the recording stream.
*
- * @returns VBox status code. Will return VINF_RECORDING_LIMIT_REACHED if the stream's recording
- * limit has been reached or VINF_RECORDING_THROTTLED if the frame is too early for the current
- * FPS setting.
+ * @returns VBox status code.
+ * @retval VINF_RECORDING_LIMIT_REACHED if the stream's recording limit has been reached.
+ * @retval VINF_RECORDING_THROTTLED if the frame is too early for the current FPS setting.
* @param x Upper left (X) coordinate where the video frame starts.
* @param y Upper left (Y) coordinate where the video frame starts.
* @param uPixelFormat Pixel format of the video frame.
@@ -435,7 +435,9 @@ int RecordingStream::SendVideoFrame(uint32_t x, uint32_t y, uint32_t uPixelForma
uint32_t uSrcWidth, uint32_t uSrcHeight, uint8_t *puSrcData, uint64_t msTimestamp)
{
AssertPtrReturn(m_pCtx, VERR_WRONG_ORDER);
- AssertReturn(NeedsUpdate(msTimestamp), VINF_RECORDING_THROTTLED); /* We ASSUME that the caller checked that first. */
+
+ if (RT_UNLIKELY(!NeedsUpdate(msTimestamp)))
+ return VINF_RECORDING_THROTTLED;
lock();
diff --git a/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp b/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp
index 2515599f..43ec2695 100644
--- a/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp
+++ b/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp
@@ -543,11 +543,26 @@ HRESULT UefiVariableStore::enrollDefaultMsSignatures(void)
GuidMs, SignatureType_X509);
if (SUCCEEDED(hrc))
{
- hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoftCa, g_cbUefiMicrosoftCa,
+ hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidGlobalVar, "KEK", g_abUefiMicrosoftKek2023, g_cbUefiMicrosoftKek2023,
GuidMs, SignatureType_X509);
if (SUCCEEDED(hrc))
- hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoftProPca, g_cbUefiMicrosoftProPca,
+ {
+ hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoft3rdCa, g_cbUefiMicrosoft3rdCa,
GuidMs, SignatureType_X509);
+ if (SUCCEEDED(hrc))
+ {
+ hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoft3rdCa2023, g_cbUefiMicrosoft3rdCa2023,
+ GuidMs, SignatureType_X509);
+ if (SUCCEEDED(hrc))
+ {
+ hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoftWinCa, g_cbUefiMicrosoftWinCa,
+ GuidMs, SignatureType_X509);
+ if (SUCCEEDED(hrc))
+ hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoftWinCa2023, g_cbUefiMicrosoftWinCa2023,
+ GuidMs, SignatureType_X509);
+ }
+ }
+ }
}
i_releaseUefiVariableStore();
diff --git a/src/VBox/Main/src-server/linux/NetIf-linux.cpp b/src/VBox/Main/src-server/linux/NetIf-linux.cpp
index f4a99eeb..83ab3b3b 100644
--- a/src/VBox/Main/src-server/linux/NetIf-linux.cpp
+++ b/src/VBox/Main/src-server/linux/NetIf-linux.cpp
@@ -43,6 +43,7 @@
#include <stdio.h>
#include <unistd.h>
#include <iprt/asm.h>
+#include <errno.h>
#include "HostNetworkInterfaceImpl.h"
#include "netif.h"
@@ -154,7 +155,27 @@ static int getInterfaceInfo(int iSocket, const char *pszName, PNETIFINFO pInfo)
/* Generate UUID from name and MAC address. */
RTUUID uuid;
RTUuidClear(&uuid);
+#ifdef VBOXNETFLT_LINUX_NAMESPACE_SUPPORT
+ uuid.au32[0] = 0; /* Use 0 as the indicator of missing namespace info. */
+ /*
+ * Namespace links use the following naming convention: "net:[1234567890]".
+ * The maximum value of inode number is 4294967295, which gives up precisely
+ * 16 characters without terminating zero.
+ */
+ char szBuf[24];
+ ssize_t len = readlink("/proc/self/ns/net", szBuf, sizeof(szBuf) - 1);
+ if (len == -1)
+ Log(("NetIfList: Failed to get namespace for VBoxSVC, error %d\n", errno));
+ else if (!RTStrStartsWith(szBuf, "net:["))
+ Log(("NetIfList: Failed to get network namespace inode from %s\n", szBuf));
+ else
+ uuid.au32[0] = RTStrToUInt32(szBuf + 5);
+ Log(("NetIfList: VBoxSVC namespace inode %u\n", uuid.au32[0]));
+ /* Hashing the name is probably an overkill as MAC addresses should ensure uniqueness */
+ uuid.au32[1] = RTStrHash1(pszName);
+#else /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
memcpy(&uuid, Req.ifr_name, RT_MIN(sizeof(Req.ifr_name), sizeof(uuid)));
+#endif /* !VBOXNETFLT_LINUX_NAMESPACE_SUPPORT */
uuid.Gen.u8ClockSeqHiAndReserved = (uint8_t)((uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80);
uuid.Gen.u16TimeHiAndVersion = (uint16_t)((uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000);
memcpy(uuid.Gen.au8Node, &Req.ifr_hwaddr.sa_data, sizeof(uuid.Gen.au8Node));
diff --git a/src/VBox/Runtime/common/efi/efisignaturedb.cpp b/src/VBox/Runtime/common/efi/efisignaturedb.cpp
index b75445f0..9cfcbd24 100644
--- a/src/VBox/Runtime/common/efi/efisignaturedb.cpp
+++ b/src/VBox/Runtime/common/efi/efisignaturedb.cpp
@@ -47,6 +47,7 @@
#include <iprt/list.h>
#include <iprt/mem.h>
#include <iprt/sg.h>
+#include <iprt/uuid.h>
#include <iprt/formats/efi-signature.h>
@@ -157,7 +158,7 @@ static PCRTEFISIGDBDESC rtEfiSigDbGetDescByGuid(PCEFI_GUID pGuid)
/**
- * Validates the given signature lsit header.
+ * Validates the given signature list header.
*
* @returns Flag whether the list header is considered valid.
* @param pLstHdr The list header to validate.
@@ -265,7 +266,44 @@ static int rtEfiSigDbLoadSigList(PRTEFISIGDBINT pThis, RTVFSFILE hVfsFileIn, uin
/**
- * Variant for written a list of signatures where each signature gets its own signature list header
+ * De-duplicate a signature database.
+ *
+ * @returns IPRT status code.
+ * @param pThis The signature database instance.
+ */
+static int rtEfiSigDbDeduplicate(PRTEFISIGDBINT pThis)
+{
+ /** @todo This currently deduplicates list nodes as a whole, not looking into signature lists.
+ * Good enough for the X.509 certificates which matter most to eliminate multiple enrollments. */
+ for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
+ {
+ PRTEFISIGNATURE pIt, pItNext;
+ RTListForEachSafe(&pThis->aLstSigTypes[i], pIt, pItNext, RTEFISIGNATURE, NdLst)
+ {
+ PRTEFISIGNATURE pIt2;
+ RTListForEach(&pThis->aLstSigTypes[i], pIt2, RTEFISIGNATURE, NdLst)
+ {
+ /* Compare up to element before pIt. */
+ if (pIt == pIt2)
+ break;
+ if ( pIt->cbSignature == pIt2->cbSignature
+ && !RTUuidCompare(&pIt->UuidOwner, &pIt2->UuidOwner)
+ && !memcmp(&pIt->abSignature[0], &pIt2->abSignature[0], pIt->cbSignature))
+ {
+ RTListNodeRemove(&pIt->NdLst);
+ RTMemFree(pIt);
+ break;
+ }
+ }
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Variant for writing a list of signatures where each signature gets its own signature list header
* (for types where each signature can differ in size like X.509).
*
* @returns IPRT status code.
@@ -455,6 +493,10 @@ RTDECL(int) RTEfiSigDbAddFromExistingDb(RTEFISIGDB hEfiSigDb, RTVFSFILE hVfsFile
&& cbFile);
}
+ int rc2 = rtEfiSigDbDeduplicate(pThis);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+
return rc;
}
@@ -491,6 +533,10 @@ RTDECL(int) RTEfiSigDbAddSignatureFromFile(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE en
rc = VERR_INVALID_PARAMETER;
}
+ int rc2 = rtEfiSigDbDeduplicate(pThis);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+
return rc;
}
@@ -522,6 +568,10 @@ RTDECL(int) RTEfiSigDbAddSignatureFromBuf(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE enm
else
rc = VERR_INVALID_PARAMETER;
+ int rc2 = rtEfiSigDbDeduplicate(pThis);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+
return rc;
}
diff --git a/src/VBox/Runtime/common/vfs/vfsmemory.cpp b/src/VBox/Runtime/common/vfs/vfsmemory.cpp
index a044f3d8..0d4f687d 100644
--- a/src/VBox/Runtime/common/vfs/vfsmemory.cpp
+++ b/src/VBox/Runtime/common/vfs/vfsmemory.cpp
@@ -704,10 +704,35 @@ static DECLCALLBACK(int) rtVfsMemFile_SetSize(void *pvThis, uint64_t cbFile, uin
AssertReturn(RTVFSFILE_SIZE_F_IS_VALID(fFlags), VERR_INVALID_PARAMETER);
PRTVFSMEMFILE pThis = (PRTVFSMEMFILE)pvThis;
- if ( (fFlags & RTVFSFILE_SIZE_F_ACTION_MASK) == RTVFSFILE_SIZE_F_NORMAL
- && (RTFOFF)cbFile >= pThis->Base.ObjInfo.cbObject)
+ if ((fFlags & RTVFSFILE_SIZE_F_ACTION_MASK) == RTVFSFILE_SIZE_F_NORMAL)
{
- /* Growing is just a matter of increasing the size of the object. */
+ if ((RTFOFF)cbFile < pThis->Base.ObjInfo.cbObject)
+ {
+ /* Remove any extent beyond the file size. */
+ bool fHit;
+ PRTVFSMEMEXTENT pExtent = rtVfsMemFile_LocateExtent(pThis, cbFile, &fHit);
+ if ( fHit
+ && cbFile < (pExtent->off + pExtent->cb))
+ {
+ /* Clear the data in this extent. */
+ uint64_t cbRemaining = cbFile - pExtent->off;
+ memset(&pExtent->abData[cbRemaining], 0, pExtent->cb - cbRemaining);
+ pExtent = RTListGetNext(&pThis->ExtentHead, pExtent, RTVFSMEMEXTENT, Entry);
+ }
+
+ while (pExtent)
+ {
+ PRTVFSMEMEXTENT pFree = pExtent;
+ pExtent = RTListGetNext(&pThis->ExtentHead, pExtent, RTVFSMEMEXTENT, Entry);
+
+ RTListNodeRemove(&pFree->Entry);
+ RTMemFree(pFree);
+ }
+
+ pThis->pCurExt = NULL;
+ }
+ /* else: Growing is just a matter of increasing the size of the object. */
+
pThis->Base.ObjInfo.cbObject = cbFile;
return VINF_SUCCESS;
}
diff --git a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
index 70c5e3dc..77459ab2 100644
--- a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
@@ -216,7 +216,7 @@ static pgprot_t rtR0MemObjLinuxConvertProt(unsigned fProt, bool fKernel)
#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
if (fKernel)
{
-# if RTLNX_VER_MIN(6,6,0)
+# if RTLNX_VER_MIN(6,6,0) || RTLNX_SUSE_MAJ_PREREQ(15, 6)
/* In kernel 6.6 mk_pte() macro was fortified with additional
* check which does not allow to use our custom mask anymore
* (see kernel commit ae1f05a617dcbc0a732fbeba0893786cd009536c).
@@ -1367,7 +1367,7 @@ DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3P
fWrite, /* force write access. */
# endif
&pMemLnx->apPages[0] /* Page array. */
-# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0)
+# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) && !RTLNX_SUSE_MAJ_PREREQ(15, 6)
, papVMAs /* vmas */
# endif
);
@@ -1413,10 +1413,8 @@ DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3P
fWrite, /* Write to memory. */
fWrite, /* force write access. */
# endif
- &pMemLnx->apPages[0] /* Page array. */
-# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0)
- , papVMAs /* vmas */
-# endif
+ &pMemLnx->apPages[0], /* Page array. */
+ papVMAs /* vmas */
);
#endif /* GET_USER_PAGES_API < KERNEL_VERSION(4, 6, 0) */
if (rc == cPages)
@@ -1440,7 +1438,7 @@ DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3P
while (rc-- > 0)
{
flush_dcache_page(pMemLnx->apPages[rc]);
-# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0)
+# if GET_USER_PAGES_API < KERNEL_VERSION(6, 5, 0) && !RTLNX_SUSE_MAJ_PREREQ(15, 6) && !RTLNX_RHEL_RANGE(9,5, 9,99)
# if RTLNX_VER_MIN(6,3,0)
vm_flags_set(papVMAs[rc], VM_DONTCOPY | VM_LOCKED);
# else
@@ -1923,7 +1921,7 @@ DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ p
/* Thes flags help making 100% sure some bad stuff wont happen (swap, core, ++).
* See remap_pfn_range() in mm/memory.c */
-#if RTLNX_VER_MIN(6,3,0)
+#if RTLNX_VER_MIN(6,3,0) || RTLNX_RHEL_RANGE(9,5, 9,99)
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
#elif RTLNX_VER_MIN(3,7,0)
vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
diff --git a/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp b/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp
index 598339db..0fdcafbf 100644
--- a/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp
+++ b/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp
@@ -147,18 +147,33 @@ void rtVccWinInitBssOnNt3(void *pvImageBase)
memset(pbToZero, 0, cbToZero);
else
{
+# if 1 /* This dynamic stupidity is because of stupid AV heuristics. */
+ static decltype(NtProtectVirtualMemory) *s_pfnNtProtectVirtualMemory = NULL;
+ if (!s_pfnNtProtectVirtualMemory)
+ s_pfnNtProtectVirtualMemory
+ = (decltype(NtProtectVirtualMemory) *)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),
+ "NtProtectVirtualMemory");
+ if (!s_pfnNtProtectVirtualMemory)
+ {
+ RT_BREAKPOINT();
+ continue;
+ }
+# else
+# define s_pfnNtProtectVirtualMemory NtProtectVirtualMemory
+# endif
+
/* The section is not writable, so temporarily make it writable. */
PVOID pvAligned = pbToZero - ((uintptr_t)pbToZero & PAGE_OFFSET_MASK);
ULONG cbAligned = RT_ALIGN_32(cbToZero + ((uintptr_t)pbToZero & PAGE_OFFSET_MASK), PAGE_SIZE);
ULONG fNewProt = paSHdrs[i].Characteristics & IMAGE_SCN_MEM_EXECUTE
? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
ULONG fOldProt = fNewProt;
- NTSTATUS rcNt = NtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fNewProt, &fOldProt);
+ NTSTATUS rcNt = s_pfnNtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fNewProt, &fOldProt);
if (NT_SUCCESS(rcNt))
{
memset(pbToZero, 0, cbToZero);
- rcNt = NtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fOldProt, &fNewProt);
+ rcNt = s_pfnNtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fOldProt, &fNewProt);
}
else
RT_BREAKPOINT();
diff --git a/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp b/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp
index 543ea05c..110eae30 100644
--- a/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp
+++ b/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp
@@ -81,7 +81,11 @@ static int rtTerminateProcess(int32_t rcExit, bool fDoAtExit)
* Terminate.
*/
for (;;)
+#if 1 /* Using NtTerminateProcess triggers heuristics in some annoying AV scanner. */
+ TerminateProcess(NtCurrentProcess(), rcExit);
+#else
NtTerminateProcess(NtCurrentProcess(), rcExit);
+#endif
}
diff --git a/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp b/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
index 8ffcab9e..15e0aa6b 100644
--- a/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
+++ b/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
@@ -6670,17 +6670,19 @@ static int iemVmxVmentryCheckCtls(PVMCPUCC pVCpu, const char *pszInstr) RT_NOEXC
IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EntryIntInfoErrCodePe);
/* Exceptions that provide an error code. */
- if ( uType == VMX_ENTRY_INT_INFO_TYPE_HW_XCPT
- && ( uVector == X86_XCPT_DF
+ if (uType == VMX_ENTRY_INT_INFO_TYPE_HW_XCPT)
+ {
+ if ( uVector == X86_XCPT_DF
|| uVector == X86_XCPT_TS
|| uVector == X86_XCPT_NP
|| uVector == X86_XCPT_SS
|| uVector == X86_XCPT_GP
|| uVector == X86_XCPT_PF
- || uVector == X86_XCPT_AC))
- { /* likely */ }
- else
- IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EntryIntInfoErrCodeVec);
+ || uVector == X86_XCPT_AC)
+ { /* likely */ }
+ else
+ IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EntryIntInfoErrCodeVec);
+ }
/* Exception error-code reserved bits. */
if (!(pVmcs->u32EntryXcptErrCode & ~VMX_ENTRY_INT_XCPT_ERR_CODE_VALID_MASK))
diff --git a/src/VBox/VMM/VMMAll/TMAll.cpp b/src/VBox/VMM/VMMAll/TMAll.cpp
index 677decdd..db39fdaa 100644
--- a/src/VBox/VMM/VMMAll/TMAll.cpp
+++ b/src/VBox/VMM/VMMAll/TMAll.cpp
@@ -712,8 +712,9 @@ void tmTimerQueuesSanityChecks(PVMCC pVM, const char *pszWhere)
# ifdef IN_RING3
/* Go thru all the timers and check that the active ones all are in the active lists. */
- uint32_t idxTimer = pQueue->cTimersAlloc;
- uint32_t cFree = 0;
+ int const rcAllocLock = PDMCritSectRwTryEnterShared(pVM, &pQueue->AllocLock);
+ uint32_t idxTimer = pQueue->cTimersAlloc;
+ uint32_t cFree = 0;
while (idxTimer-- > 0)
{
PTMTIMER const pTimer = &pQueue->paTimers[idxTimer];
@@ -778,7 +779,14 @@ void tmTimerQueuesSanityChecks(PVMCC pVM, const char *pszWhere)
Assert(((pTimer->hSelf >> TMTIMERHANDLE_QUEUE_IDX_SHIFT) & TMTIMERHANDLE_QUEUE_IDX_SMASK) == idxQueue);
}
}
- Assert(cFree == pQueue->cTimersFree);
+ if (RT_SUCCESS(rcAllocLock))
+ {
+ Assert(cFree == pQueue->cTimersFree);
+ PDMCritSectRwLeaveShared(pVM, &pQueue->AllocLock);
+ }
+ else
+ Assert(cFree >= pQueue->cTimersFree); /* Can be lower as the tmr3TimerCreate may run concurrent. */
+
# endif /* IN_RING3 */
if (pQueue->enmClock == TMCLOCK_VIRTUAL_SYNC)
diff --git a/src/VBox/VMM/VMMR3/PDM.cpp b/src/VBox/VMM/VMMR3/PDM.cpp
index 1e56b66f..3d3ff8d4 100644
--- a/src/VBox/VMM/VMMR3/PDM.cpp
+++ b/src/VBox/VMM/VMMR3/PDM.cpp
@@ -1246,7 +1246,13 @@ static DECLCALLBACK(int) pdmR3LoadExec(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersi
if (!(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_FOUND))
{
LogRel(("Device '%s'/%d not found in the saved state\n", pDevIns->pReg->szName, pDevIns->iInstance));
- if (SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT)
+ /** @todo The TPM PPI device was added due to @bugref{10701} and it is not an issue if it isn't there
+ * in the saved state because there is nothing to load. It might make sense to add a new
+ * flag to PDMDEVREG::fFlags to indicate that having a new device added for a saved state is okay.
+ * (For now I just want to get saved states unwedged).
+ */
+ if ( SSMR3HandleGetAfter(pSSM) != SSMAFTER_DEBUG_IT
+ && RTStrCmp(pDevIns->pReg->szName, "tpm-ppi"))
return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Device '%s'/%d not found in the saved state"),
pDevIns->pReg->szName, pDevIns->iInstance);
}
diff --git a/src/VBox/ValidationKit/Config.kmk b/src/VBox/ValidationKit/Config.kmk
index fe239f4d..2f72df89 100644
--- a/src/VBox/ValidationKit/Config.kmk
+++ b/src/VBox/ValidationKit/Config.kmk
@@ -114,16 +114,15 @@ ifndef VBOX_WITH_NOCRT_STATIC
-Section:.bss,RW!K
endif
TEMPLATE_VBoxValidationKitR3_LDFLAGS.win.x86 += -NoOptIData
-TEMPLATE_VBoxValidationKitR3_POST_CMDS.win.x86 = $(if $(eq $(tool_do),LINK_LIBRARY),,$(VBOX_PE_SET_VERSION) $(out)$$(NLTAB))$(TEMPLATE_VBoxValidationKitR3Base_POST_CMDS.win.x86)$$(NLTAB)
-TEMPLATE_VBoxValidationKitR3_POST_CMDS.win.amd64 = $(if $(eq $(tool_do),LINK_LIBRARY),,$(VBOX_PE_SET_VERSION) $(out)$$(NLTAB))$(TEMPLATE_VBoxValidationKitR3Base_POST_CMDS.win.amd64)$$(NLTAB)
-TEMPLATE_VBoxValidationKitR3_LNK_DEPS.win.x86 = $(if $(eq $(tool_do),LINK_LIBRARY),,$(VBOX_PE_SET_VERSION)) $(TEMPLATE_VBoxValidationKitR3Base_LNK_DEPS.win.x86)
-TEMPLATE_VBoxValidationKitR3_LNK_DEPS.win.amd64 = $(if $(eq $(tool_do),LINK_LIBRARY),,$(VBOX_PE_SET_VERSION)) $(TEMPLATE_VBoxValidationKitR3Base_LNK_DEPS.win.amd64)
-#TODO: TEMPLATE_VBoxValidationKitR3_EXTENDS = VBoxGuestR3Exe
+TEMPLATE_VBoxValidationKitR3_USES.win += vboxsetpeversion
+TEMPLATE_VBoxValidationKitR3_VBOX_SET_PE_VERSION.win.x86 = nt31
+TEMPLATE_VBoxValidationKitR3_VBOX_SET_PE_VERSION.win.amd64 = xp64
TEMPLATE_VBoxValidationKitR3_USES.win += vboximportchecker
TEMPLATE_VBoxValidationKitR3_VBOX_IMPORT_CHECKER.win.x86 = nt31
TEMPLATE_VBoxValidationKitR3_VBOX_IMPORT_CHECKER.win.amd64 = xp64
+#TODO: TEMPLATE_VBoxValidationKitR3_EXTENDS = VBoxGuestR3Exe
#
diff --git a/src/bldprogs/VBoxPeSetVersion.cpp b/src/bldprogs/VBoxPeSetVersion.cpp
index 0c17c971..2ce8ac5f 100644
--- a/src/bldprogs/VBoxPeSetVersion.cpp
+++ b/src/bldprogs/VBoxPeSetVersion.cpp
@@ -51,6 +51,8 @@
*********************************************************************************************************************************/
static const char *g_pszFilename;
static unsigned g_cVerbosity = 0;
+static enum { kUpdateCheckSum_Never, kUpdateCheckSum_WhenNeeded, kUpdateCheckSum_Always, kUpdateCheckSum_Zero }
+ g_enmUpdateChecksum = kUpdateCheckSum_WhenNeeded;
static int Error(const char *pszFormat, ...)
@@ -79,8 +81,164 @@ static void Info(unsigned iLevel, const char *pszFormat, ...)
}
+/**
+ * File size.
+ *
+ * @returns file size in bytes.
+ * @returns 0 on failure.
+ * @param pFile File to size.
+ */
+static size_t fsize(FILE *pFile)
+{
+ long cbFile;
+ off_t Pos = ftell(pFile);
+ if ( Pos >= 0
+ && !fseek(pFile, 0, SEEK_END))
+ {
+ cbFile = ftell(pFile);
+ if ( cbFile >= 0
+ && !fseek(pFile, 0, SEEK_SET))
+ return cbFile;
+ }
+ return 0;
+}
+
+
+/**
+ * Calculates a raw PE-style checksum on a plain buffer.
+ *
+ * ASSUMES pvBuf is dword aligned.
+ */
+static uint16_t CalcRawPeChecksum(void const *pvBuf, size_t cb, uint32_t uChksum)
+{
+ /*
+ * Work thru the memory in 64 bits at a time.
+ * ASSUMES well aligned input.
+ */
+ uint64_t uBigSum = uChksum;
+ uint64_t const *pu64 = (uint64_t const *)pvBuf;
+ size_t cQWords = cb / 8;
+ while (cQWords-- > 0)
+ {
+ /* We emulate add with carry here. */
+ uint64_t uTmp = uBigSum + *pu64++;
+ uBigSum = uTmp >= uBigSum ? uTmp : uTmp + 1;
+ }
+
+ /*
+ * Zeropadd any remaining bytes before adding them.
+ */
+ if (cb & 7)
+ {
+ uint8_t const *pb = (uint8_t const *)pu64;
+ uint64_t uQWord = 0;
+ switch (cb & 7)
+ {
+ case 7: uQWord |= (uint64_t)pb[6] << 48; RT_FALL_THRU();
+ case 6: uQWord |= (uint64_t)pb[5] << 40; RT_FALL_THRU();
+ case 5: uQWord |= (uint64_t)pb[4] << 32; RT_FALL_THRU();
+ case 4: uQWord |= (uint64_t)pb[3] << 24; RT_FALL_THRU();
+ case 3: uQWord |= (uint64_t)pb[2] << 16; RT_FALL_THRU();
+ case 2: uQWord |= (uint64_t)pb[1] << 8; RT_FALL_THRU();
+ case 1: uQWord |= (uint64_t)pb[0]; break;
+ }
+
+ uint64_t uTmp = uBigSum + uQWord;
+ uBigSum = uTmp >= uBigSum ? uTmp : uTmp + 1;
+ }
+
+ /*
+ * Convert the 64-bit checksum to a 16-bit one.
+ */
+ uChksum = (uBigSum & 0xffffU)
+ + ((uBigSum >> 16) & 0xffffU)
+ + ((uBigSum >> 32) & 0xffffU)
+ + ((uBigSum >> 48) & 0xffffU);
+ uChksum = (uChksum & 0xffffU)
+ + (uChksum >> 16);
+ if (uChksum > 0xffffU) Error("Checksum IPE#1");
+ return uChksum & 0xffffU;
+}
+
+
+static int UpdateChecksum(FILE *pFile)
+{
+ /*
+ * Read the whole file into memory.
+ */
+ size_t const cbFile = fsize(pFile);
+ if (!cbFile)
+ return Error("Failed to determine file size: %s", strerror(errno));
+ uint8_t * const pbFile = (uint8_t *)malloc(cbFile + 4);
+ if (!pbFile)
+ return Error("Failed to allocate %#lx bytes for checksum calculations", (unsigned long)(cbFile + 4U));
+ memset(pbFile, 0, cbFile + 4);
+
+ int rcExit;
+ size_t cItemsRead = fread(pbFile, cbFile, 1, pFile);
+ if (cItemsRead == 1)
+ {
+ /*
+ * Locate the NT headers as we need the CheckSum field in order to update it.
+ * It has the same location in 32-bit and 64-bit images.
+ */
+ IMAGE_DOS_HEADER const * const pMzHdr = (IMAGE_DOS_HEADER const *)pbFile;
+ AssertCompileMembersAtSameOffset(IMAGE_NT_HEADERS32, OptionalHeader.CheckSum, IMAGE_NT_HEADERS64, OptionalHeader.CheckSum);
+ IMAGE_NT_HEADERS32 * const pNtHdrs
+ = (IMAGE_NT_HEADERS32 *)&pbFile[pMzHdr->e_magic == IMAGE_DOS_SIGNATURE ? pMzHdr->e_lfanew : 0];
+ if ((uintptr_t)&pNtHdrs->OptionalHeader.DataDirectory[0] - (uintptr_t)pbFile < cbFile)
+ {
+ if ( pNtHdrs->Signature == IMAGE_NT_SIGNATURE
+ && ( pNtHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC
+ || pNtHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC))
+ {
+ /*
+ * Set the checksum field to zero to avoid having to do tedious
+ * adjustments of the raw checksum. Then calculate the raw check sum.
+ */
+ pNtHdrs->OptionalHeader.CheckSum = 0;
+ uint32_t uChksum = CalcRawPeChecksum(pbFile, RT_ALIGN_Z(cbFile, 2), 0);
+
+ /* Finalize the checksum by adding the image size to it. */
+ uChksum += (uint32_t)cbFile;
+ pNtHdrs->OptionalHeader.CheckSum = uChksum;
+
+ /*
+ * Write back the checksum to the file.
+ */
+ size_t const offChecksumField = (uintptr_t)&pNtHdrs->OptionalHeader.CheckSum - (uintptr_t)pbFile;
+
+ if (fseek(pFile, (long)offChecksumField, SEEK_SET) == 0)
+ {
+ if (fwrite(&pNtHdrs->OptionalHeader.CheckSum, sizeof(pNtHdrs->OptionalHeader.CheckSum), 1, pFile) == 1)
+ {
+ Info(1, "Checksum: %#x", uChksum);
+ rcExit = RTEXITCODE_SUCCESS;
+ }
+ else
+ rcExit = Error("Checksum write failed");
+ }
+ else
+ rcExit = Error("Failed seeking to %#lx for checksum write", (long)offChecksumField);
+ }
+ else
+ rcExit = Error("PE header not found");
+ }
+ else
+ rcExit = Error("NT headers not within file when checksumming");
+ }
+ else
+ rcExit = Error("Failed read in file (%#lx bytes) for checksum calculations", (unsigned long)(cbFile + 4U));
+
+ free(pbFile);
+ return rcExit;
+}
+
+
static int UpdateFile(FILE *pFile, unsigned uNtVersion, PIMAGE_SECTION_HEADER *ppaShdr)
{
+ unsigned cFileModifications = 0;
+
/*
* Locate and read the PE header.
*
@@ -181,7 +339,10 @@ static int UpdateFile(FILE *pFile, unsigned uNtVersion, PIMAGE_SECTION_HEADER *p
return Error("Failed to seek to PE header at %#lx: %s", offNtHdrs, strerror(errno));
if (fwrite(&NtHdrsNew, cbNewHdrs, 1, pFile) != 1)
return Error("Failed to write PE header at %#lx: %s", offNtHdrs, strerror(errno));
+ cFileModifications++;
}
+ else
+ Info(3, "No header changes");
/*
* Make the IAT writable for NT 3.1 and drop the non-cachable flag from .bss.
@@ -245,6 +406,7 @@ static int UpdateFile(FILE *pFile, unsigned uNtVersion, PIMAGE_SECTION_HEADER *p
if (fwrite(&paShdrs[i], sizeof(IMAGE_SECTION_HEADER), 1, pFile) != 1)
return Error("Failed to write %8.8s section header header at %#lx: %s",
paShdrs[i].Name, offShdr, strerror(errno));
+ cFileModifications++;
if (uRvaIat == UINT32_MAX && fFoundBss)
break;
}
@@ -252,7 +414,27 @@ static int UpdateFile(FILE *pFile, unsigned uNtVersion, PIMAGE_SECTION_HEADER *p
/* Advance */
uRvaEnd = paShdrs[i].VirtualAddress;
}
+ }
+ /*
+ * Recalculate the checksum if we changed anything or if it is zero.
+ */
+ if ( g_enmUpdateChecksum == kUpdateCheckSum_Always
+ || ( g_enmUpdateChecksum == kUpdateCheckSum_WhenNeeded
+ && (cFileModifications || NtHdrsNew.x32.OptionalHeader.CheckSum == 0)))
+ return UpdateChecksum(pFile);
+
+ /* Zero the checksum if explicitly requested. */
+ if ( g_enmUpdateChecksum == kUpdateCheckSum_Zero
+ && NtHdrsNew.x32.OptionalHeader.CheckSum != 0)
+ {
+ unsigned long const offCheckSumField = offNtHdrs + RT_UOFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader.CheckSum);
+ if (fseek(pFile, offCheckSumField, SEEK_SET) != 0)
+ return Error("Failed to seek to the CheckSum field in the PE at %#lx: %s", offCheckSumField, strerror(errno));
+
+ NtHdrsNew.x32.OptionalHeader.CheckSum = 0;
+ if (fwrite(&NtHdrsNew.x32.OptionalHeader.CheckSum, sizeof(NtHdrsNew.x32.OptionalHeader.CheckSum), 1, pFile) != 1)
+ return Error("Failed to write the CheckSum field in the PE header at %#lx: %s", offCheckSumField, strerror(errno));
}
return RTEXITCODE_SUCCESS;
@@ -270,7 +452,10 @@ static int Usage(FILE *pOutput)
" Quiet operation (default).\n"
" --nt31, --nt350, --nt351, --nt4, --w2k, --xp, --w2k3, --vista,\n"
" --w7, --w8, --w81, --w10\n"
- " Which version to set. Default: --nt31\n"
+ " Which version to set. Default: --nt31 (x86), --w2k3 (amd64)\n"
+ " --update-checksum-when-needed, --always-update-checksum,\n"
+ " --never-update-checksum, --zero-checksum:\n"
+ " Checksum updating. Default: --update-checksum-when-needed\n"
);
return RTEXITCODE_SYNTAX;
}
@@ -311,7 +496,9 @@ int main(int argc, char **argv)
ch = 'V';
else
{
- if (strcmp(psz, "nt31") == 0)
+ if (strcmp(psz, "default") == 0)
+ uNtVersion = 0;
+ else if (strcmp(psz, "nt31") == 0)
uNtVersion = MK_VER(3,10);
else if (strcmp(psz, "nt350") == 0)
uNtVersion = MK_VER(3,50);
@@ -323,7 +510,7 @@ int main(int argc, char **argv)
uNtVersion = MK_VER(5,0);
else if (strcmp(psz, "xp") == 0)
uNtVersion = MK_VER(5,1);
- else if (strcmp(psz, "w2k3") == 0)
+ else if (strcmp(psz, "w2k3") == 0 || strcmp(psz, "xp64") == 0)
uNtVersion = MK_VER(5,2);
else if (strcmp(psz, "vista") == 0)
uNtVersion = MK_VER(6,0);
@@ -335,6 +522,14 @@ int main(int argc, char **argv)
uNtVersion = MK_VER(6,3);
else if (strcmp(psz, "w10") == 0)
uNtVersion = MK_VER(10,0);
+ else if (strcmp(psz, "always-update-checksum") == 0)
+ g_enmUpdateChecksum = kUpdateCheckSum_Always;
+ else if (strcmp(psz, "never-update-checksum") == 0)
+ g_enmUpdateChecksum = kUpdateCheckSum_Never;
+ else if (strcmp(psz, "update-checksum-when-needed") == 0)
+ g_enmUpdateChecksum = kUpdateCheckSum_WhenNeeded;
+ else if (strcmp(psz, "zero-checksum") == 0)
+ g_enmUpdateChecksum = kUpdateCheckSum_Zero;
else
{
fprintf(stderr, "VBoxPeSetVersion: syntax error: Unknown option: --%s\n", psz);
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp b/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp
index 1b2d3671..775b1210 100644
--- a/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp
+++ b/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp
@@ -113,7 +113,7 @@ public:
PLDHashOperator
nsTEnumGo(EntityToUnicodeEntry* aEntry, void* userArg) {
- printf(" enumerated \"%s\" = %u\n",
+ printf(" enumerated \"%s\" = %u\n",
aEntry->mNode->mStr, aEntry->mNode->mUnicode);
return PL_DHASH_NEXT;
@@ -201,14 +201,14 @@ nsDEnum(const PRUint32& aKey, const char*& aData, void* userArg) {
PLDHashOperator
nsCEnumRead(const nsACString& aKey, TestUniChar* aData, void* userArg) {
- printf(" enumerated \"%s\" = %c\n",
+ printf(" enumerated \"%s\" = %u\n",
PromiseFlatCString(aKey).get(), aData->GetChar());
return PL_DHASH_NEXT;
}
PLDHashOperator
nsCEnum(const nsACString& aKey, nsAutoPtr<TestUniChar>& aData, void* userArg) {
- printf(" enumerated \"%s\" = %c\n",
+ printf(" enumerated \"%s\" = %u\n",
PromiseFlatCString(aKey).get(), aData->GetChar());
return PL_DHASH_NEXT;
}
@@ -277,7 +277,7 @@ nsrefcnt
IFoo::AddRef()
{
++refcount_;
- printf("IFoo@%p::AddRef(), refcount --> %d\n",
+ printf("IFoo@%p::AddRef(), refcount --> %d\n",
NS_STATIC_CAST(void*, this), refcount_);
return refcount_;
}
@@ -288,7 +288,7 @@ IFoo::Release()
int wrap_message = (refcount_ == 1);
if ( wrap_message )
printf(">>");
-
+
nsrefcnt newrefcount = --refcount_;
printf("IFoo@%p::Release(), refcount --> %d\n",
NS_STATIC_CAST(void*, this), newrefcount);
@@ -486,17 +486,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (13);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = UniToEntity.EnumerateRead(nsDEnumRead, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (14);
}
-
+
printf("Clearing...");
UniToEntity.Clear();
printf("OK\n");
@@ -551,17 +551,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (13);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = UniToEntityL.EnumerateRead(nsDEnumRead, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (14);
}
-
+
printf("Clearing...");
UniToEntityL.Clear();
printf("OK\n");
@@ -612,7 +612,7 @@ main(void) {
exit (18);
}
- printf("Found %c\n", myChar->GetChar());
+ printf("Found %u\n", myChar->GetChar());
}
printf("Testing non-existent entries...");
@@ -620,17 +620,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (19);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = EntToUniClass.EnumerateRead(nsCEnumRead, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (20);
}
-
+
printf("Clearing...\n");
EntToUniClass.Clear();
printf(" Clearing OK\n");
@@ -680,7 +680,7 @@ main(void) {
exit (18);
}
- printf("Found %c\n", myChar->GetChar());
+ printf("Found %u\n", myChar->GetChar());
}
printf("Testing non-existent entries...");
@@ -688,17 +688,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (19);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = EntToUniClassL.EnumerateRead(nsCEnumRead, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (20);
}
-
+
printf("Clearing...\n");
EntToUniClassL.Clear();
printf(" Clearing OK\n");
@@ -734,8 +734,8 @@ main(void) {
nsCOMPtr<IFoo> foo;
CreateIFoo(getter_AddRefs(foo));
foo->SetString(nsDependentCString(gEntities[i].mStr));
-
-
+
+
fooArray.InsertObjectAt(foo, i);
if (!EntToUniClass2.Put(foo, gEntities[i].mUnicode)) {
@@ -750,13 +750,13 @@ main(void) {
for (i = 0; i < ENTITY_COUNT; ++i) {
printf(" Getting entry %s...", gEntities[i].mStr);
-
+
if (!EntToUniClass2.Get(fooArray[i], &myChar2)) {
printf("FAILED\n");
exit (24);
}
- printf("Found %c\n", myChar2);
+ printf("Found %u\n", myChar2);
}
printf("Testing non-existent entries...");
@@ -764,17 +764,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (25);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = EntToUniClass2.EnumerateRead(nsIEnum2Read, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (26);
}
-
+
printf("Clearing...\n");
EntToUniClass2.Clear();
printf(" Clearing OK\n");
@@ -808,7 +808,7 @@ main(void) {
nsCOMPtr<IFoo> foo;
CreateIFoo(getter_AddRefs(foo));
foo->SetString(nsDependentCString(gEntities[i].mStr));
-
+
if (!UniToEntClass2.Put(gEntities[i].mUnicode, foo)) {
printf("FAILED\n");
exit (29);
@@ -820,13 +820,13 @@ main(void) {
for (i = 0; i < ENTITY_COUNT; ++i) {
printf(" Getting entry %s...", gEntities[i].mStr);
-
+
nsCOMPtr<IFoo> myEnt;
if (!UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
printf("FAILED\n");
exit (30);
}
-
+
nsCAutoString str;
myEnt->GetString(str);
printf("Found %s\n", str.get());
@@ -838,17 +838,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (31);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = UniToEntClass2.EnumerateRead(nsIEnumRead, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (32);
}
-
+
printf("Clearing...\n");
UniToEntClass2.Clear();
printf(" Clearing OK\n");
@@ -882,7 +882,7 @@ main(void) {
nsCOMPtr<IFoo> foo;
CreateIFoo(getter_AddRefs(foo));
foo->SetString(nsDependentCString(gEntities[i].mStr));
-
+
if (!UniToEntClass2L.Put(gEntities[i].mUnicode, foo)) {
printf("FAILED\n");
exit (29);
@@ -894,13 +894,13 @@ main(void) {
for (i = 0; i < ENTITY_COUNT; ++i) {
printf(" Getting entry %s...", gEntities[i].mStr);
-
+
nsCOMPtr<IFoo> myEnt;
if (!UniToEntClass2L.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
printf("FAILED\n");
exit (30);
}
-
+
nsCAutoString str;
myEnt->GetString(str);
printf("Found %s\n", str.get());
@@ -911,17 +911,17 @@ main(void) {
printf("FOUND! BAD!\n");
exit (31);
}
-
+
printf("not found; good.\n");
-
+
printf("Enumerating:\n");
-
+
count = UniToEntClass2L.EnumerateRead(nsIEnumRead, nsnull);
if (count != ENTITY_COUNT) {
printf(" Bad count!\n");
exit (32);
}
-
+
printf("Clearing...\n");
UniToEntClass2L.Clear();
printf(" Clearing OK\n");