[Pkg-virtualbox-commits] [virtualbox] 01/01: Imported Upstream version 4.3.22-dfsg
Gianfranco Costamagna
locutusofborg-guest at moszumanska.debian.org
Fri Feb 13 14:48:02 UTC 2015
This is an automated email from the git hooks/post-receive script.
locutusofborg-guest pushed a commit to annotated tag upstream/4.3.22-dfsg
in repository virtualbox.
commit a3d2501746175ab335b6c9f5dc96a543db11659a
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date: Fri Feb 13 10:46:55 2015 +0100
Imported Upstream version 4.3.22-dfsg
---
Config.kmk | 30 +-
Makefile.kmk | 13 +-
doc/manual/en_US/user_VBoxManage.xml | 3 +-
doc/manual/user_ChangeLogImpl.xml | 177 ++-
include/VBox/HGSMI/HGSMIChSetup.h | 5 +
include/VBox/VBoxGuest.h | 47 +-
include/VBox/VBoxGuestLib.h | 39 +-
include/VBox/VBoxNetCfg-win.h | 2 +
include/VBox/VBoxVideo.h | 76 +
include/VBox/VBoxVideoGuest.h | 11 +-
include/VBox/VMMDev.h | 2 +
include/VBox/VMMDevTesting.h | 10 +-
include/VBox/VMMDevTesting.mac | 3 +-
include/VBox/apic.h | 1 +
include/VBox/apic.mac | 1 +
include/VBox/err.mac | 10 +
include/VBox/shflsvc.h | 10 +-
include/VBox/sup.h | 12 +
include/VBox/vd-ifs.h | 7 +-
include/VBox/vmm/cpum.h | 2 +-
include/VBox/vmm/hm_vmx.h | 4 +-
include/VBox/vmm/pdmifs.h | 107 +-
include/VBox/vmm/pdmnetifs.h | 8 +-
include/VBox/vmm/tm.h | 2 +-
include/VBox/vmm/vm.h | 8 +-
include/VBox/vmm/vmapi.h | 2 +
include/VBox/vmm/vmcpuset.h | 6 +-
include/iprt/crypto/x509.h | 28 +-
include/iprt/initterm.h | 7 +
include/iprt/ldr.h | 10 +-
include/iprt/list.h | 4 +
include/iprt/log.h | 131 +-
include/iprt/mangling.h | 8 +
include/iprt/nt/nt.h | 57 +
include/iprt/socket.h | 3 +
include/iprt/tcp.h | 6 +-
.../Additions/common/VBoxControl/VBoxControl.cpp | 22 +-
src/VBox/Additions/common/VBoxGuest/Makefile.kmk | 1 +
.../common/VBoxGuest/VBoxGuest-darwin.cpp | 7 +
.../Additions/common/VBoxGuest/VBoxGuest-linux.c | 56 +-
.../Additions/common/VBoxGuest/VBoxGuest-solaris.c | 6 +-
.../Additions/common/VBoxGuest/VBoxGuest-win.cpp | 262 ++--
src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp | 874 ++++++-----
.../Additions/common/VBoxGuest/VBoxGuestInternal.h | 56 +-
.../Additions/common/VBoxGuest/freebsd/Makefile | 1 +
.../common/VBoxGuest/freebsd/files_vboxguest | 1 +
src/VBox/Additions/common/VBoxGuest/linux/Makefile | 3 +-
.../common/VBoxGuest/linux/files_vboxguest | 1 +
src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp | 25 +-
.../Additions/common/VBoxGuestLib/HGCMInternal.cpp | 6 +-
src/VBox/Additions/common/VBoxGuestLib/Mouse.cpp | 8 +-
.../Additions/common/VBoxGuestLib/VBGLR3Internal.h | 4 +
.../VBoxGuestLib/VBoxGuestR0LibSharedFolders.c | 8 +-
.../common/VBoxGuestLib/VBoxGuestR3Lib.cpp | 2 +-
.../VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp | 39 +-
.../VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp | 38 +-
.../common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp | 18 +-
.../VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp | 74 +-
.../VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp | 6 +-
.../common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp | 298 +++-
.../Additions/common/VBoxService/VBoxService.cpp | 45 +-
.../common/VBoxService/VBoxServiceAutoMount.cpp | 24 +-
.../common/VBoxService/VBoxServiceBalloon.cpp | 33 +-
.../VBoxService/VBoxServiceControlProcess.cpp | 2 +-
.../common/VBoxService/VBoxServiceCpuHotPlug.cpp | 43 +-
.../common/VBoxService/VBoxServiceInternal.h | 7 +
.../common/VBoxService/VBoxServicePageSharing.cpp | 32 +-
.../common/VBoxService/VBoxServiceStats.cpp | 33 +-
.../common/VBoxService/VBoxServiceVMInfo-win.cpp | 2 +-
.../common/VBoxService/VBoxServiceVMInfo.cpp | 59 +-
src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp | 69 +-
.../Additions/common/VBoxVideo/Modesetting.cpp | 87 +
src/VBox/Additions/common/crOpenGL/DD_glc.py | 0
src/VBox/Additions/common/crOpenGL/DD_glh.py | 0
src/VBox/Additions/common/crOpenGL/NULLfuncs.py | 0
.../Additions/common/crOpenGL/array/arrayspu.rc | 2 +-
src/VBox/Additions/common/crOpenGL/context.c | 2 +-
src/VBox/Additions/common/crOpenGL/cr_gl.py | 0
src/VBox/Additions/common/crOpenGL/entrypoints.py | 0
.../Additions/common/crOpenGL/feedback/feedback.py | 0
.../common/crOpenGL/feedback/feedback_funcs.py | 0
.../common/crOpenGL/feedback/feedback_state.py | 0
.../common/crOpenGL/feedback/feedbackspu_proto.py | 0
.../Additions/common/crOpenGL/getprocaddress.py | 0
src/VBox/Additions/common/crOpenGL/pack/pack.py | 0
src/VBox/Additions/common/crOpenGL/pack/packspu.rc | 4 +-
.../common/crOpenGL/pack/packspu_beginend.py | 0
.../common/crOpenGL/pack/packspu_flush.py | 0
.../Additions/common/crOpenGL/pack/packspu_get.py | 0
.../common/crOpenGL/pack/packspu_proto.py | 0
.../common/crOpenGL/passthrough/passthrough.py | 0
src/VBox/Additions/common/crOpenGL/stub_common.py | 0
src/VBox/Additions/common/crOpenGL/tsfuncs.py | 0
.../common/crOpenGL/windows_getprocaddress.py | 0
src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp | 2 +-
src/VBox/Additions/linux/Makefile.kmk | 12 -
src/VBox/Additions/linux/drm/vboxvideo_drm.c | 6 +
src/VBox/Additions/linux/export_modules | 10 +-
src/VBox/Additions/linux/installer/vboxadd-x11.sh | 21 +-
src/VBox/Additions/linux/sharedfolders/dirops.c | 8 +-
src/VBox/Additions/linux/sharedfolders/regops.c | 10 +-
src/VBox/Additions/linux/sharedfolders/vfsmod.h | 8 +-
.../Additions/solaris/SharedFolders/vboxfs_prov.c | 2 +-
.../Additions/solaris/SharedFolders/vboxfs_vfs.c | 2 +-
.../Additions/solaris/SharedFolders/vboxfs_vnode.c | 2 +-
src/VBox/Additions/x11/Installer/98vboxadd-xclient | 20 +-
src/VBox/Additions/x11/Installer/x11config.sh | 5 +-
src/VBox/Additions/x11/VBoxClient/Makefile.kmk | 7 +-
src/VBox/Additions/x11/VBoxClient/VBoxClient.h | 77 +-
src/VBox/Additions/x11/VBoxClient/clipboard.cpp | 71 +-
src/VBox/Additions/x11/VBoxClient/display.cpp | 568 ++++---
src/VBox/Additions/x11/VBoxClient/draganddrop.cpp | 77 +-
src/VBox/Additions/x11/VBoxClient/hostversion.cpp | 291 ++--
src/VBox/Additions/x11/VBoxClient/main.cpp | 310 ++--
src/VBox/Additions/x11/VBoxClient/seamless-glue.h | 29 -
src/VBox/Additions/x11/VBoxClient/seamless-guest.h | 52 -
.../Additions/x11/VBoxClient/seamless-host.cpp | 195 ---
src/VBox/Additions/x11/VBoxClient/seamless-host.h | 173 --
src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp | 52 +-
src/VBox/Additions/x11/VBoxClient/seamless-x11.h | 50 +-
src/VBox/Additions/x11/VBoxClient/seamless.cpp | 426 ++++-
src/VBox/Additions/x11/VBoxClient/seamless.h | 242 +--
.../VBoxClient/testcase/tstSeamlessX11-auto.cpp | 62 +-
.../x11/VBoxClient/testcase/tstSeamlessX11.cpp | 47 +-
src/VBox/Additions/x11/VBoxClient/thread.cpp | 99 --
src/VBox/Additions/x11/VBoxClient/thread.h | 131 --
src/VBox/Additions/x11/undefined_xorg | 11 +
src/VBox/Additions/x11/vboxmouse/Makefile.kmk | 12 +-
src/VBox/Additions/x11/vboxmouse/vboxmouse.c | 7 +-
src/VBox/Additions/x11/vboxvideo/Makefile.kmk | 40 +-
src/VBox/Additions/x11/vboxvideo/README.testing | 20 +
src/VBox/Additions/x11/vboxvideo/getmode.c | 541 +++++++
src/VBox/Additions/x11/vboxvideo/helpers.c | 91 ++
src/VBox/Additions/x11/vboxvideo/pointer.c | 146 +-
src/VBox/Additions/x11/vboxvideo/setmode.c | 45 +-
.../Additions/x11/vboxvideo/testcase/Makefile.kmk | 48 -
.../x11/vboxvideo/testcase/tstSetModeXOrg.c | 141 --
src/VBox/Additions/x11/vboxvideo/undefined | 8 +
src/VBox/Additions/x11/vboxvideo/vboxutils.c | 504 ------
src/VBox/Additions/x11/vboxvideo/vboxvideo.c | 363 ++---
src/VBox/Additions/x11/vboxvideo/vboxvideo.h | 164 +-
src/VBox/Additions/x11/vboxvideo/vboxvideo_dri2.c | 3 +-
src/VBox/Additions/x11/vboxvideo/vbva.c | 74 +-
src/VBox/Debugger/DBGCPlugInDiggers.rc | 50 +
src/VBox/Debugger/Makefile.kmk | 4 +
src/VBox/Debugger/VBoxDbg.rc | 50 +
src/VBox/Debugger/VBoxDbgConsole.cpp | 141 +-
src/VBox/Debugger/VBoxDbgConsole.h | 43 +
src/VBox/Devices/Audio/DevIchHdaCodec.cpp | 30 +-
src/VBox/Devices/Audio/DevSB16.cpp | 4 +-
src/VBox/Devices/Audio/dsound_template.h | 67 +-
src/VBox/Devices/Audio/dsoundaudio.c | 403 +++--
.../BaseTools/Source/C/PyEfiCompressor/setup.py | 0
.../Firmware/BaseTools/Source/C/PyUtility/setup.py | 0
.../BaseTools/Source/Python/AutoGen/AutoGen.py | 0
.../BaseTools/Source/Python/AutoGen/BuildEngine.py | 0
.../BaseTools/Source/Python/AutoGen/GenC.py | 0
.../BaseTools/Source/Python/AutoGen/GenDepex.py | 0
.../BaseTools/Source/Python/AutoGen/GenMake.py | 0
.../BaseTools/Source/Python/AutoGen/StrGather.py | 0
.../Source/Python/AutoGen/UniClassObject.py | 0
.../Firmware/BaseTools/Source/Python/BPDG/BPDG.py | 0
.../BaseTools/Source/Python/BPDG/GenVpd.py | 0
.../BaseTools/Source/Python/BPDG/StringTable.py | 0
.../BaseTools/Source/Python/Common/Database.py | 0
.../Source/Python/Common/DecClassObject.py | 0
.../BaseTools/Source/Python/Common/Dictionary.py | 0
.../Source/Python/Common/DscClassObject.py | 0
.../Source/Python/Common/EdkIIWorkspace.py | 0
.../Source/Python/Common/EdkIIWorkspaceBuild.py | 0
.../BaseTools/Source/Python/Common/EdkLogger.py | 0
.../BaseTools/Source/Python/Common/Expression.py | 0
.../Source/Python/Common/FdfClassObject.py | 0
.../Source/Python/Common/InfClassObject.py | 0
.../Source/Python/Common/MigrationUtilities.py | 0
.../BaseTools/Source/Python/Common/Misc.py | 0
.../BaseTools/Source/Python/Common/Parsing.py | 0
.../BaseTools/Source/Python/Common/String.py | 0
.../Source/Python/Common/TargetTxtClassObject.py | 0
.../Source/Python/Common/ToolDefClassObject.py | 0
.../Source/Python/CommonDataClass/ModuleClass.py | 0
.../Source/Python/CommonDataClass/PackageClass.py | 0
.../Source/Python/CommonDataClass/PlatformClass.py | 0
.../Firmware/BaseTools/Source/Python/Ecc/CLexer.py | 0
.../BaseTools/Source/Python/Ecc/CParser.py | 0
.../Firmware/BaseTools/Source/Python/Ecc/Check.py | 0
.../Source/Python/Ecc/CodeFragmentCollector.py | 0
.../BaseTools/Source/Python/Ecc/Configuration.py | 0
.../BaseTools/Source/Python/Ecc/Database.py | 0
.../Firmware/BaseTools/Source/Python/Ecc/Ecc.py | 0
.../BaseTools/Source/Python/Ecc/Exception.py | 0
.../BaseTools/Source/Python/Ecc/FileProfile.py | 0
.../BaseTools/Source/Python/Ecc/MetaDataParser.py | 0
.../Python/Ecc/MetaFileWorkspace/MetaDataTable.py | 0
.../Python/Ecc/MetaFileWorkspace/MetaFileParser.py | 0
.../Python/Ecc/MetaFileWorkspace/MetaFileTable.py | 0
.../BaseTools/Source/Python/Ecc/Xml/__init__.py | 0
.../EFI/Firmware/BaseTools/Source/Python/Ecc/c.py | 0
.../Firmware/BaseTools/Source/Python/Eot/CLexer.py | 0
.../BaseTools/Source/Python/Eot/CParser.py | 0
.../Source/Python/Eot/CodeFragmentCollector.py | 0
.../BaseTools/Source/Python/Eot/Database.py | 0
.../Firmware/BaseTools/Source/Python/Eot/Eot.py | 0
.../BaseTools/Source/Python/Eot/EotGlobalData.py | 0
.../BaseTools/Source/Python/Eot/FileProfile.py | 0
.../BaseTools/Source/Python/Eot/FvImage.py | 0
.../BaseTools/Source/Python/Eot/InfParserLite.py | 0
.../Firmware/BaseTools/Source/Python/Eot/Parser.py | 0
.../EFI/Firmware/BaseTools/Source/Python/Eot/c.py | 0
.../Source/Python/GenFds/AprioriSection.py | 0
.../BaseTools/Source/Python/GenFds/Capsule.py | 0
.../BaseTools/Source/Python/GenFds/CapsuleData.py | 0
.../Source/Python/GenFds/ComponentStatement.py | 0
.../Source/Python/GenFds/CompressSection.py | 0
.../BaseTools/Source/Python/GenFds/DataSection.py | 0
.../BaseTools/Source/Python/GenFds/DepexSection.py | 0
.../BaseTools/Source/Python/GenFds/EfiSection.py | 0
.../Firmware/BaseTools/Source/Python/GenFds/Fd.py | 0
.../BaseTools/Source/Python/GenFds/FdfParser.py | 0
.../Firmware/BaseTools/Source/Python/GenFds/Ffs.py | 0
.../Source/Python/GenFds/FfsFileStatement.py | 0
.../Source/Python/GenFds/FfsInfStatement.py | 0
.../Firmware/BaseTools/Source/Python/GenFds/Fv.py | 0
.../Source/Python/GenFds/FvImageSection.py | 0
.../BaseTools/Source/Python/GenFds/GenFds.py | 6 +-
.../Source/Python/GenFds/GenFdsGlobalVariable.py | 4 +
.../BaseTools/Source/Python/GenFds/GuidSection.py | 0
.../Source/Python/GenFds/OptRomFileStatement.py | 0
.../Source/Python/GenFds/OptRomInfStatement.py | 0
.../BaseTools/Source/Python/GenFds/OptionRom.py | 0
.../BaseTools/Source/Python/GenFds/Region.py | 0
.../BaseTools/Source/Python/GenFds/Rule.py | 0
.../Source/Python/GenFds/RuleComplexFile.py | 0
.../Source/Python/GenFds/RuleSimpleFile.py | 0
.../BaseTools/Source/Python/GenFds/Section.py | 0
.../BaseTools/Source/Python/GenFds/UiSection.py | 0
.../BaseTools/Source/Python/GenFds/VerSection.py | 0
.../Firmware/BaseTools/Source/Python/GenFds/Vtf.py | 0
.../Python/GenPatchPcdTable/GenPatchPcdTable.py | 0
.../Source/Python/PatchPcdValue/PatchPcdValue.py | 0
.../Source/Python/Table/TableDataModel.py | 0
.../BaseTools/Source/Python/Table/TableDec.py | 0
.../BaseTools/Source/Python/Table/TableDsc.py | 0
.../Source/Python/Table/TableEotReport.py | 0
.../BaseTools/Source/Python/Table/TableFdf.py | 0
.../BaseTools/Source/Python/Table/TableFile.py | 0
.../BaseTools/Source/Python/Table/TableFunction.py | 0
.../Source/Python/Table/TableIdentifier.py | 0
.../BaseTools/Source/Python/Table/TableInf.py | 0
.../BaseTools/Source/Python/Table/TablePcd.py | 0
.../BaseTools/Source/Python/Table/TableQuery.py | 0
.../BaseTools/Source/Python/Table/TableReport.py | 0
.../Source/Python/TargetTool/TargetTool.py | 0
.../Firmware/BaseTools/Source/Python/Trim/Trim.py | 0
.../BaseTools/Source/Python/UPT/BuildVersion.py | 0
.../Source/Python/UPT/Core/DependencyRules.py | 0
.../Python/UPT/Core/DistributionPackageClass.py | 0
.../BaseTools/Source/Python/UPT/Core/IpiDb.py | 0
.../Source/Python/UPT/Core/PackageFile.py | 0
.../BaseTools/Source/Python/UPT/Core/__init__.py | 0
.../Source/Python/UPT/GenMetaFile/GenDecFile.py | 0
.../Source/Python/UPT/GenMetaFile/GenInfFile.py | 0
.../Python/UPT/GenMetaFile/GenMetaFileMisc.py | 0
.../Source/Python/UPT/GenMetaFile/GenXmlFile.py | 0
.../Source/Python/UPT/GenMetaFile/__init__.py | 0
.../BaseTools/Source/Python/UPT/InstallPkg.py | 0
.../Source/Python/UPT/Library/CommentGenerating.py | 0
.../Source/Python/UPT/Library/CommentParsing.py | 0
.../Source/Python/UPT/Library/DataType.py | 0
.../Python/UPT/Library/ExpressionValidate.py | 0
.../Source/Python/UPT/Library/GlobalData.py | 0
.../BaseTools/Source/Python/UPT/Library/Misc.py | 0
.../Source/Python/UPT/Library/ParserValidate.py | 0
.../BaseTools/Source/Python/UPT/Library/Parsing.py | 0
.../BaseTools/Source/Python/UPT/Library/String.py | 0
.../Source/Python/UPT/Library/Xml/XmlRoutines.py | 0
.../Source/Python/UPT/Library/Xml/__init__.py | 0
.../Source/Python/UPT/Library/__init__.py | 0
.../BaseTools/Source/Python/UPT/Logger/Log.py | 0
.../Source/Python/UPT/Logger/StringTable.py | 0
.../BaseTools/Source/Python/UPT/Logger/__init__.py | 0
.../Firmware/BaseTools/Source/Python/UPT/MkPkg.py | 0
.../Source/Python/UPT/Object/POM/CommonObject.py | 0
.../Source/Python/UPT/Object/POM/ModuleObject.py | 0
.../Source/Python/UPT/Object/POM/PackageObject.py | 0
.../Source/Python/UPT/Object/POM/__init__.py | 0
.../Source/Python/UPT/Object/Parser/DecObject.py | 0
.../Python/UPT/Object/Parser/InfBinaryObject.py | 0
.../UPT/Object/Parser/InfBuildOptionObject.py | 0
.../UPT/Object/Parser/InfDefineCommonObject.py | 0
.../Python/UPT/Object/Parser/InfDefineObject.py | 0
.../Python/UPT/Object/Parser/InfDepexObject.py | 0
.../Python/UPT/Object/Parser/InfGuidObject.py | 0
.../UPT/Object/Parser/InfLibraryClassesObject.py | 0
.../Source/Python/UPT/Object/Parser/InfMisc.py | 0
.../Python/UPT/Object/Parser/InfPackagesObject.py | 0
.../Python/UPT/Object/Parser/InfPcdObject.py | 0
.../Python/UPT/Object/Parser/InfPpiObject.py | 0
.../Python/UPT/Object/Parser/InfProtocolObject.py | 0
.../Python/UPT/Object/Parser/InfSoucesObject.py | 0
.../UPT/Object/Parser/InfUserExtensionObject.py | 0
.../Source/Python/UPT/Object/Parser/__init__.py | 0
.../BaseTools/Source/Python/UPT/Object/__init__.py | 0
.../Source/Python/UPT/Parser/DecParser.py | 0
.../Source/Python/UPT/Parser/DecParserMisc.py | 0
.../Source/Python/UPT/Parser/InfAsBuiltProcess.py | 0
.../Python/UPT/Parser/InfBinarySectionParser.py | 0
.../UPT/Parser/InfBuildOptionSectionParser.py | 0
.../Python/UPT/Parser/InfDefineSectionParser.py | 0
.../Python/UPT/Parser/InfDepexSectionParser.py | 0
.../UPT/Parser/InfGuidPpiProtocolSectionParser.py | 0
.../Python/UPT/Parser/InfLibrarySectionParser.py | 0
.../Python/UPT/Parser/InfPackageSectionParser.py | 0
.../Source/Python/UPT/Parser/InfParser.py | 0
.../Source/Python/UPT/Parser/InfParserMisc.py | 0
.../Python/UPT/Parser/InfPcdSectionParser.py | 0
.../Source/Python/UPT/Parser/InfSectionParser.py | 0
.../Python/UPT/Parser/InfSourceSectionParser.py | 0
.../BaseTools/Source/Python/UPT/Parser/__init__.py | 0
.../Python/UPT/PomAdapter/DecPomAlignment.py | 0
.../Python/UPT/PomAdapter/InfPomAlignment.py | 0
.../Python/UPT/PomAdapter/InfPomAlignmentMisc.py | 0
.../Source/Python/UPT/PomAdapter/__init__.py | 0
.../Firmware/BaseTools/Source/Python/UPT/RmPkg.py | 0
.../Firmware/BaseTools/Source/Python/UPT/UPT.py | 0
.../UPT/UnitTest/CommentGeneratingUnitTest.py | 0
.../Python/UPT/UnitTest/CommentParsingUnitTest.py | 0
.../Source/Python/UPT/UnitTest/DecParserTest.py | 0
.../Python/UPT/UnitTest/DecParserUnitTest.py | 0
.../Python/UPT/UnitTest/InfBinarySectionTest.py | 0
.../BaseTools/Source/Python/UPT/Xml/CommonXml.py | 0
.../Source/Python/UPT/Xml/GuidProtocolPpiXml.py | 0
.../BaseTools/Source/Python/UPT/Xml/IniToXml.py | 0
.../Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py | 0
.../Source/Python/UPT/Xml/PackageSurfaceAreaXml.py | 0
.../BaseTools/Source/Python/UPT/Xml/PcdXml.py | 0
.../BaseTools/Source/Python/UPT/Xml/XmlParser.py | 0
.../Source/Python/UPT/Xml/XmlParserMisc.py | 0
.../BaseTools/Source/Python/UPT/Xml/__init__.py | 0
.../Source/Python/Workspace/BuildClassObject.py | 0
.../Source/Python/Workspace/MetaDataTable.py | 0
.../Source/Python/Workspace/MetaFileParser.py | 0
.../Source/Python/Workspace/MetaFileTable.py | 0
.../Source/Python/Workspace/WorkspaceDatabase.py | 0
.../BaseTools/Source/Python/build/BuildReport.py | 0
.../BaseTools/Source/Python/build/build.py | 0
src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd | Bin 1048576 -> 1048576 bytes
src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd | Bin 1048576 -> 1048576 bytes
.../Graphics/BIOS/VBoxVgaBiosAlternative.asm | 6 +-
.../Graphics/BIOS/VBoxVgaBiosAlternative.md5sum | 2 +-
src/VBox/Devices/Graphics/DevVGA-SVGA.cpp | 1217 ++++++++++----
src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h | 28 +-
src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m | 467 ++++--
src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp | 951 +++++++++--
src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h | 2 +-
src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp | 39 +-
src/VBox/Devices/Graphics/DevVGA-SVGA3d.h | 35 +-
src/VBox/Devices/Graphics/DevVGA.cpp | 14 +-
src/VBox/Devices/Graphics/DevVGA.h | 28 +-
src/VBox/Devices/Graphics/DevVGASavedState.h | 3 +-
src/VBox/Devices/Graphics/DevVGA_VBVA.cpp | 184 +++
src/VBox/Devices/Graphics/VBoxSVGA3D.def | 38 +
src/VBox/Devices/Graphics/VBoxSVGA3D.rc | 50 +
src/VBox/Devices/Graphics/VBoxSVGA3DObjC.def | 28 +
src/VBox/Devices/Graphics/shaderlib/directx.c | 166 +-
src/VBox/Devices/Graphics/shaderlib/glsl_shader.c | 12 +
src/VBox/Devices/Graphics/shaderlib/shader.c | 18 +-
src/VBox/Devices/Graphics/shaderlib/shaderapi.c | 154 +-
src/VBox/Devices/Graphics/shaderlib/shaderlib.h | 74 +-
src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h | 742 ++++-----
.../Devices/Graphics/shaderlib/wined3d_private.h | 47 +-
src/VBox/Devices/Input/DevPS2.cpp | 2 +-
src/VBox/Devices/Makefile.kmk | 190 ++-
src/VBox/Devices/Network/DrvNAT.cpp | 103 +-
src/VBox/Devices/Network/SrvIntNetR0.cpp | 7 +-
src/VBox/Devices/Network/slirp/bootp.c | 33 +-
.../Devices/Network/slirp/bsd/kern/uipc_mbuf.c | 2 +-
src/VBox/Devices/Network/slirp/debug.c | 64 +-
src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c | 39 +-
src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h | 5 +
src/VBox/Devices/Network/slirp/ip_icmp.c | 195 +--
src/VBox/Devices/Network/slirp/ip_icmp.h | 8 +
src/VBox/Devices/Network/slirp/ip_icmpwin.c | 538 +++++++
src/VBox/Devices/Network/slirp/ip_input.c | 14 +-
src/VBox/Devices/Network/slirp/ip_output.c | 13 +-
src/VBox/Devices/Network/slirp/libalias/alias.c | 4 +-
src/VBox/Devices/Network/slirp/libalias/alias_db.c | 198 +--
.../Devices/Network/slirp/libalias/alias_ftp.c | 9 +-
.../Devices/Network/slirp/libalias/alias_local.h | 2 +-
.../Devices/Network/slirp/libalias/alias_mod.c | 2 +-
.../Devices/Network/slirp/libalias/alias_mod.h | 2 +-
.../Devices/Network/slirp/libalias/alias_nbt.c | 16 +-
.../Devices/Network/slirp/libalias/alias_util.c | 2 +-
src/VBox/Devices/Network/slirp/libslirp.h | 33 +-
src/VBox/Devices/Network/slirp/misc.c | 5 +-
.../Devices/Network/slirp/resolv_conf_parser.c | 50 +-
.../Devices/Network/slirp/resolv_conf_parser.h | 16 +-
src/VBox/Devices/Network/slirp/sbuf.c | 31 +-
src/VBox/Devices/Network/slirp/slirp.c | 171 +-
src/VBox/Devices/Network/slirp/slirp.h | 7 +
src/VBox/Devices/Network/slirp/slirp_dns.c | 222 +--
src/VBox/Devices/Network/slirp/slirp_state.h | 40 +-
src/VBox/Devices/Network/slirp/socket.c | 183 +--
src/VBox/Devices/Network/slirp/socket.h | 10 +-
src/VBox/Devices/Network/slirp/tcp_input.c | 118 +-
src/VBox/Devices/Network/slirp/tcp_subr.c | 9 +-
src/VBox/Devices/Network/slirp/udp.c | 14 +-
src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm | 4 +-
.../Devices/PC/BIOS/VBoxBiosAlternative.md5sum | 2 +-
src/VBox/Devices/PC/DevACPI.cpp | 19 +
src/VBox/Devices/PC/vbox.dsl | 35 +
src/VBox/Devices/Storage/DevAHCI.cpp | 25 +-
src/VBox/Devices/Storage/DevATA.cpp | 15 +-
src/VBox/Devices/Storage/DrvVD.cpp | 84 +-
src/VBox/Devices/USB/DevOHCI.cpp | 104 +-
src/VBox/Devices/USB/VUSBDevice.cpp | 3 +-
src/VBox/Devices/USB/VUSBInternal.h | 2 +-
src/VBox/Devices/USB/VUSBUrb.cpp | 13 +-
src/VBox/Devices/VMMDev/VMMDev.cpp | 53 +-
src/VBox/Devices/VMMDev/VMMDevTesting.cpp | 63 +-
src/VBox/Devices/build/VBoxDD.rc | 50 +
src/VBox/Devices/build/VBoxDD2.rc | 50 +
src/VBox/Devices/build/VBoxDDU.rc | 50 +
src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk | 2 +
.../Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.rc | 50 +
src/VBox/Frontends/VBoxHeadless/Makefile.kmk | 8 +-
.../VirtualBox.rc => VBoxHeadless/VBoxHeadless.rc} | 30 +-
src/VBox/Frontends/VBoxManage/Makefile.kmk | 2 +
src/VBox/Frontends/VBoxManage/VBoxManage.rc | 50 +
src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp | 9 +-
src/VBox/Frontends/VBoxSDL/Makefile.kmk | 6 +
.../win/VirtualBox.rc => VBoxSDL/VBoxSDL.rc} | 30 +-
src/VBox/Frontends/VirtualBox/VirtualBox2.qrc | 4 +
src/VBox/Frontends/VirtualBox/images/os_win10.png | Bin 0 -> 2676 bytes
.../Frontends/VirtualBox/images/os_win10_64.png | Bin 0 -> 2673 bytes
src/VBox/Frontends/VirtualBox/images/os_win81.png | Bin 0 -> 2698 bytes
.../Frontends/VirtualBox/images/os_win81_64.png | Bin 0 -> 2692 bytes
.../VirtualBox/src/globals/COMWrappers.xsl | 1 +
.../VirtualBox/src/globals/UIMessageCenter.cpp | 2 +-
.../VirtualBox/src/globals/VBoxGlobal.cpp | 10 +-
.../Frontends/VirtualBox/src/globals/VBoxGlobal.h | 2 +
.../VirtualBox/src/net/UIDownloaderAdditions.cpp | 2 +-
.../src/net/UIDownloaderExtensionPack.cpp | 2 +-
.../VirtualBox/src/net/UIDownloaderUserManual.cpp | 2 +-
.../VirtualBox/src/net/UINetworkReply.cpp | 4 +-
.../src/platform/darwin/DarwinKeyboard.cpp | 5 +-
.../VirtualBox/src/platform/win/VirtualBox.rc | 24 +-
.../src/platform/win/VirtualBoxHardened.rc | 20 +-
.../VirtualBox/src/runtime/UIFrameBufferQImage.cpp | 4 +-
.../src/runtime/UIFrameBufferQuartz2D.cpp | 4 +-
.../VirtualBox/src/runtime/UIKeyboardHandler.cpp | 6 +-
.../VirtualBox/src/runtime/UIMachineLogic.cpp | 2 +-
.../VirtualBox/src/runtime/UIMachineView.cpp | 25 +
.../VirtualBox/src/runtime/UIMultiScreenLayout.cpp | 2 +-
.../Frontends/VirtualBox/src/runtime/UISession.cpp | 7 +-
.../Frontends/VirtualBox/src/runtime/UISession.h | 5 +-
.../fullscreen/UIMachineLogicFullscreen.cpp | 5 +-
.../runtime/fullscreen/UIMachineViewFullscreen.cpp | 2 +-
.../src/runtime/normal/UIMachineLogicNormal.cpp | 6 +
.../src/runtime/normal/UIMachineViewNormal.cpp | 2 +-
.../runtime/seamless/UIMachineLogicSeamless.cpp | 5 +-
.../src/runtime/seamless/UIMachineViewSeamless.cpp | 2 +-
.../settings/global/UIGlobalSettingsGeneral.cpp | 4 +-
.../src/wizards/newvm/UIWizardNewVMPageBasic1.cpp | 2 +
src/VBox/GuestHost/OpenGL/Makefile.kmk | 12 +-
src/VBox/GuestHost/OpenGL/error/VBoxOGLerrorspu.rc | 81 +
src/VBox/GuestHost/OpenGL/error/error.py | 0
src/VBox/GuestHost/OpenGL/error/errorspu.rc | 40 +-
src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py | 0
src/VBox/GuestHost/OpenGL/include/cr_blitter.h | 205 ++-
src/VBox/GuestHost/OpenGL/include/cr_compositor.h | 140 +-
src/VBox/GuestHost/OpenGL/include/cr_protocol.h | 4 +-
src/VBox/GuestHost/OpenGL/include/cr_vreg.h | 207 +--
src/VBox/GuestHost/OpenGL/packer/pack_current.py | 0
.../GuestHost/OpenGL/packer/pack_currentheader.py | 0
src/VBox/GuestHost/OpenGL/packer/pack_header.py | 0
src/VBox/GuestHost/OpenGL/packer/packer.py | 0
src/VBox/GuestHost/OpenGL/packer/packer_bbox.py | 0
src/VBox/GuestHost/OpenGL/spu_loader/dispatch.py | 0
.../GuestHost/OpenGL/spu_loader/dispatchheader.py | 0
src/VBox/GuestHost/OpenGL/spu_loader/glloader.py | 0
src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py | 0
src/VBox/GuestHost/OpenGL/spu_loader/spucopy.py | 0
src/VBox/GuestHost/OpenGL/state_tracker/convert.py | 0
.../GuestHost/OpenGL/state_tracker/dump_gen.py | 0
.../OpenGL/state_tracker/state_current.py | 0
.../GuestHost/OpenGL/state_tracker/state_defs.py | 0
.../GuestHost/OpenGL/state_tracker/state_funcs.py | 0
.../GuestHost/OpenGL/state_tracker/state_get.py | 0
.../OpenGL/state_tracker/state_isenabled.py | 0
src/VBox/GuestHost/OpenGL/util/VBoxOGLcrutil.rc | 81 +
src/VBox/GuestHost/OpenGL/util/blitter.cpp | 221 ++-
src/VBox/GuestHost/OpenGL/util/compositor.cpp | 234 +--
src/VBox/GuestHost/OpenGL/util/debug_opcodes.py | 0
src/VBox/GuestHost/OpenGL/util/error.c | 136 +-
src/VBox/GuestHost/OpenGL/util/net.c | 5 -
src/VBox/GuestHost/OpenGL/util/util.def | 1 -
src/VBox/GuestHost/OpenGL/util/util.rc | 54 +-
src/VBox/GuestHost/OpenGL/util/vreg.cpp | 372 +++--
src/VBox/HostDrivers/Support/Makefile.kmk | 7 +-
src/VBox/HostDrivers/Support/SUPDrv.c | 238 ++-
src/VBox/HostDrivers/Support/SUPDrvIOC.h | 15 +-
src/VBox/HostDrivers/Support/SUPDrvInternal.h | 2 +
src/VBox/HostDrivers/Support/SUPLib.cpp | 27 +-
src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c | 20 +-
src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp | 41 +-
...hority2014-078f0a9d03df119e434e4fec1bf0235a.taf | Bin 0 -> 730 bytes
.../Support/win/SUPHardenedVerifyImage-win.cpp | 9 +-
.../Support/win/SUPR3HardenedMain-win.cpp | 48 +-
src/VBox/HostDrivers/Support/win/VBoxDrv.rc | 56 +-
src/VBox/HostDrivers/Support/win/VBoxSupLib.rc | 59 +
.../Support/win/import-template-ntdll.h | 1 +
.../{win/drv/VBoxNetFlt-win.rc => VBoxNetFlt.rc} | 17 +-
.../HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp | 31 +-
.../HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf | 2 +-
.../VBoxNetFlt/win/drv/VBoxNetFlt-win.rc | 56 +-
.../VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc | 25 +-
src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc | 52 +-
src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc | 52 +-
src/VBox/HostDrivers/linux/export_modules | 10 +-
src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp | 49 +-
src/VBox/HostDrivers/win/load.sh | 20 +-
src/VBox/HostDrivers/win/loadall.sh | 22 +-
src/VBox/HostServices/DragAndDrop/Makefile.kmk | 3 +
.../HostServices/DragAndDrop/VBoxDragAndDropSvc.rc | 50 +
src/VBox/HostServices/GuestControl/Makefile.kmk | 3 +
.../GuestControl/VBoxGuestControlSvc.rc | 50 +
src/VBox/HostServices/GuestProperties/Makefile.kmk | 3 +
.../GuestProperties/VBoxGuestPropSvc.rc | 50 +
src/VBox/HostServices/HostChannel/Makefile.kmk | 3 +
.../HostServices/HostChannel/VBoxHostChannel.rc | 50 +
src/VBox/HostServices/SharedClipboard/Makefile.kmk | 3 +-
.../SharedClipboard/VBoxSharedClipboard.rc | 50 +
src/VBox/HostServices/SharedFolders/Makefile.kmk | 2 +
.../SharedFolders/VBoxSharedFolders.rc | 50 +
src/VBox/HostServices/SharedOpenGL/Makefile.kmk | 8 +-
.../SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp | 27 +-
.../SharedOpenGL/OpenGLTest/VBoxTestOGL.rc | 50 +
.../SharedOpenGL/crserver/VBoxSharedCrOpenGL.rc | 50 +
.../SharedOpenGL/crserverlib/server_config.c | 36 +
.../SharedOpenGL/crserverlib/server_dispatch.py | 0
.../crserverlib/server_dispatch_header.py | 0
.../SharedOpenGL/crserverlib/server_get.py | 0
.../SharedOpenGL/crserverlib/server_main.c | 3 +
.../SharedOpenGL/crserverlib/server_retval.py | 0
.../SharedOpenGL/crserverlib/server_simpleget.py | 0
.../SharedOpenGL/render/VBoxOGLrenderspu.rc | 50 +
.../SharedOpenGL/render/renderspu_cocoa_helper.h | 9 +-
.../SharedOpenGL/render/renderspu_cocoa_helper.m | 1659 ++++++++++++--------
.../HostServices/SharedOpenGL/unpacker/unpack.py | 0
.../SharedOpenGL/unpacker/unpack_extend.py | 0
.../SharedOpenGL/unpacker/unpack_header.py | 0
src/VBox/HostServices/auth/Makefile.kmk | 3 +-
.../HostServices/auth/simple/VBoxAuthSimple.rc | 50 +
src/VBox/HostServices/auth/winlogon/VBoxAuth.rc | 50 +
src/VBox/Installer/darwin/Makefile.kmk | 3 +-
src/VBox/Installer/linux/distributions_rpm | 4 +
src/VBox/Installer/linux/rpm/rules | 6 +-
src/VBox/Installer/linux/run-inst.sh | 4 +-
src/VBox/Installer/linux/vboxdrv-pardus.py | 0
src/VBox/Installer/win/InstallHelper/Makefile.kmk | 1 +
.../win/InstallHelper/VBoxInstallHelper.cpp | 73 +-
.../win/InstallHelper/VBoxInstallHelper.def | 1 +
.../win/InstallHelper/VBoxInstallHelper.rc | 50 +
src/VBox/Installer/win/VBoxMergeNetAdpCA.wxi | 3 +-
src/VBox/Installer/win/VBoxMergeNetAdpSeq.wxi | 10 +-
src/VBox/Installer/win/VirtualBox.wxs | 13 +-
src/VBox/Main/Makefile.kmk | 5 +
src/VBox/Main/cbinding/Makefile.kmk | 2 +
src/VBox/Main/cbinding/VBoxCAPI.cpp | 169 +-
src/VBox/Main/cbinding/VBoxCAPI.rc | 50 +
src/VBox/Main/cbinding/VBoxCAPIGlue.c | 82 +-
src/VBox/Main/cbinding/capiidl.xsl | 34 +-
src/VBox/Main/glue/com.cpp | 3 +-
src/VBox/Main/glue/vboxapi.py | 23 +-
src/VBox/Main/include/ConsoleImpl.h | 13 +
src/VBox/Main/include/DisplayImpl.h | 30 +
src/VBox/Main/include/DisplayUtils.h | 2 +
src/VBox/Main/include/MediumImpl.h | 3 +-
src/VBox/Main/include/MouseImpl.h | 5 +-
src/VBox/Main/src-all/Global.cpp | 14 +-
src/VBox/Main/src-client/ConsoleImpl.cpp | 300 +++-
src/VBox/Main/src-client/ConsoleImpl2.cpp | 175 ++-
src/VBox/Main/src-client/DisplayImpl.cpp | 305 +++-
src/VBox/Main/src-client/GuestImpl.cpp | 3 -
src/VBox/Main/src-client/MouseImpl.cpp | 52 +-
src/VBox/Main/src-client/README.testing | 16 +
src/VBox/Main/src-client/VMMDevInterface.cpp | 9 +
src/VBox/Main/src-client/win/VBoxC.rc | 25 +-
src/VBox/Main/src-client/win/VBoxClient-x86.rc | 25 +-
.../Main/src-helper-apps/VBoxExtPackHelperApp.rc | 50 +
src/VBox/Main/src-server/HostDnsService.cpp | 2 +-
src/VBox/Main/src-server/HostDnsService.h | 1 -
.../Main/src-server/HostDnsServiceResolvConf.cpp | 23 +-
src/VBox/Main/src-server/MachineImpl.cpp | 37 +-
src/VBox/Main/src-server/MediumImpl.cpp | 17 +-
src/VBox/Main/src-server/SnapshotImpl.cpp | 1 +
.../src-server/darwin/HostDnsServiceDarwin.cpp | 4 +-
.../Main/src-server/linux/HostDnsServiceLinux.cpp | 3 +-
src/VBox/Main/src-server/win/HostDnsServiceWin.cpp | 362 +++--
src/VBox/Main/src-server/win/VBoxSVC.rc | 25 +-
src/VBox/Main/testcase/tstMouseImpl.cpp | 3 +
src/VBox/Main/webservice/Makefile.kmk | 2 +
src/VBox/Main/webservice/VBoxWebSrv.rc | 50 +
src/VBox/NetworkServices/DHCP/Makefile.kmk | 22 +-
src/VBox/NetworkServices/DHCP/VBoxNetDHCP.rc | 54 +
src/VBox/NetworkServices/NAT/Makefile.kmk | 27 +-
src/VBox/NetworkServices/NAT/RTWinPoll.cpp | 17 +-
src/VBox/NetworkServices/NAT/RTWinSocketPair.cpp | 17 +
src/VBox/NetworkServices/NAT/VBoxNetNAT.rc | 54 +
src/VBox/NetworkServices/NAT/dhcp6.h | 18 +-
src/VBox/NetworkServices/NAT/fwtcp.c | 18 +-
src/VBox/NetworkServices/NAT/fwudp.c | 18 +-
src/VBox/NetworkServices/NAT/lwipopts.h | 17 +
src/VBox/NetworkServices/NAT/portfwd.c | 18 +-
src/VBox/NetworkServices/NAT/portfwd.h | 18 +-
src/VBox/NetworkServices/NAT/proxy.c | 18 +-
src/VBox/NetworkServices/NAT/proxy.h | 17 +
src/VBox/NetworkServices/NAT/proxy_dhcp6ds.c | 19 +-
src/VBox/NetworkServices/NAT/proxy_pollmgr.c | 18 +-
src/VBox/NetworkServices/NAT/proxy_pollmgr.h | 18 +-
src/VBox/NetworkServices/NAT/proxy_rtadvd.c | 18 +-
src/VBox/NetworkServices/NAT/proxy_tftpd.c | 18 +-
src/VBox/NetworkServices/NAT/pxdns.c | 7 +-
src/VBox/NetworkServices/NAT/pxping.c | 18 +-
src/VBox/NetworkServices/NAT/pxping_win.c | 18 +-
src/VBox/NetworkServices/NAT/pxremap.c | 18 +-
src/VBox/NetworkServices/NAT/pxremap.h | 18 +-
src/VBox/NetworkServices/NAT/pxtcp.c | 18 +-
src/VBox/NetworkServices/NAT/pxtcp.h | 18 +-
src/VBox/NetworkServices/NAT/pxudp.c | 18 +-
src/VBox/NetworkServices/NAT/rtmon_bsd.c | 19 +-
src/VBox/NetworkServices/NAT/rtmon_linux.c | 19 +-
src/VBox/NetworkServices/NAT/rtmon_win.c | 17 +
src/VBox/NetworkServices/NAT/tftp.h | 18 +-
src/VBox/NetworkServices/NAT/winpoll.h | 17 +
src/VBox/NetworkServices/NAT/winutils.h | 17 +
.../NetworkServices/NetLib/VBoxNetBaseService.cpp | 29 +-
src/VBox/NetworkServices/NetLib/shared_ptr.h | 17 +
src/VBox/Runtime/Makefile.kmk | 1 +
src/VBox/Runtime/common/crypto/x509-template.h | 19 +-
src/VBox/Runtime/common/ldr/ldrPE.cpp | 52 +-
src/VBox/Runtime/include/internal/ldrPE.h | 92 +-
src/VBox/Runtime/include/internal/socket.h | 2 +-
.../r0drv/linux/memuserkernel-r0drv-linux.c | 19 +-
src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp | 54 +-
src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h | 35 +-
src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp | 53 +-
src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp | 125 +-
src/VBox/Runtime/r3/init.cpp | 8 +
src/VBox/Runtime/r3/socket.cpp | 77 +-
src/VBox/Runtime/r3/tcp.cpp | 8 +-
src/VBox/Runtime/r3/win/VBoxRT-openssl.def | 1 -
src/VBox/Runtime/r3/win/VBoxRT.rc | 59 +
src/VBox/Runtime/r3/win/ntdll-mini-implib.def | 15 +-
src/VBox/Runtime/r3/win/path-win.cpp | 34 +-
src/VBox/Storage/ISCSI.cpp | 2 +-
src/VBox/Storage/Makefile.kmk | 1 +
src/VBox/Storage/testcase/Makefile.kmk | 4 +-
src/VBox/Storage/testcase/vbox-img.rc | 50 +
src/VBox/VMM/Makefile.kmk | 2 +
src/VBox/VMM/VMMAll/CPUMAllRegs.cpp | 2 +-
src/VBox/VMM/VMMAll/TMAllVirtual.cpp | 2 +-
src/VBox/VMM/VMMR0/HMVMXR0.cpp | 20 +-
src/VBox/VMM/VMMR0/VMMR0.def | 1 +
src/VBox/VMM/VMMR3/VMEmt.cpp | 60 +-
src/VBox/VMM/VMMR3/VMMR3.rc | 50 +
src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac | 33 +
src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac | 33 +
src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac | 33 +
src/VBox/VMM/tools/VBoxVMMPreload.cpp | 22 +-
src/bldprogs/VBoxDef2LazyLoad.cpp | 395 ++++-
src/libs/Makefile.kmk | 2 +-
.../xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp | 8 +-
.../extensions/dconnect/src/ipcDConnectService.cpp | 4 +-
src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h | 13 +
src/libs/xpcom18a4/nsprpub/Makefile.in | 0
src/libs/xpcom18a4/nsprpub/config/config.mk | 0
src/libs/xpcom18a4/nsprpub/config/rules.mk | 0
src/libs/xpcom18a4/python/client/__init__.py | 0
src/libs/xpcom18a4/python/file.py | 0
src/libs/xpcom18a4/python/primitives.py | 0
src/libs/xpcom18a4/python/server/__init__.py | 0
src/libs/xpcom18a4/python/server/enumerator.py | 0
src/libs/xpcom18a4/python/server/factory.py | 0
src/libs/xpcom18a4/python/server/loader.py | 0
src/libs/xpcom18a4/python/server/module.py | 0
src/libs/xpcom18a4/python/server/policy.py | 0
.../xpcom18a4/python/test/pyxpcom_test_tools.py | 0
.../xpcom18a4/python/test/test_com_exceptions.py | 0
src/libs/xpcom18a4/python/test/test_comfile.py | 0
.../test/test_component/py_test_component.py | 0
src/libs/xpcom18a4/python/test/test_components.py | 0
.../python/test/test_isupports_primitives.py | 0
src/libs/xpcom18a4/python/test/test_misc.py | 0
src/libs/xpcom18a4/python/test/test_streams.py | 0
.../xpcom18a4/python/test/test_test_component.py | 0
.../xpcom18a4/python/test/test_weakreferences.py | 0
src/libs/xpcom18a4/python/tools/regxpcom.py | 0
src/libs/xpcom18a4/python/xpt.py | 0
src/recompiler/Makefile.kmk | 10 +
src/recompiler/VBoxREM.rc | 54 +
702 files changed, 17308 insertions(+), 8695 deletions(-)
diff --git a/Config.kmk b/Config.kmk
index 4398062..e08e969 100644
--- a/Config.kmk
+++ b/Config.kmk
@@ -208,7 +208,7 @@ VBOX_VERSION_MINOR = 3
# This is the current build number. It should be increased every time we publish a
# new build. The define is available in every source file. Only even build numbers
# will be published, odd numbers are set during development.
-VBOX_VERSION_BUILD = 20
+VBOX_VERSION_BUILD = 22
# The raw version string. This *must not* contain any other information/fields than
# major, minor and build revision (as it is now) -- also will be used for host/guest version
# comparison.
@@ -1952,6 +1952,10 @@ endif
# 32bit X11 LIBPATH for building 32bit guest additions
VBOX_LIBPATH32_X11 ?= /usr/X11R6/lib32 /usr/X11R6/lib
+# Good windows shell.
+VBOX_GOOD_COMSPEC = $(subst \,/,$(SystemRoot))/System32/cmd.exe
+VBOX_GOOD_COMSPEC_BS ?= $(subst /,\,$(VBOX_GOOD_COMSPEC))
+
#
# Macros dealing with the darwin version we're targeting.
# The DEF in VBOX_DEF_MACOSX_VERSION_MIN mean default. The default min
@@ -2712,6 +2716,12 @@ ifdef VBOX_SIGNING_MODE
# Not Windows or mac os x build host, ignore.
VBOX_SIGNING_MODE :=
endif
+
+#
+# Complain if windows hardening is enabled but not code signing.
+#
+else if "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING) && !defined(VBOX_ONLY_BUILD)
+ $(error You need to enable code signing for a hardened windows build to work.)
endif
#
@@ -4084,6 +4094,22 @@ TEMPLATE_VBOXR3OSX105_LDFLAGS.darwin = $(VBOX_DARWIN_DEF_SDK_10_5_LDFLAGS) \
-current_version $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) \
-compatibility_version $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD)
+#
+# Template for building R3 shared objects / DLLs with the 10.7 Mac OS X SDK.
+# Identical to VBoxR3Dll, except for the DYLIB, the classic_linker and SDK bits.
+#
+TEMPLATE_VBoxR3DllOsX107 = VBox Ring 3 SO/DLLs for OS X 10.7
+TEMPLATE_VBoxR3DllOsX107_EXTENDS = VBoxR3Dll
+TEMPLATE_VBoxR3DllOsX107_TOOL = LLVMGXX42MACHO
+TEMPLATE_VBoxR3DllOsX107_DEFS.darwin = $(VBOX_DARWIN_DEF_SDK_10_7_DEFS) PIC
+TEMPLATE_VBoxR3DllOsX107_CFLAGS.darwin = $(VBOX_DARWIN_DEF_SDK_10_7_CFLAGS) -fno-common
+TEMPLATE_VBoxR3DllOsX107_CXXFLAGS.darwin = $(VBOX_DARWIN_DEF_SDK_10_7_CXXFLAGS)
+TEMPLATE_VBoxR3DllOsX107_OBJCFLAGS.darwin = $(VBOX_DARWIN_DEF_SDK_10_7_OBJCFLAGS)
+TEMPLATE_VBoxR3DllOsX107_OBJCXXFLAGS.darwin = $(VBOX_DARWIN_DEF_SDK_10_7_OBJCFLAGS)
+TEMPLATE_VBoxR3DllOsX107_LDFLAGS.darwin = $(VBOX_DARWIN_DEF_SDK_10_7_LDFLAGS) \
+ -current_version $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) \
+ -compatibility_version $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD)
+
#
# Ring-3 testcase, running automatically during the build.
@@ -5698,7 +5724,7 @@ endif
SVN ?= svn$(HOSTSUFF_EXE)
VBOX_SVN_REV_KMK = $(PATH_OUT)/revision.kmk
ifndef VBOX_SVN_REV
- VBOX_SVN_REV_FALLBACK := $(patsubst %:,, $Rev: 96996 $ )
+ VBOX_SVN_REV_FALLBACK := $(patsubst %:,, $Rev: 98236 $ )
VBOX_SVN_DEP := $(firstword $(wildcard $(PATH_ROOT)/.svn/wc.db $(abspath $(PATH_ROOT)/../.svn/wc.db) $(abspath $(PATH_ROOT)/../../.svn/wc.db) $(PATH_ROOT)/.svn/entries))
ifeq ($(which $(SVN)),)
VBOX_SVN_DEP :=
diff --git a/Makefile.kmk b/Makefile.kmk
index b39df14..3ee751d 100644
--- a/Makefile.kmk
+++ b/Makefile.kmk
@@ -810,8 +810,6 @@ VBOX_RSYNC_IN_FN = rsync -a -v --delete --delete-excluded --prune-empty-dirs \
# VM IP addresses.
#
VBOX_BLD_VM_LNX_IP := 192.168.27.2
-VBOX_BLD_VM_LNX_X86_IP := 192.168.27.11
-VBOX_BLD_VM_LNX_AMD64_IP := 192.168.27.12
VBOX_BLD_VM_OS2_IP := 192.168.27.3
VBOX_BLD_VM_SOLARIS_IP := 192.168.27.4
VBOX_BLD_VM_DARWIN_X86_IP := 192.168.27.5
@@ -874,6 +872,7 @@ additions-build-rsync-into-vms: \
additions-build-linux.rsync-into-vm
$(call MSG_L1,Rsynced the sources + tools into the VMs.)
.NOTPARALLEL: additions-build-rsync-into-vms
+.PHONY: additions-build-rsync-into-vms
VBOX_ADDITIONS_BUILD.amd64 = VBOX_ONLY_ADDITIONS=1 VBOX_WITHOUT_ADDITIONS_ISO=1 \
@@ -1190,10 +1189,10 @@ extpacks-build-linux.rsync-into-vm: $(VBOX_EXTPACKS_BUILD_WIN_HOST_FIRST)
extpacks-build-linux.build-it: extpacks-build-linux.rsync-into-vm
$(call VBOX_BLD_VM_MSG_BEGIN,Linux/amd64 extension packs)
- $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_IP) " echo $@ && dchroot -c debian-4.0-amd64 \"cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.amd64) all\""'
+ $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_IP) " echo $@/amd64 && dchroot -c debian-4.0-amd64 \"cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.amd64) all\""'
$(call VBOX_BLD_VM_MSG_END__,Linux/amd64 extension packs)
$(call VBOX_BLD_VM_MSG_BEGIN,Linux/x86 extension packs)
- $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_IP) " echo $@ && linux32 dchroot -c debian-4.0-i386 \"cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) all\""'
+ $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_IP) " echo $@/x86 && linux32 dchroot -c debian-4.0-i386 \"cd /mnt/tinderbox/$(VBOX_EXTPACKS_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_EXTPACKS_BUILD.x86) all\""'
$(call VBOX_BLD_VM_MSG_END__,Linux/x86 extension packs)
extpacks-build-linux.rsync-out-of-vm: extpacks-build-linux.build-it
@@ -1413,8 +1412,7 @@ ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),linux.amd64)
+ $(VBOX_KMK_TIME) $(KMK) $(VBOX_TESTSUITE_BUILD.amd64) all $(VBOX_TESTSUITE_HOST_BUILD_TWEAK)
else
$(call VBOX_BLD_VM_MSG_BEGIN,Linux/amd64 Validation Kit)
- #$(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_AMD64_IP) " echo $@ && dchroot -c debian-4.0-amd64 \"cd /mnt/tinderbox/$(VBOX_TESTSUITE_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_TESTSUITE_BUILD.amd64) all\""'
- $(VBOX_KMK_TIME) ssh vbox@$(VBOX_BLD_VM_LNX_AMD64_IP) " echo $@ && cd /mnt/tinderbox/$(VBOX_TESTSUITE_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_TESTSUITE_BUILD.amd64) all"
+ $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_IP) " echo $@/amd64 && dchroot -c debian-4.0-amd64 \"cd /mnt/tinderbox/$(VBOX_TESTSUITE_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_TESTSUITE_BUILD.amd64) all\""'
$(call VBOX_BLD_VM_MSG_END__,Linux/amd64 Validation Kit)
endif
@@ -1423,8 +1421,7 @@ ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),linux.x86)
+ $(VBOX_KMK_TIME) $(KMK) $(VBOX_TESTSUITE_BUILD.x86) all $(VBOX_TESTSUITE_HOST_BUILD_TWEAK)
else
$(call VBOX_BLD_VM_MSG_BEGIN,Linux/x86 Validation Kit)
- #$(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_X86_IP) "echo $@ && linux32 dchroot -c rhel3-i386 \"cd /mnt/tinderbox/$(VBOX_TESTSUITE_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_TESTSUITE_BUILD.x86) all\""'
- $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_X86_IP) "echo $@ && dchroot -c rhel3-i386 \"cd /mnt/tinderbox/$(VBOX_TESTSUITE_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_TESTSUITE_BUILD.x86) all\""'
+ $(VBOX_KMK_TIME) ssh 'vbox@$(VBOX_BLD_VM_LNX_IP) " echo $@/x86 && linux32 dchroot -c rhel3-i386 \"cd /mnt/tinderbox/$(VBOX_TESTSUITE_BUILD_SUBDIRNAME) && tools/env.sh --no-wine kmk $(VBOX_TESTSUITE_BUILD.x86) all\""'
$(call VBOX_BLD_VM_MSG_END__,Linux/x86 Validation Kit)
endif
diff --git a/doc/manual/en_US/user_VBoxManage.xml b/doc/manual/en_US/user_VBoxManage.xml
index 131b689..2f8aa5c 100644
--- a/doc/manual/en_US/user_VBoxManage.xml
+++ b/doc/manual/en_US/user_VBoxManage.xml
@@ -2686,7 +2686,8 @@ Value: 2006.01.01</screen>
</listitem>
<listitem>
- <para><computeroutput>get <vm></computeroutput>: This
+ <para><computeroutput>get <vm> <property>
+ </computeroutput>: This
retrieves the value of a single property only. If the property
cannot be found (e.g. because the guest is not running), this will
print <screen>No value set!</screen></para>
diff --git a/doc/manual/user_ChangeLogImpl.xml b/doc/manual/user_ChangeLogImpl.xml
index 6209caa..921bdaa 100644
--- a/doc/manual/user_ChangeLogImpl.xml
+++ b/doc/manual/user_ChangeLogImpl.xml
@@ -1,6 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<sect1>
+ <title>Version 4.3.22 (2014-02-12)</title>
+
+ <para>This is a maintenance release. The following items were fixed and/or
+ added:</para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>VMM: refined measurement of TSC frequency on the host, improves
+ timekeeping for guests</para>
+ </listitem>
+
+ <listitem>
+ <para>VMM: decreased CPU load resulting from guest MMIO writes to the
+ virtual APIC</para>
+ </listitem>
+
+ <listitem>
+ <para>VMM: fixed interception of debug exceptions, observed while using
+ the dbx debugger on Solaris guests (VT-x only)</para>
+ </listitem>
+
+ <listitem>
+ <para>GUI: 3D overlay window positioning code improved, fixed potential
+ misplacement of 3D accelerated guest graphics content</para>
+ </listitem>
+
+ <listitem>
+ <para>GUI: fixed accident SSL authentication failures during update
+ check on Windows hosts (bug #12969)</para>
+ </listitem>
+
+ <listitem>
+ <para>GUI: never send the "ACPI power" keyboard scancode to the guest,
+ we have the ACPI power button for that</para>
+ </listitem>
+
+ <listitem>
+ <para>GUI: was unable to properly restore seamless mode VM from
+ snapshot/saved-state under some circumstances</para>
+ </listitem>
+
+ <listitem>
+ <para>VBoxHeadless: don't crash if 3D is enabled in the VM settings
+ (bug #10250)</para>
+ </listitem>
+
+ <listitem>
+ <para>ATA: fixed several passthrough issues (bugs #12310, #1360)</para>
+ </listitem>
+
+ <listitem>
+ <para>Audio: fixed DirectSound failure when the the host has no audio
+ input device (Windows hosts only; bug #9205)</para>
+ </listitem>
+
+ <listitem>
+ <para>SB16: fixed compatibility issue (bug #13769)</para>
+ </listitem>
+
+ <listitem>
+ <para>Storage: fixed broken CD/DVD passthrough when using the
+ IDE controller (bug #12310)</para>
+ </listitem>
+
+ <listitem>
+ <para>NAT: new ping proxy for Windows hosts (bug #11871)</para>
+ </listitem>
+
+ <listitem>
+ <para>NAT: Properly report outbound connect(2) failures to
+ guest with TCP RST or ICMP (bug #10525)</para>
+ </listitem>
+
+ <listitem>
+ <para>NAT Network: no need for frequent wakeups in VBoxNetDHCP
+ and VBoxNetNAT (bug #11681)</para>
+ </listitem>
+
+ <listitem>
+ <para>Host-only adapter: prevent Windows from creating an "Unidentified
+ network" (bug #9688)</para>
+ </listitem>
+
+ <listitem>
+ <para>Bridged Networking: don't leak host-to-guest traffic to
+ the wireless network when bridging to a wireless interface
+ (bug #13714)</para>
+ </listitem>
+
+ <listitem>
+ <para>Main: fixed a possible race when changing the medium leading
+ to a deadlock under rare conditions (bug #13722)</para>
+ </listitem>
+
+ <listitem>
+ <para>VBoxManage: fixed return code if starting a VM failed
+ (bug #13773)</para>
+ </listitem>
+
+ <listitem>
+ <para>API: fixed 2 deadlock opportunities related to medium handling
+ (bugs #13789, #13801, thank you Alexander Urakov)</para>
+ </listitem>
+
+ <listitem>
+ <para>API: fixed bug in XPCOM which created too few worker threads,
+ sporadically resulting in a deadlock (bug #13802, thank you Alexander
+ Urakov)</para>
+ </listitem>
+
+ <listitem>
+ <para>SDK: fixed a garbage collection leak in the Python VirtualBox
+ webservice API binding (bug #13817)</para>
+ </listitem>
+
+ <listitem>
+ <para>Linux hosts: fixes for activated SMAP (Broadwell and later,
+ bug #13820)</para>
+ </listitem>
+
+ <listitem>
+ <para>X11 guests: prevent unwanted hiding of guest screens
+ on multi-monitor guests (bug #13287)</para>
+ </listitem>
+
+ <listitem>
+ <para>X11 guests: added support for X.Org Server 1.17</para>
+ </listitem>
+
+ <listitem>
+ <para>X11 Additions: fixed a memory leak in VBoxService if libdbus
+ is available but dbus-daemon isn't running (bug #13770)</para>
+ </listitem>
+
+ <listitem>
+ <para>Windows Additions: prevent VBox WDDM driver from loading if host
+ reports weak OpenGL capabilities. 3D content now can be shown over
+ Remote Desktop connection.</para>
+ </listitem>
+
+ <listitem>
+ <para>Winodws Additions: some fixes for recent Windows 10 Previews</para>
+ </listitem>
+
+ <listitem>
+ <para>Linux Additions: fixed a compatibility issue with 64-bit
+ Linux 2.4 kernels</para>
+ </listitem>
+
+ <listitem>
+ <para>Linux Additions: fixed a potential use-after-free when unloading
+ the VBoxGuest module</para>
+ </listitem>
+
+ <listitem>
+ <para>Linux Additions: Linux 3.19 fixes (bug #13741)</para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+
+ <sect1>
<title>Version 4.3.20 (2014-11-21)</title>
<para>This is a maintenance release. The following items were fixed and/or
@@ -9,7 +172,7 @@
<itemizedlist>
<listitem>
- <para>VMM: fixed reboot hang of 32-bit Windows SMP guests (bug #13319,
+ <para>VMM: fixed reboot hang of 32-bit Windows SMP guests (bugs #13319,
#13462)</para>
</listitem>
@@ -17,7 +180,7 @@
<para>VMM: proper <emphasis>Math Fault</emphasis> handling with certain
legacy guests (bug #9042, AMD hosts)</para>
</listitem>
-
+
<listitem>
<para>VMM: fixed a Guru Meditation <emphasis>VINF_EM_TRIPLE_FAULT</emphasis>
on older CPUs that don't support MSR-bitmaps (VT-x only;
@@ -3029,7 +3192,7 @@
<listitem>
<para>Shared Folders: if the host folder of a shared folder mapping does
not exist, keep it active but mark it as invalid to prevent
- inconsitent saved states (bug #11147)</para>
+ inconsistent saved states (bug #11147)</para>
</listitem>
<listitem>
@@ -3159,7 +3322,7 @@
</listitem>
<listitem>
- <para>EFI: fixed video mode selection loss on VM reboot (#10983)</para>
+ <para>EFI: fixed video mode selection loss on VM reboot (bug #10983)</para>
</listitem>
<listitem>
@@ -3629,7 +3792,7 @@
<listitem>
<para>AHCI: fixed a rare bug which can cause a guest memory corruption
- after the guest storage controler has been reset</para>
+ after the guest storage controller has been reset</para>
</listitem>
<listitem>
@@ -4077,7 +4240,7 @@
<listitem>
<para>NAT: increase maximum number of parallel connections making
- connections with port forwarding more robust (#8471)</para>
+ connections with port forwarding more robust (bug #8471)</para>
</listitem>
<listitem>
@@ -4618,7 +4781,7 @@
<listitem>
<para>Windows Vista and 7 guests: WDDM driver fixes and performance enhancements,
- fixed WinSAT crashes (#9267)</para>
+ fixed WinSAT crashes (bug #9267)</para>
</listitem>
<listitem>
diff --git a/include/VBox/HGSMI/HGSMIChSetup.h b/include/VBox/HGSMI/HGSMIChSetup.h
index 3084a76..3f4bcbd 100644
--- a/include/VBox/HGSMI/HGSMIChSetup.h
+++ b/include/VBox/HGSMI/HGSMIChSetup.h
@@ -55,6 +55,11 @@ AssertCompileSize(HGSMIBUFFERLOCATION, 8);
#endif
/* vsync interrupt flag, should be accessed under VGAState::lock only */
#define HGSMIHOSTFLAGS_VSYNC 0x10
+/** monitor hotplug flag, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_HOTPLUG 0x20
+/** Cursor capability state change flag, should be accessed under
+ * VGAState::lock only. @see VBVACONF32. */
+#define HGSMIHOSTFLAGS_CURSOR_CAPABILITIES 0x40
typedef struct _HGSMIHOSTFLAGS
{
diff --git a/include/VBox/VBoxGuest.h b/include/VBox/VBoxGuest.h
index 9c025eb..5797365 100644
--- a/include/VBox/VBoxGuest.h
+++ b/include/VBox/VBoxGuest.h
@@ -78,6 +78,10 @@
/** Fictive start address of the hypervisor physical memory for MmMapIoSpace. */
#define VBOXGUEST_HYPERVISOR_PHYSICAL_START UINT32_C(0xf8000000)
+#ifdef RT_OS_DARWIN
+/** Cookie used to fend off some unwanted clients to the IOService. */
+#define VBOXGUEST_DARWIN_IOSERVICE_COOKIE 0x56426F78 /* 'VBox' */
+#endif
#if !defined(IN_RC) && !defined(IN_RING0_AGNOSTIC) && !defined(IPRT_NO_CRT)
/** @name VBoxGuest IOCTL codes and structures.
@@ -377,8 +381,27 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4);
#endif
/** IOCTL to for setting the mouse driver callback. (kernel only) */
+/** @note The callback will be called in interrupt context with the VBoxGuest
+ * device event spinlock held. */
#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK VBOXGUEST_IOCTL_CODE(31, sizeof(VBoxGuestMouseSetNotifyCallback))
+typedef DECLCALLBACK(void) FNVBOXGUESTMOUSENOTIFY(void *pfnUser);
+typedef FNVBOXGUESTMOUSENOTIFY *PFNVBOXGUESTMOUSENOTIFY;
+
+/** Input buffer for VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK. */
+typedef struct VBoxGuestMouseSetNotifyCallback
+{
+ /**
+ * Mouse notification callback.
+ *
+ * @param pvUser The callback argument.
+ */
+ PFNVBOXGUESTMOUSENOTIFY pfnNotify;
+ /** The callback argument*/
+ void *pvUser;
+} VBoxGuestMouseSetNotifyCallback;
+
+
typedef enum VBOXGUESTCAPSACQUIRE_FLAGS
{
VBOXGUESTCAPSACQUIRE_FLAGS_NONE = 0,
@@ -419,23 +442,17 @@ typedef struct VBoxGuestCapsAquire
**/
#define VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE VBOXGUEST_IOCTL_CODE(32, sizeof(VBoxGuestCapsAquire))
+/** IOCTL to VBoxGuest to set guest capabilities. */
+#define VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES VBOXGUEST_IOCTL_CODE_(33, sizeof(VBoxGuestSetCapabilitiesInfo))
-
-typedef DECLCALLBACK(void) FNVBOXGUESTMOUSENOTIFY(void *pfnUser);
-typedef FNVBOXGUESTMOUSENOTIFY *PFNVBOXGUESTMOUSENOTIFY;
-
-/** Input buffer for VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK. */
-typedef struct VBoxGuestMouseSetNotifyCallback
+/** Input and output buffer layout of the VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES
+ * IOCtl. */
+typedef struct VBoxGuestSetCapabilitiesInfo
{
- /**
- * Mouse notification callback.
- *
- * @param pvUser The callback argument.
- */
- PFNVBOXGUESTMOUSENOTIFY pfnNotify;
- /** The callback argument*/
- void *pvUser;
-} VBoxGuestMouseSetNotifyCallback;
+ uint32_t u32OrMask;
+ uint32_t u32NotMask;
+} VBoxGuestSetCapabilitiesInfo;
+AssertCompileSize(VBoxGuestSetCapabilitiesInfo, 8);
#ifdef RT_OS_OS2
diff --git a/include/VBox/VBoxGuestLib.h b/include/VBox/VBoxGuestLib.h
index dea1a6a..bd1ade6 100644
--- a/include/VBox/VBoxGuestLib.h
+++ b/include/VBox/VBoxGuestLib.h
@@ -432,7 +432,7 @@ VBGLR3DECL(int) VbglR3GetHostTime(PRTTIMESPEC pTime);
VBGLR3DECL(int) VbglR3InterruptEventWaits(void);
VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cch);
VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot);
-VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose);
+VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn);
VBGLR3DECL(int) VbglR3PidFile(const char *pszPath, PRTFILE phFile);
VBGLR3DECL(void) VbglR3ClosePidFile(const char *pszPath, RTFILE hFile);
VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot);
@@ -480,13 +480,28 @@ VBGLR3DECL(int) VbglR3SetPointerShapeReq(struct VMMDevReqMousePointer *pReq)
/** @name Display
* @{ */
-VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, uint32_t *piDisplay, bool fAck);
-VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits,
- uint32_t *piDisplay, uint32_t *pcOriginX, uint32_t *pcOriginY,
- bool *pfEnabled, bool fAck);
+/** The folder for saving video mode hints to between sessions. */
+#define VBGLR3HOSTDISPSAVEDMODEPATH "/var/lib/VBoxGuestAdditions"
+/** The path to the file for saving video mode hints to between sessions. */
+#define VBGLR3HOSTDISPSAVEDMODE VBGLR3HOSTDISPSAVEDMODEPATH \
+ "/SavedVideoModes"
+
+VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy,
+ uint32_t *pcBits,
+ uint32_t *piDisplay,
+ uint32_t *pdx, uint32_t *pdy,
+ bool *pfEnabled,
+ bool *pfChangeOrigin,
+ bool fAck);
VBGLR3DECL(bool) VbglR3HostLikesVideoMode(uint32_t cx, uint32_t cy, uint32_t cBits);
-VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t cy, uint32_t cBits);
-VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits);
+VBGLR3DECL(int) VbglR3VideoModeGetHighestSavedScreen(unsigned *pcScreen);
+VBGLR3DECL(int) VbglR3SaveVideoMode(unsigned cScreen, unsigned cx,
+ unsigned cy, unsigned cBits, unsigned x,
+ unsigned y, bool fEnabled);
+VBGLR3DECL(int) VbglR3RetrieveVideoMode(unsigned cScreen, unsigned *pcx,
+ unsigned *pcy, unsigned *pcBits,
+ unsigned *px, unsigned *py,
+ bool *pfEnabled);
/** @} */
/** @name VM Statistics
@@ -754,6 +769,16 @@ VBGLR3DECL(int) VbglR3HostChannelQuery(const char *pszName, uint32_t u32HGCMCli
void *pvParm, uint32_t cbParm, void *pvData, uint32_t cbData,
uint32_t *pu32SizeDataReturned);
+/** @name Mode hint storage
+ * @{ */
+VBGLR3DECL(int) VbglR3ReadVideoMode(unsigned cDisplay, unsigned *cx,
+ unsigned *cy, unsigned *cBPP, unsigned *x,
+ unsigned *y, unsigned *fEnabled);
+VBGLR3DECL(int) VbglR3WriteVideoMode(unsigned cDisplay, unsigned cx,
+ unsigned cy, unsigned cBPP, unsigned x,
+ unsigned y, unsigned fEnabled);
+/** @} */
+
#endif /* IN_RING3 */
/** @} */
diff --git a/include/VBox/VBoxNetCfg-win.h b/include/VBox/VBoxNetCfg-win.h
index 8dcaa0a..3bf0664 100644
--- a/include/VBox/VBoxNetCfg-win.h
+++ b/include/VBox/VBoxNetCfg-win.h
@@ -65,6 +65,8 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc, IN
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc, IN LPCWSTR const * apInfFullPaths, IN UINT cInfFullPaths);
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetAdpUninstall(IN INetCfg *pNc);
+
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
OUT GUID *pGuid, OUT BSTR *lppszName,
OUT BSTR *pErrMsg);
diff --git a/include/VBox/VBoxVideo.h b/include/VBox/VBoxVideo.h
index cc148c4..7a8b3c7 100644
--- a/include/VBox/VBoxVideo.h
+++ b/include/VBox/VBoxVideo.h
@@ -855,6 +855,12 @@ typedef struct VBVABUFFER
#define VBVA_CMDVBVA_SUBMIT 16 /* inform host about VBVA Command submission */
#define VBVA_CMDVBVA_FLUSH 17 /* inform host about VBVA Command submission */
#define VBVA_CMDVBVA_CTL 18 /* G->H DMA command */
+#define VBVA_QUERY_MODE_HINTS 19 /* Query most recent mode hints sent. */
+/** Report the guest virtual desktop position and size for mapping host and
+ * guest pointer positions. */
+#define VBVA_REPORT_INPUT_MAPPING 20
+/** Report the guest cursor position and query the host position. */
+#define VBVA_CURSOR_POSITION 21
/* host->guest commands */
#define VBVAHG_EVENT 1
@@ -910,6 +916,16 @@ typedef struct VBVAHOSTCMD
/* VBVACONF32::u32Index */
#define VBOX_VBVA_CONF32_MONITOR_COUNT 0
#define VBOX_VBVA_CONF32_HOST_HEAP_SIZE 1
+/** Returns VINF_SUCCESS if the host can report mode hints via VBVA.
+ * Set value to VERR_NOT_SUPPORTED before calling. */
+#define VBOX_VBVA_CONF32_MODE_HINT_REPORTING 2
+/** Returns VINF_SUCCESS if the host can receive guest cursor information via
+ * VBVA. Set value to VERR_NOT_SUPPORTED before calling. */
+#define VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING 3
+/** Returns the currently available host cursor capabilities. Available if
+ * VBVACONF32::VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING returns success.
+ * @see VMMDevReqMouseStatus::mouseFeatures. */
+#define VBOX_VBVA_CONF32_CURSOR_CAPABILITIES 4
typedef struct VBVACONF32
{
@@ -1076,6 +1092,10 @@ typedef struct VBVAMOUSEPOINTERSHAPE
#define VBVACAPS_COMPLETEGCMD_BY_IOREAD 0x00000001
/* the guest driver can handle video adapter IRQs */
#define VBVACAPS_IRQ 0x00000002
+/** The guest can read video mode hints sent via VBVA. */
+#define VBVACAPS_VIDEO_MODE_HINTS 0x00000004
+/** The guest can switch to a software cursor on demand. */
+#define VBVACAPS_DISABLE_CURSOR_INTEGRATION 0x00000008
typedef struct VBVACAPS
{
int32_t rc;
@@ -1109,6 +1129,62 @@ typedef struct VBVASCANLINEINFO
uint32_t u32ScanLine;
} VBVASCANLINEINFO;
+/** Query the most recent mode hints received from the host. */
+typedef struct VBVAQUERYMODEHINTS
+{
+ /** The maximum number of screens to return hints for. */
+ uint16_t cHintsQueried;
+ /** The size of the mode hint structures directly following this one. */
+ uint16_t cbHintStructureGuest;
+ /** The return code for the operation. Initialise to VERR_NOT_SUPPORTED. */
+ int32_t rc;
+} VBVAQUERYMODEHINTS;
+
+/** Structure in which a mode hint is returned. The guest allocates an array
+ * of these immediately after the VBVAQUERYMODEHINTS structure. To accomodate
+ * future extensions, the VBVAQUERYMODEHINTS structure specifies the size of
+ * the VBVAMODEHINT structures allocated by the guest, and the host only fills
+ * out structure elements which fit into that size. The host should fill any
+ * unused members (e.g. dx, dy) or structure space on the end with ~0. The
+ * whole structure can legally be set to ~0 to skip a screen. */
+typedef struct VBVAMODEHINT
+{
+ uint32_t magic;
+ uint32_t cx;
+ uint32_t cy;
+ uint32_t cBPP; /* Which has never been used... */
+ uint32_t cDisplay;
+ uint32_t dx; /**< X offset into the virtual frame-buffer. */
+ uint32_t dy; /**< Y offset into the virtual frame-buffer. */
+ uint32_t fEnabled; /* Not fFlags. Add new members for new flags. */
+} VBVAMODEHINT;
+
+#define VBVAMODEHINT_MAGIC UINT32_C(0x0801add9)
+
+/** Report the rectangle relative to which absolute pointer events should be
+ * expressed. This information remains valid until the next VBVA resize event
+ * for any screen, at which time it is reset to the bounding rectangle of all
+ * virtual screens.
+ * @see VBVA_REPORT_INPUT_MAPPING. */
+typedef struct VBVAREPORTINPUTMAPPING
+{
+ int32_t x; /**< Upper left X co-ordinate relative to the first screen. */
+ int32_t y; /**< Upper left Y co-ordinate relative to the first screen. */
+ uint32_t cx; /**< Rectangle width. */
+ uint32_t cy; /**< Rectangle height. */
+} VBVAREPORTINPUTMAPPING;
+
+/** Report the guest cursor position and query the host one. The host may wish
+ * to use the guest information to re-position its own cursor (though this is
+ * currently unlikely).
+ * @see VBVA_CURSOR_POSITION */
+typedef struct VBVACURSORPOSITION
+{
+ uint32_t fReportPosition; /**< Are we reporting a position? */
+ uint32_t x; /**< Guest cursor X position */
+ uint32_t y; /**< Guest cursor Y position */
+} VBVACURSORPOSITION;
+
#pragma pack()
typedef uint64_t VBOXVIDEOOFFSET;
diff --git a/include/VBox/VBoxVideoGuest.h b/include/VBox/VBoxVideoGuest.h
index e88afe6..3939519 100644
--- a/include/VBox/VBoxVideoGuest.h
+++ b/include/VBox/VBoxVideoGuest.h
@@ -31,6 +31,7 @@
#include <VBox/HGSMI/HGSMI.h>
#include <VBox/HGSMI/HGSMIChSetup.h>
+#include <VBox/VBoxVideo.h>
#ifdef VBOX_XPDM_MINIPORT
RT_C_DECLS_BEGIN
@@ -221,6 +222,8 @@ RTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
uint32_t *poffGuestHeapMemory,
uint32_t *pcbGuestHeapMemory,
uint32_t *poffHostFlags);
+RTDECL(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t fCaps);
/** @todo we should provide a cleanup function too as part of the API */
RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
void *pvGuestHeapMemory,
@@ -244,7 +247,7 @@ RTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint32_t cbHostArea);
RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint32_t u32Index, uint32_t *pulValue);
-RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+RTDECL(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint32_t fFlags,
uint32_t cHotX,
uint32_t cHotY,
@@ -252,6 +255,8 @@ RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint32_t cHeight,
uint8_t *pPixels,
uint32_t cbLength);
+RTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
+ uint32_t *pxHost, uint32_t *pyHost);
/** @} */
@@ -324,6 +329,10 @@ RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint32_t cHeight,
uint16_t cBPP,
uint16_t fFlags);
+RTDECL(int) VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t cOriginX, int32_t cOriginY,
+ uint32_t cWidth, uint32_t cHeight);
+RTDECL(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ unsigned cScreens, VBVAMODEHINT *paHints);
/** @} */
diff --git a/include/VBox/VMMDev.h b/include/VBox/VMMDev.h
index fb85062..b5576a7 100644
--- a/include/VBox/VMMDev.h
+++ b/include/VBox/VMMDev.h
@@ -508,6 +508,8 @@ AssertCompileSize(VMMDevReqGuestCapabilities2, 24+8);
* request sets this automatically, but VMMDevReq_SetGuestCapabilities does
* not. */
#define VMMDEV_GUEST_SUPPORTS_GRAPHICS RT_BIT_32(2)
+/** The mask of valid events, for sanity checking. */
+#define VMMDEV_GUEST_CAPABILITIES_MASK UINT32_C(0x00000007)
/** @} */
diff --git a/include/VBox/VMMDevTesting.h b/include/VBox/VMMDevTesting.h
index 7bc4c7a..d78257a 100644
--- a/include/VBox/VMMDevTesting.h
+++ b/include/VBox/VMMDevTesting.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010-2012 Oracle Corporation
+ * Copyright (C) 2010-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -36,10 +36,10 @@
#define VMMDEV_TESTING_MMIO_BASE UINT32_C(0x00101000)
/** The size of the MMIO range used for testing. */
#define VMMDEV_TESTING_MMIO_SIZE UINT32_C(0x00001000)
-/** The NOP MMIO register - 124 RW. */
+/** The NOP MMIO register - 1248 RW. */
#define VMMDEV_TESTING_MMIO_NOP (VMMDEV_TESTING_MMIO_BASE + 0x000)
-/** The XXX MMIO register - 124 RW. */
-#define VMMDEV_TESTING_MMIO_TODO (VMMDEV_TESTING_MMIO_BASE + 0x004)
+/** The go-to-ring-3-NOP MMIO register - 1248 RW. */
+#define VMMDEV_TESTING_MMIO_NOP_R3 (VMMDEV_TESTING_MMIO_BASE + 0x008)
/** The real mode selector to use.
* @remarks Requires that the A20 gate is enabled. */
#define VMMDEV_TESTING_MMIO_RM_SEL 0xffff
@@ -60,6 +60,8 @@
#define VMMDEV_TESTING_IOPORT_CMD (VMMDEV_TESTING_IOPORT_BASE + 3)
/** Data register which use depends on the current command - 1s, 4 WO. */
#define VMMDEV_TESTING_IOPORT_DATA (VMMDEV_TESTING_IOPORT_BASE + 4)
+/** The go-to-ring-3-NOP I/O port - 1,2,4 RW. */
+#define VMMDEV_TESTING_IOPORT_NOP_R3 (VMMDEV_TESTING_IOPORT_BASE + 5)
/** @name Commands.
* @{ */
diff --git a/include/VBox/VMMDevTesting.mac b/include/VBox/VMMDevTesting.mac
index 105f7be..b9bb1f5 100644
--- a/include/VBox/VMMDevTesting.mac
+++ b/include/VBox/VMMDevTesting.mac
@@ -3,7 +3,7 @@
%define VMMDEV_TESTING_MMIO_BASE 0x00101000
%define VMMDEV_TESTING_MMIO_SIZE 0x00001000
%define VMMDEV_TESTING_MMIO_NOP (VMMDEV_TESTING_MMIO_BASE + 0x000)
-%define VMMDEV_TESTING_MMIO_TODO (VMMDEV_TESTING_MMIO_BASE + 0x004)
+%define VMMDEV_TESTING_MMIO_NOP_R3 (VMMDEV_TESTING_MMIO_BASE + 0x008)
%define VMMDEV_TESTING_MMIO_RM_SEL 0xffff
%define VMMDEV_TESTING_MMIO_RM_OFF(val) ((val) - 0xffff0)
%define VMMDEV_TESTING_IOPORT_BASE 0x0510
@@ -13,6 +13,7 @@
%define VMMDEV_TESTING_IOPORT_TS_HIGH (VMMDEV_TESTING_IOPORT_BASE + 2)
%define VMMDEV_TESTING_IOPORT_CMD (VMMDEV_TESTING_IOPORT_BASE + 3)
%define VMMDEV_TESTING_IOPORT_DATA (VMMDEV_TESTING_IOPORT_BASE + 4)
+%define VMMDEV_TESTING_IOPORT_NOP_R3 (VMMDEV_TESTING_IOPORT_BASE + 5)
%define VMMDEV_TESTING_CMD_INIT 0xcab1e000
%define VMMDEV_TESTING_CMD_TERM 0xcab1e001
%define VMMDEV_TESTING_CMD_SUB_NEW 0xcab1e002
diff --git a/include/VBox/apic.h b/include/VBox/apic.h
index 0b22f11..815c622 100644
--- a/include/VBox/apic.h
+++ b/include/VBox/apic.h
@@ -40,6 +40,7 @@
#define APIC_REG_LVT_ERR 0x0370
#define APIC_REG_LVT_PC 0x0340
#define APIC_REG_LVT_THMR 0x0330
+#define APIC_REG_LVT_CMCI 0x02F0
#define APIC_REG_LVT_MODE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
#define APIC_REG_LVT_MODE_FIXED 0
#define APIC_REG_LVT_MODE_NMI RT_BIT(10)
diff --git a/include/VBox/apic.mac b/include/VBox/apic.mac
index 9f6bea4..c8b4408 100644
--- a/include/VBox/apic.mac
+++ b/include/VBox/apic.mac
@@ -8,6 +8,7 @@
%define APIC_REG_LVT_ERR 0x0370
%define APIC_REG_LVT_PC 0x0340
%define APIC_REG_LVT_THMR 0x0330
+%define APIC_REG_LVT_CMCI 0x02F0
%define APIC_REG_LVT_MODE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10))
%define APIC_REG_LVT_MODE_FIXED 0
%define APIC_REG_LVT_MODE_NMI RT_BIT(10)
diff --git a/include/VBox/err.mac b/include/VBox/err.mac
index 0d59e83..0b4d237 100644
--- a/include/VBox/err.mac
+++ b/include/VBox/err.mac
@@ -646,6 +646,7 @@
%define VERR_SUPDRV_APIPORT_OPEN_ERROR (-3739)
%define VERR_SUPDRV_SESSION_PROCESS_ENUM_ERROR (-3740)
%define VERR_SUPDRV_CSRSS_NOT_FOUND (-3741)
+%define VERR_SUPDRV_APIPORT_OPEN_ERROR_TYPE (-3742)
%define VERR_SUPLIB_PATH_NOT_ABSOLUTE (-3750)
%define VERR_SUPLIB_PATH_NOT_CLEAN (-3751)
%define VERR_SUPLIB_PATH_TOO_LONG (-3752)
@@ -927,8 +928,17 @@
%define VERR_SUP_VP_UNKOWN_MEM_TYPE (-5666)
%define VERR_SUP_VP_NOT_OWNED_BY_TRUSTED_INSTALLER (-5667)
%define VERR_SUP_VP_IMAGE_TOO_BIG (-5668)
+%define VERR_SUP_VP_STUB_NOT_FOUND (-5669)
+%define VERR_SUP_VP_STUB_OPEN_ERROR (-5670)
+%define VERR_SUP_VP_STUB_THREAD_NOT_FOUND (-5671)
+%define VERR_SUP_VP_STUB_THREAD_OPEN_ERROR (-5672)
+%define VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED (-5673)
+%define VERR_SUP_VP_FILE_MODE_ERROR (-5674)
+%define VERR_SUP_VP_CREATE_READ_EVT_SEM_FAILED (-5675)
%define VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL (-6000)
%define VERR_EXTPACK_VBOX_VERSION_MISMATCH (-6001)
%define VERR_GSTCTL_GUEST_ERROR (-6200)
%define VWRN_GSTCTL_OBJECTSTATE_CHANGED 6220
+%define VERR_MAIN_CONFIG_CONSTRUCTOR_COM_ERROR (-6400)
+%define VERR_MAIN_CONFIG_CONSTRUCTOR_IPE (-6401)
%include "iprt/err.mac"
diff --git a/include/VBox/shflsvc.h b/include/VBox/shflsvc.h
index dafcac7..ac65a2e 100644
--- a/include/VBox/shflsvc.h
+++ b/include/VBox/shflsvc.h
@@ -176,21 +176,21 @@ typedef const SHFLSTRING *PCSHFLSTRING;
/** Calculate size of the string. */
DECLINLINE(uint32_t) ShflStringSizeOfBuffer(PCSHFLSTRING pString)
{
- return pString? sizeof (SHFLSTRING) - sizeof (pString->String) + pString->u16Size: 0;
+ return pString ? sizeof(SHFLSTRING) - sizeof(pString->String) + pString->u16Size : 0;
}
DECLINLINE(uint32_t) ShflStringLength(PCSHFLSTRING pString)
{
- return pString? pString->u16Length: 0;
+ return pString ? pString->u16Length : 0;
}
DECLINLINE(PSHFLSTRING) ShflStringInitBuffer(void *pvBuffer, uint32_t u32Size)
{
PSHFLSTRING pString = NULL;
+ const uint32_t u32HeaderSize = sizeof(SHFLSTRING);
- uint32_t u32HeaderSize = sizeof (SHFLSTRING) - sizeof (pString->String);
-
- /* Check that the buffer size is big enough to hold a zero sized string
+ /*
+ * Check that the buffer size is big enough to hold a zero sized string
* and is not too big to fit into 16 bit variables.
*/
if (u32Size >= u32HeaderSize && u32Size - u32HeaderSize <= 0xFFFF)
diff --git a/include/VBox/sup.h b/include/VBox/sup.h
index 5c82afa..9e104a3 100644
--- a/include/VBox/sup.h
+++ b/include/VBox/sup.h
@@ -1083,6 +1083,18 @@ SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszMo
SUPR3DECL(int) SUPR3FreeModule(void *pvImageBase);
/**
+ * Lock down the module loader interface.
+ *
+ * This will lock down the module loader interface. No new modules can be
+ * loaded and all loaded modules can no longer be freed.
+ *
+ * @returns VBox status code.
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3LockDownLoader(PRTERRINFO pErrInfo);
+
+/**
* Get the address of a symbol in a ring-0 module.
*
* @returns VBox status code.
diff --git a/include/VBox/vd-ifs.h b/include/VBox/vd-ifs.h
index 6d80e92..b37ccb1 100644
--- a/include/VBox/vd-ifs.h
+++ b/include/VBox/vd-ifs.h
@@ -1055,8 +1055,13 @@ typedef struct VDINTERFACETCPNET
* @param Sock Socket descriptor.
* @param pszAddress The address to connect to.
* @param uPort The port to connect to.
+ * @param cMillies Number of milliseconds to wait for the connect attempt to complete.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ * Use RT_SOCKETCONNECT_DEFAULT_WAIT to wait for the default time
+ * configured on the running system.
*/
- DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort));
+ DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort,
+ RTMSINTERVAL cMillies));
/**
* Close a TCP connection.
diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h
index d3ca4c0..04c722f 100644
--- a/include/VBox/vmm/cpum.h
+++ b/include/VBox/vmm/cpum.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/include/VBox/vmm/hm_vmx.h b/include/VBox/vmm/hm_vmx.h
index 7deb357..d195541 100644
--- a/include/VBox/vmm/hm_vmx.h
+++ b/include/VBox/vmm/hm_vmx.h
@@ -1729,12 +1729,12 @@ typedef VMXMSRS *PVMXMSRS;
/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */
#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) ((a) & 0xfff)
/** 12-15: Access type. */
-#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a) & 0xf000)
+#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) (((a) & 0xf000) >> 12)
/* Rest reserved. */
/** @} */
-/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types
+/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE return values
* @{
*/
/** Linear read access. */
diff --git a/include/VBox/vmm/pdmifs.h b/include/VBox/vmm/pdmifs.h
index e8d3aba..bd54da8 100644
--- a/include/VBox/vmm/pdmifs.h
+++ b/include/VBox/vmm/pdmifs.h
@@ -630,12 +630,53 @@ typedef struct PDMIDISPLAYPORT
*/
DECLR3CALLBACKMEMBER(void, pfnSetViewPort,(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy));
#endif
+
+ /**
+ * Send a video mode hint to the VGA device.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param cx The X resolution.
+ * @param cy The Y resolution.
+ * @param cBPP The bit count.
+ * @param iDisplay The screen number.
+ * @param dx X offset into the virtual framebuffer or ~0.
+ * @param dy Y offset into the virtual framebuffer or ~0.
+ * @param fEnabled Is this screen currently enabled?
+ * @param fNotifyGuest Should the device send the guest an IRQ?
+ * Set for the last hint of a series.
+ * @thread Schedules on the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSendModeHint,
+ (PPDMIDISPLAYPORT pInterface, uint32_t cx, uint32_t cy,
+ uint32_t cBPP, uint32_t iDisplay, uint32_t dx,
+ uint32_t dy, uint32_t fEnabled, uint32_t fNotifyGuest));
+
+ /**
+ * Send the guest a notification about host cursor capabilities changes.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fCapabilitiesAdded New supported capabilities.
+ * @param fCapabilitiesRemoved No longer supported capabilities.
+ * @thread Any.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnReportHostCursorCapabilities, (PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
+ uint32_t fCapabilitiesRemoved));
+
+ /**
+ * Tell the graphics device about the host cursor position.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param x X offset into the cursor range.
+ * @param y Y offset into the cursor range.
+ * @thread Any.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnReportHostCursorPosition, (PPDMIDISPLAYPORT pInterface, uint32_t x, uint32_t y));
} PDMIDISPLAYPORT;
/** PDMIDISPLAYPORT interface ID. */
#ifdef VBOX_WITH_VMSVGA
-#define PDMIDISPLAYPORT_IID "f7ed5b9a-3940-4862-9310-1de7e3d118a4"
+#define PDMIDISPLAYPORT_IID "e8da6d7e-8490-11e4-91d8-ab609a010f13"
#else
-#define PDMIDISPLAYPORT_IID "22d3d93d-3407-487a-8308-85367eae00bb"
+#define PDMIDISPLAYPORT_IID "db067c60-8490-11e4-8424-032afeb83818"
#endif
@@ -798,7 +839,7 @@ typedef struct PDMIDISPLAYCONNECTOR
* @param uScreenId The screen updates are for.
* @param fRenderThreadMode if true - the graphics device has a separate thread that does all rendering.
* This means that:
- * 1. all pfnVBVAXxx callbacks (including the current pfnVBVAEnable call), except displayVBVAMousePointerShape
+ * 1. most pfnVBVAXxx callbacks (see the individual documentation for each one)
* will be called in the context of the render thread rather than the emulation thread
* 2. PDMIDISPLAYCONNECTOR implementor (i.e. DisplayImpl) must NOT notify crogl backend
* about vbva-originated events (e.g. resize), because crogl is working in CrCmd mode,
@@ -894,6 +935,15 @@ typedef struct PDMIDISPLAYCONNECTOR
uint32_t cx, uint32_t cy,
const void *pvShape));
+ /**
+ * The guest capabilities were updated.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fCapabilities The new capability flag state.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVAGuestCapabilityUpdate,(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities));
+
/** Read-only attributes.
* For preformance reasons some readonly attributes are kept in the interface.
* We trust the interface users to respect the readonlyness of these.
@@ -910,9 +960,21 @@ typedef struct PDMIDISPLAYCONNECTOR
/** The display height. */
uint32_t cy;
/** @} */
+
+ /**
+ * The guest display input mapping rectangle was updated.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param xOrigin Upper left X co-ordinate relative to the first screen.
+ * @param yOrigin Upper left Y co-ordinate relative to the first screen.
+ * @param cx Rectangle width.
+ * @param cy Rectangle height.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVAInputMappingUpdate,(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy));
} PDMIDISPLAYCONNECTOR;
/** PDMIDISPLAYCONNECTOR interface ID. */
-#define PDMIDISPLAYCONNECTOR_IID "906d0c25-091f-497e-908c-1d70cb7e6114"
+#define PDMIDISPLAYCONNECTOR_IID "e883a720-85fb-11e4-a307-0b06689c9661"
/** Pointer to a block port interface. */
@@ -1307,6 +1369,26 @@ typedef struct PDMISECKEY
/** PDMISECKEY interface ID. */
#define PDMISECKEY_IID "a7336c4a-2ca0-489d-ad2d-f740f215a1e6"
+/** Pointer to a secret key helper interface. */
+typedef struct PDMISECKEYHLP *PPDMISECKEYHLP;
+
+/**
+ * Secret key helper interface for non critical functionality.
+ */
+typedef struct PDMISECKEYHLP
+{
+ /**
+ * Notifies the interface provider that a key couldn't be retrieved from the key store.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnKeyMissingNotify, (PPDMISECKEYHLP pInterface));
+
+} PDMISECKEYHLP;
+/** PDMISECKEY interface ID. */
+#define PDMISECKEYHLP_IID "7be96168-4156-40ac-86d2-3073bf8b318e"
+
/**
* Media geometry structure.
*/
@@ -1426,9 +1508,11 @@ typedef struct PDMIMEDIA
* @param pIfSecKey The secret key interface to use.
* Use NULL to clear the currently set interface and clear all secret
* keys from the user.
+ * @param pIfSecKeyHlp The secret key helper interface to use.
* @thread Any thread.
*/
- DECLR3CALLBACKMEMBER(int, pfnSetSecKeyIf,(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey));
+ DECLR3CALLBACKMEMBER(int, pfnSetSecKeyIf,(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey,
+ PPDMISECKEYHLP pIfSecKeyHlp));
/**
* Get the media size in bytes.
@@ -1556,7 +1640,7 @@ typedef struct PDMIMEDIA
} PDMIMEDIA;
/** PDMIMEDIA interface ID. */
-#define PDMIMEDIA_IID "b4acf420-c9e3-4333-9ed5-e86f6b2d5f1a"
+#define PDMIMEDIA_IID "d8997ad8-4dda-4352-aa99-99bf87d54102"
/** Pointer to a block BIOS interface. */
@@ -2192,9 +2276,18 @@ typedef struct PDMIACPIPORT
* @param pfLocked Is set to true if the CPU is still locked by the guest, false otherwise.
*/
DECLR3CALLBACKMEMBER(int, pfnGetCpuStatus,(PPDMIACPIPORT pInterface, unsigned uCpu, bool *pfLocked));
+
+ /**
+ * Send an ACPI monitor hot-plug event.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing
+ * the called function pointer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMonitorHotPlugEvent,(PPDMIACPIPORT pInterface));
} PDMIACPIPORT;
/** PDMIACPIPORT interface ID. */
-#define PDMIACPIPORT_IID "30d3dc4c-6a73-40c8-80e9-34309deacbb3"
+#define PDMIACPIPORT_IID "d64233e3-7bb0-4ef1-a313-2bcfafbe6260"
/** Pointer to an ACPI connector interface. */
diff --git a/include/VBox/vmm/pdmnetifs.h b/include/VBox/vmm/pdmnetifs.h
index e928044..b87ce6c 100644
--- a/include/VBox/vmm/pdmnetifs.h
+++ b/include/VBox/vmm/pdmnetifs.h
@@ -425,10 +425,16 @@ typedef struct PDMINETWORKNATCONFIG
DECLR3CALLBACKMEMBER(int, pfnRedirectRuleCommand ,(PPDMINETWORKNATCONFIG pInterface, bool fRemove,
bool fUdp, const char *pHostIp, uint16_t u16HostPort,
const char *pGuestIp, uint16_t u16GuestPort));
+ /**
+ * Inform NAT about host DNS settings change.
+ *
+ * IHostNameResolutionConfigurationChangeEvent.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyDnsChanged, (PPDMINETWORKNATCONFIG pInterface));
} PDMINETWORKNATCONFIG;
/** PDMINETWORKNATCONFIG interface ID. */
-#define PDMINETWORKNATCONFIG_IID "0f001d62-4d2f-11df-93b3-2fd0b3a36a6b"
+#define PDMINETWORKNATCONFIG_IID "dc961028-3523-4b52-a93b-e38168a4a9fa"
/** @} */
RT_C_DECLS_END
diff --git a/include/VBox/vmm/tm.h b/include/VBox/vmm/tm.h
index 8f857a4..8dc5931 100644
--- a/include/VBox/vmm/tm.h
+++ b/include/VBox/vmm/tm.h
@@ -117,7 +117,7 @@ VMM_INT_DECL(uint64_t) TMVirtualSyncGet(PVM pVM);
VMM_INT_DECL(uint64_t) TMVirtualSyncGetNoCheck(PVM pVM);
VMM_INT_DECL(uint64_t) TMVirtualSyncGetEx(PVM pVM, bool fCheckTimers);
VMM_INT_DECL(uint64_t) TMVirtualSyncGetWithDeadlineNoCheck(PVM pVM, uint64_t *pcNsToDeadline);
-VMM_INT_DECL(uint64_t) TMVirtualSyncGetNsToDeadline(PVM pVM);
+VMMDECL(uint64_t) TMVirtualSyncGetNsToDeadline(PVM pVM);
VMM_INT_DECL(uint64_t) TMVirtualToNano(PVM pVM, uint64_t u64VirtualTicks);
VMM_INT_DECL(uint64_t) TMVirtualToMicro(PVM pVM, uint64_t u64VirtualTicks);
VMM_INT_DECL(uint64_t) TMVirtualToMilli(PVM pVM, uint64_t u64VirtualTicks);
diff --git a/include/VBox/vmm/vm.h b/include/VBox/vmm/vm.h
index aff74f7..3b6c9c5 100644
--- a/include/VBox/vmm/vm.h
+++ b/include/VBox/vmm/vm.h
@@ -684,10 +684,10 @@ typedef struct VMCPU
# define VMCPU_ASSERT_EMT_RETURN(pVCpu, rc) AssertReturn(VMCPU_IS_EMT(pVCpu), (rc))
#else
# define VMCPU_ASSERT_EMT_RETURN(pVCpu, rc) \
- AssertMsg(VMCPU_IS_EMT(pVCpu), \
- ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%#x\n", \
- RTThreadNativeSelf(), (pVCpu)->hNativeThread, (pVCpu)->idCpu), \
- (rc))
+ AssertMsgReturn(VMCPU_IS_EMT(pVCpu), \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%#x\n", \
+ RTThreadNativeSelf(), (pVCpu)->hNativeThread, (pVCpu)->idCpu), \
+ (rc))
#endif
/** @def VMCPU_ASSERT_EMT_OR_GURU
diff --git a/include/VBox/vmm/vmapi.h b/include/VBox/vmm/vmapi.h
index d5a8dd7..7f5d1ba 100644
--- a/include/VBox/vmm/vmapi.h
+++ b/include/VBox/vmm/vmapi.h
@@ -471,8 +471,10 @@ VMMR3_INT_DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPrior
/** @} */
VMMR3_INT_DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags);
VMMR3_INT_DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags);
+VMMR3DECL(int) VMR3NotifyCpuDeviceReady(PVM pVM, VMCPUID idCpu);
VMMR3_INT_DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts);
VMMR3_INT_DECL(int) VMR3WaitU(PUVMCPU pUVMCpu);
+VMMR3DECL(int) VMR3WaitForDeviceReady(PVM pVM, VMCPUID idCpu);
VMMR3_INT_DECL(int) VMR3AsyncPdmNotificationWaitU(PUVMCPU pUVCpu);
VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM);
VMMR3_INT_DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM);
diff --git a/include/VBox/vmm/vmcpuset.h b/include/VBox/vmm/vmcpuset.h
index 8d92dbb..6a85daf 100644
--- a/include/VBox/vmm/vmcpuset.h
+++ b/include/VBox/vmm/vmcpuset.h
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -42,6 +42,10 @@
#define VMCPUSET_ADD(pSet, idCpu) ASMBitSet( &(pSet)->au32Bitmap[0], (idCpu))
/** Deletes a CPU from the set. */
#define VMCPUSET_DEL(pSet, idCpu) ASMBitClear(&(pSet)->au32Bitmap[0], (idCpu))
+/** Adds a CPU to the set, atomically. */
+#define VMCPUSET_ATOMIC_ADD(pSet, idCpu) ASMAtomicBitSet( &(pSet)->au32Bitmap[0], (idCpu))
+/** Deletes a CPU from the set, atomically. */
+#define VMCPUSET_ATOMIC_DEL(pSet, idCpu) ASMAtomicBitClear(&(pSet)->au32Bitmap[0], (idCpu))
/** Empties the set. */
#define VMCPUSET_EMPTY(pSet) memset(&(pSet)->au32Bitmap[0], '\0', sizeof((pSet)->au32Bitmap))
/** Fills the set. */
diff --git a/include/iprt/crypto/x509.h b/include/iprt/crypto/x509.h
index ac26788..eb1957d 100644
--- a/include/iprt/crypto/x509.h
+++ b/include/iprt/crypto/x509.h
@@ -196,6 +196,24 @@ RTDECL(bool) RTCrX509Name_MatchWithString(PCRTCRX509NAME pThis, const char *pszS
RTDECL(int) RTCrX509Name_FormatAsString(PCRTCRX509NAME pThis, char *pszBuf, size_t cbBuf, size_t *pcbActual);
+/**
+ * One X.509 OtherName (IPRT representation).
+ */
+typedef struct RTCRX509OTHERNAME
+{
+ /** The sequence core. */
+ RTASN1SEQUENCECORE SeqCore;
+ /** The name type identifier. */
+ RTASN1OBJID TypeId;
+ /** The name value (explicit tag 0). */
+ RTASN1DYNTYPE Value;
+} RTCRX509OTHERNAME;
+/** Pointer to a X.509 OtherName (IPRT representation). */
+typedef RTCRX509OTHERNAME *PRTCRX509OTHERNAME;
+/** Pointer to a const X.509 OtherName (IPRT representation). */
+typedef RTCRX509OTHERNAME const *PCRTCRX509OTHERNAME;
+RTASN1TYPE_STANDARD_PROTOTYPES(RTCRX509OTHERNAME, RTDECL, RTCrX509OtherName, SeqCore.Asn1Core);
+
typedef enum RTCRX509GENERALNAMECHOICE
{
@@ -230,14 +248,8 @@ typedef struct RTCRX509GENERALNAME
/** The value union. */
union
{
- /** Tag 0: Other. */
- struct
- {
- /** Context tag 0. */
- RTASN1CONTEXTTAG0 CtxTag0;
- /** User defined. */
- RTASN1DYNTYPE Other;
- } *pT0;
+ /** Tag 0: Other Name. */
+ PRTCRX509OTHERNAME pT0_OtherName;
/** Tag 1: RFC-822 Name. */
PRTASN1STRING pT1_Rfc822;
/** Tag 2: DNS name. */
diff --git a/include/iprt/initterm.h b/include/iprt/initterm.h
index 1853fbb..47d1823 100644
--- a/include/iprt/initterm.h
+++ b/include/iprt/initterm.h
@@ -108,6 +108,13 @@ RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char ***
RTR3DECL(void) RTR3Term(void);
/**
+ * Is IPRT succesfully initialized?
+ *
+ * @returns true/false.
+ */
+RTR3DECL(bool) RTR3InitIsInitialized(void);
+
+/**
* Are we running in unobtrusive mode?
* @returns true/false.
*/
diff --git a/include/iprt/ldr.h b/include/iprt/ldr.h
index c6582b9..af94813 100644
--- a/include/iprt/ldr.h
+++ b/include/iprt/ldr.h
@@ -359,11 +359,15 @@ typedef RTLDRARCH *PRTLDRARCH;
* @{ */
/** Open for debugging or introspection reasons.
* This will skip a few of the stricter validations when loading images. */
-#define RTLDR_O_FOR_DEBUG RT_BIT_32(0)
+#define RTLDR_O_FOR_DEBUG RT_BIT_32(0)
/** Open for signature validation. */
-#define RTLDR_O_FOR_VALIDATION RT_BIT_32(1)
+#define RTLDR_O_FOR_VALIDATION RT_BIT_32(1)
+/** The arch specification is just a guideline for FAT binaries. */
+#define RTLDR_O_WHATEVER_ARCH RT_BIT_32(2)
+/** Ignore the architecture specification if there is no code. */
+#define RTLDR_O_IGNORE_ARCH_IF_NO_CODE RT_BIT_32(3)
/** Mask of valid flags. */
-#define RTLDR_O_VALID_MASK UINT32_C(0x00000003)
+#define RTLDR_O_VALID_MASK UINT32_C(0x0000000f)
/** @} */
/**
diff --git a/include/iprt/list.h b/include/iprt/list.h
index 3233cd1..5ad9d68 100644
--- a/include/iprt/list.h
+++ b/include/iprt/list.h
@@ -53,6 +53,8 @@ typedef struct RTLISTNODE
} RTLISTNODE;
/** Pointer to a list node. */
typedef RTLISTNODE *PRTLISTNODE;
+/** Pointer to a const list node. */
+typedef RTLISTNODE const *PCRTLISTNODE;
/** Pointer to a list node pointer. */
typedef PRTLISTNODE *PPRTLISTNODE;
@@ -64,6 +66,8 @@ typedef PRTLISTNODE *PPRTLISTNODE;
typedef RTLISTNODE RTLISTANCHOR;
/** Pointer to a doubly linked list anchor. */
typedef RTLISTANCHOR *PRTLISTANCHOR;
+/** Pointer to a const doubly linked list anchor. */
+typedef RTLISTANCHOR const *PCRTLISTANCHOR;
/**
diff --git a/include/iprt/log.h b/include/iprt/log.h
index f0ce1c1..059a7c7 100644
--- a/include/iprt/log.h
+++ b/include/iprt/log.h
@@ -939,9 +939,13 @@ RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, c
#endif
-/** @def LogIt
+/** @def LogRelIt
* Write to specific logger if group enabled.
*/
+/** @def LogRelMaxIt
+ * Write to specific logger if group enabled and at less than a_cMax messages
+ * have hit the log. Uses a static variable to count.
+ */
#ifdef RTLOG_REL_ENABLED
# if defined(LOG_USE_C99)
# define _LogRelRemoveParentheseis(...) __VA_ARGS__
@@ -955,6 +959,24 @@ RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, c
_LogIt(LOG_INSTANCE, a_fFlags, a_iGroup, __VA_ARGS__); \
} while (0)
# define LogRelIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) _LogRelIt(a_pvInst, a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
+# define _LogRelMaxIt(a_cMax, a_pvInst, a_fFlags, a_iGroup, ...) \
+ do \
+ { \
+ PRTLOGGER LogRelIt_pLogger = (PRTLOGGER)(a_pvInst) ? (PRTLOGGER)(a_pvInst) : RTLogRelDefaultInstance(); \
+ if ( LogRelIt_pLogger \
+ && !(LogRelIt_pLogger->fFlags & RTLOGFLAGS_DISABLED)) \
+ { \
+ static uint32_t s_LogRelMaxIt_cLogged = 0; \
+ if (s_LogRelMaxIt_cLogged < (a_cMax)) \
+ { \
+ s_LogRelMaxIt_cLogged++; \
+ RTLogLoggerEx(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
+ } \
+ } \
+ _LogIt(LOG_INSTANCE, a_fFlags, a_iGroup, __VA_ARGS__); \
+ } while (0)
+# define LogRelMaxIt(a_cMax, a_pvInst, a_fFlags, a_iGroup, fmtargs) \
+ _LogRelMaxIt(a_cMax, a_pvInst, a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
# else
# define LogRelIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) \
do \
@@ -969,12 +991,34 @@ RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, c
} \
LogIt(LOG_INSTANCE, a_fFlags, a_iGroup, fmtargs); \
} while (0)
+# define LogRelMaxIt(a_cMax, a_pvInst, a_fFlags, a_iGroup, fmtargs) \
+ do \
+ { \
+ PRTLOGGER LogRelIt_pLogger = (PRTLOGGER)(a_pvInst) ? (PRTLOGGER)(a_pvInst) : RTLogRelDefaultInstance(); \
+ if ( LogRelIt_pLogger \
+ && !(LogRelIt_pLogger->fFlags & RTLOGFLAGS_DISABLED)) \
+ { \
+ unsigned LogIt_fFlags = LogRelIt_pLogger->afGroups[(unsigned)(a_iGroup) < LogRelIt_pLogger->cGroups ? (unsigned)(a_iGroup) : 0]; \
+ if ((LogIt_fFlags & ((a_fFlags) | RTLOGGRPFLAGS_ENABLED)) == ((a_fFlags) | RTLOGGRPFLAGS_ENABLED)) \
+ { \
+ static uint32_t s_LogRelMaxIt_cLogged = 0; \
+ if (s_LogRelMaxIt_cLogged < (a_cMax)) \
+ { \
+ s_LogRelMaxIt_cLogged++; \
+ LogRelIt_pLogger->pfnLogger fmtargs; \
+ } \
+ } \
+ } \
+ LogIt(LOG_INSTANCE, a_fFlags, a_iGroup, fmtargs); \
+ } while (0)
# endif
#else /* !RTLOG_REL_ENABLED */
# define LogRelIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) do { } while (0)
+# define LogRelMaxIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) do { } while (0)
# if defined(LOG_USE_C99)
# define _LogRelRemoveParentheseis(...) __VA_ARGS__
# define _LogRelIt(a_pvInst, a_fFlags, a_iGroup, ...) do { } while (0)
+# define _LogRelMaxIt(a_cMax, a_pvInst, a_fFlags, a_iGroup, ...) do { } while (0)
# endif
#endif /* !RTLOG_REL_ENABLED */
@@ -1102,6 +1146,91 @@ RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, c
#define LogRelNoName(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_NONAME, LOG_GROUP, a)
+/** @def LogRelMax
+ * Level 1 logging.
+ */
+#define LogRelMax(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def LogRelMax2
+ * Level 2 logging.
+ */
+#define LogRelMax2(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
+
+/** @def LogRelMax3
+ * Level 3 logging.
+ */
+#define LogRelMax3(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
+
+/** @def LogRelMax4
+ * Level 4 logging.
+ */
+#define LogRelMax4(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
+
+/** @def LogRelMax5
+ * Level 5 logging.
+ */
+#define LogRelMax5(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
+
+/** @def LogRelMax6
+ * Level 6 logging.
+ */
+#define LogRelMax6(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
+
+/** @def LogRelFlow
+ * Logging of execution flow.
+ */
+#define LogRelMaxFlow(a_cMax, a) LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
+
+/** @def LogRelMaxFunc
+ * Release logging. Prepends the given log message with the function name
+ * followed by a semicolon and space.
+ */
+#ifdef LOG_USE_C99
+# define LogRelMaxFunc(a_cMax, a) \
+ _LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", \
+ __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+# define LogFuncMax(a_cMax, a) \
+ _LogItMax(a_cMax, LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", \
+ __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelMaxFunc(a_cMax, a) \
+ do { LogRelMax(a_cMax, (LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRelMax(a_cMax, a); } while (0)
+#endif
+
+/** @def LogRelMaxThisFunc
+ * The same as LogRelFunc but for class functions (methods): the resulting log
+ * line is additionally prepended with a hex value of |this| pointer.
+ * @param a_cMax Max number of times this should hit the log.
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogRelMaxThisFunc(a_cMax, a) \
+ _LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", \
+ this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelMaxThisFunc(a_cMax, a) \
+ do { LogRelMax(a_cMax, ("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogRelMax(a_cMax, a); } while (0)
+#endif
+
+/** @def LogRelMaxFlowFunc
+ * Release logging. Macro to log the execution flow inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param a_cMax Max number of times this should hit the log.
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogRelMaxFlowFunc(a_cMax, a) \
+ _LogRelMaxIt(a_cMax, LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", \
+ __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelMaxFlowFunc(a_cMax, a) \
+ do { LogRelMaxFlow(a_cMax, (LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRelFlow(a_cMax, a); } while (0)
+#endif
+
+
/** @def LogRelIsItEnabled
* Checks whether the specified logging group is enabled or not.
*/
diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h
index 4f1b59c..6b6fcb0 100644
--- a/include/iprt/mangling.h
+++ b/include/iprt/mangling.h
@@ -1141,6 +1141,7 @@
# define RTR3InitExe RT_MANGLER(RTR3InitExe)
# define RTR3InitExeNoArguments RT_MANGLER(RTR3InitExeNoArguments)
# define RTR3InitEx RT_MANGLER(RTR3InitEx)
+# define RTR3InitIsInitialized RT_MANGLER(RTR3InitIsInitialized)
# define RTR3InitIsUnobtrusive RT_MANGLER(RTR3InitIsUnobtrusive)
# define rtR3MemAlloc RT_MANGLER(rtR3MemAlloc)
# define rtR3MemFree RT_MANGLER(rtR3MemFree)
@@ -2554,6 +2555,7 @@
# define RTCrX509NameConstraints_DecodeAsn1 RT_MANGLER(RTCrX509NameConstraints_DecodeAsn1)
# define RTCrX509Name_DecodeAsn1 RT_MANGLER(RTCrX509Name_DecodeAsn1)
# define RTCrX509OldAuthorityKeyIdentifier_DecodeAsn1 RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_DecodeAsn1)
+# define RTCrX509OtherName_DecodeAsn1 RT_MANGLER(RTCrX509OtherName_DecodeAsn1)
# define RTCrX509PolicyConstraints_DecodeAsn1 RT_MANGLER(RTCrX509PolicyConstraints_DecodeAsn1)
# define RTCrX509PolicyInformation_DecodeAsn1 RT_MANGLER(RTCrX509PolicyInformation_DecodeAsn1)
# define RTCrX509PolicyMapping_DecodeAsn1 RT_MANGLER(RTCrX509PolicyMapping_DecodeAsn1)
@@ -2651,6 +2653,9 @@
# define RTCrX509OldAuthorityKeyIdentifier_Compare RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Compare)
# define RTCrX509OldAuthorityKeyIdentifier_Delete RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Delete)
# define RTCrX509OldAuthorityKeyIdentifier_Enum RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Enum)
+# define RTCrX509OtherName_Compare RT_MANGLER(RTCrX509OtherName_Compare)
+# define RTCrX509OtherName_Delete RT_MANGLER(RTCrX509OtherName_Delete)
+# define RTCrX509OtherName_Enum RT_MANGLER(RTCrX509OtherName_Enum)
# define RTCrX509PolicyConstraints_Compare RT_MANGLER(RTCrX509PolicyConstraints_Compare)
# define RTCrX509PolicyConstraints_Delete RT_MANGLER(RTCrX509PolicyConstraints_Delete)
# define RTCrX509PolicyConstraints_Enum RT_MANGLER(RTCrX509PolicyConstraints_Enum)
@@ -2718,6 +2723,8 @@
# define RTCrX509Name_RecodeAsUtf8 RT_MANGLER(RTCrX509Name_RecodeAsUtf8)
# define RTCrX509OldAuthorityKeyIdentifier_Clone RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Clone)
# define RTCrX509OldAuthorityKeyIdentifier_Init RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_Init)
+# define RTCrX509OtherName_Clone RT_MANGLER(RTCrX509OtherName_Clone)
+# define RTCrX509OtherName_Init RT_MANGLER(RTCrX509OtherName_Init)
# define RTCrX509PolicyConstraints_Clone RT_MANGLER(RTCrX509PolicyConstraints_Clone)
# define RTCrX509PolicyConstraints_Init RT_MANGLER(RTCrX509PolicyConstraints_Init)
# define RTCrX509PolicyInformation_Clone RT_MANGLER(RTCrX509PolicyInformation_Clone)
@@ -2754,6 +2761,7 @@
# define RTCrX509NameConstraints_CheckSanity RT_MANGLER(RTCrX509NameConstraints_CheckSanity)
# define RTCrX509Name_CheckSanity RT_MANGLER(RTCrX509Name_CheckSanity)
# define RTCrX509OldAuthorityKeyIdentifier_CheckSanity RT_MANGLER(RTCrX509OldAuthorityKeyIdentifier_CheckSanity)
+# define RTCrX509OtherName_CheckSanity RT_MANGLER(RTCrX509OtherName_CheckSanity)
# define RTCrX509PolicyConstraints_CheckSanity RT_MANGLER(RTCrX509PolicyConstraints_CheckSanity)
# define RTCrX509PolicyInformation_CheckSanity RT_MANGLER(RTCrX509PolicyInformation_CheckSanity)
# define RTCrX509PolicyMapping_CheckSanity RT_MANGLER(RTCrX509PolicyMapping_CheckSanity)
diff --git a/include/iprt/nt/nt.h b/include/iprt/nt/nt.h
index 2051214..74be0ce 100644
--- a/include/iprt/nt/nt.h
+++ b/include/iprt/nt/nt.h
@@ -2191,6 +2191,63 @@ typedef NTSTATUS (NTAPI *PFNLDRREGISTERDLLNOTIFICATION)(ULONG, PLDR_DLL_NOTIFICA
NTSYSAPI NTSTATUS NTAPI LdrUnregisterDllNotification(PVOID pvCookie);
typedef NTSTATUS (NTAPI *PFNLDRUNREGISTERDLLNOTIFICATION)(PVOID);
+NTSYSAPI NTSTATUS NTAPI LdrLoadDll(IN PWSTR pwszSearchPathOrFlags OPTIONAL, IN PULONG pfFlags OPTIONAL,
+ IN PCUNICODE_STRING pName, OUT PHANDLE phMod);
+typedef NTSTATUS (NTAPI *PFNLDRLOADDLL)(IN PWSTR pwszSearchPathOrFlags OPTIONAL, IN PULONG pfFlags OPTIONAL,
+ IN PCUNICODE_STRING pName, OUT PHANDLE phMod);
+NTSYSAPI NTSTATUS NTAPI LdrUnloadDll(IN HANDLE hMod);
+typedef NTSTATUS (NTAPI *PFNLDRUNLOADDLL)(IN HANDLE hMod);
+NTSYSAPI NTSTATUS NTAPI LdrGetDllHandle(IN PCWSTR pwszDllPath OPTIONAL, IN PULONG pfFlags OPTIONAL,
+ IN PCUNICODE_STRING pName, OUT PHANDLE phDll);
+typedef NTSTATUS (NTAPI *PFNLDRGETDLLHANDLE)(IN PCWSTR pwszDllPath OPTIONAL, IN PULONG pfFlags OPTIONAL,
+ IN PCUNICODE_STRING pName, OUT PHANDLE phDll);
+#define LDRGETDLLHANDLEEX_F_UNCHANGED_REFCOUNT RT_BIT_32(0)
+#define LDRGETDLLHANDLEEX_F_PIN RT_BIT_32(1)
+/** @since Windows XP. */
+NTSYSAPI NTSTATUS NTAPI LdrGetDllHandleEx(IN ULONG fFlags, IN PCWSTR pwszDllPath OPTIONAL, IN PULONG pfFlags OPTIONAL,
+ IN PCUNICODE_STRING pName, OUT PHANDLE phDll);
+/** @since Windows XP. */
+typedef NTSTATUS (NTAPI *PFNLDRGETDLLHANDLEEX)(IN ULONG fFlags, IN PCWSTR pwszDllPath OPTIONAL, IN PULONG pfFlags OPTIONAL,
+ IN PCUNICODE_STRING pName, OUT PHANDLE phDll);
+/** @since Windows 7. */
+NTSYSAPI NTSTATUS NTAPI LdrGetDllHandleByMapping(IN PVOID pvBase, OUT PHANDLE phDll);
+/** @since Windows 7. */
+typedef NTSTATUS (NTAPI *PFNLDRGETDLLHANDLEBYMAPPING)(IN PVOID pvBase, OUT PHANDLE phDll);
+/** @since Windows 7. */
+NTSYSAPI NTSTATUS NTAPI LdrGetDllHandleByName(IN PCUNICODE_STRING pName OPTIONAL, IN PCUNICODE_STRING pFullName OPTIONAL,
+ OUT PHANDLE phDll);
+/** @since Windows 7. */
+typedef NTSTATUS (NTAPI *PFNLDRGETDLLHANDLEBYNAME)(IN PCUNICODE_STRING pName OPTIONAL, IN PCUNICODE_STRING pFullName OPTIONAL,
+ OUT PHANDLE phDll);
+#define LDRADDREFDLL_F_PIN RT_BIT_32(0)
+NTSYSAPI NTSTATUS NTAPI LdrAddRefDll(IN ULONG fFlags, IN HANDLE hDll);
+typedef NTSTATUS (NTAPI *PFNLDRADDREFDLL)(IN ULONG fFlags, IN HANDLE hDll);
+NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress(IN HANDLE hDll, IN ANSI_STRING const *pSymbol OPTIONAL,
+ IN ULONG uOrdinal OPTIONAL, OUT PVOID *ppvSymbol);
+typedef NTSTATUS (NTAPI *PFNLDRGETPROCEDUREADDRESS)(IN HANDLE hDll, IN PCANSI_STRING pSymbol OPTIONAL,
+ IN ULONG uOrdinal OPTIONAL, OUT PVOID *ppvSymbol);
+#define LDRGETPROCEDUREADDRESSEX_F_DONT_RECORD_FORWARDER RT_BIT_32(0)
+/** @since Windows Vista. */
+NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddressEx(IN HANDLE hDll, IN ANSI_STRING const *pSymbol OPTIONAL,
+ IN ULONG uOrdinal OPTIONAL, OUT PVOID *ppvSymbol, ULONG fFlags);
+/** @since Windows Vista. */
+typedef NTSTATUS (NTAPI *PFNLDRGETPROCEDUREADDRESSEX)(IN HANDLE hDll, IN ANSI_STRING const *pSymbol OPTIONAL,
+ IN ULONG uOrdinal OPTIONAL, OUT PVOID *ppvSymbol, ULONG fFlags);
+#define LDRLOCKLOADERLOCK_F_RAISE_ERRORS RT_BIT_32(0)
+#define LDRLOCKLOADERLOCK_F_NO_WAIT RT_BIT_32(1)
+#define LDRLOCKLOADERLOCK_DISP_INVALID UINT32_C(0)
+#define LDRLOCKLOADERLOCK_DISP_ACQUIRED UINT32_C(1)
+#define LDRLOCKLOADERLOCK_DISP_NOT_ACQUIRED UINT32_C(2)
+/** @since Windows XP. */
+NTSYSAPI NTSTATUS NTAPI LdrLockLoaderLock(IN ULONG fFlags, OUT PULONG puDisposition OPTIONAL, OUT PVOID *ppvCookie);
+/** @since Windows XP. */
+typedef NTSTATUS (NTAPI *PFNLDRLOCKLOADERLOCK)(IN ULONG fFlags, OUT PULONG puDisposition OPTIONAL, OUT PVOID *ppvCookie);
+#define LDRUNLOCKLOADERLOCK_F_RAISE_ERRORS RT_BIT_32(0)
+/** @since Windows XP. */
+NTSYSAPI NTSTATUS NTAPI LdrUnlockLoaderLock(IN ULONG fFlags, OUT PVOID pvCookie);
+/** @since Windows XP. */
+typedef NTSTATUS (NTAPI *PFNLDRUNLOCKLOADERLOCK)(IN ULONG fFlags, OUT PVOID pvCookie);
+
NTSYSAPI NTSTATUS NTAPI RtlExpandEnvironmentStrings_U(PVOID, PUNICODE_STRING, PUNICODE_STRING, PULONG);
NTSYSAPI VOID NTAPI RtlExitUserProcess(NTSTATUS rcExitCode); /**< Vista and later. */
NTSYSAPI VOID NTAPI RtlExitUserThread(NTSTATUS rcExitCode);
diff --git a/include/iprt/socket.h b/include/iprt/socket.h
index 0b577c5..a498ad3 100644
--- a/include/iprt/socket.h
+++ b/include/iprt/socket.h
@@ -44,6 +44,9 @@ RT_C_DECLS_BEGIN
* @{
*/
+/** Use the system default timeout for the connet attempt. */
+#define RT_SOCKETCONNECT_DEFAULT_WAIT (RT_INDEFINITE_WAIT - 1)
+
/**
* Retains a reference to the socket handle.
*
diff --git a/include/iprt/tcp.h b/include/iprt/tcp.h
index 0e6a4e9..987b1ff 100644
--- a/include/iprt/tcp.h
+++ b/include/iprt/tcp.h
@@ -180,6 +180,10 @@ typedef struct RTTCPCLIENTCONNECTCANCEL *PRTTCPCLIENTCONNECTCANCEL;
* @param pszAddress The address to connect to.
* @param uPort The port to connect to.
* @param pSock Where to store the handle to the established connection.
+ * @param cMillies Number of milliseconds to wait for the connect attempt to complete.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ * Use RT_SOCKETCONNECT_DEFAULT_WAIT to wait for the default time
+ * configured on the running system.
* @param ppCancelCookie Where to store information for canceling the
* operation (from a different thread). Optional.
*
@@ -193,7 +197,7 @@ typedef struct RTTCPCLIENTCONNECTCANCEL *PRTTCPCLIENTCONNECTCANCEL;
* @sa RTTcpClientCancelConnect
*/
RTR3DECL(int) RTTcpClientConnectEx(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock,
- PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie);
+ RTMSINTERVAL cMillies, PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie);
/**
* Cancels a RTTcpClientConnectEx call on a different thread.
diff --git a/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp b/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
index 13242a0..010a004 100644
--- a/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
+++ b/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp
@@ -1176,7 +1176,7 @@ static RTEXITCODE getGuestProperty(int argc, char **argv)
int rc = VINF_SUCCESS;
rc = VbglR3GuestPropConnect(&u32ClientId);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
/*
@@ -1220,7 +1220,7 @@ static RTEXITCODE getGuestProperty(int argc, char **argv)
}
if (VERR_TOO_MUCH_DATA == rc)
VBoxControlError("Temporarily unable to retrieve the property\n");
- else if (!RT_SUCCESS(rc) && (rc != VERR_NOT_FOUND))
+ else if (RT_FAILURE(rc) && rc != VERR_NOT_FOUND)
VBoxControlError("Failed to retrieve the property value, error %Rrc\n", rc);
}
@@ -1293,15 +1293,15 @@ static RTEXITCODE setGuestProperty(int argc, char *argv[])
uint32_t u32ClientId = 0;
int rc = VINF_SUCCESS;
rc = VbglR3GuestPropConnect(&u32ClientId);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
- if (RT_SUCCESS(rc))
+ else
{
if (pszFlags != NULL)
rc = VbglR3GuestPropWrite(u32ClientId, pszName, pszValue, pszFlags);
else
rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, pszValue);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to store the property value, error %Rrc\n", rc);
}
@@ -1341,12 +1341,12 @@ static RTEXITCODE deleteGuestProperty(int argc, char *argv[])
*/
uint32_t u32ClientId = 0;
int rc = VbglR3GuestPropConnect(&u32ClientId);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
- if (RT_SUCCESS(rc))
+ else
{
rc = VbglR3GuestPropDelete(u32ClientId, pszName);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to delete the property value, error %Rrc\n", rc);
}
@@ -1484,7 +1484,7 @@ static RTEXITCODE waitGuestProperty(int argc, char **argv)
int rc = VINF_SUCCESS;
rc = VbglR3GuestPropConnect(&u32ClientId);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
/*
@@ -1531,7 +1531,7 @@ static RTEXITCODE waitGuestProperty(int argc, char **argv)
else if (rc == VERR_INTERRUPTED)
VBoxControlError("The request timed out or was interrupted\n");
#ifndef RT_OS_WINDOWS /* Windows guests do not do this right */
- else if (!RT_SUCCESS(rc) && (rc != VERR_NOT_FOUND))
+ else if (RT_FAILURE(rc) && rc != VERR_NOT_FOUND)
VBoxControlError("Failed to get a notification, error %Rrc\n", rc);
#endif
}
@@ -1615,7 +1615,7 @@ static RTEXITCODE listSharedFolders(int argc, char **argv)
uint32_t u32ClientId;
int rc = VbglR3SharedFolderConnect(&u32ClientId);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
VBoxControlError("Failed to connect to the shared folder service, error %Rrc\n", rc);
else
{
diff --git a/src/VBox/Additions/common/VBoxGuest/Makefile.kmk b/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
index 1ae3c47..7740185 100644
--- a/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
@@ -37,6 +37,7 @@ if1of ($(KBUILD_TARGET), darwin freebsd haiku $(if $(defined VBOX_WITH_ADDITION_
VBoxGuest_DEFS.haiku = VBOX_SVN_REV=$(VBOX_SVN_REV) _KERNEL_MODE=1
VBoxGuest_DEFS.linux = KBUILD_MODNAME=KBUILD_STR\(vboxguest\) KBUILD_BASENAME=KBUILD_STR\(vboxguest\) DEBUG_HASH=2 DEBUG_HASH2=3 EXPORT_SYMTAB
VBoxGuest_DEFS.solaris = VBOX_SVN_REV=$(VBOX_SVN_REV)
+ VBoxGuest_DEFS.win = VBOX_GUESTDRV_WITH_RELEASE_LOGGER # VBOX_WITH_VRDP_SESSION_HANDLING
VBoxGuest_DEFS.darwin = VBOX_GUESTDRV_WITH_RELEASE_LOGGER
ifeq ($(KBUILD_TYPE),release)
# Allow stopping/removing the driver without a reboot
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp
index 3eb7dab..256b38c 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp
@@ -907,6 +907,13 @@ bool org_virtualbox_VBoxGuestClient::initWithTask(task_t OwningTask, void *pvSec
if (!OwningTask)
return false;
+
+ if (u32Type != VBOXGUEST_DARWIN_IOSERVICE_COOKIE)
+ {
+ Log(("org_virtualbox_VBoxGuestClient::initWithTask: Bad cookie %#x\n", u32Type));
+ return false;
+ }
+
if (IOUserClient::initWithTask(OwningTask, pvSecurityId , u32Type))
{
m_Task = OwningTask;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
index a482489..5464a95 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
@@ -1,4 +1,4 @@
-/* $Rev: 88900 $ */
+/* $Rev: 97220 $ */
/** @file
* VBoxGuest - Linux specifics.
*
@@ -130,17 +130,6 @@ static char g_szDbgLogDst[128];
# endif
#endif
-/** Our file node major id.
- * Either set dynamically at run time or statically at compile time. */
-#ifdef CONFIG_VBOXGUEST_MAJOR
-static unsigned int g_iModuleMajor = CONFIG_VBOXGUEST_MAJOR;
-#else
-static unsigned int g_iModuleMajor = 0;
-#endif
-#ifdef CONFIG_VBOXADD_MAJOR
-# error "CONFIG_VBOXADD_MAJOR -> CONFIG_VBOXGUEST_MAJOR"
-#endif
-
/** The input device handle */
#ifdef VBOXGUEST_WITH_INPUT_DRIVER
static struct input_dev *g_pInputDevice = NULL;
@@ -485,10 +474,11 @@ static int __init vboxguestLinuxCreateInputDevice(void)
static void vboxguestLinuxTermInputDevice(void)
{
VbglGRFree(&g_pMouseStatusReq->header);
+ /* See documentation of input_register_device(): input_free_device()
+ * should not be called after a device has been registered. */
input_unregister_device(g_pInputDevice);
- input_free_device(g_pInputDevice);
}
-#endif
+#endif /* VBOXGUEST_WITH_INPUT_DRIVER */
/**
@@ -503,23 +493,11 @@ static int __init vboxguestLinuxInitDeviceNodes(void)
/*
* The full feature device node.
*/
- if (g_iModuleMajor > 0)
- {
- rc = register_chrdev(g_iModuleMajor, DEVICE_NAME, &g_FileOps);
- if (rc < 0)
- {
- LogRel((DEVICE_NAME ": register_chrdev failed: g_iModuleMajor: %d, rc: %d\n", g_iModuleMajor, rc));
- return rc;
- }
- }
- else
+ rc = misc_register(&g_MiscDevice);
+ if (rc)
{
- rc = misc_register(&g_MiscDevice);
- if (rc)
- {
- LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME, rc));
- return rc;
- }
+ LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME, rc));
+ return rc;
}
/*
@@ -529,10 +507,7 @@ static int __init vboxguestLinuxInitDeviceNodes(void)
if (rc)
{
LogRel((DEVICE_NAME ": misc_register failed for %s (rc=%d)\n", DEVICE_NAME_USER, rc));
- if (g_iModuleMajor > 0)
- unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
- else
- misc_deregister(&g_MiscDevice);
+ misc_deregister(&g_MiscDevice);
return rc;
}
@@ -545,10 +520,7 @@ static int __init vboxguestLinuxInitDeviceNodes(void)
*/
static void vboxguestLinuxTermDeviceNodes(void)
{
- if (g_iModuleMajor > 0)
- unregister_chrdev(g_iModuleMajor, DEVICE_NAME);
- else
- misc_deregister(&g_MiscDevice);
+ misc_deregister(&g_MiscDevice);
misc_deregister(&g_MiscDeviceUser);
}
@@ -652,8 +624,8 @@ static int __init vboxguestLinuxModInit(void)
if (rc >= 0)
{
/* some useful information for the user but don't show this on the console */
- LogRel((DEVICE_NAME ": major %d, IRQ %d, I/O port %RTiop, MMIO at %RHp (size 0x%x)\n",
- g_iModuleMajor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO));
+ LogRel((DEVICE_NAME ": misc device minor %d, IRQ %d, I/O port %RTiop, MMIO at %RHp (size 0x%x)\n",
+ g_MiscDevice.minor, g_pPciDev->irq, g_IOPortBase, g_MMIOPhysAddr, g_cbMMIO));
printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
VBOX_VERSION_STRING " (interface " RT_XSTR(VMMDEV_VERSION) ")\n");
return rc;
@@ -734,7 +706,11 @@ static int vboxguestLinuxOpen(struct inode *pInode, struct file *pFilp)
*/
rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
if (RT_SUCCESS(rc))
+ {
pFilp->private_data = pSession;
+ if (MINOR(pInode->i_rdev) == g_MiscDeviceUser.minor)
+ pSession->fUserSession = true;
+ }
Log(("vboxguestLinuxOpen: g_DevExt=%p pSession=%p rc=%d/%d (pid=%d/%d %s)\n",
&g_DevExt, pSession, rc, vboxguestLinuxConvertToNegErrno(rc),
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
index 7c7ff3f..d709229 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
@@ -335,7 +335,7 @@ static int VBoxGuestSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
if (RT_SUCCESS(rc))
{
- rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0);
+ rc = ddi_create_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0 /* fFlags */);
if (rc == DDI_SUCCESS)
{
g_pDip = pDip;
@@ -780,13 +780,13 @@ static int VBoxGuestSolarisAddIRQ(dev_info_t *pDip)
if (rc == DDI_SUCCESS)
{
/* Initialize the mutex. */
- mutex_init(&g_IrqMtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(uIntrPriority));
+ mutex_init(&g_IrqMtx, NULL /* pszDesc */, MUTEX_DRIVER, DDI_INTR_PRI(uIntrPriority));
/* Assign interrupt handler functions and enable interrupts. */
for (int i = 0; i < IntrAllocated; i++)
{
rc = ddi_intr_add_handler(g_pIntr[i], (ddi_intr_handler_t *)VBoxGuestSolarisISR,
- NULL /* No Private Data */, NULL);
+ NULL /* pvArg1 */, NULL /* pvArg2 */);
if (rc == DDI_SUCCESS)
rc = ddi_intr_enable(g_pIntr[i]);
if (rc != DDI_SUCCESS)
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
index 5a8a459..da21ce5 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
@@ -97,7 +97,7 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
NTSTATUS rc = STATUS_SUCCESS;
- Log(("VBoxGuest::DriverEntry. Driver built: %s %s\n", __DATE__, __TIME__));
+ LogFunc(("Driver built: %s %s\n", __DATE__, __TIME__));
/*
* Check if the the NT version is supported and initializing
@@ -107,14 +107,28 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
ULONG ulMinorVer;
ULONG ulBuildNo;
BOOLEAN fCheckedBuild = PsGetVersion(&ulMajorVer, &ulMinorVer, &ulBuildNo, NULL);
- Log(("VBoxGuest::DriverEntry: Running on Windows NT version %u.%u, build %u\n", ulMajorVer, ulMinorVer, ulBuildNo));
+
+ /* Use RTLogBackdoorPrintf to make sure that this goes to VBox.log */
+ RTLogBackdoorPrintf("VBoxGuest: Windows version %u.%u, build %u\n", ulMajorVer, ulMinorVer, ulBuildNo);
if (fCheckedBuild)
- Log(("VBoxGuest::DriverEntry: Running on a Windows checked build (debug)!\n"));
+ RTLogBackdoorPrintf("VBoxGuest: Windows checked build\n");
+
#ifdef DEBUG
vbgdNtDoTests();
#endif
switch (ulMajorVer)
{
+ case 10:
+ switch (ulMinorVer)
+ {
+ case 0:
+ /* Windows 10 Preview builds starting with 9926. */
+ default:
+ /* Also everything newer. */
+ g_enmVbgdNtVer = VBGDNTVER_WIN10;
+ break;
+ }
+ break;
case 6: /* Windows Vista or Windows 7 (based on minor ver) */
switch (ulMinorVer)
{
@@ -131,17 +145,17 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
g_enmVbgdNtVer = VBGDNTVER_WIN81;
break;
case 4:
- g_enmVbgdNtVer = VBGDNTVER_WIN10;
- break;
+ /* Windows 10 Preview builds. */
default:
- Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n", ulMajorVer, ulMinorVer));
- rc = STATUS_DRIVER_UNABLE_TO_LOAD;
+ /* Also everything newer. */
+ g_enmVbgdNtVer = VBGDNTVER_WIN10;
break;
}
break;
case 5:
switch (ulMinorVer)
{
+ default:
case 2:
g_enmVbgdNtVer = VBGDNTVER_WIN2K3;
break;
@@ -151,20 +165,25 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
case 0:
g_enmVbgdNtVer = VBGDNTVER_WIN2K;
break;
- default:
- Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n", ulMajorVer, ulMinorVer));
- rc = STATUS_DRIVER_UNABLE_TO_LOAD;
}
break;
case 4:
g_enmVbgdNtVer = VBGDNTVER_WINNT4;
break;
default:
- if (ulMajorVer < 4)
- Log(("VBoxGuest::DriverEntry: At least Windows NT4 required! (%u.%u)\n", ulMajorVer, ulMinorVer));
+ if (ulMajorVer > 6)
+ {
+ /* "Windows 10 mode" for Windows 8.1+. */
+ g_enmVbgdNtVer = VBGDNTVER_WIN10;
+ }
else
- Log(("VBoxGuest::DriverEntry: Too new version %u.%u!\n", ulMajorVer, ulMinorVer));
- rc = STATUS_DRIVER_UNABLE_TO_LOAD;
+ {
+ if (ulMajorVer < 4)
+ LogRelFunc(("At least Windows NT4 required! (%u.%u)\n", ulMajorVer, ulMinorVer));
+ else
+ LogRelFunc(("Unknown version %u.%u!\n", ulMajorVer, ulMinorVer));
+ rc = STATUS_DRIVER_UNABLE_TO_LOAD;
+ }
break;
}
@@ -191,7 +210,7 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
#endif
}
- Log(("VBoxGuest::DriverEntry returning %#x\n", rc));
+ LogFlowFunc(("Returning %#x\n", rc));
return rc;
}
@@ -207,7 +226,7 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
static NTSTATUS vbgdNtAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
{
NTSTATUS rc;
- Log(("VBoxGuest::vbgdNtGuestAddDevice\n"));
+ LogFlowFuncEnter();
/*
* Create device.
@@ -255,7 +274,7 @@ static NTSTATUS vbgdNtAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
/* Driver is ready now. */
pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- Log(("VBoxGuest::vbgdNtGuestAddDevice: returning with rc = 0x%x (success)\n", rc));
+ LogFlowFunc(("Returning with rc=0x%x (success)\n", rc));
return rc;
}
@@ -263,7 +282,7 @@ static NTSTATUS vbgdNtAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
}
else
{
- Log(("VBoxGuest::vbgdNtGuestAddDevice: IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n"));
+ LogFlowFunc(("IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n"));
rc = STATUS_DEVICE_NOT_CONNECTED;
}
@@ -271,12 +290,13 @@ static NTSTATUS vbgdNtAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
IoDeleteSymbolicLink(&DosName);
}
else
- Log(("VBoxGuest::vbgdNtGuestAddDevice: IoCreateSymbolicLink failed with rc=%#x!\n", rc));
+ LogFlowFunc(("IoCreateSymbolicLink failed with rc=%#x!\n", rc));
IoDeleteDevice(pDeviceObject);
}
else
- Log(("VBoxGuest::vbgdNtGuestAddDevice: IoCreateDevice failed with rc=%#x!\n", rc));
- Log(("VBoxGuest::vbgdNtGuestAddDevice: returning with rc = 0x%x\n", rc));
+ LogFlowFunc(("IoCreateDevice failed with rc=%#x!\n", rc));
+
+ LogFlowFunc(("Returning with rc=0x%x\n", rc));
return rc;
}
#endif
@@ -310,31 +330,31 @@ static void vbgdNtShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceList)
"CmResourceTypeSubAllocateFrom",
};
- Log(("VBoxGuest::vbgdNtShowDeviceResources: Type %s",
- uType < RT_ELEMENTS(s_apszName) ? s_apszName[uType] : "Unknown"));
+ LogFlowFunc(("Type=%s",
+ uType < RT_ELEMENTS(s_apszName) ? s_apszName[uType] : "Unknown"));
switch (uType)
{
case CmResourceTypePort:
case CmResourceTypeMemory:
- Log(("VBoxGuest::vbgdNtShowDeviceResources: Start %8X%8.8lX length %X\n",
- pResource->u.Port.Start.HighPart, pResource->u.Port.Start.LowPart,
- pResource->u.Port.Length));
+ LogFlowFunc(("Start %8X%8.8lX, length=%X\n",
+ pResource->u.Port.Start.HighPart, pResource->u.Port.Start.LowPart,
+ pResource->u.Port.Length));
break;
case CmResourceTypeInterrupt:
- Log(("VBoxGuest::vbgdNtShowDeviceResources: Level %X, Vector %X, Affinity %X\n",
- pResource->u.Interrupt.Level, pResource->u.Interrupt.Vector,
- pResource->u.Interrupt.Affinity));
+ LogFlowFunc(("Level=%X, vector=%X, affinity=%X\n",
+ pResource->u.Interrupt.Level, pResource->u.Interrupt.Vector,
+ pResource->u.Interrupt.Affinity));
break;
case CmResourceTypeDma:
- Log(("VBoxGuest::vbgdNtShowDeviceResources: Channel %d, Port %X\n",
- pResource->u.Dma.Channel, pResource->u.Dma.Port));
+ LogFlowFunc(("Channel %d, Port %X\n",
+ pResource->u.Dma.Channel, pResource->u.Dma.Port));
break;
default:
- Log(("\n"));
+ LogFlowFunc(("\n"));
break;
}
}
@@ -359,14 +379,14 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
#endif
- Log(("VBoxGuest::vbgdNtInit\n"));
+ LogFlowFuncEnter();
int rc = STATUS_SUCCESS;
#ifdef TARGET_NT4
/*
* Let's have a look at what our PCI adapter offers.
*/
- Log(("VBoxGuest::vbgdNtInit: Starting to scan PCI resources of VBoxGuest ...\n"));
+ LogFlowFunc(("Starting to scan PCI resources of VBoxGuest ...\n"));
/* Assign the PCI resources. */
PCM_RESOURCE_LIST pResourceList = NULL;
@@ -403,8 +423,8 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
{
pDevExt->Core.pVMMDevMemory = (VMMDevMemory *)pvMMIOBase;
- Log(("VBoxGuest::vbgdNtInit: pvMMIOBase = 0x%p, pDevExt = 0x%p, pDevExt->Core.pVMMDevMemory = 0x%p\n",
- pvMMIOBase, pDevExt, pDevExt ? pDevExt->Core.pVMMDevMemory : NULL));
+ LogFlowFunc(("pvMMIOBase=0x%p, pDevExt=0x%p, pDevExt->Core.pVMMDevMemory=0x%p\n",
+ pvMMIOBase, pDevExt, pDevExt ? pDevExt->Core.pVMMDevMemory : NULL));
int vrc = VBoxGuestInitDevExt(&pDevExt->Core,
pDevExt->Core.IOPortBase,
@@ -413,12 +433,12 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::vbgdNtInit: Could not init device extension, rc = %Rrc!\n", vrc));
+ LogFlowFunc(("Could not init device extension, rc=%Rrc\n", vrc));
rc = STATUS_DEVICE_CONFIGURATION_ERROR;
}
}
else
- Log(("VBoxGuest::vbgdNtInit: Could not map physical address of VMMDev, rc = 0x%x!\n", rc));
+ LogFlowFunc(("Could not map physical address of VMMDev, rc=0x%x\n", rc));
}
if (NT_SUCCESS(rc))
@@ -427,7 +447,7 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
sizeof(VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::vbgdNtInit: Alloc for pPowerStateRequest failed, rc = %Rrc\n", vrc));
+ LogFlowFunc(("Alloc for pPowerStateRequest failed, rc=%Rrc\n", vrc));
rc = STATUS_UNSUCCESSFUL;
}
}
@@ -437,7 +457,7 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
/*
* Register DPC and ISR.
*/
- Log(("VBoxGuest::vbgdNtInit: Initializing DPC/ISR ...\n"));
+ LogFlowFunc(("Initializing DPC/ISR ...\n"));
IoInitializeDpcRequest(pDevExt->pDeviceObject, vbgdNtDpcHandler);
#ifdef TARGET_NT4
@@ -448,8 +468,8 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
if ( pDevExt->interruptLevel
|| pDevExt->interruptVector)
{
- Log(("VBoxGuest::vbgdNtInit: Getting interrupt vector (HAL): Bus: %u, IRQL: %u, Vector: %u\n",
- pDevExt->busNumber, pDevExt->interruptLevel, pDevExt->interruptVector));
+ LogFlowFunc(("Getting interrupt vector (HAL): Bus=%u, IRQL=%u, Vector=%u\n",
+ pDevExt->busNumber, pDevExt->interruptLevel, pDevExt->interruptVector));
uInterruptVector = HalGetInterruptVector(PCIBus,
pDevExt->busNumber,
@@ -457,16 +477,16 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
pDevExt->interruptVector,
&irqLevel,
&pDevExt->interruptAffinity);
- Log(("VBoxGuest::vbgdNtInit: HalGetInterruptVector returns vector %u\n", uInterruptVector));
+ LogFlowFunc(("HalGetInterruptVector returns vector=%u\n", uInterruptVector));
if (uInterruptVector == 0)
- Log(("VBoxGuest::vbgdNtInit: No interrupt vector found!\n"));
+ LogFunc(("No interrupt vector found!\n"));
}
else
- Log(("VBoxGuest::vbgdNtInit: Device does not provide an interrupt!\n"));
+ LogFlowFunc(("Device does not provide an interrupt!\n"));
#endif
if (pDevExt->interruptVector)
{
- Log(("VBoxGuest::vbgdNtInit: Connecting interrupt ...\n"));
+ LogFlowFunc(("Connecting interrupt ...\n"));
rc = IoConnectInterrupt(&pDevExt->pInterruptObject, /* Out: interrupt object. */
(PKSERVICE_ROUTINE)vbgdNtIsrHandler, /* Our ISR handler. */
@@ -486,19 +506,19 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
pDevExt->interruptAffinity, /* CPU affinity. */
FALSE); /* Don't save FPU stack. */
if (NT_ERROR(rc))
- Log(("VBoxGuest::vbgdNtInit: Could not connect interrupt, rc = 0x%x\n", rc));
+ LogFlowFunc(("Could not connect interrupt, rc=0x%x\n", rc));
}
else
- Log(("VBoxGuest::vbgdNtInit: No interrupt vector found!\n"));
+ LogFlowFunc(("No interrupt vector found!\n"));
}
#ifdef VBOX_WITH_HGCM
- Log(("VBoxGuest::vbgdNtInit: Allocating kernel session data ...\n"));
+ LogFunc(("Allocating kernel session data ...\n"));
int vrc = VBoxGuestCreateKernelSession(&pDevExt->Core, &pDevExt->pKernelSession);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::vbgdNtInit: Failed to allocated kernel session data! rc = %Rrc\n", rc));
+ LogFlowFunc(("Failed to allocated kernel session data, rc=%Rrc\n", rc));
rc = STATUS_UNSUCCESSFUL;
}
#endif
@@ -506,16 +526,17 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
if (RT_SUCCESS(rc))
{
ULONG ulValue = 0;
- NTSTATUS rcNt = vbgdNtRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled", &ulValue);
+ NTSTATUS rcNt = vbgdNtRegistryReadDWORD(RTL_REGISTRY_SERVICES,
+ L"VBoxGuest", L"LoggingEnabled", &ulValue);
if (NT_SUCCESS(rcNt))
{
pDevExt->Core.fLoggingEnabled = ulValue >= 0xFF;
if (pDevExt->Core.fLoggingEnabled)
- Log(("Logging to release log enabled (0x%x)", ulValue));
+ LogRelFunc(("Logging to host log enabled (0x%x)", ulValue));
}
/* Ready to rumble! */
- Log(("VBoxGuest::vbgdNtInit: Device is ready!\n"));
+ LogRelFunc(("Device is ready!\n"));
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, WORKING);
}
else
@@ -524,7 +545,7 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
/** @todo r=bird: The error cleanup here is completely missing. We'll leak a
* whole bunch of things... */
- Log(("VBoxGuest::vbgdNtInit: Returned with rc = 0x%x\n", rc));
+ LogFlowFunc(("Returned with rc=0x%x\n", rc));
return rc;
}
@@ -537,7 +558,7 @@ NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STR
*/
NTSTATUS vbgdNtCleanup(PDEVICE_OBJECT pDevObj)
{
- Log(("VBoxGuest::vbgdNtCleanup\n"));
+ LogFlowFuncEnter();
PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
if (pDevExt)
@@ -568,6 +589,7 @@ NTSTATUS vbgdNtCleanup(PDEVICE_OBJECT pDevObj)
/* According to MSDN we have to unmap previously mapped memory. */
vbgdNtUnmapVMMDevMemory(pDevExt);
}
+
return STATUS_SUCCESS;
}
@@ -579,7 +601,8 @@ NTSTATUS vbgdNtCleanup(PDEVICE_OBJECT pDevObj)
*/
static void vbgdNtUnload(PDRIVER_OBJECT pDrvObj)
{
- Log(("VBoxGuest::vbgdNtGuestUnload\n"));
+ LogFlowFuncEnter();
+
#ifdef TARGET_NT4
vbgdNtCleanup(pDrvObj->DeviceObject);
@@ -602,7 +625,7 @@ static void vbgdNtUnload(PDRIVER_OBJECT pDrvObj)
* so don't do anything here (yet). */
#endif /* !TARGET_NT4 */
- Log(("VBoxGuest::vbgdNtGuestUnload: returning\n"));
+ LogFlowFunc(("Returning\n"));
}
@@ -623,7 +646,7 @@ static NTSTATUS vbgdNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
if (pDevExt->devState != WORKING)
{
- Log(("VBoxGuest::vbgdNtGuestCreate: device is not working currently: %d!\n", pDevExt->devState));
+ LogFlowFunc(("Device is not working currently, state=%d\n", pDevExt->devState));
rc = STATUS_UNSUCCESSFUL;
}
else if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
@@ -632,7 +655,7 @@ static NTSTATUS vbgdNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* We are not remotely similar to a directory...
* (But this is possible.)
*/
- Log(("VBoxGuest::vbgdNtGuestCreate: Uhm, we're not a directory!\n"));
+ LogFlowFunc(("Uhm, we're not a directory!\n"));
rc = STATUS_NOT_A_DIRECTORY;
}
else
@@ -640,8 +663,7 @@ static NTSTATUS vbgdNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
#ifdef VBOX_WITH_HGCM
if (pFileObj)
{
- Log(("VBoxGuest::vbgdNtGuestCreate: File object type = %d\n",
- pFileObj->Type));
+ LogFlowFunc(("File object type=%d\n", pFileObj->Type));
int vrc;
PVBOXGUESTSESSION pSession;
@@ -669,7 +691,7 @@ static NTSTATUS vbgdNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
pIrp->IoStatus.Status = rc;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- Log(("VBoxGuest::vbgdNtGuestCreate: Returning 0x%x\n", rc));
+ LogFlowFunc(("Returning rc=0x%x\n", rc));
return rc;
}
@@ -686,8 +708,8 @@ static NTSTATUS vbgdNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
PFILE_OBJECT pFileObj = pStack->FileObject;
- Log(("VBoxGuest::vbgdNtGuestClose: pDevExt=0x%p pFileObj=0x%p FsContext=0x%p\n",
- pDevExt, pFileObj, pFileObj->FsContext));
+ LogFlowFunc(("pDevExt=0x%p, pFileObj=0x%p, FsContext=0x%p\n",
+ pDevExt, pFileObj, pFileObj->FsContext));
#ifdef VBOX_WITH_HGCM
/* Close both, R0 and R3 sessions. */
@@ -728,8 +750,8 @@ static NTSTATUS vbgdNtIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
if (pFileObj) /* ... then we might have a session object as well! */
pSession = (PVBOXGUESTSESSION)pFileObj->FsContext;
- Log(("VBoxGuest::vbgdNtIOCtl: uCmd=%u, pDevExt=0x%p, pSession=0x%p\n",
- uCmd, pDevExt, pSession));
+ LogFlowFunc(("uCmd=%u, pDevExt=0x%p, pSession=0x%p\n",
+ uCmd, pDevExt, pSession));
/* We don't have a session associated with the file object? So this seems
* to be a kernel call then. */
@@ -737,7 +759,7 @@ static NTSTATUS vbgdNtIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* shall have its own context of course, no hacks, pleeease. */
if (pSession == NULL)
{
- Log(("VBoxGuest::vbgdNtIOCtl: Using kernel session data ...\n"));
+ LogFlowFunc(("Using kernel session data ...\n"));
pSession = pDevExt->pKernelSession;
}
@@ -788,7 +810,7 @@ static NTSTATUS vbgdNtIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- //Log(("VBoxGuest::vbgdNtGuestDeviceControl: returned cbOut=%d rc=%#x\n", cbOut, Status));
+ //LogFlowFunc(("Returned cbOut=%d rc=%#x\n", cbOut, Status));
return Status;
}
@@ -867,7 +889,7 @@ NTSTATUS vbgdNtSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
- Log(("VBoxGuest::vbgdNtGuestSystemControl\n"));
+ LogFlowFuncEnter();
/* Always pass it on to the next driver. */
IoSkipCurrentIrpStackLocation(pIrp);
@@ -887,7 +909,7 @@ NTSTATUS vbgdNtShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
- Log(("VBoxGuest::vbgdNtGuestShutdown\n"));
+ LogFlowFuncEnter();
VMMDevPowerStateRequest *pReq = pDevExt->pPowerStateRequest;
if (pReq)
@@ -897,11 +919,9 @@ NTSTATUS vbgdNtShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
int rc = VbglGRPerform(&pReq->header);
if (RT_FAILURE(rc))
- {
- Log(("VBoxGuest::vbgdNtGuestShutdown: Error performing request to VMMDev! "
- "rc = %Rrc\n", rc));
- }
+ LogFlowFunc(("Error performing request to VMMDev, rc=%Rrc\n", rc));
}
+
return STATUS_SUCCESS;
}
@@ -915,7 +935,7 @@ NTSTATUS vbgdNtShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
*/
NTSTATUS vbgdNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- Log(("VBoxGuest::vbgdNtGuestNotSupportedStub\n"));
+ LogFlowFuncEnter();
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
@@ -936,9 +956,11 @@ NTSTATUS vbgdNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
void vbgdNtDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext)
{
PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
- Log(("VBoxGuest::vbgdNtGuestDpcHandler: pDevExt=0x%p\n", pDevExt));
+#ifndef DEBUG_andy
+ LogFlowFunc(("pDevExt=0x%p\n", pDevExt));
+#endif
- /* test & reset the counter */
+ /* Test & reset the counter. */
if (ASMAtomicXchgU32(&pDevExt->Core.u32MousePosChangedSeq, 0))
{
/* we need a lock here to avoid concurrency with the set event ioctl handler thread,
@@ -971,8 +993,8 @@ BOOLEAN vbgdNtIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext)
if (pDevExt == NULL)
return FALSE;
- /*Log(("VBoxGuest::vbgdNtGuestIsrHandler: pDevExt = 0x%p, pVMMDevMemory = 0x%p\n",
- pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL));*/
+ /*LogFlowFunc(("pDevExt=0x%p, pVMMDevMemory=0x%p\n",
+ pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL));*/
/* Enter the common ISR routine and do the actual work. */
BOOLEAN fIRQTaken = VBoxGuestCommonISR(&pDevExt->Core);
@@ -981,11 +1003,16 @@ BOOLEAN vbgdNtIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext)
* sure we're called at the right IRQL. */
if (fIRQTaken)
{
- Log(("VBoxGuest::vbgdNtGuestIsrHandler: IRQ was taken! pInterrupt = 0x%p, pDevExt = 0x%p\n",
- pInterrupt, pDevExt));
- if (ASMAtomicUoReadU32(&pDevExt->Core.u32MousePosChangedSeq) || !RTListIsEmpty(&pDevExt->Core.WakeUpList))
+#ifndef DEBUG_andy
+ LogFlowFunc(("IRQ was taken! pInterrupt=0x%p, pDevExt=0x%p\n",
+ pInterrupt, pDevExt));
+#endif
+ if (ASMAtomicUoReadU32( &pDevExt->Core.u32MousePosChangedSeq)
+ || !RTListIsEmpty(&pDevExt->Core.WakeUpList))
{
- Log(("VBoxGuest::vbgdNtGuestIsrHandler: Requesting DPC ...\n"));
+#ifndef DEBUG_andy
+ LogFlowFunc(("Requesting DPC ...\n"));
+#endif
IoRequestDpc(pDevExt->pDeviceObject, pDevExt->pCurrentIrp, NULL);
}
}
@@ -1052,8 +1079,8 @@ NTSTATUS vbgdNtRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName,
NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTWIN pDevExt)
{
/* Enumerate the resource list. */
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: Found %d resources\n",
- pResList->List->PartialResourceList.Count));
+ LogFlowFunc(("Found %d resources\n",
+ pResList->List->PartialResourceList.Count));
NTSTATUS rc = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialData = NULL;
@@ -1070,10 +1097,10 @@ NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTW
/* Overflow protection. */
if (rangeCount < PCI_TYPE0_ADDRESSES)
{
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: I/O range: Base = %08x:%08x, Length = %08x\n",
- pPartialData->u.Port.Start.HighPart,
- pPartialData->u.Port.Start.LowPart,
- pPartialData->u.Port.Length));
+ LogFlowFunc(("I/O range: Base=%08x:%08x, length=%08x\n",
+ pPartialData->u.Port.Start.HighPart,
+ pPartialData->u.Port.Start.LowPart,
+ pPartialData->u.Port.Length));
/* Save the IO port base. */
/** @todo Not so good.
@@ -1086,10 +1113,10 @@ NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTW
pBaseAddress->RangeInMemory = FALSE;
pBaseAddress->ResourceMapped = FALSE;
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: I/O range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
- pPartialData->u.Port.Start.HighPart,
- pPartialData->u.Port.Start.LowPart,
- pPartialData->u.Port.Length));
+ LogFlowFunc(("I/O range for VMMDev found! Base=%08x:%08x, length=%08x\n",
+ pPartialData->u.Port.Start.HighPart,
+ pPartialData->u.Port.Start.LowPart,
+ pPartialData->u.Port.Length));
/* Next item ... */
rangeCount++; pBaseAddress++;
@@ -1099,10 +1126,10 @@ NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTW
case CmResourceTypeInterrupt:
{
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: Interrupt: Level = %x, Vector = %x, Mode = %x\n",
- pPartialData->u.Interrupt.Level,
- pPartialData->u.Interrupt.Vector,
- pPartialData->Flags));
+ LogFlowFunc(("Interrupt: Level=%x, vector=%x, mode=%x\n",
+ pPartialData->u.Interrupt.Level,
+ pPartialData->u.Interrupt.Vector,
+ pPartialData->Flags));
/* Save information. */
pDevExt->interruptLevel = pPartialData->u.Interrupt.Level;
@@ -1122,10 +1149,10 @@ NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTW
/* Overflow protection. */
if (rangeCount < PCI_TYPE0_ADDRESSES)
{
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: Memory range: Base = %08x:%08x, Length = %08x\n",
- pPartialData->u.Memory.Start.HighPart,
- pPartialData->u.Memory.Start.LowPart,
- pPartialData->u.Memory.Length));
+ LogFlowFunc(("Memory range: Base=%08x:%08x, length=%08x\n",
+ pPartialData->u.Memory.Start.HighPart,
+ pPartialData->u.Memory.Start.LowPart,
+ pPartialData->u.Memory.Length));
/* We only care about read/write memory. */
/** @todo Reconsider memory type. */
@@ -1142,26 +1169,23 @@ NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTW
pBaseAddress->RangeInMemory = TRUE;
pBaseAddress->ResourceMapped = FALSE;
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: Memory range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
- pPartialData->u.Memory.Start.HighPart,
- pPartialData->u.Memory.Start.LowPart,
- pPartialData->u.Memory.Length));
+ LogFlowFunc(("Memory range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
+ pPartialData->u.Memory.Start.HighPart,
+ pPartialData->u.Memory.Start.LowPart,
+ pPartialData->u.Memory.Length));
/* Next item ... */
rangeCount++; pBaseAddress++; cMMIORange++;
}
else
- {
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: Ignoring memory: Flags = %08x\n",
- pPartialData->Flags));
- }
+ LogFlowFunc(("Ignoring memory: Flags=%08x\n", pPartialData->Flags));
}
break;
}
default:
{
- Log(("VBoxGuest::vbgdNtScanPCIResourceList: Unhandled resource found, type = %d\n", pPartialData->Type));
+ LogFlowFunc(("Unhandled resource found, type=%d\n", pPartialData->Type));
break;
}
}
@@ -1195,11 +1219,11 @@ NTSTATUS vbgdNtMapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt, PHYSICAL_ADDRESS Phy
if (PhysAddr.LowPart > 0) /* We're mapping below 4GB. */
{
VMMDevMemory *pVMMDevMemory = (VMMDevMemory *)MmMapIoSpace(PhysAddr, cbToMap, MmNonCached);
- Log(("VBoxGuest::vbgdNtMapVMMDevMemory: pVMMDevMemory = 0x%x\n", pVMMDevMemory));
+ LogFlowFunc(("pVMMDevMemory = 0x%x\n", pVMMDevMemory));
if (pVMMDevMemory)
{
- Log(("VBoxGuest::vbgdNtMapVMMDevMemory: VMMDevMemory: Version = 0x%x, Size = %d\n",
- pVMMDevMemory->u32Version, pVMMDevMemory->u32Size));
+ LogFlowFunc(("VMMDevMemory: Version = 0x%x, Size = %d\n",
+ pVMMDevMemory->u32Version, pVMMDevMemory->u32Size));
/* Check version of the structure; do we have the right memory version? */
if (pVMMDevMemory->u32Version == VMMDEV_MEMORY_VERSION)
@@ -1209,13 +1233,14 @@ NTSTATUS vbgdNtMapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt, PHYSICAL_ADDRESS Phy
if (pcbMMIO) /* Optional. */
*pcbMMIO = pVMMDevMemory->u32Size;
- Log(("VBoxGuest::vbgdNtMapVMMDevMemory: VMMDevMemory found and mapped! pvMMIOBase = 0x%p\n",
- *ppvMMIOBase));
+ LogFlowFunc(("VMMDevMemory found and mapped! pvMMIOBase = 0x%p\n",
+ *ppvMMIOBase));
}
else
{
/* Not our version, refuse operation and unmap the memory. */
- Log(("VBoxGuest::vbgdNtMapVMMDevMemory: Wrong version (%u), refusing operation!\n", pVMMDevMemory->u32Version));
+ LogFlowFunc(("Wrong version (%u), refusing operation!\n", pVMMDevMemory->u32Version));
+
vbgdNtUnmapVMMDevMemory(pDevExt);
rc = STATUS_UNSUCCESSFUL;
}
@@ -1234,7 +1259,7 @@ NTSTATUS vbgdNtMapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt, PHYSICAL_ADDRESS Phy
*/
void vbgdNtUnmapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt)
{
- Log(("VBoxGuest::vbgdNtUnmapVMMDevMemory: pVMMDevMemory = 0x%x\n", pDevExt->Core.pVMMDevMemory));
+ LogFlowFunc(("pVMMDevMemory = 0x%x\n", pDevExt->Core.pVMMDevMemory));
if (pDevExt->Core.pVMMDevMemory)
{
MmUnmapIoSpace((void*)pDevExt->Core.pVMMDevMemory, pDevExt->vmmDevPhysMemoryLength);
@@ -1324,7 +1349,6 @@ VBOXOSTYPE vbgdNtVersionToOSType(VBGDNTVER enmNtVer)
}
#ifdef DEBUG
-
/**
* A quick implementation of AtomicTestAndClear for uint32_t and multiple bits.
*/
@@ -1373,7 +1397,6 @@ static void vbgdNtDoTests(void)
vbgdNtTestAtomicTestAndClearBitsU32(0x11, 0x32, 0x10);
vbgdNtTestAtomicTestAndClearBitsU32(0x22, 0x23, 0x22);
}
-
#endif /* DEBUG */
#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
@@ -1522,6 +1545,5 @@ int VbgdNtIOCtl_DpcLatencyChecker(void)
ExFreePoolWithTag(pData, VBOXGUEST_DPC_TAG);
return VINF_SUCCESS;
}
-
#endif /* VBOX_WITH_DPC_LATENCY_CHECKER */
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
index a6fcaf7..a828bb8 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2013 Oracle Corporation
+ * Copyright (C) 2007-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -65,20 +65,21 @@
#ifdef VBOX_WITH_HGCM
static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User);
#endif
-#ifdef DEBUG
-static void testSetMouseStatus(void);
-#endif
-static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures);
static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags);
#define VBOXGUEST_ACQUIRE_STYLE_EVENTS (VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
+/** Return the mask of VMM device events that this session is allowed to see,
+ * ergo, all events except those in "acquire" mode which have not been acquired
+ * by this session. */
DECLINLINE(uint32_t) VBoxGuestCommonGetHandledEventsLocked(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
{
if (!pDevExt->u32AcquireModeGuestCaps)
return VMMDEV_EVENT_VALID_EVENT_MASK;
+ /** @note VMMDEV_EVENT_VALID_EVENT_MASK should actually be the mask of valid
+ * capabilities, but that doesn't affect this code. */
uint32_t u32AllowedGuestCaps = pSession->u32AquiredGuestCaps | (VMMDEV_EVENT_VALID_EVENT_MASK & ~pDevExt->u32AcquireModeGuestCaps);
uint32_t u32CleanupEvents = VBOXGUEST_ACQUIRE_STYLE_EVENTS;
if (u32AllowedGuestCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS)
@@ -97,6 +98,9 @@ DECLINLINE(uint32_t) VBoxGuestCommonGetAndCleanPendingEventsLocked(PVBOXGUESTDEV
return fMatches;
}
+/** Puts a capability in "acquire" or "set" mode and returns the mask of
+ * capabilities currently in the other mode. Once a capability has been put in
+ * one of the two modes it can no longer be removed from that mode. */
DECLINLINE(bool) VBoxGuestCommonGuestCapsModeSet(PVBOXGUESTDEVEXT pDevExt, uint32_t fCaps, bool fAcquire, uint32_t *pu32OtherVal)
{
uint32_t *pVal = fAcquire ? &pDevExt->u32AcquireModeGuestCaps : &pDevExt->u32SetModeGuestCaps;
@@ -119,6 +123,180 @@ DECLINLINE(bool) VBoxGuestCommonGuestCapsModeSet(PVBOXGUESTDEVEXT pDevExt, uint3
return fResult;
}
+
+/**
+ * Sets the interrupt filter mask during initialization and termination.
+ *
+ * This will ASSUME that we're the ones in carge over the mask, so
+ * we'll simply clear all bits we don't set.
+ *
+ * @returns VBox status code (ignored).
+ * @param fMask The new mask.
+ */
+static int vboxGuestSetFilterMask(VMMDevCtlGuestFilterMask *pReq,
+ uint32_t fMask)
+{
+ int rc;
+
+ pReq->u32OrMask = fMask;
+ pReq->u32NotMask = ~fMask;
+ rc = VbglGRPerform(&pReq->header);
+ if (RT_FAILURE(rc))
+ LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc));
+ return rc;
+}
+
+
+/**
+ * Sets the guest capabilities to the host.
+ *
+ * This will ASSUME that we're the ones in charge of the mask, so
+ * we'll simply clear all bits we don't set.
+ *
+ * @returns VBox status code.
+ * @param fMask The new mask.
+ */
+static int vboxGuestSetCapabilities(VMMDevReqGuestCapabilities2 *pReq,
+ uint32_t fMask)
+{
+ int rc;
+
+ pReq->u32OrMask = fMask;
+ pReq->u32NotMask = ~fMask;
+ rc = VbglGRPerform(&pReq->header);
+ if (RT_FAILURE(rc))
+ LogRelFunc(("failed with rc=%Rrc\n", rc));
+ return rc;
+}
+
+
+/**
+ * Sets the mouse status to the host.
+ *
+ * This will ASSUME that we're the ones in charge of the mask, so
+ * we'll simply clear all bits we don't set.
+ *
+ * @returns VBox status code.
+ * @param fMask The new mask.
+ */
+static int vboxGuestSetMouseStatus(VMMDevReqMouseStatus *pReq, uint32_t fMask)
+{
+ int rc;
+
+ pReq->mouseFeatures = fMask;
+ pReq->pointerXPos = 0;
+ pReq->pointerYPos = 0;
+ rc = VbglGRPerform(&pReq->header);
+ if (RT_FAILURE(rc))
+ LogRelFunc(("failed with rc=%Rrc\n", rc));
+ return rc;
+}
+
+
+/** Host flags to be updated by a given invocation of the
+ * vboxGuestUpdateHostFlags() method. */
+enum
+{
+ HostFlags_FilterMask = 1,
+ HostFlags_Capabilities = 2,
+ HostFlags_MouseStatus = 4,
+ HostFlags_All = 7,
+ HostFlags_SizeHack = (unsigned)-1
+};
+
+
+static int vboxGuestGetHostFlagsFromSessions(PVBOXGUESTDEVEXT pDevExt,
+ PVBOXGUESTSESSION pSession,
+ uint32_t *pfFilterMask,
+ uint32_t *pfCapabilities,
+ uint32_t *pfMouseStatus)
+{
+ PVBOXGUESTSESSION pIterator;
+ uint32_t fFilterMask = 0, fCapabilities = 0, fMouseStatus = 0;
+ unsigned cSessions = 0;
+ int rc = VINF_SUCCESS;
+
+ RTListForEach(&pDevExt->SessionList, pIterator, VBOXGUESTSESSION, ListNode)
+ {
+ fFilterMask |= pIterator->fFilterMask;
+ fCapabilities |= pIterator->fCapabilities;
+ fMouseStatus |= pIterator->fMouseStatus;
+ ++cSessions;
+ }
+ if (!cSessions)
+ if (fFilterMask | fCapabilities | fMouseStatus)
+ rc = VERR_INTERNAL_ERROR;
+ if (cSessions == 1 && pSession)
+ if ( fFilterMask != pSession->fFilterMask
+ || fCapabilities != pSession->fCapabilities
+ || fMouseStatus != pSession->fMouseStatus)
+ rc = VERR_INTERNAL_ERROR;
+ if (cSessions > 1 && pSession)
+ if ( ~fFilterMask & pSession->fFilterMask
+ || ~fCapabilities & pSession->fCapabilities
+ || ~fMouseStatus & pSession->fMouseStatus)
+ rc = VERR_INTERNAL_ERROR;
+ *pfFilterMask = fFilterMask;
+ *pfCapabilities = fCapabilities;
+ *pfMouseStatus = fMouseStatus;
+ return rc;
+}
+
+
+/** Check which host flags in a given category are being asserted by some guest
+ * session and assert exactly those on the host which are being asserted by one
+ * or more sessions. pCallingSession is purely for sanity checking and can be
+ * NULL.
+ * @note Takes the session spin-lock.
+ */
+static int vboxGuestUpdateHostFlags(PVBOXGUESTDEVEXT pDevExt,
+ PVBOXGUESTSESSION pSession,
+ unsigned enmFlags)
+{
+ int rc;
+ VMMDevCtlGuestFilterMask *pFilterReq = NULL;
+ VMMDevReqGuestCapabilities2 *pCapabilitiesReq = NULL;
+ VMMDevReqMouseStatus *pStatusReq = NULL;
+ uint32_t fFilterMask = 0, fCapabilities = 0, fMouseStatus = 0;
+
+ rc = VbglGRAlloc((VMMDevRequestHeader **)&pFilterReq, sizeof(*pFilterReq),
+ VMMDevReq_CtlGuestFilterMask);
+ if (RT_SUCCESS(rc))
+ rc = VbglGRAlloc((VMMDevRequestHeader **)&pCapabilitiesReq,
+ sizeof(*pCapabilitiesReq),
+ VMMDevReq_SetGuestCapabilities);
+ if (RT_SUCCESS(rc))
+ rc = VbglGRAlloc((VMMDevRequestHeader **)&pStatusReq,
+ sizeof(*pStatusReq), VMMDevReq_SetMouseStatus);
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ if (RT_SUCCESS(rc))
+ rc = vboxGuestGetHostFlagsFromSessions(pDevExt, pSession, &fFilterMask,
+ &fCapabilities, &fMouseStatus);
+ if (RT_SUCCESS(rc))
+ {
+ fFilterMask |= pDevExt->fFixedEvents;
+ /* Since VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR is inverted in the session
+ * capabilities we invert it again before sending it to the host. */
+ fMouseStatus ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
+ if (enmFlags & HostFlags_FilterMask)
+ vboxGuestSetFilterMask(pFilterReq, fFilterMask);
+ fCapabilities |= pDevExt->u32GuestCaps;
+ if (enmFlags & HostFlags_Capabilities)
+ vboxGuestSetCapabilities(pCapabilitiesReq, fCapabilities);
+ if (enmFlags & HostFlags_MouseStatus)
+ vboxGuestSetMouseStatus(pStatusReq, fMouseStatus);
+ }
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
+ if (pFilterReq)
+ VbglGRFree(&pFilterReq->header);
+ if (pCapabilitiesReq)
+ VbglGRFree(&pCapabilitiesReq->header);
+ if (pStatusReq)
+ VbglGRFree(&pStatusReq->header);
+ return rc;
+}
+
+
/*******************************************************************************
* Global Variables *
*******************************************************************************/
@@ -181,7 +359,7 @@ static int vboxGuestInitFixateGuestMappings(PVBOXGUESTDEVEXT pDevExt)
* instance in VT-x and AMD-V mode.
*/
if (pReq->hypervisorSize == 0)
- Log(("vboxGuestInitFixateGuestMappings: nothing to do\n"));
+ LogFlowFunc(("Nothing to do\n"));
else
{
/*
@@ -193,7 +371,7 @@ static int vboxGuestInitFixateGuestMappings(PVBOXGUESTDEVEXT pDevExt)
RTR0MEMOBJ ahTries[5];
uint32_t iTry;
bool fBitched = false;
- Log(("vboxGuestInitFixateGuestMappings: cbHypervisor=%#x\n", cbHypervisor));
+ LogFlowFunc(("cbHypervisor=%#x\n", cbHypervisor));
for (iTry = 0; iTry < RT_ELEMENTS(ahTries); iTry++)
{
/*
@@ -323,33 +501,6 @@ static void vboxGuestTermUnfixGuestMappings(PVBOXGUESTDEVEXT pDevExt)
/**
- * Sets the interrupt filter mask during initialization and termination.
- *
- * This will ASSUME that we're the ones in carge over the mask, so
- * we'll simply clear all bits we don't set.
- *
- * @returns VBox status code (ignored).
- * @param pDevExt The device extension.
- * @param fMask The new mask.
- */
-static int vboxGuestSetFilterMask(PVBOXGUESTDEVEXT pDevExt, uint32_t fMask)
-{
- VMMDevCtlGuestFilterMask *pReq;
- int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
- if (RT_SUCCESS(rc))
- {
- pReq->u32OrMask = fMask;
- pReq->u32NotMask = ~fMask;
- rc = VbglGRPerform(&pReq->header);
- if (RT_FAILURE(rc))
- LogRel(("vboxGuestSetFilterMask: failed with rc=%Rrc\n", rc));
- VbglGRFree(&pReq->header);
- }
- return rc;
-}
-
-
-/**
* Inflate the balloon by one chunk represented by an R0 memory object.
*
* The caller owns the balloon mutex.
@@ -547,11 +698,12 @@ int VBoxGuestReinitDevExtAfterHibernation(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE e
{
rc = VBoxGuestReportDriverStatus(true /* Driver is active */);
if (RT_FAILURE(rc))
- Log(("VBoxGuest::VBoxGuestReinitDevExtAfterHibernation: could not report guest driver status, rc=%Rrc\n", rc));
+ LogFlowFunc(("Could not report guest driver status, rc=%Rrc\n", rc));
}
else
- Log(("VBoxGuest::VBoxGuestReinitDevExtAfterHibernation: could not report guest information to host, rc=%Rrc\n", rc));
- Log(("VBoxGuest::VBoxGuestReinitDevExtAfterHibernation: returned with rc=%Rrc\n", rc));
+ LogFlowFunc(("Could not report guest information to host, rc=%Rrc\n", rc));
+
+ LogFlowFunc(("Returned with rc=%Rrc\n", rc));
return rc;
}
@@ -654,7 +806,7 @@ static int vboxGuestSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
pDevExt->MemBalloon.cChunks++;
else
{
- Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc));
+ LogFlowFunc(("Inflating failed, rc=%Rrc\n", rc));
RTR0MemObjFree(*pMemObj, true);
*pMemObj = NIL_RTR0MEMOBJ;
}
@@ -666,7 +818,7 @@ static int vboxGuestSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
if (RT_SUCCESS(rc))
pDevExt->MemBalloon.cChunks--;
else
- Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
+ LogFlowFunc(("Deflating failed, rc=%Rrc\n", rc));
}
VbglGRFree(&pReq->header);
@@ -701,8 +853,8 @@ static void vboxGuestCloseMemBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION
rc = vboxGuestBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
if (RT_FAILURE(rc))
{
- LogRel(("vboxGuestCloseMemBalloon: Deflate failed with rc=%Rrc. Will leak %u chunks.\n",
- rc, pDevExt->MemBalloon.cChunks));
+ LogRelFunc(("Deflating balloon failed with rc=%Rrc; will leak %u chunks\n",
+ rc, pDevExt->MemBalloon.cChunks));
break;
}
pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
@@ -711,8 +863,8 @@ static void vboxGuestCloseMemBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION
VbglGRFree(&pReq->header);
}
else
- LogRel(("vboxGuestCloseMemBalloon: Failed to allocate VMMDev request buffer (rc=%Rrc). Will leak %u chunks.\n",
- rc, pDevExt->MemBalloon.cChunks));
+ LogRelFunc(("Failed to allocate VMMDev request buffer, rc=%Rrc; will leak %u chunks\n",
+ rc, pDevExt->MemBalloon.cChunks));
RTMemFree(pDevExt->MemBalloon.paMemObj);
pDevExt->MemBalloon.paMemObj = NULL;
}
@@ -755,13 +907,26 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
* Create the release log.
*/
static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+ RTUINT fFlags = RTLOGFLAGS_PREFIX_TIME | RTLOGFLAGS_PREFIX_TID
+ | RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG;
PRTLOGGER pRelLogger;
- rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all",
- "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL);
+ rc = RTLogCreate(&pRelLogger, fFlags, "all",
+#ifdef DEBUG
+ "VBOXGUEST_LOG",
+#else
+ "VBOXGUEST_RELEASE_LOG",
+#endif
+ RT_ELEMENTS(s_apszGroups), s_apszGroups,
+ RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL);
if (RT_SUCCESS(rc))
+ {
RTLogRelSetDefaultInstance(pRelLogger);
+
+ /* Explicitly flush the log in case of VBOXGUEST_RELEASE_LOG=buffered. */
+ RTLogFlush(pRelLogger);
+ }
/** @todo Add native hook for getting logger config parameters and setting
- * them. On linux we should use the module parameter stuff... */
+ * them. On Linux we use the module parameter stuff (see vboxguestLinuxModInit). */
#endif
/*
@@ -790,6 +955,7 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
#endif
RTListInit(&pDevExt->WokenUpList);
RTListInit(&pDevExt->FreeList);
+ RTListInit(&pDevExt->SessionList);
pDevExt->fLoggingEnabled = false;
pDevExt->f32PendingEvents = 0;
pDevExt->u32MousePosChangedSeq = 0;
@@ -800,12 +966,8 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
pDevExt->MemBalloon.fUseKernelAPI = true;
pDevExt->MemBalloon.paMemObj = NULL;
pDevExt->MemBalloon.pOwner = NULL;
- for (i = 0; i < RT_ELEMENTS(pDevExt->acMouseFeatureUsage); ++i)
- pDevExt->acMouseFeatureUsage[i] = 0;
- pDevExt->fMouseStatus = 0;
pDevExt->MouseNotifyCallback.pfnNotify = NULL;
pDevExt->MouseNotifyCallback.pvUser = NULL;
- pDevExt->cISR = 0;
/*
* If there is an MMIO region validate the version and size.
@@ -819,12 +981,12 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
&& pVMMDev->u32Size <= cbMMIO)
{
pDevExt->pVMMDevMemory = pVMMDev;
- Log(("VBoxGuestInitDevExt: VMMDevMemory: mapping=%p size=%#RX32 (%#RX32) version=%#RX32\n",
- pVMMDev, pVMMDev->u32Size, cbMMIO, pVMMDev->u32Version));
+ LogFlowFunc(("VMMDevMemory: mapping=%p size=%#RX32 (%#RX32), version=%#RX32\n",
+ pVMMDev, pVMMDev->u32Size, cbMMIO, pVMMDev->u32Version));
}
else /* try live without it. */
- LogRel(("VBoxGuestInitDevExt: Bogus VMMDev memory; u32Version=%RX32 (expected %RX32) u32Size=%RX32 (expected <= %RX32)\n",
- pVMMDev->u32Version, VMMDEV_MEMORY_VERSION, pVMMDev->u32Size, cbMMIO));
+ LogRelFunc(("Bogus VMMDev memory; u32Version=%RX32 (expected %RX32), u32Size=%RX32 (expected <= %RX32)\n",
+ pVMMDev->u32Version, VMMDEV_MEMORY_VERSION, pVMMDev->u32Size, cbMMIO));
}
pDevExt->u32AcquireModeGuestCaps = 0;
@@ -839,7 +1001,7 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
rc = RTSpinlockCreate(&pDevExt->SessionSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestSession");
if (RT_FAILURE(rc))
{
- LogRel(("VBoxGuestInitDevExt: failed to create spinlock, rc=%Rrc!\n", rc));
+ LogRelFunc(("Failed to create spinlock, rc=%Rrc\n", rc));
if (pDevExt->EventSpinlock != NIL_RTSPINLOCK)
RTSpinlockDestroy(pDevExt->EventSpinlock);
return rc;
@@ -848,7 +1010,7 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
rc = RTSemFastMutexCreate(&pDevExt->MemBalloon.hMtx);
if (RT_FAILURE(rc))
{
- LogRel(("VBoxGuestInitDevExt: failed to create mutex, rc=%Rrc!\n", rc));
+ LogRelFunc(("Failed to create mutex, rc=%Rrc\n", rc));
RTSpinlockDestroy(pDevExt->SessionSpinlock);
RTSpinlockDestroy(pDevExt->EventSpinlock);
return rc;
@@ -871,46 +1033,37 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
rc = VBoxGuestReportGuestInfo(enmOSType);
if (RT_SUCCESS(rc))
{
- rc = vboxGuestSetFilterMask(pDevExt, fFixedEvents);
+ /* Set the fixed event and disable the guest graphics capability
+ * by default. The guest specific graphics driver will re-enable
+ * the graphics capability if and when appropriate. */
+ rc = vboxGuestUpdateHostFlags(pDevExt, NULL,
+ HostFlags_FilterMask
+ | HostFlags_Capabilities);
if (RT_SUCCESS(rc))
{
- /*
- * Disable guest graphics capability by default. The guest specific
- * graphics driver will re-enable this when it is necessary.
- */
- rc = VBoxGuestSetGuestCapabilities(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
- if (RT_SUCCESS(rc))
- {
- vboxGuestInitFixateGuestMappings(pDevExt);
-
-#ifdef DEBUG
- testSetMouseStatus(); /* Other tests? */
-#endif
+ vboxGuestInitFixateGuestMappings(pDevExt);
- rc = VBoxGuestReportDriverStatus(true /* Driver is active */);
- if (RT_FAILURE(rc))
- LogRel(("VBoxGuestInitDevExt: VBoxReportGuestDriverStatus failed, rc=%Rrc\n", rc));
-
- Log(("VBoxGuestInitDevExt: returns success\n"));
- return VINF_SUCCESS;
- }
+ rc = VBoxGuestReportDriverStatus(true /* Driver is active */);
+ if (RT_FAILURE(rc))
+ LogRelFunc(("VBoxReportGuestDriverStatus failed, rc=%Rrc\n", rc));
- LogRel(("VBoxGuestInitDevExt: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
+ LogFlowFunc(("VBoxGuestInitDevExt: returns success\n"));
+ return VINF_SUCCESS;
}
else
- LogRel(("VBoxGuestInitDevExt: vboxGuestSetFilterMask failed, rc=%Rrc\n", rc));
+ LogRelFunc(("Failed to set host flags, rc=%Rrc\n", rc));
}
else
- LogRel(("VBoxGuestInitDevExt: VBoxReportGuestInfo failed, rc=%Rrc\n", rc));
+ LogRelFunc(("VBoxGuestInitDevExt: VBoxReportGuestInfo failed, rc=%Rrc\n", rc));
VbglGRFree((VMMDevRequestHeader *)pDevExt->pIrqAckEvents);
}
else
- LogRel(("VBoxGuestInitDevExt: VBoxGRAlloc failed, rc=%Rrc\n", rc));
+ LogRelFunc(("VBoxGRAlloc failed, rc=%Rrc\n", rc));
VbglTerminate();
}
else
- LogRel(("VBoxGuestInitDevExt: VbglInit failed, rc=%Rrc\n", rc));
+ LogRelFunc(("VbglInit failed, rc=%Rrc\n", rc));
rc2 = RTSemFastMutexDestroy(pDevExt->MemBalloon.hMtx); AssertRC(rc2);
rc2 = RTSpinlockDestroy(pDevExt->EventSpinlock); AssertRC(rc2);
@@ -962,8 +1115,14 @@ void VBoxGuestDeleteDevExt(PVBOXGUESTDEVEXT pDevExt)
* Clean up the bits that involves the host first.
*/
vboxGuestTermUnfixGuestMappings(pDevExt);
- VBoxGuestSetGuestCapabilities(0, UINT32_MAX); /* clears all capabilities */
- vboxGuestSetFilterMask(pDevExt, 0); /* filter all events */
+ if (!RTListIsEmpty(&pDevExt->SessionList))
+ {
+ LogRelFunc(("session list not empty!\n"));
+ RTListInit(&pDevExt->SessionList);
+ }
+ /* Update the host flags (mouse status etc) not to reflect this session. */
+ pDevExt->fFixedEvents = 0;
+ vboxGuestUpdateHostFlags(pDevExt, NULL, HostFlags_All);
vboxGuestCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL);
/*
@@ -1020,6 +1179,9 @@ int VBoxGuestCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSe
pSession->Process = RTProcSelf();
pSession->R0Process = RTR0ProcHandleSelf();
pSession->pDevExt = pDevExt;
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ RTListAppend(&pDevExt->SessionList, &pSession->ListNode);
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
*ppSession = pSession;
LogFlow(("VBoxGuestCreateUserSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
@@ -1050,10 +1212,13 @@ int VBoxGuestCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *pp
pSession->Process = NIL_RTPROCESS;
pSession->R0Process = NIL_RTR0PROCESS;
pSession->pDevExt = pDevExt;
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ RTListAppend(&pDevExt->SessionList, &pSession->ListNode);
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
*ppSession = pSession;
- LogFlow(("VBoxGuestCreateKernelSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
- pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+ LogFlowFunc(("pSession=%p proc=%RTproc (%d) r0proc=%p\n",
+ pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
return VINF_SUCCESS;
}
@@ -1068,9 +1233,12 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
void VBoxGuestCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
{
unsigned i; NOREF(i);
- Log(("VBoxGuestCloseSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
- pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+ LogFlowFunc(("pSession=%p proc=%RTproc (%d) r0proc=%p\n",
+ pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ RTListNodeRemove(&pSession->ListNode);
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
VBoxGuestCommonGuestCapsAcquire(pDevExt, pSession, 0, UINT32_MAX, VBOXGUESTCAPSACQUIRE_FLAGS_NONE);
VBoxGuestCommonIOCtl_CancelAllWaitEvents(pDevExt, pSession);
@@ -1083,7 +1251,7 @@ void VBoxGuestCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
Info.result = 0;
Info.u32ClientID = pSession->aHGCMClientIds[i];
pSession->aHGCMClientIds[i] = 0;
- Log(("VBoxGuestCloseSession: disconnecting client id %#RX32\n", Info.u32ClientID));
+ LogFlowFunc(("Disconnecting client ID=%#RX32\n", Info.u32ClientID));
VbglR0HGCMInternalDisconnect(&Info, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
}
#endif
@@ -1092,9 +1260,13 @@ void VBoxGuestCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
pSession->Process = NIL_RTPROCESS;
pSession->R0Process = NIL_RTR0PROCESS;
vboxGuestCloseMemBalloon(pDevExt, pSession);
- /* Reset any mouse status flags which the session may have set. */
- VBoxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession, 0);
RTMemFree(pSession);
+ /* Update the host flags (mouse status etc) not to reflect this session. */
+ vboxGuestUpdateHostFlags(pDevExt, NULL, HostFlags_All
+#ifdef RT_OS_WINDOWS
+ & (~HostFlags_MouseStatus)
+#endif
+ );
}
@@ -1130,7 +1302,7 @@ static PVBOXGUESTWAIT VBoxGuestWaitAlloc(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSES
if (!pWait)
{
if (s_cErrors++ < 32)
- LogRel(("VBoxGuestWaitAlloc: out-of-memory!\n"));
+ LogRelFunc(("Out of memory, returning NULL\n"));
return NULL;
}
@@ -1138,7 +1310,7 @@ static PVBOXGUESTWAIT VBoxGuestWaitAlloc(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSES
if (RT_FAILURE(rc))
{
if (s_cErrors++ < 32)
- LogRel(("VBoxGuestCommonIOCtl: RTSemEventMultiCreate failed with rc=%Rrc!\n", rc));
+ LogRelFunc(("RTSemEventMultiCreate failed with rc=%Rrc\n", rc));
RTMemFree(pWait);
return NULL;
}
@@ -1268,8 +1440,8 @@ int VBoxGuestSetGuestCapabilities(uint32_t fOr, uint32_t fNot)
int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetGuestCapabilities);
if (RT_FAILURE(rc))
{
- Log(("VBoxGuestSetGuestCapabilities: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
- sizeof(*pReq), sizeof(*pReq), rc));
+ LogFlowFunc(("Failed to allocate %u (%#x) bytes to cache the request; rc=%Rrc\n",
+ sizeof(*pReq), sizeof(*pReq), rc));
return rc;
}
@@ -1278,7 +1450,7 @@ int VBoxGuestSetGuestCapabilities(uint32_t fOr, uint32_t fNot)
rc = VbglGRPerform(&pReq->header);
if (RT_FAILURE(rc))
- Log(("VBoxGuestSetGuestCapabilities: VbglGRPerform failed, rc=%Rrc!\n", rc));
+ LogFlowFunc(("VbglGRPerform failed, rc=%Rrc\n", rc));
VbglGRFree(&pReq->header);
return rc;
@@ -1297,7 +1469,7 @@ int VBoxGuestSetGuestCapabilities(uint32_t fOr, uint32_t fNot)
*/
int VBoxGuestCommonIOCtlFast(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
{
- Log(("VBoxGuestCommonIOCtlFast: iFunction=%#x pDevExt=%p pSession=%p\n", iFunction, pDevExt, pSession));
+ LogFlowFunc(("iFunction=%#x pDevExt=%p pSession=%p\n", iFunction, pDevExt, pSession));
NOREF(iFunction);
NOREF(pDevExt);
@@ -1316,7 +1488,8 @@ int VBoxGuestCommonIOCtlFast(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBO
*/
static int VBoxGuestCommonIOCtl_GetVMMDevPort(PVBOXGUESTDEVEXT pDevExt, VBoxGuestPortInfo *pInfo, size_t *pcbDataReturned)
{
- Log(("VBoxGuestCommonIOCtl: GETVMMDEVPORT\n"));
+ LogFlowFuncEnter();
+
pInfo->portAddress = pDevExt->IOPortBase;
pInfo->pVMMDevMemory = (VMMDevMemory *)pDevExt->pVMMDevMemory;
if (pcbDataReturned)
@@ -1332,27 +1505,14 @@ static int VBoxGuestCommonIOCtl_GetVMMDevPort(PVBOXGUESTDEVEXT pDevExt, VBoxGues
* returns IPRT status code.
* @param pDevExt The device extension.
* @param pNotify The new callback information.
- * @note This function takes the session spinlock to update the callback
- * information, but the interrupt handler will not do this. To make
- * sure that the interrupt handler sees a consistent structure, we
- * set the function pointer to NULL before updating the data and only
- * set it to the correct value once the data is updated. Since the
- * interrupt handler executes atomically this ensures that the data is
- * valid if the function pointer is non-NULL.
*/
int VBoxGuestCommonIOCtl_SetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, VBoxGuestMouseSetNotifyCallback *pNotify)
{
- Log(("VBoxGuestCommonIOCtl: SET_MOUSE_NOTIFY_CALLBACK\n"));
+ LogFlowFuncEnter();
RTSpinlockAcquire(pDevExt->EventSpinlock);
pDevExt->MouseNotifyCallback = *pNotify;
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
-
- /* Make sure no active ISR is referencing the old data - hacky but should be
- * effective. */
- while (pDevExt->cISR > 0)
- ASMNopPause();
-
return VINF_SUCCESS;
}
#endif
@@ -1369,18 +1529,20 @@ DECLINLINE(int) WaitEventCheckCondition(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESS
int iEvent, const uint32_t fReqEvents)
{
uint32_t fMatches = VBoxGuestCommonGetAndCleanPendingEventsLocked(pDevExt, pSession, fReqEvents);
- if (fMatches)
+ if (fMatches || pSession->fPendingCancelWaitEvents)
{
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
pInfo->u32EventFlagsOut = fMatches;
pInfo->u32Result = VBOXGUEST_WAITEVENT_OK;
if (fReqEvents & ~((uint32_t)1 << iEvent))
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns %#x\n", pInfo->u32EventFlagsOut));
+ LogFlowFunc(("WAITEVENT: returns %#x\n", pInfo->u32EventFlagsOut));
else
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
+ LogFlowFunc(("WAITEVENT: returns %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
+ pSession->fPendingCancelWaitEvents = false;
return VINF_SUCCESS;
}
+
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
return VERR_TIMEOUT;
}
@@ -1406,7 +1568,7 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
iEvent = ASMBitFirstSetU32(fReqEvents) - 1;
if (RT_UNLIKELY(iEvent < 0))
{
- LogRel(("VBoxGuestCommonIOCtl: WAITEVENT: Invalid input mask %#x!!\n", fReqEvents));
+ LogRel(("Invalid input mask %#x\n", fReqEvents));
return VERR_INVALID_PARAMETER;
}
@@ -1421,7 +1583,7 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
if (!pInfo->u32TimeoutIn)
{
pInfo->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT;
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns VERR_TIMEOUT\n"));
+ LogFlowFunc(("Returning VERR_TIMEOUT\n"));
return VERR_TIMEOUT;
}
@@ -1476,9 +1638,9 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
pInfo->u32EventFlagsOut = fResEvents;
pInfo->u32Result = VBOXGUEST_WAITEVENT_OK;
if (fReqEvents & ~((uint32_t)1 << iEvent))
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns %#x\n", pInfo->u32EventFlagsOut));
+ LogFlowFunc(("Returning %#x\n", pInfo->u32EventFlagsOut));
else
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
+ LogFlowFunc(("Returning %#x/%d\n", pInfo->u32EventFlagsOut, iEvent));
rc = VINF_SUCCESS;
}
else if ( fResEvents == UINT32_MAX
@@ -1486,12 +1648,12 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
{
pInfo->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED;
rc = VERR_INTERRUPTED;
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns VERR_INTERRUPTED\n"));
+ LogFlowFunc(("Returning VERR_INTERRUPTED\n"));
}
else if (rc == VERR_TIMEOUT)
{
pInfo->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT;
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns VERR_TIMEOUT (2)\n"));
+ LogFlowFunc(("Returning VERR_TIMEOUT (2)\n"));
}
else
{
@@ -1499,11 +1661,11 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
{
static unsigned s_cErrors = 0;
if (s_cErrors++ < 32)
- LogRel(("VBoxGuestCommonIOCtl: WAITEVENT: returns %Rrc but no events!\n", rc));
+ LogRelFunc(("Returning %Rrc but no events\n", rc));
rc = VERR_INTERNAL_ERROR;
}
pInfo->u32Result = VBOXGUEST_WAITEVENT_ERROR;
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: returns %Rrc\n", rc));
+ LogFlowFunc(("Returning %Rrc\n", rc));
}
return rc;
@@ -1515,8 +1677,13 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
PVBOXGUESTWAIT pWait;
PVBOXGUESTWAIT pSafe;
int rc = 0;
+ /* Was as least one WAITEVENT in process for this session? If not we
+ * set a flag that the next call should be interrupted immediately. This
+ * is needed so that a user thread can reliably interrupt another one in a
+ * WAITEVENT loop. */
+ bool fCancelledOne = false;
- Log(("VBoxGuestCommonIOCtl: CANCEL_ALL_WAITEVENTS\n"));
+ LogFlowFunc(("CANCEL_ALL_WAITEVENTS\n"));
/*
* Walk the event list and wake up anyone with a matching session.
@@ -1526,6 +1693,7 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
{
if (pWait->pSession == pSession)
{
+ fCancelledOne = true;
pWait->fResEvents = UINT32_MAX;
RTListNodeRemove(&pWait->ListNode);
#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
@@ -1536,6 +1704,8 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
#endif
}
}
+ if (!fCancelledOne)
+ pSession->fPendingCancelWaitEvents = true;
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
Assert(rc == 0);
NOREF(rc);
@@ -1733,32 +1903,32 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
const uint32_t cbReq = pReqHdr->size;
const uint32_t cbMinSize = (uint32_t)vmmdevGetRequestSize(enmType);
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST type %d\n", pReqHdr->requestType));
+ LogFlowFunc(("Type=%d\n", pReqHdr->requestType));
if (cbReq < cbMinSize)
{
- LogRel(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid hdr size %#x, expected >= %#x; type=%#x!!\n",
- cbReq, cbMinSize, enmType));
+ LogRelFunc(("Invalid hdr size %#x, expected >= %#x; type=%#x!!\n",
+ cbReq, cbMinSize, enmType));
return VERR_INVALID_PARAMETER;
}
if (cbReq > cbData)
{
- LogRel(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid size %#x, expected >= %#x (hdr); type=%#x!!\n",
- cbData, cbReq, enmType));
+ LogRelFunc(("Invalid size %#x, expected >= %#x (hdr); type=%#x!!\n",
+ cbData, cbReq, enmType));
return VERR_INVALID_PARAMETER;
}
rc = VbglGRVerify(pReqHdr, cbData);
if (RT_FAILURE(rc))
{
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid header: size %#x, expected >= %#x (hdr); type=%#x; rc=%Rrc!!\n",
- cbData, cbReq, enmType, rc));
+ LogFlowFunc(("Invalid header: size %#x, expected >= %#x (hdr); type=%#x; rc=%Rrc\n",
+ cbData, cbReq, enmType, rc));
return rc;
}
rc = VBoxGuestCheckIfVMMReqAllowed(pDevExt, pSession, enmType, pReqHdr);
if (RT_FAILURE(rc))
{
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: Operation not allowed! type=%#x rc=%Rrc\n", enmType, rc));
+ LogFlowFunc(("Operation not allowed! type=%#x, rc=%Rrc\n", enmType, rc));
return rc;
}
@@ -1772,8 +1942,8 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
rc = VbglGRAlloc(&pReqCopy, cbReq, enmType);
if (RT_FAILURE(rc))
{
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
- cbReq, cbReq, rc));
+ LogFlowFunc(("Failed to allocate %u (%#x) bytes to cache the request; rc=%Rrc\n",
+ cbReq, cbReq, rc));
return rc;
}
memcpy(pReqCopy, pReqHdr, cbReq);
@@ -1793,10 +1963,11 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
*pcbDataReturned = cbReq;
}
else if (RT_FAILURE(rc))
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: VbglGRPerform - rc=%Rrc!\n", rc));
+ LogFlowFunc(("VbglGRPerform failed; rc=%Rrc\n", rc));
else
{
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: request execution failed; VMMDev rc=%Rrc!\n", pReqCopy->rc));
+ LogFlowFunc(("Request execution failed; VMMDev rc=%Rrc\n",
+ pReqCopy->rc));
rc = pReqCopy->rc;
}
@@ -1805,25 +1976,66 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
}
-static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt, VBoxGuestFilterMaskInfo *pInfo)
+static int VBoxGuestCommonIOCtl_CtlFilterMask(PVBOXGUESTDEVEXT pDevExt,
+ PVBOXGUESTSESSION pSession,
+ VBoxGuestFilterMaskInfo *pInfo)
{
- VMMDevCtlGuestFilterMask *pReq;
- int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_CtlGuestFilterMask);
- if (RT_FAILURE(rc))
- {
- Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
- sizeof(*pReq), sizeof(*pReq), rc));
- return rc;
- }
+ int rc;
- pReq->u32OrMask = pInfo->u32OrMask;
- pReq->u32NotMask = pInfo->u32NotMask;
- pReq->u32NotMask &= ~pDevExt->fFixedEvents; /* don't permit these to be cleared! */
- rc = VbglGRPerform(&pReq->header);
- if (RT_FAILURE(rc))
- Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: VbglGRPerform failed, rc=%Rrc!\n", rc));
+ if ((pInfo->u32OrMask | pInfo->u32NotMask) & ~VMMDEV_EVENT_VALID_EVENT_MASK)
+ return VERR_INVALID_PARAMETER;
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ pSession->fFilterMask |= pInfo->u32OrMask;
+ pSession->fFilterMask &= ~pInfo->u32NotMask;
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
+ rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_FilterMask);
+ return rc;
+}
- VbglGRFree(&pReq->header);
+
+static int VBoxGuestCommonIOCtl_SetCapabilities(PVBOXGUESTDEVEXT pDevExt,
+ PVBOXGUESTSESSION pSession,
+ VBoxGuestSetCapabilitiesInfo *pInfo)
+{
+ int rc;
+
+ if ( (pInfo->u32OrMask | pInfo->u32NotMask)
+ & ~VMMDEV_GUEST_CAPABILITIES_MASK)
+ return VERR_INVALID_PARAMETER;
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ pSession->fCapabilities |= pInfo->u32OrMask;
+ pSession->fCapabilities &= ~pInfo->u32NotMask;
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
+ rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_Capabilities);
+ return rc;
+}
+
+
+/**
+ * Sets the mouse status features for this session and updates them
+ * globally.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevExt The device extention.
+ * @param pSession The session.
+ * @param fFeatures New bitmap of enabled features.
+ */
+static int vboxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt,
+ PVBOXGUESTSESSION pSession,
+ uint32_t fFeatures)
+{
+ int rc;
+
+ if (fFeatures & ~VMMDEV_MOUSE_GUEST_MASK)
+ return VERR_INVALID_PARAMETER;
+ /* Since this is more of a negative feature we invert it to get the real
+ * feature (when the guest does not need the host cursor). */
+ fFeatures ^= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
+ RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ pSession->fMouseStatus = fFeatures;
+ RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
+ rc = vboxGuestUpdateHostFlags(pDevExt, pSession, HostFlags_MouseStatus);
return rc;
}
@@ -1894,7 +2106,7 @@ static int VBoxGuestHGCMAsyncWaitCallbackWorker(VMMDevHGCMRequestHeader volatile
&& rc != VERR_TIMEOUT
&& ( !fInterruptible
|| rc != VERR_INTERRUPTED))
- LogRel(("VBoxGuestHGCMAsyncWaitCallback: wait failed! %Rrc\n", rc));
+ LogRelFlow(("wait failed! %Rrc\n", rc));
VBoxGuestWaitFreeUnlocked(pDevExt, pWait);
return rc;
@@ -1909,7 +2121,7 @@ static int VBoxGuestHGCMAsyncWaitCallbackWorker(VMMDevHGCMRequestHeader volatile
static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)
{
PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
- Log(("VBoxGuestHGCMAsyncWaitCallback: requestType=%d\n", pHdr->header.requestType));
+ LogFlowFunc(("requestType=%d\n", pHdr->header.requestType));
return VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr,
pDevExt,
false /* fInterruptible */,
@@ -1926,7 +2138,7 @@ static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallbackInterruptible(VMMDevHGCMR
void *pvUser, uint32_t u32User)
{
PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser;
- Log(("VBoxGuestHGCMAsyncWaitCallbackInterruptible: requestType=%d\n", pHdr->header.requestType));
+ LogFlowFunc(("requestType=%d\n", pHdr->header.requestType));
return VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr,
pDevExt,
true /* fInterruptible */,
@@ -1945,15 +2157,15 @@ static int VBoxGuestCommonIOCtl_HGCMConnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUEST
* call is performed in an ASYNC fashion. The function is not able
* to deal with cancelled requests.
*/
- Log(("VBoxGuestCommonIOCtl: HGCM_CONNECT: %.128s\n",
- pInfo->Loc.type == VMMDevHGCMLoc_LocalHost || pInfo->Loc.type == VMMDevHGCMLoc_LocalHost_Existing
- ? pInfo->Loc.u.host.achName : "<not local host>"));
+ LogFlowFunc(("%.128s\n",
+ pInfo->Loc.type == VMMDevHGCMLoc_LocalHost || pInfo->Loc.type == VMMDevHGCMLoc_LocalHost_Existing
+ ? pInfo->Loc.u.host.achName : "<not local host>"));
rc = VbglR0HGCMInternalConnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
if (RT_SUCCESS(rc))
{
- Log(("VBoxGuestCommonIOCtl: HGCM_CONNECT: u32Client=%RX32 result=%Rrc (rc=%Rrc)\n",
- pInfo->u32ClientID, pInfo->result, rc));
+ LogFlowFunc(("u32Client=%RX32 result=%Rrc (rc=%Rrc)\n",
+ pInfo->u32ClientID, pInfo->result, rc));
if (RT_SUCCESS(pInfo->result))
{
/*
@@ -1975,7 +2187,7 @@ static int VBoxGuestCommonIOCtl_HGCMConnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUEST
VBoxGuestHGCMDisconnectInfo Info;
if (s_cErrors++ < 32)
- LogRel(("VBoxGuestCommonIOCtl: HGCM_CONNECT: too many HGCMConnect calls for one session!\n"));
+ LogRelFunc(("Too many HGCMConnect calls for one session\n"));
Info.result = 0;
Info.u32ClientID = pInfo->u32ClientID;
@@ -1983,6 +2195,8 @@ static int VBoxGuestCommonIOCtl_HGCMConnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGUEST
return VERR_TOO_MANY_OPEN_FILES;
}
}
+ else
+ rc = pInfo->result;
if (pcbDataReturned)
*pcbDataReturned = sizeof(*pInfo);
}
@@ -2011,7 +2225,7 @@ static int VBoxGuestCommonIOCtl_HGCMDisconnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGU
{
static unsigned s_cErrors = 0;
if (s_cErrors++ > 32)
- LogRel(("VBoxGuestCommonIOCtl: HGCM_DISCONNECT: u32Client=%RX32\n", u32ClientId));
+ LogRelFunc(("u32Client=%RX32\n", u32ClientId));
return VERR_INVALID_HANDLE;
}
@@ -2020,11 +2234,11 @@ static int VBoxGuestCommonIOCtl_HGCMDisconnect(PVBOXGUESTDEVEXT pDevExt, PVBOXGU
* call is performed in an ASYNC fashion. The function is not able
* to deal with cancelled requests.
*/
- Log(("VBoxGuestCommonIOCtl: HGCM_DISCONNECT: u32Client=%RX32\n", pInfo->u32ClientID));
+ LogFlowFunc(("u32Client=%RX32\n", pInfo->u32ClientID));
rc = VbglR0HGCMInternalDisconnect(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, RT_INDEFINITE_WAIT);
if (RT_SUCCESS(rc))
{
- Log(("VBoxGuestCommonIOCtl: HGCM_DISCONNECT: result=%Rrc\n", pInfo->result));
+ LogFlowFunc(("Disconnected with rc=%Rrc\n", pInfo->result)); /** int32_t vs. int! */
if (pcbDataReturned)
*pcbDataReturned = sizeof(*pInfo);
}
@@ -2056,7 +2270,7 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
*/
if (pInfo->cParms > 4096) /* (Just make sure it doesn't overflow the next check.) */
{
- LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: cParm=%RX32 is not sane\n", pInfo->cParms));
+ LogRelFunc(("cParm=%RX32 is not sane\n", pInfo->cParms));
return VERR_INVALID_PARAMETER;
}
@@ -2069,8 +2283,8 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
cbActual += pInfo->cParms * sizeof(HGCMFunctionParameter);
if (cbData < cbActual)
{
- LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n",
- cbData, cbData, cbActual, cbActual));
+ LogRelFunc(("cbData=%#zx (%zu) required size is %#zx (%zu)\n",
+ cbData, cbData, cbActual, cbActual));
return VERR_INVALID_PARAMETER;
}
@@ -2086,7 +2300,7 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
{
static unsigned s_cErrors = 0;
if (s_cErrors++ > 32)
- LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: Invalid handle. u32Client=%RX32\n", u32ClientId));
+ LogRelFunc(("Invalid handle; u32Client=%RX32\n", u32ClientId));
return VERR_INVALID_HANDLE;
}
@@ -2096,27 +2310,28 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
* deal with cancelled requests, so we let user more requests
* be interruptible (should add a flag for this later I guess).
*/
- Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));
+ LogFlowFunc(("u32Client=%RX32\n", pInfo->u32ClientID));
fFlags = !fUserData && pSession->R0Process == NIL_RTR0PROCESS ? VBGLR0_HGCMCALL_F_KERNEL : VBGLR0_HGCMCALL_F_USER;
+ uint32_t cbInfo = (uint32_t)(cbData - cbExtra);
#ifdef RT_ARCH_AMD64
if (f32bit)
{
if (fInterruptible)
- rc = VbglR0HGCMInternalCall32(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+ rc = VbglR0HGCMInternalCall32(pInfo, cbInfo, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
else
- rc = VbglR0HGCMInternalCall32(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
+ rc = VbglR0HGCMInternalCall32(pInfo, cbInfo, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
}
else
#endif
{
if (fInterruptible)
- rc = VbglR0HGCMInternalCall(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+ rc = VbglR0HGCMInternalCall(pInfo, cbInfo, fFlags, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
else
- rc = VbglR0HGCMInternalCall(pInfo, cbData - cbExtra, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
+ rc = VbglR0HGCMInternalCall(pInfo, cbInfo, fFlags, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
}
if (RT_SUCCESS(rc))
{
- Log(("VBoxGuestCommonIOCtl: HGCM_CALL: result=%Rrc\n", pInfo->result));
+ LogFlowFunc(("Result rc=%Rrc\n", pInfo->result)); /** int32_t vs. int! */
if (pcbDataReturned)
*pcbDataReturned = cbActual;
}
@@ -2127,17 +2342,18 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
{
static unsigned s_cErrors = 0;
if (s_cErrors++ < 32)
- LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: %s Failed. rc=%Rrc.\n", f32bit ? "32" : "64", rc));
+ LogRelFunc(("%s-bit call failed; rc=%Rrc\n",
+ f32bit ? "32" : "64", rc));
}
else
- Log(("VBoxGuestCommonIOCtl: HGCM_CALL: %s Failed. rc=%Rrc.\n", f32bit ? "32" : "64", rc));
+ LogFlowFunc(("%s-bit call failed; rc=%Rrc\n",
+ f32bit ? "32" : "64", rc));
}
return rc;
}
-
-
#endif /* VBOX_WITH_HGCM */
+
/**
* Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3.
*
@@ -2156,11 +2372,9 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
static int VBoxGuestCommonIOCtl_CheckMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
VBoxGuestCheckBalloonInfo *pInfo, size_t *pcbDataReturned)
{
- VMMDevGetMemBalloonChangeRequest *pReq;
- int rc;
+ LogFlowFuncEnter();
- Log(("VBoxGuestCommonIOCtl: CHECK_MEMORY_BALLOON\n"));
- rc = RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
+ int rc = RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
AssertRCReturn(rc, rc);
/*
@@ -2169,11 +2383,15 @@ static int VBoxGuestCommonIOCtl_CheckMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVB
*/
if ( pDevExt->MemBalloon.pOwner != pSession
&& pDevExt->MemBalloon.pOwner == NULL)
+ {
pDevExt->MemBalloon.pOwner = pSession;
+ }
if (pDevExt->MemBalloon.pOwner == pSession)
{
- rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest), VMMDevReq_GetMemBalloonChangeRequest);
+ VMMDevGetMemBalloonChangeRequest *pReq;
+ rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest),
+ VMMDevReq_GetMemBalloonChangeRequest);
if (RT_SUCCESS(rc))
{
/*
@@ -2202,7 +2420,7 @@ static int VBoxGuestCommonIOCtl_CheckMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVB
*pcbDataReturned = sizeof(VBoxGuestCheckBalloonInfo);
}
else
- LogRel(("VBoxGuestCommonIOCtl: CHECK_MEMORY_BALLOON: VbglGRPerform failed. rc=%Rrc\n", rc));
+ LogRelFunc(("VbglGRPerform failed; rc=%Rrc\n", rc));
VbglGRFree(&pReq->header);
}
}
@@ -2210,7 +2428,8 @@ static int VBoxGuestCommonIOCtl_CheckMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVB
rc = VERR_PERMISSION_DENIED;
RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
- Log(("VBoxGuestCommonIOCtl: CHECK_MEMORY_BALLOON returns %Rrc\n", rc));
+
+ LogFlowFunc(("Returns %Rrc\n", rc));
return rc;
}
@@ -2244,7 +2463,8 @@ static int VBoxGuestCommonIOCtl_ChangeMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PV
if (pDevExt->MemBalloon.pOwner == pSession)
{
- rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, !!pInfo->fInflate);
+ rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr,
+ !!pInfo->fInflate);
if (pcbDataReturned)
*pcbDataReturned = 0;
}
@@ -2270,197 +2490,25 @@ static int VBoxGuestCommonIOCtl_ChangeMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PV
static int VBoxGuestCommonIOCtl_WriteCoreDump(PVBOXGUESTDEVEXT pDevExt, VBoxGuestWriteCoreDump *pInfo)
{
VMMDevReqWriteCoreDump *pReq = NULL;
- int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_WriteCoreDump);
+ int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevReqWriteCoreDump),
+ VMMDevReq_WriteCoreDump);
if (RT_FAILURE(rc))
{
- Log(("VBoxGuestCommonIOCtl: WRITE_CORE_DUMP: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
- sizeof(*pReq), sizeof(*pReq), rc));
+ LogFlowFunc(("Failed to allocate %u (%#x) bytes to cache the request; rc=%Rrc\n",
+ sizeof(VMMDevReqWriteCoreDump), sizeof(VMMDevReqWriteCoreDump), rc));
return rc;
}
pReq->fFlags = pInfo->fFlags;
rc = VbglGRPerform(&pReq->header);
if (RT_FAILURE(rc))
- Log(("VBoxGuestCommonIOCtl: WRITE_CORE_DUMP: VbglGRPerform failed, rc=%Rrc!\n", rc));
+ LogFlowFunc(("VbglGRPerform failed, rc=%Rrc\n", rc));
VbglGRFree(&pReq->header);
return rc;
}
-#ifdef DEBUG
-/** Unit test SetMouseStatus instead of really executing the request. */
-static bool g_test_fSetMouseStatus = false;
-/** When unit testing SetMouseStatus, the fake RC for the GR to return. */
-static int g_test_SetMouseStatusGRRC;
-/** When unit testing SetMouseStatus this will be set to the status passed to
- * the GR. */
-static uint32_t g_test_statusSetMouseStatus;
-#endif
-
-static int vboxguestcommonSetMouseStatus(uint32_t fFeatures)
-{
- VMMDevReqMouseStatus *pReq;
- int rc;
-
- LogRelFlowFunc(("fFeatures=%u\n", (int) fFeatures));
- rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_SetMouseStatus);
- if (RT_SUCCESS(rc))
- {
- pReq->mouseFeatures = fFeatures;
- pReq->pointerXPos = 0;
- pReq->pointerYPos = 0;
-#ifdef DEBUG
- if (g_test_fSetMouseStatus)
- {
- g_test_statusSetMouseStatus = pReq->mouseFeatures;
- rc = g_test_SetMouseStatusGRRC;
- }
- else
-#endif
- rc = VbglGRPerform(&pReq->header);
- VbglGRFree(&pReq->header);
- }
- LogRelFlowFunc(("rc=%Rrc\n", rc));
- return rc;
-}
-
-
-/**
- * Sets the mouse status features for this session and updates them
- * globally. We aim to ensure that if several threads call this in
- * parallel the most recent status will always end up being set.
- *
- * @returns VBox status code.
- *
- * @param pDevExt The device extention.
- * @param pSession The session.
- * @param fFeatures New bitmap of enabled features.
- */
-static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures)
-{
- uint32_t fNewDevExtStatus = 0;
- unsigned i;
- int rc;
- /* Exit early if nothing has changed - hack to work around the
- * Windows Additions not using the common code. */
- bool fNoAction;
-
- RTSpinlockAcquire(pDevExt->SessionSpinlock);
-
- /* For all the bits which the guest is allowed to set, check whether the
- * requested value is different to the current one and adjust the global
- * usage counter and if appropriate the global state if so. */
- for (i = 0; i < sizeof(fFeatures) * 8; i++)
- {
- if (RT_BIT_32(i) & VMMDEV_MOUSE_GUEST_MASK)
- {
- if ( (RT_BIT_32(i) & fFeatures)
- && !(RT_BIT_32(i) & pSession->fMouseStatus))
- pDevExt->acMouseFeatureUsage[i]++;
- else if ( !(RT_BIT_32(i) & fFeatures)
- && (RT_BIT_32(i) & pSession->fMouseStatus))
- pDevExt->acMouseFeatureUsage[i]--;
- }
- if (pDevExt->acMouseFeatureUsage[i] > 0)
- fNewDevExtStatus |= RT_BIT_32(i);
- }
-
- pSession->fMouseStatus = fFeatures & VMMDEV_MOUSE_GUEST_MASK;
- fNoAction = (pDevExt->fMouseStatus == fNewDevExtStatus);
- pDevExt->fMouseStatus = fNewDevExtStatus;
-
- RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock);
- if (fNoAction)
- return VINF_SUCCESS;
-
- do
- {
- fNewDevExtStatus = pDevExt->fMouseStatus;
- rc = vboxguestcommonSetMouseStatus(fNewDevExtStatus);
- } while ( RT_SUCCESS(rc)
- && fNewDevExtStatus != pDevExt->fMouseStatus);
-
- return rc;
-}
-
-
-#ifdef DEBUG
-/** Unit test for the SET_MOUSE_STATUS IoCtl. Since this is closely tied to
- * the code in question it probably makes most sense to keep it next to the
- * code. */
-static void testSetMouseStatus(void)
-{
- uint32_t u32Data;
- int rc;
- RTSPINLOCK Spinlock;
-
- g_test_fSetMouseStatus = true;
- rc = RTSpinlockCreate(&Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestTest");
- AssertRCReturnVoid(rc);
- {
- VBOXGUESTDEVEXT DevExt = { 0 };
- VBOXGUESTSESSION Session = { 0 };
-
- g_test_statusSetMouseStatus = ~0;
- g_test_SetMouseStatusGRRC = VINF_SUCCESS;
- DevExt.SessionSpinlock = Spinlock;
- u32Data = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertRCSuccess(rc);
- AssertMsg( g_test_statusSetMouseStatus
- == VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE,
- ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
- DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR) - 1] = 1;
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertRCSuccess(rc);
- AssertMsg( g_test_statusSetMouseStatus
- == ( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
- | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR),
- ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
- u32Data = VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE; /* Can't change this */
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertRCSuccess(rc);
- AssertMsg( g_test_statusSetMouseStatus
- == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,
- ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
- u32Data = VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertRCSuccess(rc);
- AssertMsg( g_test_statusSetMouseStatus
- == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,
- ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
- u32Data = 0;
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertRCSuccess(rc);
- AssertMsg( g_test_statusSetMouseStatus
- == VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR,
- ("Actual status: 0x%x\n", g_test_statusSetMouseStatus));
- AssertMsg(DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR) - 1] == 1,
- ("Actual value: %d\n", DevExt.acMouseFeatureUsage[ASMBitFirstSetU32(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR)]));
- g_test_SetMouseStatusGRRC = VERR_UNRESOLVED_ERROR;
- /* This should succeed as the host request should not be made
- * since nothing has changed. */
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertRCSuccess(rc);
- /* This should fail with VERR_UNRESOLVED_ERROR as set above. */
- u32Data = VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
- rc = VBoxGuestCommonIOCtl(VBOXGUEST_IOCTL_SET_MOUSE_STATUS, &DevExt,
- &Session, &u32Data, sizeof(u32Data), NULL);
- AssertMsg(rc == VERR_UNRESOLVED_ERROR, ("rc == %Rrc\n", rc));
- /* Untested paths: out of memory; race setting status to host */
- }
- RTSpinlockDestroy(Spinlock);
- g_test_fSetMouseStatus = false;
-}
-#endif
-
/**
* Guest backdoor logging.
@@ -2472,12 +2520,14 @@ static void testSetMouseStatus(void)
* @param cbData Size of the buffer.
* @param pcbDataReturned Where to store the amount of returned data. Can be NULL.
*/
-static int VBoxGuestCommonIOCtl_Log(PVBOXGUESTDEVEXT pDevExt, const char *pch, size_t cbData, size_t *pcbDataReturned)
+static int VBoxGuestCommonIOCtl_Log(PVBOXGUESTDEVEXT pDevExt, const char *pch, size_t cbData, size_t *pcbDataReturned, bool fUserSession)
{
NOREF(pch);
NOREF(cbData);
if (pDevExt->fLoggingEnabled)
RTLogBackdoorPrintf("%.*s", cbData, pch);
+ else if (!fUserSession)
+ LogRel(("%.*s", cbData, pch));
else
Log(("%.*s", cbData, pch));
if (pcbDataReturned)
@@ -2493,6 +2543,18 @@ static bool VBoxGuestCommonGuestCapsValidateValues(uint32_t fCaps)
return true;
}
+/** Check whether any unreported VMM device events should be reported to any of
+ * the currently listening sessions. In addition, report any events in
+ * @a fGenFakeEvents.
+ * @note This is called by GUEST_CAPS_ACQUIRE in case any pending events can now
+ * be dispatched to the session which acquired capabilities. The fake
+ * events are a hack to wake up threads in that session which would not
+ * otherwise be woken.
+ * @todo Why not just use CANCEL_ALL_WAITEVENTS to do the waking up rather than
+ * adding additional code to the driver?
+ * @todo Why does acquiring capabilities block and unblock events? Capabilities
+ * are supposed to control what is reported to the host, we already have
+ * separate requests for blocking and unblocking events. */
static void VBoxGuestCommonCheckEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fGenFakeEvents)
{
RTSpinlockAcquire(pDevExt->EventSpinlock);
@@ -2530,36 +2592,40 @@ static void VBoxGuestCommonCheckEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSI
#endif
}
+/** Switch the capabilities in @a fOrMask to "acquire" mode if they are not
+ * already in "set" mode. If @a enmFlags is not set to
+ * VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE, also try to acquire those
+ * capabilities for the current session and release those in @a fNotFlag. */
static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags)
{
uint32_t fSetCaps = 0;
if (!VBoxGuestCommonGuestCapsValidateValues(fOrMask))
{
- LogRel(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- invalid fOrMask\n",
- pSession, fOrMask, fNotMask, enmFlags));
+ LogRelFunc(("pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- invalid fOrMask\n",
+ pSession, fOrMask, fNotMask, enmFlags));
return VERR_INVALID_PARAMETER;
}
if ( enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE
&& enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_NONE)
{
- LogRel(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- invalid enmFlags %d\n",
- pSession, fOrMask, fNotMask, enmFlags));
+ LogRelFunc(("pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- invalid enmFlags %d\n",
+ pSession, fOrMask, fNotMask, enmFlags));
return VERR_INVALID_PARAMETER;
}
if (!VBoxGuestCommonGuestCapsModeSet(pDevExt, fOrMask, true, &fSetCaps))
{
- LogRel(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- calling caps acquire for set caps\n",
- pSession, fOrMask, fNotMask, enmFlags));
+ LogRelFunc(("pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- calling caps acquire for set caps\n",
+ pSession, fOrMask, fNotMask, enmFlags));
return VERR_INVALID_STATE;
}
if (enmFlags & VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE)
{
- Log(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- configured acquire caps: 0x%x\n",
- pSession, fOrMask, fNotMask, enmFlags));
+ LogRelFunc(("pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- configured acquire caps: 0x%x\n",
+ pSession, fOrMask, fNotMask, enmFlags));
return VINF_SUCCESS;
}
@@ -2599,7 +2665,7 @@ static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
if (fOtherConflictingCaps)
{
- Log(("VBoxGuest: Caps 0x%x were busy\n", fOtherConflictingCaps));
+ LogFlowFunc(("Caps 0x%x were busy\n", fOtherConflictingCaps));
return VERR_RESOURCE_BUSY;
}
@@ -2613,7 +2679,7 @@ static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
int rc = VBoxGuestSetGuestCapabilities(fSessionOrCaps, fSessionNotCaps);
if (RT_FAILURE(rc))
{
- LogRel(("VBoxGuestCommonGuestCapsAcquire: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
+ LogRelFunc(("VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
/* Failure branch
* this is generally bad since e.g. failure to release the caps may result in other sessions not being able to use it
@@ -2644,7 +2710,7 @@ static int VBoxGuestCommonIOCTL_GuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOX
{
int rc = VBoxGuestCommonGuestCapsAcquire(pDevExt, pSession, pAcquire->u32OrMask, pAcquire->u32NotMask, pAcquire->enmFlags);
if (RT_FAILURE(rc))
- LogRel(("VBoxGuestCommonGuestCapsAcquire: failed rc=%Rrc\n", rc));
+ LogRelFunc(("Failed, rc=%Rrc\n", rc));
pAcquire->rc = rc;
return VINF_SUCCESS;
}
@@ -2669,8 +2735,8 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
void *pvData, size_t cbData, size_t *pcbDataReturned)
{
int rc;
- Log(("VBoxGuestCommonIOCtl: iFunction=%#x pDevExt=%p pSession=%p pvData=%p cbData=%zu\n",
- iFunction, pDevExt, pSession, pvData, cbData));
+ LogFlowFunc(("iFunction=%#x, pDevExt=%p, pSession=%p, pvData=%p, cbData=%zu\n",
+ iFunction, pDevExt, pSession, pvData, cbData));
/*
* Make sure the returned data size is set to zero.
@@ -2781,7 +2847,7 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)))
{
CHECKRET_MIN_SIZE("LOG", 1);
- rc = VBoxGuestCommonIOCtl_Log(pDevExt, (char *)pvData, cbData, pcbDataReturned);
+ rc = VBoxGuestCommonIOCtl_Log(pDevExt, (char *)pvData, cbData, pcbDataReturned, pSession->fUserSession);
}
else
{
@@ -2814,8 +2880,10 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
break;
case VBOXGUEST_IOCTL_CTL_FILTER_MASK:
- CHECKRET_MIN_SIZE("CTL_FILTER_MASK", sizeof(VBoxGuestFilterMaskInfo));
- rc = VBoxGuestCommonIOCtl_CtlFilterMask(pDevExt, (VBoxGuestFilterMaskInfo *)pvData);
+ CHECKRET_MIN_SIZE("CTL_FILTER_MASK",
+ sizeof(VBoxGuestFilterMaskInfo));
+ rc = VBoxGuestCommonIOCtl_CtlFilterMask(pDevExt, pSession,
+ (VBoxGuestFilterMaskInfo *)pvData);
break;
#ifdef VBOX_WITH_HGCM
@@ -2853,7 +2921,7 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
case VBOXGUEST_IOCTL_SET_MOUSE_STATUS:
CHECKRET_SIZE("SET_MOUSE_STATUS", sizeof(uint32_t));
- rc = VBoxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession,
+ rc = vboxGuestCommonIOCtl_SetMouseStatus(pDevExt, pSession,
*(uint32_t *)pvData);
break;
@@ -2870,17 +2938,24 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
*pcbDataReturned = sizeof(VBoxGuestCapsAquire);
break;
+ case VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES:
+ CHECKRET_MIN_SIZE("SET_GUEST_CAPABILITIES",
+ sizeof(VBoxGuestSetCapabilitiesInfo));
+ rc = VBoxGuestCommonIOCtl_SetCapabilities(pDevExt, pSession,
+ (VBoxGuestSetCapabilitiesInfo *)pvData);
+ break;
+
default:
{
- LogRel(("VBoxGuestCommonIOCtl: Unknown request iFunction=%#x stripped size=%#x\n",
- iFunction, VBOXGUEST_IOCTL_STRIP_SIZE(iFunction)));
+ LogRelFunc(("Unknown request iFunction=%#x, stripped size=%#x\n",
+ iFunction, VBOXGUEST_IOCTL_STRIP_SIZE(iFunction)));
rc = VERR_NOT_SUPPORTED;
break;
}
}
}
- Log(("VBoxGuestCommonIOCtl: returns %Rrc *pcbDataReturned=%zu\n", rc, pcbDataReturned ? *pcbDataReturned : 0));
+ LogFlowFunc(("Returning %Rrc *pcbDataReturned=%zu\n", rc, pcbDataReturned ? *pcbDataReturned : 0));
return rc;
}
@@ -2896,9 +2971,6 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
*/
bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
{
-#ifndef RT_OS_WINDOWS
- VBoxGuestMouseSetNotifyCallback MouseNotifyCallback = { NULL, NULL };
-#endif
bool fMousePositionChanged = false;
VMMDevEvents volatile *pReq = pDevExt->pIrqAckEvents;
int rc = 0;
@@ -2911,11 +2983,9 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
return false;
/*
- * Enter the spinlock, increase the ISR count and check if it's our IRQ or
- * not.
+ * Enter the spinlock and check if it's our IRQ or not.
*/
RTSpinlockAcquire(pDevExt->EventSpinlock);
- ASMAtomicIncU32(&pDevExt->cISR);
fOurIrq = pDevExt->pVMMDevMemory->V.V1_04.fHaveEvents;
if (fOurIrq)
{
@@ -2934,18 +3004,21 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
PVBOXGUESTWAIT pWait;
PVBOXGUESTWAIT pSafe;
- Log3(("VBoxGuestCommonISR: acknowledge events succeeded %#RX32\n", fEvents));
-
+#ifndef DEBUG_andy
+ LogFlowFunc(("Acknowledge events succeeded: %#RX32\n", fEvents));
+#endif
/*
* VMMDEV_EVENT_MOUSE_POSITION_CHANGED can only be polled for.
*/
if (fEvents & VMMDEV_EVENT_MOUSE_POSITION_CHANGED)
{
-#ifndef RT_OS_WINDOWS
- MouseNotifyCallback = pDevExt->MouseNotifyCallback;
-#endif
fMousePositionChanged = true;
fEvents &= ~VMMDEV_EVENT_MOUSE_POSITION_CHANGED;
+#ifndef RT_OS_WINDOWS
+ if (pDevExt->MouseNotifyCallback.pfnNotify)
+ pDevExt->MouseNotifyCallback.pfnNotify
+ (pDevExt->MouseNotifyCallback.pvUser);
+#endif
}
#ifdef VBOX_WITH_HGCM
@@ -2998,11 +3071,13 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
ASMAtomicWriteU32(&pDevExt->f32PendingEvents, fEvents);
}
else /* something is serious wrong... */
- Log(("VBoxGuestCommonISR: acknowledge events failed rc=%Rrc (events=%#x)!!\n",
- pReq->header.rc, pReq->events));
+ LogFlowFunc(("Acknowledging events failed, rc=%Rrc (events=%#x)\n",
+ pReq->header.rc, pReq->events));
}
+#ifndef DEBUG_andy
else
- LogFlow(("VBoxGuestCommonISR: not ours\n"));
+ LogFlowFunc(("Not ours\n"));
+#endif
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
@@ -3023,13 +3098,8 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
{
ASMAtomicIncU32(&pDevExt->u32MousePosChangedSeq);
VBoxGuestNativeISRMousePollEvent(pDevExt);
-#ifndef RT_OS_WINDOWS
- if (MouseNotifyCallback.pfnNotify)
- MouseNotifyCallback.pfnNotify(MouseNotifyCallback.pvUser);
-#endif
}
- ASMAtomicDecU32(&pDevExt->cISR);
Assert(rc == 0);
NOREF(rc);
return fOurIrq;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
index b2a427c..79bdc74 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
@@ -157,30 +157,26 @@ typedef struct VBOXGUESTDEVEXT
/** Spinlock various items in the VBOXGUESTSESSION. */
RTSPINLOCK SessionSpinlock;
+ /** List of guest sessions (VBOXGUESTSESSION). We currently traverse this
+ * but do not search it, so a list data type should be fine. Use under the
+ * #SessionSpinlock lock. */
+ RTLISTANCHOR SessionList;
/** Flag indicating whether logging to the release log
* is enabled. */
bool fLoggingEnabled;
/** Memory balloon information for RTR0MemObjAllocPhysNC(). */
VBOXGUESTMEMBALLOON MemBalloon;
- /** For each mouse status feature the number of sessions which have
- * enabled it. A feature is enabled globally if at least one session has
- * requested it. */
- /** @todo can we programmatically determine the size of the array and
- * still get the following alignment right? */
- uint32_t volatile acMouseFeatureUsage[32];
- /** The mouse feature status matching the counts above. These are updated
- * together inside the session spinlock. */
- uint32_t volatile fMouseStatus;
- /** Counter of number of active ISRs. Currently used for safely removing
- * the mouse handler callback. */
- uint32_t volatile cISR;
/** Callback and user data for a kernel mouse handler. */
VBoxGuestMouseSetNotifyCallback MouseNotifyCallback;
- /* list of caps used in acquire mode */
+ /** Guest capabilities which have been set to "acquire" mode. This means
+ * that only one session can use them at a time, and that they will be
+ * automatically cleaned up if that session exits without doing so. */
uint32_t u32AcquireModeGuestCaps;
- /* list of caps used in set mode */
+ /** Guest capabilities which have been set to "set" mode. This just means
+ * that they have been blocked from ever being set to "acquire" mode. */
uint32_t u32SetModeGuestCaps;
- /* currently acquired (and reported) guest caps */
+ /** Mask of all capabilities which are currently acquired by some session
+ * and as such reported to the host. */
uint32_t u32GuestCaps;
} VBOXGUESTDEVEXT;
/** Pointer to the VBoxGuest driver data. */
@@ -196,6 +192,8 @@ typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
*/
typedef struct VBOXGUESTSESSION
{
+ /** The list node. */
+ RTLISTNODE ListNode;
#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
/** Pointer to the next session with the same hash. */
PVBOXGUESTSESSION pNextHash;
@@ -222,17 +220,39 @@ typedef struct VBOXGUESTSESSION
/** The last consumed VMMDEV_EVENT_MOUSE_POSITION_CHANGED sequence number.
* Used to implement polling. */
uint32_t volatile u32MousePosChangedSeq;
+ /** VMMDev events requested. An event type requested in any guest session
+ * will be added to the host filter.
+ * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
+ uint32_t fFilterMask;
+ /** Capabilities supported. A capability enabled in any guest session will
+ * be enabled for the host.
+ * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
+ uint32_t fCapabilities;
/** Mouse features supported. A feature enabled in any guest session will
- * be enabled for the host. */
- uint32_t volatile fMouseStatus;
+ * be enabled for the host.
+ * @note We invert the VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR feature in this
+ * bitmap. The logic of this is that the real feature is when the host
+ * cursor is not needed, and we tell the host it is not needed if any
+ * session explicitly fails to assert it. Storing it inverted simplifies
+ * the checks.
+ * Use under the VBOXGUESTDEVEXT#SessionSpinlock lock. */
+ uint32_t fMouseStatus;
#ifdef RT_OS_DARWIN
/** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
void *pvVBoxGuestClient;
/** Whether this session has been opened or not. */
bool fOpened;
#endif
- /* Guest Caps Acquired & Reported by this session */
+ /** Mask of guest capabilities acquired by this session. These will all be
+ * reported to the host. */
uint32_t u32AquiredGuestCaps;
+ /** Whether a CANCEL_ALL_WAITEVENTS is pending. This happens when
+ * CANCEL_ALL_WAITEVENTS is called, but no call to WAITEVENT is in process
+ * in the current session. In that case the next call will be interrupted
+ * at once. */
+ bool volatile fPendingCancelWaitEvents;
+ /** Does this session belong to a root process or a user one? */
+ bool fUserSession;
} VBOXGUESTSESSION;
RT_C_DECLS_BEGIN
diff --git a/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile b/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
index a25cc9f..e53c03c 100644
--- a/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
+++ b/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
@@ -77,6 +77,7 @@ SRCS += \
.PATH: ${.CURDIR}/common/string
SRCS += \
RTStrCopy.c \
+ RTStrCopyEx.c \
RTStrCopyP.c \
strformat.c \
strformatrt.c \
diff --git a/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest b/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest
index 3252085..bcf74f2 100755
--- a/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest
+++ b/src/VBox/Additions/common/VBoxGuest/freebsd/files_vboxguest
@@ -112,6 +112,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/common/misc/RTAssertMsg2WeakV.cpp=>common/misc/RTAssertMsg2WeakV.c \
${PATH_ROOT}/src/VBox/Runtime/common/misc/assert.cpp=>common/misc/assert.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopy.cpp=>common/string/RTStrCopy.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>common/string/strformatrt.c \
diff --git a/src/VBox/Additions/common/VBoxGuest/linux/Makefile b/src/VBox/Additions/common/VBoxGuest/linux/Makefile
index db520ac..aaa50e1 100644
--- a/src/VBox/Additions/common/VBoxGuest/linux/Makefile
+++ b/src/VBox/Additions/common/VBoxGuest/linux/Makefile
@@ -1,4 +1,4 @@
-# $Revision: 95611 $
+# $Revision: 97163 $
## @file
# VirtualBox Guest Additions Module Makefile.
#
@@ -73,6 +73,7 @@ MOD_OBJS = \
common/misc/assert.o \
common/misc/thread.o \
common/string/RTStrCopy.o \
+ common/string/RTStrCopyEx.o \
common/string/RTStrCopyP.o \
common/string/strformat.o \
common/string/strformatrt.o \
diff --git a/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest b/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
index f9f8a9d..26faae0 100755
--- a/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
+++ b/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
@@ -122,6 +122,7 @@ FILES_VBOXGUEST_NOBIN=" \
${PATH_ROOT}/src/VBox/Runtime/common/misc/assert.cpp=>common/misc/assert.c \
${PATH_ROOT}/src/VBox/Runtime/common/misc/thread.cpp=>common/misc/thread.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopy.cpp=>common/string/RTStrCopy.c \
+ ${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyEx.cpp=>common/string/RTStrCopyEx.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/RTStrCopyP.cpp=>common/string/RTStrCopyP.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>common/string/strformatrt.c \
diff --git a/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp b/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
index 5521c14..ff1cc31 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 83575 $ */
+/* $Revision: 97151 $ */
/** @file
* VBoxGuestLib - Host-Guest Communication Manager.
*
@@ -137,36 +137,27 @@ DECLVBGL(int) VbglHGCMConnect (VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo
if (!pHandle || !pData)
return VERR_INVALID_PARAMETER;
- pHandleData = vbglHGCMHandleAlloc ();
-
- rc = VINF_SUCCESS;
-
+ pHandleData = vbglHGCMHandleAlloc();
if (!pHandleData)
- {
rc = VERR_NO_MEMORY;
- }
else
{
rc = vbglDriverOpen (&pHandleData->driver);
-
if (RT_SUCCESS(rc))
{
rc = vbglDriverIOCtl (&pHandleData->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, pData, sizeof (*pData));
-
+ if (RT_SUCCESS(rc))
+ rc = pData->result;
if (RT_SUCCESS(rc))
{
*pHandle = pHandleData;
+ return rc;
}
- else
- {
- vbglDriverClose (&pHandleData->driver);
- }
- }
- if (RT_FAILURE(rc))
- {
- vbglHGCMHandleFree (pHandleData);
+ vbglDriverClose (&pHandleData->driver);
}
+
+ vbglHGCMHandleFree (pHandleData);
}
return rc;
diff --git a/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp b/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
index efd8d76..6bfac26 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
@@ -1,10 +1,10 @@
-/* $Revision: 88366 $ */
+/* $Revision: 97150 $ */
/** @file
* VBoxGuestLib - Host-Guest Communication Manager internal functions, implemented by VBoxGuest
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -336,7 +336,7 @@ static int vbglR0HGCMInternalPreprocessCall(VBoxGuestHGCMCallInfo const *pCallIn
*/
/** @todo A more efficient strategy would be to combine buffers. However it
* is probably going to be more massive than the current code, so
- * it can wait till later. */
+ * it can wait till later. */
bool fCopyIn = pSrcParm->type != VMMDevHGCMParmType_LinAddr_Out
&& pSrcParm->type != VMMDevHGCMParmType_LinAddr_Locked_Out;
if (cb <= PAGE_SIZE / 2 - 16)
diff --git a/src/VBox/Additions/common/VBoxGuestLib/Mouse.cpp b/src/VBox/Additions/common/VBoxGuestLib/Mouse.cpp
index 03554ac..85722cf 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/Mouse.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/Mouse.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 79259 $ */
+/* $Revision: 97151 $ */
/** @file
* VBoxGuestLibR0 - Mouse Integration.
*/
@@ -45,9 +45,7 @@ DECLVBGL(int) VbglSetMouseNotifyCallback(PFNVBOXGUESTMOUSENOTIFY pfnNotify,
{
VBoxGuestMouseSetNotifyCallback NotifyCallback;
VBGLDRIVER *pDriver;
- int rc;
-
- rc = vbglGetDriver(&pDriver);
+ int rc = vbglGetDriver(&pDriver);
if (RT_FAILURE(rc))
return rc;
NotifyCallback.pfnNotify = pfnNotify;
@@ -84,6 +82,8 @@ DECLVBGL(int) VbglGetMouseStatus(uint32_t *pfFeatures, uint32_t *px,
&Req.header, sizeof(Req));
if (RT_FAILURE(rc))
return rc;
+ if (RT_FAILURE(Req.header.rc))
+ return Req.header.rc;
if (pfFeatures)
*pfFeatures = Req.mouseFeatures;
if (px)
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h b/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
index 463c13d..42bc6c1 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBGLR3Internal.h
@@ -108,6 +108,10 @@ DECLINLINE(void) VbglHGCMParmPtrSetString(HGCMFunctionParameter *pParm, const ch
#endif /* ___iprt_string_h */
+#ifdef VBOX_VBGLR3_XFREE86
+# undef strlen
+#endif /* VBOX_VBGLR3_XFREE86 */
+
RT_C_DECLS_END
#endif
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
index 3ecb438..adbc159 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
@@ -1,4 +1,4 @@
-/* $Revision: 84251 $ */
+/* $Revision: 97149 $ */
/** @file
* VBoxGuestR0LibSharedFolders - Ring 0 Shared Folders calls.
*/
@@ -446,7 +446,7 @@ DECLVBGL(int) VbglR0SharedFolderReadPageList(PVBSFCLIENT pClient, PVBSFMAP pMap,
uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
{
uint32_t cbToRead = *pcbBuffer;
- uint32_t cbData = sizeof(VBoxSFRead) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]);
+ uint32_t cbData = (uint32_t)(sizeof(VBoxSFRead) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]));
VBoxSFRead *pData = (VBoxSFRead *)RTMemTmpAlloc(cbData);
HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1);
uint16_t iPage;
@@ -526,7 +526,7 @@ DECLVBGL(int) VbglR0SfWritePhysCont(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHAND
{
uint32_t cbToWrite = *pcbBuffer;
uint32_t cPages = RT_ALIGN_32((PhysBuffer & PAGE_OFFSET_MASK) + cbToWrite, PAGE_SIZE) >> PAGE_SHIFT;
- uint32_t cbData = sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]);
+ uint32_t cbData = (uint32_t)(sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]));
VBoxSFWrite *pData = (VBoxSFWrite *)RTMemTmpAlloc(cbData);
HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1);
uint32_t iPage;
@@ -574,7 +574,7 @@ DECLVBGL(int) VbglR0SharedFolderWritePageList(PVBSFCLIENT pClient, PVBSFMAP pMap
uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
{
uint32_t cbToWrite = *pcbBuffer;
- uint32_t cbData = sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]);
+ uint32_t cbData = (uint32_t)(sizeof(VBoxSFWrite) + RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]));
VBoxSFWrite *pData = (VBoxSFWrite *)RTMemTmpAlloc(cbData);
HGCMPageListInfo *pPgLst = (HGCMPageListInfo *)(pData + 1);
uint16_t iPage;
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
index 7abe60e..da2f12f 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
@@ -229,7 +229,7 @@ static int vbglR3Init(const char *pszDeviceName)
return VERR_NOT_FOUND;
io_connect_t uConnection;
- kr = IOServiceOpen(ServiceObject, mach_task_self(), 0, &uConnection);
+ kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXGUEST_DARWIN_IOSERVICE_COOKIE, &uConnection);
IOObjectRelease(ServiceObject);
if (kr != kIOReturnSuccess)
return VERR_OPEN_FAILED;
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
index c6ab654..e982b1f 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDaemonize.cpp
@@ -42,6 +42,7 @@
#else /* the unices */
# include <sys/types.h>
# include <sys/stat.h>
+# include <sys/wait.h>
# include <stdio.h>
# include <fcntl.h>
# include <stdlib.h>
@@ -65,16 +66,24 @@
*
* @param fNoChDir Pass false to change working directory to root.
* @param fNoClose Pass false to redirect standard file streams to /dev/null.
+ * @param fRespawn Restart the daemonised process after five seconds if it
+ * terminates abnormally.
+ * @param pcRespawn Where to store a count of how often we have respawned,
+ * intended for avoiding error spamming. Optional.
*
* @todo Use RTProcDaemonize instead of this.
+ * @todo Implement fRespawn on OS/2.
+ * @todo Make the respawn interval configurable. But not until someone
+ * actually needs that.
*/
-VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose)
+VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose, bool fRespawn, unsigned *pcRespawn)
{
#if defined(RT_OS_OS2)
PPIB pPib;
PTIB pTib;
DosGetInfoBlocks(&pTib, &pPib);
+ AssertRelease(!fRespawn);
/* Get the full path to the executable. */
char szExe[CCHMAXPATH];
APIRET rc = DosQueryModuleName(pPib->pib_hmte, sizeof(szExe), szExe);
@@ -210,6 +219,34 @@ VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose)
exit(0);
# endif /* RT_OS_LINUX */
+ if (fRespawn)
+ {
+ /* We implement re-spawning as a third fork(), with the parent process
+ * monitoring the child and re-starting it after a delay if it exits
+ * abnormally. */
+ unsigned cRespawn = 0;
+ for (;;)
+ {
+ int iStatus, rcWait;
+
+ if (pcRespawn != NULL)
+ *pcRespawn = cRespawn;
+ pid = fork();
+ if (pid == -1)
+ return RTErrConvertFromErrno(errno);
+ if (pid == 0)
+ return VINF_SUCCESS;
+ do
+ rcWait = waitpid(pid, &iStatus, 0);
+ while (rcWait == -1 && errno == EINTR);
+ if (rcWait == -1)
+ exit(1);
+ if (WIFEXITED(iStatus) && WEXITSTATUS(iStatus) == 0)
+ exit(0);
+ sleep(5);
+ ++cRespawn;
+ }
+ }
return VINF_SUCCESS;
#endif
}
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
index b586035..16572b5 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp
@@ -120,6 +120,7 @@ using namespace guestProp;
* Connects to the guest property service.
*
* @returns VBox status code
+ * @returns VERR_NOT_SUPPORTED if guest properties are not available on the host.
* @param pu32ClientId Where to put the client id on success. The client id
* must be passed to all the other calls to the service.
*/
@@ -138,6 +139,8 @@ VBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId)
rc = Info.result;
if (RT_SUCCESS(rc))
*pu32ClientId = Info.u32ClientID;
+ if (rc == VERR_NOT_IMPLEMENTED || rc == VERR_HGCM_SERVICE_NOT_FOUND)
+ rc = VERR_NOT_SUPPORTED;
}
return rc;
}
@@ -565,7 +568,7 @@ VBGLR3DECL(int) VbglR3GuestPropEnumRaw(uint32_t u32ClientId,
|| rc == VERR_BUFFER_OVERFLOW))
{
int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual);
- if (!RT_SUCCESS(rc2))
+ if (RT_FAILURE(rc2))
rc = rc2;
}
return rc;
@@ -580,8 +583,6 @@ VBGLR3DECL(int) VbglR3GuestPropEnumRaw(uint32_t u32ClientId,
* @retval VINF_SUCCESS on success, *ppHandle points to a handle for continuing
* the enumeration and *ppszName, *ppszValue, *pu64Timestamp and
* *ppszFlags are set.
- * @retval VERR_NOT_FOUND if no matching properties were found. In this case
- * the return parameters are not initialised.
* @retval VERR_TOO_MUCH_DATA if it was not possible to determine the amount
* of local space needed to store all the enumeration data. This is
* due to a race between allocating space and the host adding new
@@ -596,14 +597,21 @@ VBGLR3DECL(int) VbglR3GuestPropEnumRaw(uint32_t u32ClientId,
* @param ppHandle where the handle for continued enumeration is stored
* on success. This must be freed with
* VbglR3GuestPropEnumFree when it is no longer needed.
- * @param ppszName Where to store the first property name on success.
- * Should not be freed. Optional.
- * @param ppszValue Where to store the first property value on success.
- * Should not be freed. Optional.
- * @param ppszValue Where to store the first timestamp value on success.
- * Optional.
- * @param ppszFlags Where to store the first flags value on success.
- * Should not be freed. Optional.
+ * @param ppszName Where to store the next property name. This will be
+ * set to NULL if there are no more properties to
+ * enumerate. This pointer should not be freed. Optional.
+ * @param ppszValue Where to store the next property value. This will be
+ * set to NULL if there are no more properties to
+ * enumerate. This pointer should not be freed. Optional.
+ * @param pu64Timestamp Where to store the next property timestamp. This
+ * will be set to zero if there are no more properties
+ * to enumerate. Optional.
+ * @param ppszFlags Where to store the next property flags. This will be
+ * set to NULL if there are no more properties to
+ * enumerate. This pointer should not be freed. Optional.
+ *
+ * @remarks While all output parameters are optional, you need at least one to
+ * figure out when to stop.
*/
VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId,
char const * const *papszPatterns,
@@ -672,10 +680,8 @@ VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId,
ppszName = &pszNameTmp;
rc = VbglR3GuestPropEnumNext(Handle.get(), ppszName, ppszValue,
pu64Timestamp, ppszFlags);
- if (RT_SUCCESS(rc) && *ppszName != NULL)
+ if (RT_SUCCESS(rc))
*ppHandle = Handle.release();
- else if (RT_SUCCESS(rc))
- rc = VERR_NOT_FOUND; /* No matching properties found. */
}
else if (rc == VERR_BUFFER_OVERFLOW)
rc = VERR_TOO_MUCH_DATA;
@@ -784,6 +790,8 @@ VBGLR3DECL(int) VbglR3GuestPropEnumNext(PVBGLR3GUESTPROPENUM pHandle,
*/
VBGLR3DECL(void) VbglR3GuestPropEnumFree(PVBGLR3GUESTPROPENUM pHandle)
{
+ if (!pHandle)
+ return;
RTMemFree(pHandle->pchBuf);
RTMemFree(pHandle);
}
@@ -848,7 +856,7 @@ VBGLR3DECL(int) VbglR3GuestPropDelSet(uint32_t u32ClientId,
while (RT_SUCCESS(rc) && pszName)
{
rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, NULL);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
break;
rc = VbglR3GuestPropEnumNext(pHandle,
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
index cc298cb..a534c79 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
@@ -59,19 +59,11 @@ VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot)
*/
VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot)
{
- VMMDevReqGuestCapabilities2 Req;
-
- vmmdevInitRequest(&Req.header, VMMDevReq_SetGuestCapabilities);
- Req.u32OrMask = fOr;
- Req.u32NotMask = fNot;
- int rc = vbglR3GRPerform(&Req.header);
-#if defined(DEBUG)
- if (RT_SUCCESS(rc))
- LogRel(("Successfully changed guest capabilities: or mask 0x%x, not mask 0x%x.\n", fOr, fNot));
- else
- LogRel(("Failed to change guest capabilities: or mask 0x%x, not mask 0x%x. rc=%Rrc.\n", fOr, fNot, rc));
-#endif
- return rc;
+ VBoxGuestSetCapabilitiesInfo Info;
+ Info.u32OrMask = fOr;
+ Info.u32NotMask = fNot;
+ return vbglR3DoIOCtl(VBOXGUEST_IOCTL_SET_GUEST_CAPABILITIES, &Info,
+ sizeof(Info));
}
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp
index 25af47d..7736958 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibRuntimeXF86.cpp
@@ -33,83 +33,20 @@
#include <iprt/assert.h>
#include <iprt/log.h>
#include <iprt/mem.h>
-#include <iprt/string.h>
#if defined(VBOX_VBGLR3_XFREE86)
extern "C" {
# define XFree86LOADER
# include <xf86_ansic.h>
-# include <errno.h>
# undef size_t
}
#else
-# include <ctype.h>
-# include <errno.h>
# include <stdarg.h>
-# include <stdio.h>
# include <stdlib.h>
# define xalloc malloc
-# define xf86vsnprintf vsnprintf
-# define xf86errno errno
-# define xf86strtoul strtoul
-# define xf86isspace isspace
# define xfree free
extern "C" void ErrorF(const char *f, ...);
-extern "C" void VErrorF(const char *f, va_list args);
#endif
-/* This is risky as it restricts call to the ANSI format type specifiers. */
-RTDECL(size_t) RTStrPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
-{
- va_list args;
- int cbRet;
- va_start(args, pszFormat);
- cbRet = xf86vsnprintf(pszBuffer, cchBuffer, pszFormat, args);
- va_end(args);
- return cbRet >= 0 ? cbRet : 0;
-}
-
-RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32)
-{
- char *pszNext = NULL;
- xf86errno = 0;
- unsigned long ul = xf86strtoul(pszValue, &pszNext, uBase);
- if (ppszNext)
- *ppszNext = pszNext;
- if (RT_UNLIKELY(pszValue == pszNext))
- return VERR_NO_DIGITS;
- if (RT_UNLIKELY(ul > UINT32_MAX))
- ul = UINT32_MAX;
- if (pu32)
- *pu32 = (uint32_t) ul;
- if (RT_UNLIKELY(xf86errno == EINVAL))
- return VERR_INVALID_PARAMETER;
- if (RT_UNLIKELY(xf86errno == ERANGE))
- return VWRN_NUMBER_TOO_BIG;
- if (RT_UNLIKELY(xf86errno))
- /* RTErrConvertFromErrno() is not available */
- return VERR_UNRESOLVED_ERROR;
- if (RT_UNLIKELY(*pszValue == '-'))
- return VWRN_NEGATIVE_UNSIGNED;
- if (RT_UNLIKELY(*pszNext))
- {
- while (*pszNext)
- if (!xf86isspace(*pszNext))
- return VWRN_TRAILING_CHARS;
- return VWRN_TRAILING_SPACES;
- }
- return VINF_SUCCESS;
-}
-
-RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32)
-{
- char *psz;
- int rc = RTStrToUInt32Ex(pszValue, &psz, uBase, pu32);
- if (RT_SUCCESS(rc) && *psz)
- if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
- rc = -rc;
- return rc;
-}
-
RTDECL(void) RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
{
ErrorF("Assertion failed! Expression: %s at %s in\n", pszExpr,
@@ -119,10 +56,7 @@ RTDECL(void) RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char
RTDECL(void) RTAssertMsg2Weak(const char *pszFormat, ...)
{
- va_list args;
- va_start(args, pszFormat);
- VErrorF(pszFormat, args);
- va_end(args);
+ NOREF(pszFormat);
}
RTDECL(bool) RTAssertShouldPanic(void)
@@ -137,10 +71,7 @@ RTDECL(PRTLOGGER) RTLogRelDefaultInstance(void)
RTDECL(void) RTLogLoggerEx(PRTLOGGER, unsigned, unsigned, const char *pszFormat, ...)
{
- va_list args;
- va_start(args, pszFormat);
- VErrorF(pszFormat, args);
- va_end(args);
+ NOREF(pszFormat);
}
RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag)
@@ -153,4 +84,3 @@ RTDECL(void) RTMemTmpFree(void *pv)
{
xfree(pv);
}
-
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp
index 1ebec9c..776af7b 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSharedFolders.cpp
@@ -249,7 +249,11 @@ VBGLR3DECL(int) VbglR3SharedFolderGetName(uint32_t u32ClientId, uint32_t u32Root
if (pString)
{
RT_ZERO(*pString);
- ShflStringInitBuffer(pString, SHFL_MAX_LEN);
+ if (!ShflStringInitBuffer(pString, SHFL_MAX_LEN))
+ {
+ RTMemFree(pString);
+ return VERR_INVALID_PARAMETER;
+ }
VbglHGCMParmUInt32Set(&Msg.root, u32Root);
VbglHGCMParmPtrSet(&Msg.name, pString, cbString);
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
index 5554c18..64861a6 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp
@@ -28,15 +28,17 @@
/*******************************************************************************
* Header Files *
*******************************************************************************/
+#include "VBGLR3Internal.h"
+
+#include <VBox/log.h>
+#include <VBox/HostServices/GuestPropertySvc.h> /* For Save and RetrieveVideoMode */
#include <iprt/assert.h>
#if !defined(VBOX_VBGLR3_XFREE86) && !defined(VBOX_VBGLR3_XORG)
# include <iprt/mem.h>
#endif
#include <iprt/string.h>
-#include <VBox/log.h>
-#include <VBox/HostServices/GuestPropertySvc.h> /* For Save and RetrieveVideoMode */
-#include "VBGLR3Internal.h"
+#include <stdio.h>
#ifdef VBOX_VBGLR3_XFREE86
/* Rather than try to resolve all the header file conflicts, I will just
@@ -139,12 +141,13 @@ VBGLR3DECL(int) VbglR3SetPointerShapeReq(VMMDevReqMousePointer *pReq)
rc = pReq->header.rc;
return rc;
}
+
+
/**
* Query the last display change request sent from the host to the guest.
*
* @returns iprt status value
* @param pcx Where to store the horizontal pixel resolution
- * requested (a value of zero means do not change).
* @param pcy Where to store the vertical pixel resolution
* requested (a value of zero means do not change).
* @param pcBits Where to store the bits per pixel requested (a value
@@ -157,35 +160,22 @@ VBGLR3DECL(int) VbglR3SetPointerShapeReq(VMMDevReqMousePointer *pReq)
* most recent host request, otherwise it will return the
* last request to be acknowledged.
*
- * @param pcOriginX New horizontal position of the secondary monitor.
- * @param pcOriginY New vertical position of the secondary monitor.
- * param pfEnabled Secondary monitor is enabled or not.
- *
*/
-VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits,
- uint32_t *piDisplay, uint32_t *pcOriginX, uint32_t *pcOriginY,
- bool *pfEnabled, bool fAck)
+static int getDisplayChangeRequest2(uint32_t *pcx, uint32_t *pcy,
+ uint32_t *pcBits, uint32_t *piDisplay,
+ bool fAck)
{
- VMMDevDisplayChangeRequestEx Req;
- int rc = VINF_SUCCESS;
+ VMMDevDisplayChangeRequest2 Req;
+
AssertPtrReturn(pcx, VERR_INVALID_PARAMETER);
AssertPtrReturn(pcy, VERR_INVALID_PARAMETER);
AssertPtrReturn(pcBits, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pcOriginX, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pcOriginY, VERR_INVALID_PARAMETER);
AssertPtrReturn(piDisplay, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pfEnabled, VERR_INVALID_PARAMETER);
RT_ZERO(Req);
- rc = vmmdevInitRequest(&Req.header, VMMDevReq_GetDisplayChangeRequestEx);
- if (RT_FAILURE(rc))
- {
- LogRelFlowFunc(("DisplayChangeRequest Extended not supported. Can't Init the Req.\n"));
- return rc;
- }
-
+ vmmdevInitRequest(&Req.header, VMMDevReq_GetDisplayChangeRequest2);
if (fAck)
Req.eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
- rc = vbglR3GRPerform(&Req.header);
+ int rc = vbglR3GRPerform(&Req.header);
if (RT_SUCCESS(rc))
rc = Req.header.rc;
if (RT_SUCCESS(rc))
@@ -194,11 +184,6 @@ VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, ui
*pcy = Req.yres;
*pcBits = Req.bpp;
*piDisplay = Req.display;
- *pcOriginX = Req.cxOrigin;
- *pcOriginY = Req.cyOrigin;
- *pfEnabled = Req.fEnabled;
- LogRel(("VbglR3GetDisplayChangeRequestEx: pcx=%d pcy=%d display=%d orgX=%d orgY=%d and Enabled=%d\n",
- *pcx, *pcy, *piDisplay, *pcOriginX, *pcOriginY, *pfEnabled));
}
return rc;
}
@@ -209,11 +194,12 @@ VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, ui
*
* @returns iprt status value
* @param pcx Where to store the horizontal pixel resolution
+ * requested (a value of zero means do not change).
* @param pcy Where to store the vertical pixel resolution
* requested (a value of zero means do not change).
* @param pcBits Where to store the bits per pixel requested (a value
* of zero means do not change).
- * @param iDisplay Where to store the display number the request was for
+ * @param piDisplay Where to store the display number the request was for
* - 0 for the primary display, 1 for the first
* secondary display, etc.
* @param fAck whether or not to acknowledge the newest request sent by
@@ -221,20 +207,41 @@ VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, ui
* most recent host request, otherwise it will return the
* last request to be acknowledged.
*
+ * @param pdx New horizontal position of the secondary monitor.
+ * Optional.
+ * @param pdy New vertical position of the secondary monitor.
+ * Optional.
+ * param pfEnabled Secondary monitor is enabled or not.
+ * Optional.
+ * param pfChangeOrigin Whether the mode hint retrieved included information
+ * about origin/display offset inside the frame-buffer.
+ * Optional.
+ *
*/
-VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, uint32_t *piDisplay, bool fAck)
+VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy,
+ uint32_t *pcBits,
+ uint32_t *piDisplay,
+ uint32_t *pdx, uint32_t *pdy,
+ bool *pfEnabled,
+ bool *pfChangeOrigin,
+ bool fAck)
{
- VMMDevDisplayChangeRequest2 Req;
-
+ VMMDevDisplayChangeRequestEx Req;
+ int rc = VINF_SUCCESS;
AssertPtrReturn(pcx, VERR_INVALID_PARAMETER);
AssertPtrReturn(pcy, VERR_INVALID_PARAMETER);
AssertPtrReturn(pcBits, VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(pdx, VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(pdy, VERR_INVALID_PARAMETER);
AssertPtrReturn(piDisplay, VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(pfEnabled, VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(pfChangeOrigin, VERR_INVALID_PARAMETER);
RT_ZERO(Req);
- vmmdevInitRequest(&Req.header, VMMDevReq_GetDisplayChangeRequest2);
+ rc = vmmdevInitRequest(&Req.header, VMMDevReq_GetDisplayChangeRequestEx);
+ AssertRCReturn(rc, rc);
if (fAck)
Req.eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
- int rc = vbglR3GRPerform(&Req.header);
+ rc = vbglR3GRPerform(&Req.header);
if (RT_SUCCESS(rc))
rc = Req.header.rc;
if (RT_SUCCESS(rc))
@@ -243,6 +250,24 @@ VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint
*pcy = Req.yres;
*pcBits = Req.bpp;
*piDisplay = Req.display;
+ if (pdx)
+ *pdx = Req.cxOrigin;
+ if (pdy)
+ *pdy = Req.cyOrigin;
+ if (pfEnabled)
+ *pfEnabled = Req.fEnabled;
+ if (pfChangeOrigin)
+ *pfChangeOrigin = Req.fChangeOrigin;
+ }
+ /* NEEDS TESTING: test below with current Additions on VBox 4.1 or older. */
+ /** @todo Can we find some standard grep-able string for "NEEDS TESTING"? */
+ if (rc == VERR_NOT_IMPLEMENTED) /* Fall back to the old API. */
+ {
+ if (pfEnabled)
+ *pfEnabled = true;
+ if (pfChangeOrigin)
+ *pfChangeOrigin = false;
+ return getDisplayChangeRequest2(pcx, pcy, pcBits, piDisplay, fAck);
}
return rc;
}
@@ -275,15 +300,68 @@ VBGLR3DECL(bool) VbglR3HostLikesVideoMode(uint32_t cx, uint32_t cy, uint32_t cBi
}
/**
- * Save video mode parameters to the registry.
+ * Get the highest screen number for which there is a saved video mode or "0"
+ * if there are no saved modes.
*
* @returns iprt status value
- * @param pszName the name to save the mode parameters under
- * @param cx mode width
- * @param cy mode height
- * @param cBits bits per pixel for the mode
+ * @returns VERR_NOT_SUPPORTED if the guest property service is not available.
+ * @param pcScreen where to store the virtual screen number
*/
-VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t cy, uint32_t cBits)
+VBGLR3DECL(int) VbglR3VideoModeGetHighestSavedScreen(unsigned *pcScreen)
+{
+#if defined(VBOX_WITH_GUEST_PROPS)
+ using namespace guestProp;
+
+ int rc, rc2 = VERR_UNRESOLVED_ERROR;
+ uint32_t u32ClientId = 0;
+ const char *pszPattern = VIDEO_PROP_PREFIX"*";
+ PVBGLR3GUESTPROPENUM pHandle = NULL;
+ const char *pszName;
+ unsigned cHighestScreen = 0;
+
+ AssertPtrReturn(pcScreen, VERR_INVALID_POINTER);
+ rc = VbglR3GuestPropConnect(&u32ClientId);
+ if (RT_SUCCESS(rc))
+ rc = VbglR3GuestPropEnum(u32ClientId, &pszPattern, 1, &pHandle,
+ &pszName, NULL, NULL, NULL);
+ if (u32ClientId != 0)
+ rc2 = VbglR3GuestPropDisconnect(u32ClientId);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ while (pszName != NULL && RT_SUCCESS(rc))
+ {
+ uint32_t cScreen;
+
+ rc = RTStrToUInt32Full(pszName + sizeof(VIDEO_PROP_PREFIX) - 1, 10,
+ &cScreen);
+ if (RT_SUCCESS(rc)) /* There may be similar properties with text. */
+ cHighestScreen = RT_MAX(cHighestScreen, cScreen);
+ rc = VbglR3GuestPropEnumNext(pHandle, &pszName, NULL, NULL, NULL);
+ }
+ VbglR3GuestPropEnumFree(pHandle);
+ if (RT_SUCCESS(rc))
+ *pcScreen = cHighestScreen;
+ return rc;
+#else /* !VBOX_WITH_GUEST_PROPS */
+ return VERR_NOT_SUPPORTED;
+#endif /* !VBOX_WITH_GUEST_PROPS */
+}
+
+/**
+ * Save video mode parameters to the guest property store.
+ *
+ * @returns iprt status value
+ * @param cScreen virtual screen number
+ * @param cx mode width
+ * @param cy mode height
+ * @param cBits bits per pixel for the mode
+ * @param x virtual screen X offset
+ * @param y virtual screen Y offset
+ * @param fEnabled is this virtual screen enabled?
+ */
+VBGLR3DECL(int) VbglR3SaveVideoMode(unsigned cScreen, unsigned cx, unsigned cy,
+ unsigned cBits, unsigned x, unsigned y,
+ bool fEnabled)
{
#if defined(VBOX_WITH_GUEST_PROPS)
using namespace guestProp;
@@ -291,16 +369,53 @@ VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t c
char szModeName[MAX_NAME_LEN];
char szModeParms[MAX_VALUE_LEN];
uint32_t u32ClientId = 0;
- RTStrPrintf(szModeName, sizeof(szModeName), VIDEO_PROP_PREFIX"%s", pszName);
- RTStrPrintf(szModeParms, sizeof(szModeParms), "%dx%dx%d", cx, cy, cBits);
- int rc = VbglR3GuestPropConnect(&u32ClientId);
+ unsigned cx2, cy2, cBits2, x2, y2, cHighestScreen, cHighestScreen2;
+ bool fEnabled2;
+ int rc, rc2 = VERR_UNRESOLVED_ERROR;
+
+ rc = VbglR3VideoModeGetHighestSavedScreen(&cHighestScreen);
+ RTStrPrintf(szModeName, sizeof(szModeName), VIDEO_PROP_PREFIX"%u", cScreen);
+ RTStrPrintf(szModeParms, sizeof(szModeParms), "%ux%ux%u,%ux%u,%u", cx, cy,
+ cBits, x, y, (unsigned) fEnabled);
if (RT_SUCCESS(rc))
+ rc = VbglR3GuestPropConnect(&u32ClientId);
+ if (RT_SUCCESS(rc))
+ {
rc = VbglR3GuestPropWriteValue(u32ClientId, szModeName, szModeParms);
+ /* Write out the mode using the legacy name too, in case the user
+ * re-installs older Additions. */
+ if (cScreen == 0)
+ {
+ RTStrPrintf(szModeParms, sizeof(szModeParms), "%ux%ux%u", cx, cy,
+ cBits);
+ VbglR3GuestPropWriteValue(u32ClientId, VIDEO_PROP_PREFIX"SavedMode",
+ szModeParms);
+ }
+ }
if (u32ClientId != 0)
- VbglR3GuestPropDisconnect(u32ClientId); /* Return value ignored, because what can we do anyway? */
+ rc2 = VbglR3GuestPropDisconnect(u32ClientId);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ /* Sanity check 1. We do not try to make allowance for someone else
+ * changing saved settings at the same time as us. */
+ if (RT_SUCCESS(rc))
+ {
+ rc = VbglR3RetrieveVideoMode(cScreen, &cx2, &cy2, &cBits2, &x2, &y2,
+ &fEnabled2);
+ if ( RT_SUCCESS(rc)
+ && ( cx != cx2 || cy != cy2 || cBits != cBits2
+ || x != x2 || y != y2 || fEnabled != fEnabled2))
+ rc = VERR_WRITE_ERROR;
+ }
+ /* Sanity check 2. Same comment. */
+ if (RT_SUCCESS(rc))
+ rc = VbglR3VideoModeGetHighestSavedScreen(&cHighestScreen2);
+ if (RT_SUCCESS(rc))
+ if (cHighestScreen2 != RT_MAX(cHighestScreen, cScreen))
+ rc = VERR_INTERNAL_ERROR;
return rc;
#else /* !VBOX_WITH_GUEST_PROPS */
- return VERR_NOT_IMPLEMENTED;
+ return VERR_NOT_SUPPORTED;
#endif /* !VBOX_WITH_GUEST_PROPS */
}
@@ -309,12 +424,19 @@ VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t c
* Retrieve video mode parameters from the guest property store.
*
* @returns iprt status value
- * @param pszName the name under which the mode parameters are saved
- * @param pcx where to store the mode width
- * @param pcy where to store the mode height
- * @param pcBits where to store the bits per pixel for the mode
+ * @param cScreen the virtual screen number
+ * @param pcx where to store the mode width
+ * @param pcy where to store the mode height
+ * @param pcBits where to store the bits per pixel for the mode
+ * @param px where to store the virtual screen X offset
+ * @param py where to store the virtual screen Y offset
+ * @param pfEnabled where to store whether this virtual screen is enabled
*/
-VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits)
+VBGLR3DECL(int) VbglR3RetrieveVideoMode(unsigned cScreen,
+ unsigned *pcx, unsigned *pcy,
+ unsigned *pcBits,
+ unsigned *px, unsigned *py,
+ bool *pfEnabled)
{
#if defined(VBOX_WITH_GUEST_PROPS)
using namespace guestProp;
@@ -325,59 +447,71 @@ VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint
*/
/* The buffer for VbglR3GuestPropReadValue. If this is too small then
* something is wrong with the data stored in the property. */
+ char szModeName[MAX_NAME_LEN];
char szModeParms[1024];
uint32_t u32ClientId = 0;
- uint32_t cx, cy, cBits;
+ int cMatches;
+ unsigned cx, cy, cBits;
+ unsigned x = 0;
+ unsigned y = 0;
+ unsigned fEnabled = 1;
+ int rc;
+ int rc2 = VERR_UNRESOLVED_ERROR;
- int rc = VbglR3GuestPropConnect(&u32ClientId);
+ /** @todo add a VbglR3GuestPropReadValueF/FV that does the RTStrPrintf for you. */
+ RTStrPrintf(szModeName, sizeof(szModeName), VIDEO_PROP_PREFIX"%u", cScreen);
+ rc = VbglR3GuestPropConnect(&u32ClientId);
if (RT_SUCCESS(rc))
{
- char szModeName[MAX_NAME_LEN];
- RTStrPrintf(szModeName, sizeof(szModeName), VIDEO_PROP_PREFIX"%s", pszName);
- /** @todo add a VbglR3GuestPropReadValueF/FV that does the RTStrPrintf for you. */
rc = VbglR3GuestPropReadValue(u32ClientId, szModeName, szModeParms,
sizeof(szModeParms), NULL);
+ /* Try legacy single screen name. */
+ if (rc == VERR_NOT_FOUND && cScreen == 0)
+ rc = VbglR3GuestPropReadValue(u32ClientId,
+ VIDEO_PROP_PREFIX"SavedMode",
+ szModeParms, sizeof(szModeParms),
+ NULL);
}
+ if (u32ClientId != 0)
+ rc2 = VbglR3GuestPropDisconnect(u32ClientId);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
/*
* Now we convert the string returned to numeric values.
*/
- char *pszNext;
- if (RT_SUCCESS(rc))
- /* Extract the width from the string */
- rc = RTStrToUInt32Ex(szModeParms, &pszNext, 10, &cx);
- if ((rc != VWRN_TRAILING_CHARS) || (*pszNext != 'x'))
- rc = VERR_PARSE_ERROR;
if (RT_SUCCESS(rc))
{
- /* Extract the height from the string */
- ++pszNext;
- rc = RTStrToUInt32Ex(pszNext, &pszNext, 10, &cy);
+ char c1, c2;
+ cMatches = sscanf(szModeParms, "%ux%ux%u%c%ux%u,%u%c", &cx, &cy, &cBits,
+ &c1, &x, &y, &fEnabled, &c2);
+ if ((cMatches == 7 && c1 == ',') || cMatches == 3)
+ rc = VINF_SUCCESS;
+ else if (cMatches < 0)
+ rc = VERR_READ_ERROR;
+ else
+ rc = VERR_PARSE_ERROR;
}
- if ((rc != VWRN_TRAILING_CHARS) || (*pszNext != 'x'))
- rc = VERR_PARSE_ERROR;
- if (RT_SUCCESS(rc))
- {
- /* Extract the bpp from the string */
- ++pszNext;
- rc = RTStrToUInt32Full(pszNext, 10, &cBits);
- }
- if (rc != VINF_SUCCESS)
- rc = VERR_PARSE_ERROR;
-
/*
* And clean up and return the values if we successfully obtained them.
*/
- if (u32ClientId != 0)
- VbglR3GuestPropDisconnect(u32ClientId); /* Return value ignored, because what can we do anyway? */
if (RT_SUCCESS(rc))
{
- *pcx = cx;
- *pcy = cy;
- *pcBits = cBits;
+ if (pcx)
+ *pcx = cx;
+ if (pcy)
+ *pcy = cy;
+ if (pcBits)
+ *pcBits = cBits;
+ if (px)
+ *px = x;
+ if (py)
+ *py = y;
+ if (pfEnabled)
+ *pfEnabled = RT_BOOL(fEnabled);
}
return rc;
#else /* !VBOX_WITH_GUEST_PROPS */
- return VERR_NOT_IMPLEMENTED;
+ return VERR_NOT_SUPPORTED;
#endif /* !VBOX_WITH_GUEST_PROPS */
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxService.cpp b/src/VBox/Additions/common/VBoxService/VBoxService.cpp
index 8ce44da..341e8fc 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxService.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxService.cpp
@@ -138,6 +138,37 @@ static struct
#endif
};
+/* Default call-backs for services which do not need special behaviour. */
+
+/** @copydoc VBOXSERVICE::pfnPreInit */
+DECLCALLBACK(int) VBoxServiceDefaultPreInit(void)
+{
+ return VINF_SUCCESS;
+}
+
+/** @copydoc VBOXSERVICE::pfnOption */
+DECLCALLBACK(int) VBoxServiceDefaultOption(const char **ppszShort, int argc,
+ char **argv, int *pi)
+{
+ NOREF(ppszShort);
+ NOREF(argc);
+ NOREF(argv);
+ NOREF(pi);
+
+ return -1;
+}
+
+/** @copydoc VBOXSERVICE::pfnInit */
+DECLCALLBACK(int) VBoxServiceDefaultInit(void)
+{
+ return VINF_SUCCESS;
+}
+
+/** @copydoc VBOXSERVICE::pfnTerm */
+DECLCALLBACK(void) VBoxServiceDefaultTerm(void)
+{
+ return;
+}
/**
* Release logger callback.
@@ -231,7 +262,7 @@ int VBoxServiceLogCreate(const char *pszLogFile)
char szError[RTPATH_MAX + 128] = "";
int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all",
"VBOXSERVICE_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
- RTLOGDEST_STDOUT,
+ RTLOGDEST_STDOUT | RTLOGDEST_USER,
VBoxServiceLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
szError, sizeof(szError), pszLogFile);
if (RT_SUCCESS(rc))
@@ -594,6 +625,11 @@ int VBoxServiceStartServices(void)
* the thread's actual worker loop. If the thread decides
* to exit the loop before we skipped the fShutdown check
* below the service will fail to start! */
+ /** @todo This presumably means either a one-shot service or that
+ * something has gone wrong. In the second case treating it as failure
+ * to start is probably right, so we need a way to signal the first
+ * rather than leaving the idle thread hanging around. A flag in the
+ * service description? */
RTThreadUserWait(g_aServices[j].Thread, 60 * 1000);
if (g_aServices[j].fShutdown)
{
@@ -1032,11 +1068,11 @@ int main(int argc, char **argv)
if ( dwErr == ERROR_ALREADY_EXISTS
|| dwErr == ERROR_ACCESS_DENIED)
{
- VBoxServiceError("%s is already running! Terminating.", g_pszProgName);
+ VBoxServiceError("%s is already running! Terminating.\n", g_pszProgName);
return RTEXITCODE_FAILURE;
}
- VBoxServiceError("CreateMutex failed with last error %u! Terminating", GetLastError());
+ VBoxServiceError("CreateMutex failed with last error %u! Terminating.\n", GetLastError());
return RTEXITCODE_FAILURE;
}
@@ -1057,7 +1093,8 @@ int main(int argc, char **argv)
rcExit = VBoxServiceWinEnterCtrlDispatcher();
#else
VBoxServiceVerbose(1, "Daemonizing...\n");
- rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */);
+ rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */,
+ false /* fRespawn */, NULL /* pcRespawn */);
if (RT_FAILURE(rc))
return VBoxServiceError("Daemon failed: %Rrc\n", rc);
/* in-child */
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
index d757072..1834b79 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010-2012 Oracle Corporation
+ * Copyright (C) 2010-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -68,24 +68,6 @@ static RTSEMEVENTMULTI g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
/** The Shared Folders service client ID. */
static uint32_t g_SharedFoldersSvcClientID = 0;
-/** @copydoc VBOXSERVICE::pfnPreInit */
-static DECLCALLBACK(int) VBoxServiceAutoMountPreInit(void)
-{
- return VINF_SUCCESS;
-}
-
-
-/** @copydoc VBOXSERVICE::pfnOption */
-static DECLCALLBACK(int) VBoxServiceAutoMountOption(const char **ppszShort, int argc, char **argv, int *pi)
-{
- NOREF(ppszShort);
- NOREF(argc);
- NOREF(argv);
- NOREF(pi);
-
- return -1;
-}
-
/** @copydoc VBOXSERVICE::pfnInit */
static DECLCALLBACK(int) VBoxServiceAutoMountInit(void)
@@ -618,8 +600,8 @@ VBOXSERVICE g_AutoMount =
/* pszOptions. */
NULL,
/* methods */
- VBoxServiceAutoMountPreInit,
- VBoxServiceAutoMountOption,
+ VBoxServiceDefaultPreInit,
+ VBoxServiceDefaultOption,
VBoxServiceAutoMountInit,
VBoxServiceAutoMountWorker,
VBoxServiceAutoMountStop,
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
index 3d5d0a8..26b030e 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
@@ -226,25 +226,6 @@ static int VBoxServiceBalloonSetUser(uint32_t cNewChunks)
}
-/** @copydoc VBOXSERVICE::pfnPreInit */
-static DECLCALLBACK(int) VBoxServiceBalloonPreInit(void)
-{
- return VINF_SUCCESS;
-}
-
-
-/** @copydoc VBOXSERVICE::pfnOption */
-static DECLCALLBACK(int) VBoxServiceBalloonOption(const char **ppszShort, int argc, char **argv, int *pi)
-{
- NOREF(ppszShort);
- NOREF(argc);
- NOREF(argv);
- NOREF(pi);
-
- return -1;
-}
-
-
/** @copydoc VBOXSERVICE::pfnInit */
static DECLCALLBACK(int) VBoxServiceBalloonInit(void)
{
@@ -395,14 +376,6 @@ DECLCALLBACK(int) VBoxServiceBalloonWorker(bool volatile *pfShutdown)
return 0;
}
-/** @copydoc VBOXSERVICE::pfnTerm */
-static DECLCALLBACK(void) VBoxServiceBalloonTerm(void)
-{
- VBoxServiceVerbose(3, "VBoxServiceBalloonTerm\n");
- return;
-}
-
-
/** @copydoc VBOXSERVICE::pfnStop */
static DECLCALLBACK(void) VBoxServiceBalloonStop(void)
{
@@ -424,10 +397,10 @@ VBOXSERVICE g_MemBalloon =
/* pszOptions. */
NULL,
/* methods */
- VBoxServiceBalloonPreInit,
- VBoxServiceBalloonOption,
+ VBoxServiceDefaultPreInit,
+ VBoxServiceDefaultOption,
VBoxServiceBalloonInit,
VBoxServiceBalloonWorker,
VBoxServiceBalloonStop,
- VBoxServiceBalloonTerm
+ VBoxServiceDefaultTerm
};
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
index 1d17d80..315eef8 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
@@ -525,7 +525,7 @@ static int gstcntlProcessProcLoop(PVBOXSERVICECTRLPROCESS pProcess)
pProcess->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
NULL /* pvData */, 0 /* cbData */);
if (rc == VERR_INTERRUPTED)
- rc = VINF_SUCCESS; /* SIGCHLD by quick childs! */
+ rc = VINF_SUCCESS; /* SIGCHLD send by quick childs! */
if (RT_FAILURE(rc))
VBoxServiceError("[PID %RU32]: Error reporting starting status to host, rc=%Rrc\n",
pProcess->uPID, rc);
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
index ba3a64c..f0a7d1e 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
@@ -396,32 +396,6 @@ static int VBoxServiceCpuHotPlugGetACPIDevicePath(char **ppszPath, uint32_t idCp
#endif /* RT_OS_LINUX */
-/** @copydoc VBOXSERVICE::pfnPreInit */
-static DECLCALLBACK(int) VBoxServiceCpuHotPlugPreInit(void)
-{
- return VINF_SUCCESS;
-}
-
-
-/** @copydoc VBOXSERVICE::pfnOption */
-static DECLCALLBACK(int) VBoxServiceCpuHotPlugOption(const char **ppszShort, int argc, char **argv, int *pi)
-{
- NOREF(ppszShort);
- NOREF(argc);
- NOREF(argv);
- NOREF(pi);
-
- return -1;
-}
-
-
-/** @copydoc VBOXSERVICE::pfnInit */
-static DECLCALLBACK(int) VBoxServiceCpuHotPlugInit(void)
-{
- return VINF_SUCCESS;
-}
-
-
/**
* Handles VMMDevCpuEventType_Plug.
*
@@ -619,15 +593,8 @@ static DECLCALLBACK(void) VBoxServiceCpuHotPlugStop(void)
}
-/** @copydoc VBOXSERVICE::pfnTerm */
-static DECLCALLBACK(void) VBoxServiceCpuHotPlugTerm(void)
-{
- return;
-}
-
-
/**
- * The 'timesync' service description.
+ * The 'CpuHotPlug' service description.
*/
VBOXSERVICE g_CpuHotPlug =
{
@@ -640,11 +607,11 @@ VBOXSERVICE g_CpuHotPlug =
/* pszOptions. */
NULL,
/* methods */
- VBoxServiceCpuHotPlugPreInit,
- VBoxServiceCpuHotPlugOption,
- VBoxServiceCpuHotPlugInit,
+ VBoxServiceDefaultPreInit,
+ VBoxServiceDefaultOption,
+ VBoxServiceDefaultInit,
VBoxServiceCpuHotPlugWorker,
VBoxServiceCpuHotPlugStop,
- VBoxServiceCpuHotPlugTerm
+ VBoxServiceDefaultTerm
};
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
index a3f09fb..5055d7f 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
@@ -94,6 +94,13 @@ typedef VBOXSERVICE *PVBOXSERVICE;
/** Pointer to a const VBOXSERVICE. */
typedef VBOXSERVICE const *PCVBOXSERVICE;
+/* Default call-backs for services which do not need special behaviour. */
+DECLCALLBACK(int) VBoxServiceDefaultPreInit(void);
+DECLCALLBACK(int) VBoxServiceDefaultOption(const char **ppszShort, int argc,
+ char **argv, int *pi);
+DECLCALLBACK(int) VBoxServiceDefaultInit(void);
+DECLCALLBACK(void) VBoxServiceDefaultTerm(void);
+
/** The service name.
* @note Used on windows to name the service as well as the global mutex. */
#define VBOXSERVICE_NAME "VBoxService"
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
index c954d5c..3ec167c 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
@@ -524,25 +524,6 @@ void VBoxServicePageSharingInspectGuest()
}
#endif
-/** @copydoc VBOXSERVICE::pfnPreInit */
-static DECLCALLBACK(int) VBoxServicePageSharingPreInit(void)
-{
- return VINF_SUCCESS;
-}
-
-
-/** @copydoc VBOXSERVICE::pfnOption */
-static DECLCALLBACK(int) VBoxServicePageSharingOption(const char **ppszShort, int argc, char **argv, int *pi)
-{
- NOREF(ppszShort);
- NOREF(argc);
- NOREF(argv);
- NOREF(pi);
-
- return -1;
-}
-
-
/** @copydoc VBOXSERVICE::pfnInit */
static DECLCALLBACK(int) VBoxServicePageSharingInit(void)
{
@@ -730,13 +711,6 @@ DECLCALLBACK(int) VBoxServicePageSharingWorkerProcess(bool volatile *pfShutdown)
#endif /* RT_OS_WINDOWS */
-/** @copydoc VBOXSERVICE::pfnTerm */
-static DECLCALLBACK(void) VBoxServicePageSharingTerm(void)
-{
- VBoxServiceVerbose(3, "VBoxServicePageSharingTerm\n");
-}
-
-
/** @copydoc VBOXSERVICE::pfnStop */
static DECLCALLBACK(void) VBoxServicePageSharingStop(void)
{
@@ -758,8 +732,8 @@ VBOXSERVICE g_PageSharing =
/* pszOptions. */
NULL,
/* methods */
- VBoxServicePageSharingPreInit,
- VBoxServicePageSharingOption,
+ VBoxServiceDefaultPreInit,
+ VBoxServiceDefaultOption,
VBoxServicePageSharingInit,
#ifdef RT_OS_WINDOWS
VBoxServicePageSharingWorkerProcess,
@@ -767,5 +741,5 @@ VBOXSERVICE g_PageSharing =
VBoxServicePageSharingWorker,
#endif
VBoxServicePageSharingStop,
- VBoxServicePageSharingTerm
+ VBoxServiceDefaultTerm
};
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
index 8083e84..38a51fc 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
@@ -84,25 +84,6 @@ static VBOXSTATSCONTEXT gCtx = {0};
static RTSEMEVENTMULTI g_VMStatEvent = NIL_RTSEMEVENTMULTI;
-/** @copydoc VBOXSERVICE::pfnPreInit */
-static DECLCALLBACK(int) VBoxServiceVMStatsPreInit(void)
-{
- return VINF_SUCCESS;
-}
-
-
-/** @copydoc VBOXSERVICE::pfnOption */
-static DECLCALLBACK(int) VBoxServiceVMStatsOption(const char **ppszShort, int argc, char **argv, int *pi)
-{
- NOREF(ppszShort);
- NOREF(argc);
- NOREF(argv);
- NOREF(pi);
-
- return -1;
-}
-
-
/** @copydoc VBOXSERVICE::pfnInit */
static DECLCALLBACK(int) VBoxServiceVMStatsInit(void)
{
@@ -680,14 +661,6 @@ DECLCALLBACK(int) VBoxServiceVMStatsWorker(bool volatile *pfShutdown)
}
-/** @copydoc VBOXSERVICE::pfnTerm */
-static DECLCALLBACK(void) VBoxServiceVMStatsTerm(void)
-{
- VBoxServiceVerbose(3, "VBoxServiceVMStatsTerm\n");
- return;
-}
-
-
/** @copydoc VBOXSERVICE::pfnStop */
static DECLCALLBACK(void) VBoxServiceVMStatsStop(void)
{
@@ -709,11 +682,11 @@ VBOXSERVICE g_VMStatistics =
/* pszOptions. */
NULL,
/* methods */
- VBoxServiceVMStatsPreInit,
- VBoxServiceVMStatsOption,
+ VBoxServiceDefaultPreInit,
+ VBoxServiceDefaultOption,
VBoxServiceVMStatsInit,
VBoxServiceVMStatsWorker,
VBoxServiceVMStatsStop,
- VBoxServiceVMStatsTerm
+ VBoxServiceDefaultTerm
};
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
index ae565d1..fae5f14 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
@@ -260,7 +260,7 @@ static int VBoxServiceVMInfoWinProcessesGetTokenInfo(PVBOXSERVICEVMINFOPROC pPro
break;
default:
- VBoxServiceError("Token class not implemented: %ld", tkClass);
+ VBoxServiceError("Token class not implemented: %ld\n", tkClass);
rc = VERR_NOT_IMPLEMENTED;
break;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
index d8dbe7c..45ca3ae 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
@@ -553,13 +553,13 @@ static int vboxserviceVMInfoWriteUsers(void)
while ( (ut_user = getutxent())
&& RT_SUCCESS(rc))
{
-#ifdef RT_OS_DARWIN /* No ut_user->ut_session on Darwin */
+# ifdef RT_OS_DARWIN /* No ut_user->ut_session on Darwin */
VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32)\n",
ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid);
-#else
+# else
VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32, session: %RU32)\n",
ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid, ut_user->ut_session);
-#endif
+# endif
if (cUsersInList > cListSize)
{
cListSize += 32;
@@ -589,16 +589,17 @@ static int vboxserviceVMInfoWriteUsers(void)
}
}
-#ifdef VBOX_WITH_DBUS
-# if defined(RT_OS_LINUX) /* Not yet for Solaris/FreeBSB. */
+# ifdef VBOX_WITH_DBUS
+# if defined(RT_OS_LINUX) /* Not yet for Solaris/FreeBSB. */
DBusError dbErr;
DBusConnection *pConnection = NULL;
int rc2 = RTDBusLoadLib();
+ bool fHaveLibDbus = false;
if (RT_SUCCESS(rc2))
{
/* Handle desktop sessions using ConsoleKit. */
VBoxServiceVerbose(4, "Checking ConsoleKit sessions ...\n");
-
+ fHaveLibDbus = true;
dbus_error_init(&dbErr);
pConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbErr);
}
@@ -734,9 +735,16 @@ static int vboxserviceVMInfoWriteUsers(void)
dbus_message_unref(pReplyUnixUser);
}
else
- VBoxServiceError("ConsoleKit: unable to retrieve user for session '%s' (msg type=%d): %s",
- *ppszCurSession, dbus_message_get_type(pMsgUnixUser),
- dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available");
+ {
+ static int s_iBitchedAboutConsoleKit = 0;
+ if (s_iBitchedAboutConsoleKit < 1)
+ {
+ s_iBitchedAboutConsoleKit++;
+ VBoxServiceError("ConsoleKit: unable to retrieve user for session '%s' (msg type=%d): %s\n",
+ *ppszCurSession, dbus_message_get_type(pMsgUnixUser),
+ dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available");
+ }
+ }
if (pMsgUnixUser)
dbus_message_unref(pMsgUnixUser);
@@ -746,7 +754,7 @@ static int vboxserviceVMInfoWriteUsers(void)
}
else
{
- VBoxServiceError("ConsoleKit: unable to retrieve session parameters (msg type=%d): %s",
+ VBoxServiceError("ConsoleKit: unable to retrieve session parameters (msg type=%d): %s\n",
dbus_message_get_type(pMsgSessions),
dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available");
}
@@ -762,10 +770,13 @@ static int vboxserviceVMInfoWriteUsers(void)
else
{
static int s_iBitchedAboutConsoleKit = 0;
- if (s_iBitchedAboutConsoleKit++ < 3)
+ if (s_iBitchedAboutConsoleKit < 3)
+ {
+ s_iBitchedAboutConsoleKit++;
VBoxServiceError("Unable to invoke ConsoleKit (%d/3) -- maybe not installed / used? Error: %s\n",
s_iBitchedAboutConsoleKit,
dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available");
+ }
}
if (pMsgSessions)
@@ -774,16 +785,19 @@ static int vboxserviceVMInfoWriteUsers(void)
else
{
static int s_iBitchedAboutDBus = 0;
- if (s_iBitchedAboutDBus++ < 3)
+ if (s_iBitchedAboutDBus < 3)
+ {
+ s_iBitchedAboutDBus++;
VBoxServiceError("Unable to connect to system D-Bus (%d/3): %s\n", s_iBitchedAboutDBus,
- pConnection && dbus_error_is_set(&dbErr) ? dbErr.message : "D-Bus not installed");
+ fHaveLibDbus && dbus_error_is_set(&dbErr) ? dbErr.message : "D-Bus not installed");
+ }
}
- if ( pConnection
+ if ( fHaveLibDbus
&& dbus_error_is_set(&dbErr))
dbus_error_free(&dbErr);
-# endif /* RT_OS_LINUX */
-#endif /* VBOX_WITH_DBUS */
+# endif /* RT_OS_LINUX */
+# endif /* VBOX_WITH_DBUS */
/** @todo Fedora/others: Handle systemd-loginctl. */
@@ -821,7 +835,8 @@ static int vboxserviceVMInfoWriteUsers(void)
RTMemFree(papszUsers);
endutxent(); /* Close utmpx file. */
-#endif
+#endif /* !RT_OS_WINDOWS && !RT_OS_FREEBSD && !RT_OS_HAIKU && !RT_OS_OS2 */
+
Assert(RT_FAILURE(rc) || cUsersInList == 0 || (pszUserList && *pszUserList));
/* If the user enumeration above failed, reset the user count to 0 except
@@ -1351,8 +1366,11 @@ DECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown)
else
{
static int s_iBitchedAboutLAClientInfo = 0;
- if (s_iBitchedAboutLAClientInfo++ < 10)
+ if (s_iBitchedAboutLAClientInfo < 10)
+ {
+ s_iBitchedAboutLAClientInfo++;
VBoxServiceError("Error getting active location awareness client info, rc=%Rrc\n", rc2);
+ }
}
}
else if (RT_FAILURE(rc2))
@@ -1373,8 +1391,11 @@ DECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown)
{
static int s_iBitchedAboutLAClient = 0;
if ( (rc2 != VERR_NOT_FOUND) /* No location awareness installed, skip. */
- && s_iBitchedAboutLAClient++ < 3)
+ && s_iBitchedAboutLAClient < 3)
+ {
+ s_iBitchedAboutLAClient++;
VBoxServiceError("VRDP: Querying connected location awareness client failed with rc=%Rrc\n", rc2);
+ }
}
VBoxServiceVerbose(3, "VRDP: Handling location awareness done\n");
diff --git a/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp b/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
index 72b7ed1..4e32bd2 100644
--- a/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
+++ b/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
@@ -237,6 +237,21 @@ static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
}
+/**
+ * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
+ * @returns IPRT status value.
+ * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
+ * @returns VERR_NO_MEMORY if a heap allocation fails.
+ * @param pCtx the context of the guest heap to use.
+ * @param fCaps the capabilities to report, see VBVACAPS.
+ */
+RTDECL(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t fCaps)
+{
+ return vboxHGSMISendCapsInfo(pCtx, fCaps);
+}
+
+
/** Tell the host about the location of the area of VRAM set aside for the host
* heap. */
static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
@@ -495,7 +510,6 @@ RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
* Pass the host a new mouse pointer shape via an HGSMI command.
*
* @returns success or failure
- * @todo why not return an iprt status code?
* @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags
* @param cHotX horizontal position of the hot spot
* @param cHotY vertical position of the hot spot
@@ -504,7 +518,7 @@ RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
* @param pPixels pixel data, @see VMMDevReqMousePointer for the format
* @param cbLength size in bytes of the pixel data
*/
-RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+RTDECL(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint32_t fFlags,
uint32_t cHotX,
uint32_t cHotY,
@@ -532,7 +546,7 @@ RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
{
LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n",
cbData, cbLength));
- return false;
+ return VERR_INVALID_PARAMETER;
}
/* Allocate the IO buffer. */
p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx,
@@ -563,7 +577,54 @@ RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
else
rc = VERR_NO_MEMORY;
LogFlowFunc(("rc %d\n", rc));
- return RT_SUCCESS(rc);
+ return rc;
+}
+
+
+/**
+ * Report the guest cursor position. The host may wish to use this information
+ * to re-position its own cursor (though this is currently unlikely). The
+ * current host cursor position is returned.
+ * @param pCtx The context containing the heap used.
+ * @param fReportPosition Are we reporting a position?
+ * @param x Guest cursor X position.
+ * @param y Guest cursor Y position.
+ * @param pxHost Host cursor X position is stored here. Optional.
+ * @param pyHost Host cursor Y position is stored here. Optional.
+ * @returns iprt status code.
+ * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
+ */
+RTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
+ uint32_t *pxHost, uint32_t *pyHost)
+{
+ int rc = VINF_SUCCESS;
+ VBVACURSORPOSITION *p;
+ Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y));
+
+ /* Allocate the IO buffer. */
+ p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION);
+ if (p)
+ {
+ /* Prepare data to be sent to the host. */
+ p->fReportPosition = fReportPosition ? 1 : 0;
+ p->x = x;
+ p->y = y;
+ rc = VBoxHGSMIBufferSubmit(pCtx, p);
+ if (RT_SUCCESS(rc))
+ {
+ if (pxHost)
+ *pxHost = p->x;
+ if (pyHost)
+ *pyHost = p->y;
+ Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y));
+ }
+ /* Free the IO buffer. */
+ VBoxHGSMIBufferFree(pCtx, p);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ LogFunc(("rc = %d\n", rc));
+ return rc;
}
diff --git a/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp b/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
index 894e9a2..256455e 100644
--- a/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
+++ b/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
@@ -25,6 +25,10 @@
#include <iprt/asm.h>
#include <iprt/log.h>
+#ifndef VBOX_GUESTR3XF86MOD
+# include <string.h>
+#endif
+
/**
* Gets the count of virtual monitors attached to the guest via an HGSMI
* command
@@ -274,3 +278,86 @@ RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
VBoxHGSMIBufferFree(pCtx, p);
}
}
+
+
+/** Report the rectangle relative to which absolute pointer events should be
+ * expressed. This information remains valid until the next VBVA resize event
+ * for any screen, at which time it is reset to the bounding rectangle of all
+ * virtual screens.
+ * @param pCtx The context containing the heap to use.
+ * @param cOriginX Upper left X co-ordinate relative to the first screen.
+ * @param cOriginY Upper left Y co-ordinate relative to the first screen.
+ * @param cWidth Rectangle width.
+ * @param cHeight Rectangle height.
+ * @returns iprt status code.
+ * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
+ */
+RTDECL(int) VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t cOriginX, int32_t cOriginY,
+ uint32_t cWidth, uint32_t cHeight)
+{
+ int rc = VINF_SUCCESS;
+ VBVAREPORTINPUTMAPPING *p;
+ Log(("%s: cOriginX=%u, cOriginY=%u, cWidth=%u, cHeight=%u\n", __PRETTY_FUNCTION__, (unsigned)cOriginX, (unsigned)cOriginX,
+ (unsigned)cWidth, (unsigned)cHeight));
+
+ /* Allocate the IO buffer. */
+ p = (VBVAREPORTINPUTMAPPING *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAREPORTINPUTMAPPING), HGSMI_CH_VBVA,
+ VBVA_REPORT_INPUT_MAPPING);
+ if (p)
+ {
+ /* Prepare data to be sent to the host. */
+ p->x = cOriginX;
+ p->y = cOriginY;
+ p->cx = cWidth;
+ p->cy = cHeight;
+ rc = VBoxHGSMIBufferSubmit(pCtx, p);
+ /* Free the IO buffer. */
+ VBoxHGSMIBufferFree(pCtx, p);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ LogFunc(("rc = %d\n", rc));
+ return rc;
+}
+
+
+/**
+ * Get most recent video mode hints.
+ * @param pCtx the context containing the heap to use
+ * @param cScreens the number of screens to query hints for, starting at 0.
+ * @param pHints array of VBVAMODEHINT structures for receiving the hints.
+ * @returns iprt status code
+ * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
+ * @returns VERR_NOT_SUPPORTED Host does not support this command.
+ */
+RTDECL(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ unsigned cScreens, VBVAMODEHINT *paHints)
+{
+ int rc;
+ AssertPtrReturn(paHints, VERR_INVALID_POINTER);
+ void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAQUERYMODEHINTS)
+ + cScreens * sizeof(VBVAMODEHINT),
+ HGSMI_CH_VBVA, VBVA_QUERY_MODE_HINTS);
+ if (!p)
+ {
+ LogFunc(("HGSMIHeapAlloc failed\n"));
+ return VERR_NO_MEMORY;
+ }
+ else
+ {
+ VBVAQUERYMODEHINTS *pQuery = (VBVAQUERYMODEHINTS *)p;
+
+ pQuery->cHintsQueried = cScreens;
+ pQuery->cbHintStructureGuest = sizeof(VBVAMODEHINT);
+ pQuery->rc = VERR_NOT_SUPPORTED;
+
+ VBoxHGSMIBufferSubmit(pCtx, p);
+ rc = pQuery->rc;
+ if (RT_SUCCESS(rc))
+ memcpy(paHints, ((uint8_t *)p) + sizeof(VBVAQUERYMODEHINTS),
+ cScreens * sizeof(VBVAMODEHINT));
+
+ VBoxHGSMIBufferFree(pCtx, p);
+ }
+ return rc;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/DD_glc.py b/src/VBox/Additions/common/crOpenGL/DD_glc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/DD_glh.py b/src/VBox/Additions/common/crOpenGL/DD_glh.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/NULLfuncs.py b/src/VBox/Additions/common/crOpenGL/NULLfuncs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc b/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
index 19972f3..2d3b993 100644
--- a/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
@@ -1,6 +1,6 @@
/* $Id: arrayspu.rc $ */
/** @file
- * VBoxOGLarrayspu.so - Resource file containing version info and icon.
+ * VBoxOGLarrayspu - Resource file containing version info and icon.
*/
/*
diff --git a/src/VBox/Additions/common/crOpenGL/context.c b/src/VBox/Additions/common/crOpenGL/context.c
index 3b0af50..fc8962c 100644
--- a/src/VBox/Additions/common/crOpenGL/context.c
+++ b/src/VBox/Additions/common/crOpenGL/context.c
@@ -601,7 +601,7 @@ void stubSetPFA( ContextInfo *ctx, CGLPixelFormatAttribute *attribs, int size, G
SET_ATTR_V(attribs, i, kCGLPFASamples, 0);
SET_ATTR_V(attribs, i, kCGLPFADisplayMask, 0); */
SET_ATTR(attribs, i, kCGLPFABackingStore);
- SET_ATTR(attribs, i, kCGLPFAWindow);
+ //SET_ATTR(attribs, i, kCGLPFAWindow); // kCGLPFAWindow deprecated starting from OSX 10.7
SET_ATTR_V(attribs, i, kCGLPFADisplayMask, ctx->disp_mask);
SET_ATTR(attribs, i, 0);
diff --git a/src/VBox/Additions/common/crOpenGL/cr_gl.py b/src/VBox/Additions/common/crOpenGL/cr_gl.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/entrypoints.py b/src/VBox/Additions/common/crOpenGL/entrypoints.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/getprocaddress.py b/src/VBox/Additions/common/crOpenGL/getprocaddress.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/pack.py b/src/VBox/Additions/common/crOpenGL/pack/pack.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu.rc b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
index 4b49610..7b726f6 100644
--- a/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
@@ -1,10 +1,10 @@
/* $Id: packspu.rc $ */
/** @file
- * VBoxOGLpackspu.so - Resource file containing version info and icon.
+ * VBoxOGLpackspu - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py b/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/stub_common.py b/src/VBox/Additions/common/crOpenGL/stub_common.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/tsfuncs.py b/src/VBox/Additions/common/crOpenGL/tsfuncs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py b/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp b/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp
index 4e4c64a..267da06 100644
--- a/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp
+++ b/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp
@@ -129,7 +129,7 @@ status_t VBoxDisplayService::_ServiceThread()
if (RT_SUCCESS(rc))
{
uint32_t cx, cy, cBits, iDisplay;
- int rc2 = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &iDisplay, true);
+ int rc2 = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &iDisplay, NULL, NULL, NULL, NULL, true);
LogFlow(("rc2=%d screen %d size changed (%d, %d, %d)\n", rc2, iDisplay, cx, cy, cBits));
if (RT_SUCCESS(rc2))
diff --git a/src/VBox/Additions/linux/Makefile.kmk b/src/VBox/Additions/linux/Makefile.kmk
index 26f2da7..1b4fcc9 100644
--- a/src/VBox/Additions/linux/Makefile.kmk
+++ b/src/VBox/Additions/linux/Makefile.kmk
@@ -121,9 +121,6 @@ VBOX_ADD_STRIP_BIN += \
VBOX_ADD_STRIP_BIN.linux += \
VBoxClient
-VBOX_ADD_BIN.linux += \
- VBoxClient-all
-
VBOX_ADD_STRIP_SBIN += \
VBoxService \
$(if $(VBOX_WITH_LIGHTDM_GREETER),vbox-greeter)
@@ -379,15 +376,6 @@ ifdef VBOX_WITH_LIGHTDM_GREETER_PACKING
$(VBOX_REL_LNX_ADD_INST)module-autologon.sh=>installer/module-autologon
endif
-#
-# VBoxClient-all
-#
-INSTALLS += LnxAdd-Nostrip-Bin
-LnxAdd-Nostrip-Bin_INST = $(VBOX_LNX_ADD_INST_BIN_DIR)
-LnxAdd-Nostrip-Bin_INSTTYPE = stage
-LnxAdd-Nostrip-Bin_EXEC_SOURCES = \
- $(VBOX_REL_X11_ADD_INST)98vboxadd-xclient=>VBoxClient-all
-
#
# And the init scripts
diff --git a/src/VBox/Additions/linux/drm/vboxvideo_drm.c b/src/VBox/Additions/linux/drm/vboxvideo_drm.c
index f979a35..ca5b2b7 100644
--- a/src/VBox/Additions/linux/drm/vboxvideo_drm.c
+++ b/src/VBox/Additions/linux/drm/vboxvideo_drm.c
@@ -144,6 +144,12 @@ static struct drm_driver driver =
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+ /* If this is missing a warning gets printed to dmesg. We will not
+ * attempt to make kernels work to which the change (915b4d11b) got back-
+ * ported, as the problem is only cosmetic. */
+ .set_busid = drm_pci_set_busid,
+#endif
# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) && !defined(DRM_FOPS_AS_POINTER)
.fops =
{
diff --git a/src/VBox/Additions/linux/export_modules b/src/VBox/Additions/linux/export_modules
index 9df9389..d98be71 100755
--- a/src/VBox/Additions/linux/export_modules
+++ b/src/VBox/Additions/linux/export_modules
@@ -47,13 +47,15 @@ VBOX_C_YEAR=`date +%Y`
mkdir $PATH_TMP || exit 1
# Create auto-generated version file, needed by all modules
-echo "#ifndef __version_generated_h__" > $PATH_TMP/version-generated.h
-echo "#define __version_generated_h__" >> $PATH_TMP/version-generated.h
+echo "#ifndef ___version_generated_h___" > $PATH_TMP/version-generated.h
+echo "#define ___version_generated_h___" >> $PATH_TMP/version-generated.h
echo "" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_MAJOR $VBOX_VERSION_MAJOR" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_MINOR $VBOX_VERSION_MINOR" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_BUILD $VBOX_VERSION_BUILD" >> $PATH_TMP/version-generated.h
+echo "#define VBOX_VERSION_STRING_RAW \"$VBOX_VERSION_MAJOR.$VBOX_VERSION_MINOR.$VBOX_VERSION_BUILD\"" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_STRING \"$VBOX_VERSION_MAJOR.$VBOX_VERSION_MINOR.$VBOX_VERSION_BUILD\"" >> $PATH_TMP/version-generated.h
+echo "#define VBOX_API_VERSION_STRING \"${VBOX_VERSION_MAJOR}_${VBOX_VERSION_MINOR}\"" >> $PATH_TMP/version-generated.h
echo "" >> $PATH_TMP/version-generated.h
echo "#endif" >> $PATH_TMP/version-generated.h
@@ -66,8 +68,8 @@ echo "" >> $PATH_TMP/revision-generated.h
echo "#endif" >> $PATH_TMP/revision-generated.h
# Create auto-generated product file, needed by all modules
-echo "#ifndef __product_generated_h__" > $PATH_TMP/product-generated.h
-echo "#define __product_generated_h__" >> $PATH_TMP/product-generated.h
+echo "#ifndef ___product_generated_h___" > $PATH_TMP/product-generated.h
+echo "#define ___product_generated_h___" >> $PATH_TMP/product-generated.h
echo "" >> $PATH_TMP/product-generated.h
echo "#define VBOX_VENDOR \"$VBOX_VENDOR\"" >> $PATH_TMP/product-generated.h
echo "#define VBOX_VENDOR_SHORT \"$VBOX_VENDOR_SHORT\"" >> $PATH_TMP/product-generated.h
diff --git a/src/VBox/Additions/linux/installer/vboxadd-x11.sh b/src/VBox/Additions/linux/installer/vboxadd-x11.sh
index 7188e4f..3cc8745 100755
--- a/src/VBox/Additions/linux/installer/vboxadd-x11.sh
+++ b/src/VBox/Additions/linux/installer/vboxadd-x11.sh
@@ -1,6 +1,6 @@
#! /bin/sh
#
-# Linux Additions X11 setup init script ($Revision: 92745 $)
+# Linux Additions X11 setup init script ($Revision: 97087 $)
#
#
@@ -297,6 +297,11 @@ setup()
case "`uname -r`" in 2.4.*)
test -c /dev/psaux && nopsaux="";;
esac
+ # Should we use the VMSVGA driver instead of VBoxVideo?
+ vmsvga=""
+ if ! grep 80eebeef /proc/bus/pci/devices > /dev/null; then
+ vmsvga="--vmsvga"
+ fi
# The video driver to install for X.Org 6.9+
vboxvideo_src=
# The mouse driver to install for X.Org 6.9+
@@ -341,24 +346,24 @@ setup()
1.11.* )
xserver_version="X.Org Server 1.11"
vboxvideo_src=vboxvideo_drv_111.so
- test "$system" = "redhat" || setupxorgconf=""
+ test "$system" = "redhat" && test -z "${vmsvga}" || setupxorgconf=""
;;
1.10.* )
xserver_version="X.Org Server 1.10"
vboxvideo_src=vboxvideo_drv_110.so
- test "$system" = "redhat" || setupxorgconf=""
+ test "$system" = "redhat" && test -z "${vmsvga}" || setupxorgconf=""
;;
1.9.* )
xserver_version="X.Org Server 1.9"
vboxvideo_src=vboxvideo_drv_19.so
# Fedora 14 to 16 patched out vboxvideo detection
- test "$system" = "redhat" || setupxorgconf=""
+ test "$system" = "redhat" && test -z "${vmsvga}" || setupxorgconf=""
;;
1.8.* )
xserver_version="X.Org Server 1.8"
vboxvideo_src=vboxvideo_drv_18.so
# Fedora 13 shipped without vboxvideo detection
- test "$system" = "redhat" || setupxorgconf=""
+ test "$system" = "redhat" && test -z "${vmsvga}" || setupxorgconf=""
;;
1.7.* )
xserver_version="X.Org Server 1.7"
@@ -477,7 +482,7 @@ setup()
if grep -q "VirtualBox generated" "$i"; then
generated="$generated `printf "$i\n"`"
else
- "$lib_dir/x11config.sh" $autokeyboard $automouse $nopsaux "$i"
+ "$lib_dir/x11config.sh" $autokeyboard $automouse $nopsaux $vmsvga "$i"
fi
configured="true"
fi
@@ -490,7 +495,7 @@ setup()
nobak_cfg="`expr "${main_cfg}" : '\([^.]*\)'`.vbox.nobak"
if test -z "$configured"; then
touch "$main_cfg"
- "$lib_dir/x11config.sh" $autokeyboard $automouse $nopsaux --noBak "$main_cfg"
+ "$lib_dir/x11config.sh" $autokeyboard $automouse $nopsaux $vmsvga --noBak "$main_cfg"
touch "${nobak_cfg}"
fi
fi
@@ -551,6 +556,7 @@ EOF
# And set up VBoxClient to start when the X session does
install_x11_startup_app "$lib_dir/98vboxadd-xclient" "$share_dir/vboxclient.desktop" VBoxClient VBoxClient-all ||
fail "See the log file $LOG for more information."
+ ln -s "$lib_dir/98vboxadd-xclient" /usr/bin/VBoxClient-all 2>/dev/null
succ_msg
}
@@ -631,6 +637,7 @@ EOF
rm /etc/X11/xinit/xinitrc.d/98vboxadd-xclient.sh 2>/dev/null
rm /etc/xdg/autostart/vboxclient.desktop 2>/dev/null
rm /usr/share/autostart/vboxclient.desktop 2>/dev/null
+ rm /usr/bin/VBoxClient-all 2>/dev/null
# Remove other files
rm /usr/share/xserver-xorg/pci/vboxvideo.ids 2>/dev/null
diff --git a/src/VBox/Additions/linux/sharedfolders/dirops.c b/src/VBox/Additions/linux/sharedfolders/dirops.c
index dcaddab..f1465bd 100644
--- a/src/VBox/Additions/linux/sharedfolders/dirops.c
+++ b/src/VBox/Additions/linux/sharedfolders/dirops.c
@@ -126,15 +126,13 @@ static int sf_getdent(struct file *dir, char d_name[NAME_MAX])
TRACE();
- sf_g = GET_GLOB_INFO(dir->f_dentry->d_inode->i_sb);
+ inode = GET_F_DENTRY(dir)->d_inode;
+ sf_i = GET_INODE_INFO(inode);
+ sf_g = GET_GLOB_INFO(inode->i_sb);
sf_d = dir->private_data;
BUG_ON(!sf_g);
BUG_ON(!sf_d);
-
- inode = dir->f_dentry->d_inode;
- sf_i = GET_INODE_INFO(inode);
-
BUG_ON(!sf_i);
if (sf_i->force_reread)
diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c b/src/VBox/Additions/linux/sharedfolders/regops.c
index d5ba778..4a3aa36 100644
--- a/src/VBox/Additions/linux/sharedfolders/regops.c
+++ b/src/VBox/Additions/linux/sharedfolders/regops.c
@@ -108,7 +108,7 @@ static ssize_t sf_reg_read(struct file *file, char *buf, size_t size, loff_t *of
size_t tmp_size;
size_t left = size;
ssize_t total_bytes_read = 0;
- struct inode *inode = file->f_dentry->d_inode;
+ struct inode *inode = GET_F_DENTRY(file)->d_inode;
struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
struct sf_reg_info *sf_r = file->private_data;
loff_t pos = *off;
@@ -183,7 +183,7 @@ static ssize_t sf_reg_write(struct file *file, const char *buf, size_t size, lof
size_t tmp_size;
size_t left = size;
ssize_t total_bytes_written = 0;
- struct inode *inode = file->f_dentry->d_inode;
+ struct inode *inode = GET_F_DENTRY(file)->d_inode;
struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
struct sf_reg_info *sf_r = file->private_data;
@@ -454,7 +454,7 @@ static int sf_reg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
static struct page *sf_reg_nopage(struct vm_area_struct *vma, unsigned long vaddr, int *type)
# define SET_TYPE(t) *type = (t)
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 0) */
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */
static struct page *sf_reg_nopage(struct vm_area_struct *vma, unsigned long vaddr, int unused)
# define SET_TYPE(t)
#endif
@@ -465,7 +465,7 @@ static struct page *sf_reg_nopage(struct vm_area_struct *vma, unsigned long vadd
uint32_t nread = PAGE_SIZE;
int err;
struct file *file = vma->vm_file;
- struct inode *inode = file->f_dentry->d_inode;
+ struct inode *inode = GET_F_DENTRY(file)->d_inode;
struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
struct sf_reg_info *sf_r = file->private_data;
@@ -605,7 +605,7 @@ struct inode_operations sf_reg_iops =
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
static int sf_readpage(struct file *file, struct page *page)
{
- struct inode *inode = file->f_dentry->d_inode;
+ struct inode *inode = GET_F_DENTRY(file)->d_inode;
struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
struct sf_reg_info *sf_r = file->private_data;
uint32_t nread = PAGE_SIZE;
diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.h b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
index 6a20eb7..b310a42 100644
--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
@@ -145,7 +145,7 @@ int sf_get_volume_info(struct super_block *sb,STRUCT_STATFS *stat);
# define SET_GLOB_INFO(sb, sf_g) (sb)->s_fs_info = sf_g
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 6, 19) || defined(KERNEL_FC6)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) || defined(KERNEL_FC6)
/* FC6 kernel 2.6.18, vanilla kernel 2.6.19+ */
# define GET_INODE_INFO(i) ((struct sf_inode_info *) (i)->i_private)
# define SET_INODE_INFO(i, sf_i) (i)->i_private = sf_i
@@ -155,5 +155,11 @@ int sf_get_volume_info(struct super_block *sb,STRUCT_STATFS *stat);
# define SET_INODE_INFO(i, sf_i) (i)->u.generic_ip = sf_i
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
+# define GET_F_DENTRY(f) (f->f_path.dentry)
+#else
+# define GET_F_DENTRY(f) (f->f_dentry)
+#endif
+
#endif
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
index de546a8..1128686 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2008-2013 Oracle Corporation
+ * Copyright (C) 2008-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c
index adab7b1..7f2e7bd 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 2009-2011 Oracle Corporation
+ * Copyright (C) 2009-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
index 0170f7d..d82e2ac 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009-2013 Oracle Corporation
+ * Copyright (C) 2009-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/x11/Installer/98vboxadd-xclient b/src/VBox/Additions/x11/Installer/98vboxadd-xclient
index bd32a03..f0d4236 100755
--- a/src/VBox/Additions/x11/Installer/98vboxadd-xclient
+++ b/src/VBox/Additions/x11/Installer/98vboxadd-xclient
@@ -15,19 +15,19 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-# It can happen that pidfiles from a sudo session can land in the user's
-# home directory and prevent new ones from being created. This is not really
-# our fault, but the user may not quite appreciate that...
+# Sanity check: if non-writeable PID-files are present in the user home
+# directory VBoxClient will fail to start.
for i in $HOME/.vboxclient-*.pid; do
- if test -r $i && ! ps -e | grep `cat $i`; then
- rm -f $i
- fi
+ test -w $i || rm -f $i
done
-# This script can also be triggered by a connection over SSH, which is not what
-# we had in mind, so we do not start VBoxClient in that case. We do not use
-# "exit" here as this script is "source"d, not executed.
-if test -z "${SSH_CONNECTION}"; then
+if test -f /proc/modules && ! grep -q vboxguest /proc/modules 2>/dev/null; then
+ # Do not start if the kernel module is not present.
+ notify-send "VBoxClient: the VirtualBox kernel service is not running. Exiting."
+elif test -z "${SSH_CONNECTION}"; then
+ # This script can also be triggered by a connection over SSH, which is not
+ # what we had in mind, so we do not start VBoxClient in that case. We do
+ # not use "exit" here as this script is "source"d, not executed.
/usr/bin/VBoxClient --clipboard
/usr/bin/VBoxClient --checkhostversion
/usr/bin/VBoxClient --display
diff --git a/src/VBox/Additions/x11/Installer/x11config.sh b/src/VBox/Additions/x11/Installer/x11config.sh
index 6580552..f844f89 100755
--- a/src/VBox/Additions/x11/Installer/x11config.sh
+++ b/src/VBox/Additions/x11/Installer/x11config.sh
@@ -17,6 +17,7 @@ auto_mouse=""
auto_keyboard=""
no_bak=""
old_mouse_dev="/dev/psaux"
+video_driver="vboxvideo"
tab=`printf '\t'`
@@ -117,7 +118,7 @@ EndSection
Section "Device"
BoardName "VirtualBox Graphics"
- Driver "vboxvideo"
+ Driver "${video_driver}"
Identifier "Device[0]"
VendorName "Oracle Corporation"
EndSection
@@ -148,6 +149,8 @@ do
no_bak=1 ;;
--nopsaux)
old_mouse_dev="/dev/input/mice" ;;
+ --vmsvga)
+ video_driver="vmware" ;;
*)
reconfigure "$1" ;;
esac
diff --git a/src/VBox/Additions/x11/VBoxClient/Makefile.kmk b/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
index 9a4e587..ece98ee 100644
--- a/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
+++ b/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
@@ -56,9 +56,7 @@ ifdef VBOX_X11_SEAMLESS_GUEST
VBoxClient_DEFS += SEAMLESS_GUEST DYNAMIC_RESIZE
VBoxClient_SOURCES += \
seamless.cpp \
- seamless-host.cpp \
seamless-x11.cpp \
- thread.cpp \
display.cpp \
hostversion.cpp
VBoxClient_LIBS += \
@@ -107,9 +105,8 @@ $$(tstSeamlessX11-auto_0_OUTDIR)/tstSeamlessX11-auto.run: \
tstSeamlessX11_TEMPLATE = VBOXR3TSTEXE
tstSeamlessX11_SOURCES = \
testcase/tstSeamlessX11.cpp \
- seamless-host.cpp \
- seamless-x11.cpp \
- thread.cpp
+ seamless.cpp \
+ seamless-x11.cpp
tstSeamlessX11_LIBPATH = \
$(VBOX_LIBPATH_X11)
tstSeamlessX11_LIBS = \
diff --git a/src/VBox/Additions/x11/VBoxClient/VBoxClient.h b/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
index 63d5842..f52522f 100644
--- a/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
+++ b/src/VBox/Additions/x11/VBoxClient/VBoxClient.h
@@ -18,36 +18,73 @@
#ifndef ___vboxclient_vboxclient_h
# define ___vboxclient_vboxclient_h
+#include <VBox/log.h>
#include <iprt/cpp/utils.h>
+#include <iprt/string.h>
-/** Namespace for VBoxClient-specific things */
-namespace VBoxClient {
+/** Exit with a fatal error. */
+#define VBClFatalError(format) \
+do { \
+ char *pszMessage = RTStrAPrintf2 format; \
+ LogRel(format); \
+ vbclFatalError(pszMessage); \
+} while(0)
-/** A simple class describing a service. VBoxClient will run exactly one
+/** Exit with a fatal error. */
+extern void vbclFatalError(char *pszMessage);
+
+/** Call clean-up for the current service and exit. */
+extern void VBClCleanUp();
+
+/** A simple interface describing a service. VBoxClient will run exactly one
* service per invocation. */
-class Service : public RTCNonCopyable
+struct VBCLSERVICE
{
-public:
/** Get the services default path to pidfile, relative to $HOME */
- virtual const char *getPidFilePath() = 0;
+ /** @todo Should this also have a component relative to the X server number?
+ */
+ const char *(*getPidFilePath)(void);
+ /** Special initialisation, if needed. @a pause and @a resume are
+ * guaranteed not to be called until after this returns. */
+ int (*init)(struct VBCLSERVICE **ppInterface);
/** Run the service main loop */
- virtual int run(bool fDaemonised = false) = 0;
- /** Clean up any global resources before we shut down hard */
- virtual void cleanup() = 0;
- /** Virtual destructor. Not used */
- virtual ~Service() {}
+ int (*run)(struct VBCLSERVICE **ppInterface, bool fDaemonised);
+ /** Pause the service loop. This is used to allow the service to disable
+ * itself when the X server is switched out. It must be safe to call on a
+ * different thread if the VT monitoring thread is used. */
+ int (*pause)(struct VBCLSERVICE **ppInterface);
+ /** Resume after pausing. The same applies here as for @a pause. */
+ int (*resume)(struct VBCLSERVICE **ppInterface);
+ /** Clean up any global resources before we shut down hard. The last calls
+ * to @a pause and @a resume are guaranteed to finish before this is called.
+ */
+ void (*cleanup)(struct VBCLSERVICE **ppInterface);
};
-extern Service *GetClipboardService();
-extern Service *GetSeamlessService();
-extern Service *GetDisplayService();
-extern Service *GetHostVersionService();
-#ifdef VBOX_WITH_DRAG_AND_DROP
-extern Service *GetDragAndDropService();
-#endif /* VBOX_WITH_DRAG_AND_DROP */
+/** Default handler for various struct VBCLSERVICE member functions. */
+static int VBClServiceDefaultHandler(struct VBCLSERVICE **pSelf)
+{
+ return VINF_SUCCESS;
+}
-extern void CleanUp();
+/** Default handler for the struct VBCLSERVICE clean-up member function.
+ * Usually used because the service is cleaned up automatically when the user
+ * process/X11 exits. */
+static void VBClServiceDefaultCleanup(struct VBCLSERVICE **ppInterface)
+{
+ NOREF(ppInterface);
+}
+
+union _XEvent; /* We do not want to pull in the X11 header files here. */
+extern void VBClCheckXOrgVT(union _XEvent *pEvent);
+extern int VBClStartVTMonitor();
-} /* namespace VBoxClient */
+extern struct VBCLSERVICE **VBClGetClipboardService();
+extern struct VBCLSERVICE **VBClGetSeamlessService();
+extern struct VBCLSERVICE **VBClGetDisplayService();
+extern struct VBCLSERVICE **VBClGetHostVersionService();
+#ifdef VBOX_WITH_DRAG_AND_DROP
+extern struct VBCLSERVICE **VBClGetDragAndDropService();
+#endif /* VBOX_WITH_DRAG_AND_DROP */
#endif /* !___vboxclient_vboxclient_h */
diff --git a/src/VBox/Additions/x11/VBoxClient/clipboard.cpp b/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
index 24ba7e9..a17be6d 100644
--- a/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
@@ -277,29 +277,58 @@ int vboxClipboardMain(void)
return rc;
}
-class ClipboardService : public VBoxClient::Service
+static const char *getPidFilePath()
{
-public:
- virtual const char *getPidFilePath()
- {
- return ".vboxclient-clipboard.pid";
- }
- virtual int run(bool fDaemonised /* = false */)
- {
- int rc = vboxClipboardConnect();
- if (RT_SUCCESS(rc))
- rc = vboxClipboardMain();
- if (RT_FAILURE(rc))
- LogRelFunc(("guest clipboard service terminated abnormally: return code %Rrc\n", rc));
- return rc;
- }
- virtual void cleanup()
- {
- /* Nothing to do. */
- }
+ return ".vboxclient-clipboard.pid";
+}
+
+static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
+{
+ int rc;
+
+ NOREF(ppInterface);
+ /* Initialise the guest library. */
+ rc = VbglR3InitUser();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
+ rc = vboxClipboardConnect();
+ if (RT_SUCCESS(rc))
+ rc = vboxClipboardMain();
+ if (rc == VERR_NOT_SUPPORTED)
+ rc = VINF_SUCCESS; /* Prevent automatic restart. */
+ if (RT_FAILURE(rc))
+ LogRelFunc(("guest clipboard service terminated abnormally: return code %Rrc\n", rc));
+ return rc;
+}
+
+static void cleanup(struct VBCLSERVICE **ppInterface)
+{
+ NOREF(ppInterface);
+ VbglR3Term();
+}
+
+struct VBCLSERVICE vbclClipboardInterface =
+{
+ getPidFilePath,
+ VBClServiceDefaultHandler, /* init */
+ run,
+ VBClServiceDefaultHandler, /* pause */
+ VBClServiceDefaultHandler, /* resume */
+ cleanup
+};
+
+struct CLIPBOARDSERVICE
+{
+ struct VBCLSERVICE *pInterface;
};
-VBoxClient::Service *VBoxClient::GetClipboardService()
+struct VBCLSERVICE **VBClGetClipboardService()
{
- return new ClipboardService;
+ struct CLIPBOARDSERVICE *pService =
+ (struct CLIPBOARDSERVICE *)RTMemAlloc(sizeof(*pService));
+
+ if (!pService)
+ VBClFatalError(("Out of memory\n"));
+ pService->pInterface = &vbclClipboardInterface;
+ return &pService->pInterface;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/display.cpp b/src/VBox/Additions/x11/VBoxClient/display.cpp
index e4a0eb4..534bfeb 100644
--- a/src/VBox/Additions/x11/VBoxClient/display.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/display.cpp
@@ -23,12 +23,12 @@
#include <errno.h>
#include <X11/Xlib.h>
-#include <X11/cursorfont.h>
-#include <X11/extensions/Xrandr.h>
+#include <X11/Xatom.h>
#include <iprt/assert.h>
#include <iprt/err.h>
#include <iprt/file.h>
+#include <iprt/mem.h>
#include <iprt/string.h>
#include <iprt/thread.h>
#include <VBox/log.h>
@@ -37,262 +37,390 @@
#include "VBoxClient.h"
-static int initDisplay(Display *pDisplay)
+/* TESTING: Dynamic resizing and mouse integration toggling should work
+ * correctly with a range of X servers (pre-1.3, 1.3 and later under Linux, 1.3
+ * and later under Solaris) with Guest Additions installed. Switching to a
+ * virtual terminal while a user session is in place should disable dynamic
+ * resizing and cursor integration, switching back should re-enable them. */
+
+/** Most recent information received for a particular screen. */
+struct screenInformation
{
- int rc = VINF_SUCCESS;
- uint32_t fMouseFeatures = 0;
+ unsigned cx;
+ unsigned cy;
+ unsigned cBPP;
+ unsigned x;
+ unsigned y;
+ bool fEnabled;
+ bool fUpdateSize;
+ bool fUpdatePosition;
+};
- LogRelFlowFunc(("testing dynamic resizing\n"));
- int iDummy;
- if (!XRRQueryExtension(pDisplay, &iDummy, &iDummy))
- rc = VERR_NOT_SUPPORTED;
- if (RT_SUCCESS(rc))
- rc = VbglR3CtlFilterMask(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0);
- else
- VbglR3CtlFilterMask(0, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
- /* Log and ignore the return value, as there is not much we can do with
- * it. */
- LogRelFlowFunc(("dynamic resizing: result %Rrc\n", rc));
- /* Enable support for switching between hardware and software cursors */
- LogRelFlowFunc(("enabling relative mouse re-capturing support\n"));
- rc = VbglR3GetMouseStatus(&fMouseFeatures, NULL, NULL);
- if (RT_SUCCESS(rc))
- {
- rc = VbglR3CtlFilterMask(VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
- 0);
- if (RT_SUCCESS(rc))
- rc = VbglR3SetMouseStatus
- ( fMouseFeatures
- & ~VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
- }
+/** Display magic number, start of a UUID. */
+#define DISPLAYSTATE_MAGIC UINT32_C(0xf0029993)
+
+/** State information needed for the service. The main VBoxClient code provides
+ * the daemon logic needed by all services. */
+struct DISPLAYSTATE
+{
+ /** The service interface. */
+ struct VBCLSERVICE *pInterface;
+ /** Magic number for sanity checks. */
+ uint32_t magic;
+ /** Are we initialised yet? */
+ bool mfInit;
+ /** The connection to the server. */
+ Display *pDisplay;
+ /** Can we use version 1.2 or later of the RandR protocol here? */
+ bool fHaveRandR12;
+ /** The command argument to use for the xrandr binary. Currently only
+ * used to support the non-standard location on some Solaris systems -
+ * would it make sense to use absolute paths on all systems? */
+ const char *pcszXrandr;
+ /** The number of screens we are currently aware of. */
+ unsigned cScreensTracked;
+ /** Array of information about different screens. */
+ struct screenInformation *paScreenInformation;
+};
+
+/** Tell the VBoxGuest driver we no longer want any events and tell the host
+ * we no longer support any capabilities. */
+static int disableEventsAndCaps()
+{
+ int rc = VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS);
if (RT_FAILURE(rc))
- {
- VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED);
- VbglR3SetMouseStatus( fMouseFeatures
- | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
- }
- LogRelFlowFunc(("mouse re-capturing support: result %Rrc\n", rc));
+ VBClFatalError(("Failed to unset graphics capability, rc=%Rrc.\n", rc));
+ rc = VbglR3SetMouseStatus(VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to unset mouse status, rc=%Rrc.\n", rc));
+ rc = VbglR3CtlFilterMask(0, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED
+ | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to unset filter mask, rc=%Rrc.\n", rc));
return VINF_SUCCESS;
}
-void cleanupDisplay(void)
+/** Tell the VBoxGuest driver which events we want and tell the host which
+ * capabilities we support. */
+static int enableEventsAndCaps()
{
- uint32_t fMouseFeatures = 0;
- LogRelFlowFunc(("\n"));
- VbglR3CtlFilterMask(0, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
- | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED);
- int rc = VbglR3GetMouseStatus(&fMouseFeatures, NULL, NULL);
- if (RT_SUCCESS(rc))
- VbglR3SetMouseStatus( fMouseFeatures
- | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
- LogRelFlowFunc(("returning\n"));
+ int rc = VbglR3CtlFilterMask( VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED
+ | VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to set filter mask, rc=%Rrc.\n", rc));
+ rc = VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to set graphics capability, rc=%Rrc.\n", rc));
+ rc = VbglR3SetMouseStatus(0);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to set mouse status, rc=%Rrc.\n", rc));
+ return VINF_SUCCESS;
}
-/** This thread just runs a dummy X11 event loop to be sure that we get
- * terminated should the X server exit. */
-static int x11ConnectionMonitor(RTTHREAD, void *)
+static int initDisplay(struct DISPLAYSTATE *pState)
{
- XEvent ev;
- Display *pDisplay = XOpenDisplay(NULL);
- while (true)
- XNextEvent(pDisplay, &ev);
- return 0;
+ char szCommand[256];
+ int status;
+
+ /* Initialise the guest library. */
+ int rc = VbglR3InitUser();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
+ pState->pDisplay = XOpenDisplay(NULL);
+ if (!pState->pDisplay)
+ return VERR_NOT_FOUND;
+ pState->fHaveRandR12 = false;
+ pState->pcszXrandr = "xrandr";
+ if (RTFileExists("/usr/X11/bin/xrandr"))
+ pState->pcszXrandr = "/usr/X11/bin/xrandr";
+ status = system(pState->pcszXrandr);
+ if (WEXITSTATUS(status) != 0) /* Utility or extension not available. */
+ VBClFatalError(("Failed to execute the xrandr utility.\n"));
+ RTStrPrintf(szCommand, sizeof(szCommand), "%s --q12", pState->pcszXrandr);
+ status = system(szCommand);
+ if (WEXITSTATUS(status) == 0)
+ pState->fHaveRandR12 = true;
+ pState->cScreensTracked = 0;
+ pState->paScreenInformation = NULL;
+ return VINF_SUCCESS;
}
-/**
- * This method first resets the current resolution using RandR to wake up
- * the graphics driver, then sets the resolution requested if it is among
- * those offered by the driver.
- */
-static void setSize(Display *pDisplay, uint32_t cx, uint32_t cy)
+static void updateScreenInformation(struct DISPLAYSTATE *pState, unsigned cx, unsigned cy, unsigned cBPP, unsigned iDisplay,
+ unsigned x, unsigned y, bool fEnabled, bool fUpdatePosition)
{
- XRRScreenConfiguration *pConfig;
- XRRScreenSize *pSizes;
- int cSizes;
- pConfig = XRRGetScreenInfo(pDisplay, DefaultRootWindow(pDisplay));
- /* Reset the current mode */
- LogRelFlowFunc(("Setting size %ux%u\n", cx, cy));
- if (pConfig)
+ uint32_t i;
+
+ if (iDisplay >= pState->cScreensTracked)
{
- pSizes = XRRConfigSizes(pConfig, &cSizes);
- unsigned uDist = UINT32_MAX;
- int iMode = -1;
- for (int i = 0; i < cSizes; ++i)
+ pState->paScreenInformation =
+ (struct screenInformation *)RTMemRealloc(pState->paScreenInformation,
+ (iDisplay + 1) * sizeof(*pState->paScreenInformation));
+ if (!pState->paScreenInformation)
+ VBClFatalError(("Failed to re-allocate screen information.\n"));
+ for (i = pState->cScreensTracked; i < iDisplay + 1; ++i)
+ RT_ZERO(pState->paScreenInformation[i]);
+ pState->cScreensTracked = iDisplay + 1;
+ }
+ pState->paScreenInformation[iDisplay].cx = cx;
+ pState->paScreenInformation[iDisplay].cy = cy;
+ pState->paScreenInformation[iDisplay].cBPP = cBPP;
+ pState->paScreenInformation[iDisplay].x = x;
+ pState->paScreenInformation[iDisplay].y = y;
+ pState->paScreenInformation[iDisplay].fEnabled = fEnabled;
+ pState->paScreenInformation[iDisplay].fUpdateSize = true;
+ pState->paScreenInformation[iDisplay].fUpdatePosition = fUpdatePosition;
+}
+
+static void updateSizeHintsProperty(struct DISPLAYSTATE *pState)
+{
+ int32_t *paSizeHints = (int32_t *)RTMemTmpAllocZ(pState->cScreensTracked * sizeof(int32_t));
+ unsigned i;
+
+ if (paSizeHints == NULL)
+ VBClFatalError(("Failed to allocate size hint property memory.\n"));
+ for (i = 0; i < pState->cScreensTracked; ++i)
+ {
+ if ( pState->paScreenInformation[i].fEnabled
+ && pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0)
+ paSizeHints[i] = (pState->paScreenInformation[i].cx & 0x8fff) << 16 | (pState->paScreenInformation[i].cy & 0x8fff);
+ else if (pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0)
+ paSizeHints[i] = -1;
+ }
+ XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay), XInternAtom(pState->pDisplay, "VBOX_SIZE_HINTS", 0),
+ XA_INTEGER, 32, PropModeReplace, (unsigned char *)paSizeHints, pState->cScreensTracked);
+ XFlush(pState->pDisplay);
+ RTMemTmpFree(paSizeHints);
+}
+
+static void notifyXServer(struct DISPLAYSTATE *pState)
+{
+ char szCommand[256];
+ unsigned i;
+ bool fUpdateInformation = false;
+
+ /** @note The xrandr command can fail if something else accesses RandR at
+ * the same time. We just ignore failure for now and let the user try
+ * again as we do not know what someone else is doing. */
+ for (i = 0; i < pState->cScreensTracked; ++i)
+ if (pState->paScreenInformation[i].fUpdateSize)
+ fUpdateInformation = true;
+ if ( !pState->fHaveRandR12 && pState->paScreenInformation[0].fUpdateSize
+ && pState->paScreenInformation[0].cx > 0 && pState->paScreenInformation[0].cy > 0)
+ {
+ RTStrPrintf(szCommand, sizeof(szCommand), "%s -s %ux%u",
+ pState->pcszXrandr, pState->paScreenInformation[0].cx, pState->paScreenInformation[0].cy);
+ system(szCommand);
+ pState->paScreenInformation[0].fUpdateSize = false;
+ }
+ else if (pState->fHaveRandR12 && fUpdateInformation)
+ for (i = 0; i < pState->cScreensTracked; ++i)
{
-#define VBCL_SQUARE(x) (x) * (x)
- unsigned uThisDist = VBCL_SQUARE(pSizes[i].width - cx)
- + VBCL_SQUARE(pSizes[i].height - cy);
- LogRelFlowFunc(("Found size %dx%d, distance %u\n", pSizes[i].width,
- pSizes[i].height, uThisDist));
-#undef VBCL_SQUARE
- if (uThisDist < uDist)
+ if (pState->paScreenInformation[i].fUpdateSize)
{
- uDist = uThisDist;
- iMode = i;
+ RTStrPrintf(szCommand, sizeof(szCommand), "%s --output VGA-%u --preferred", pState->pcszXrandr, i);
+ system(szCommand);
}
+ if (pState->paScreenInformation[i].fUpdatePosition)
+ {
+ RTStrPrintf(szCommand, sizeof(szCommand), "%s --output VGA-%u --auto --pos %ux%u",
+ pState->pcszXrandr, i, pState->paScreenInformation[i].x, pState->paScreenInformation[i].y);
+ system(szCommand);
+ }
+ pState->paScreenInformation[i].fUpdateSize = pState->paScreenInformation[i].fUpdatePosition = false;
}
- if (iMode >= 0)
- {
- Time config_timestamp = 0;
- XRRConfigTimes(pConfig, &config_timestamp);
- LogRelFlowFunc(("Setting new size %d\n", iMode));
- XRRSetScreenConfig(pDisplay, pConfig,
- DefaultRootWindow(pDisplay), iMode,
- RR_Rotate_0, config_timestamp);
- }
- XRRFreeScreenConfigInfo(pConfig);
+ else
+ {
+ RTStrPrintf(szCommand, sizeof(szCommand), "%s", pState->pcszXrandr);
+ system(szCommand);
}
}
+static void updateMouseCapabilities(struct DISPLAYSTATE *pState)
+{
+ uint32_t fFeatures = 0;
+ int rc;
+ unsigned i;
+
+ rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
+
+ if (rc != VINF_SUCCESS)
+ VBClFatalError(("Failed to get mouse status, rc=%Rrc\n", rc));
+ XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay),
+ XInternAtom(pState->pDisplay, "VBOX_MOUSE_CAPABILITIES", 0), XA_INTEGER, 32, PropModeReplace,
+ (unsigned char *)&fFeatures, 1);
+ XFlush(pState->pDisplay);
+ if (pState->fHaveRandR12)
+ for (i = 0; i < pState->cScreensTracked; ++i)
+ pState->paScreenInformation[i].fUpdateSize = true;
+ else
+ pState->paScreenInformation[0].fUpdateSize = true;
+}
+
/**
* Display change request monitor thread function.
- * Before entering the loop, we re-read the last request
- * received, and if the first one received inside the
- * loop is identical we ignore it, because it is probably
- * stale.
*/
-static int runDisplay(Display *pDisplay)
+static void runDisplay(struct DISPLAYSTATE *pState)
{
+ int status, rc;
+ unsigned i, cScreensTracked;
+ char szCommand[256];
+
LogRelFlowFunc(("\n"));
- Cursor hClockCursor = XCreateFontCursor(pDisplay, XC_watch);
- Cursor hArrowCursor = XCreateFontCursor(pDisplay, XC_left_ptr);
- int RRMaj, RRMin;
- bool fExtDispReqSupport = true;
- if (!XRRQueryVersion(pDisplay, &RRMaj, &RRMin))
- RRMin = 0;
- const char *pcszXrandr = "xrandr";
- if (RTFileExists("/usr/X11/bin/xrandr"))
- pcszXrandr = "/usr/X11/bin/xrandr";
- int rc = RTThreadCreate(NULL, x11ConnectionMonitor, NULL, 0,
- RTTHREADTYPE_INFREQUENT_POLLER, 0, "X11 monitor");
- if (RT_FAILURE(rc))
- return rc;
+ rc = VbglR3VideoModeGetHighestSavedScreen(&cScreensTracked);
+ if (rc != VINF_SUCCESS && rc != VERR_NOT_SUPPORTED)
+ VBClFatalError(("Failed to get the number of saved screen modes, rc=%Rrc\n", rc));
+ /* Make sure that we have an entry for screen 1 at least. */
+ updateScreenInformation(pState, 1024, 768, 0, 1, 0, 0, true, false);
+ if (rc == VINF_SUCCESS)
+ {
+ /* The "8" is for the sanity test below. */
+ for (i = 0; i < RT_MAX(cScreensTracked + 1, 8); ++i)
+ {
+ unsigned cx = 0, cy = 0, cBPP = 0, x = 0, y = 0;
+ bool fEnabled = true;
+
+ rc = VbglR3RetrieveVideoMode(i, &cx, &cy, &cBPP, &x, &y,
+ &fEnabled);
+ /* Sanity test for VbglR3VideoModeGetHighestSavedScreen(). */
+ if (i > cScreensTracked && rc != VERR_NOT_FOUND)
+ VBClFatalError(("Internal error retrieving the number of saved screen modes.\n"));
+ if (rc == VINF_SUCCESS)
+ updateScreenInformation(pState, cx, cy, cBPP, i, x, y, fEnabled, true);
+ }
+ }
while (true)
{
- uint32_t fEvents = 0, cx = 0, cy = 0, cBits = 0, iDisplay = 0, cxOrg = 0, cyOrg = 0;
- bool fEnabled = false;
- rc = VbglR3WaitEvent( VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
- | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
- RT_INDEFINITE_WAIT, &fEvents);
- if (RT_FAILURE(rc) && rc != VERR_INTERRUPTED) /* VERR_NO_MEMORY? */
- return rc;
- /* Jiggle the mouse pointer to wake up the driver. */
- XGrabPointer(pDisplay,
- DefaultRootWindow(pDisplay), true, 0, GrabModeAsync,
- GrabModeAsync, None, hClockCursor, CurrentTime);
- XFlush(pDisplay);
- XGrabPointer(pDisplay,
- DefaultRootWindow(pDisplay), true, 0, GrabModeAsync,
- GrabModeAsync, None, hArrowCursor, CurrentTime);
- XFlush(pDisplay);
- XUngrabPointer(pDisplay, CurrentTime);
- XFlush(pDisplay);
- /* And if it is a size hint, set the new size now that the video
- * driver has had a chance to update its list. */
- if (RT_SUCCESS(rc) && (fEvents & VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST))
+ uint32_t fEvents;
+ updateMouseCapabilities(pState);
+ updateSizeHintsProperty(pState);
+ notifyXServer(pState);
+ do
+ rc = VbglR3WaitEvent( VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
+ | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
+ RT_INDEFINITE_WAIT, &fEvents);
+ while(rc == VERR_INTERRUPTED);
+ if (RT_FAILURE(rc)) /* VERR_NO_MEMORY? */
+ VBClFatalError(("event wait failed, rc=%Rrc\n", rc));
+ /* If it is a size hint, set the new size. */
+ if (fEvents & VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST)
{
- int rc2 = VbglR3GetDisplayChangeRequestEx(&cx, &cy, &cBits,
- &iDisplay, &cxOrg, &cyOrg, &fEnabled, true);
- /* Extended display version not supported on host */
- if (RT_FAILURE(rc2))
+ uint32_t cx = 0, cy = 0, cBPP = 0, iDisplay = 0, x = 0, y = 0;
+ bool fEnabled = true, fUpdatePosition = true;
+ VMMDevSeamlessMode Mode;
+
+ rc = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBPP, &iDisplay,
+ &x, &y, &fEnabled,
+ &fUpdatePosition, true);
+ if (rc != VINF_SUCCESS)
+ VBClFatalError(("Failed to get display change request, rc=%Rrc\n",
+ rc));
+ else
+ LogRelFlowFunc(("Got size hint from host cx=%d, cy=%d, bpp=%d, iDisplay=%d, x=%d, y=%d fEnabled=%d\n",
+ cx, cy, cBPP, iDisplay, x, y, fEnabled));
+ if (iDisplay > INT32_MAX)
+ VBClFatalError(("Received a size hint for too high display number %u\n",
+ (unsigned) iDisplay));
+ updateScreenInformation(pState, cx, cy, cBPP, iDisplay, x, y, fEnabled, fUpdatePosition);
+ rc = VbglR3SeamlessGetLastEvent(&Mode);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to check seamless mode, rc=%Rrc\n", rc));
+ if (Mode == VMMDev_Seamless_Disabled)
{
- LogRel(("GetDisplayChangeReq Extended Version not supported. "
- "Trying for Normal Mode with cx=%d & cy=%d\n", cx, cy));
- fExtDispReqSupport = false;
- rc2 = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &iDisplay, true);
+ rc = VbglR3SaveVideoMode(iDisplay, cx, cy, cBPP, x, y,
+ fEnabled);
+ if (RT_FAILURE(rc) && rc != VERR_NOT_SUPPORTED)
+ VBClFatalError(("Failed to save size hint, rc=%Rrc\n", rc));
}
- else
- LogRelFlowFunc(("Got Extended Param from Host cx=%d, cy=%d, bpp=%d, iDisp=%d, "
- "OrgX=%d, OrgY=%d Enb=%d\n", cx, cy, cBits, iDisplay,
- cxOrg, cyOrg, fEnabled));
- /* If we are not stopping, sleep for a bit to avoid using up
- too much CPU while retrying. */
- if (RT_FAILURE(rc2))
- RTThreadYield();
- else
- if (RRMin < 2)
- setSize(pDisplay, cx, cy);
- else
- {
- char szCommand[256];
- if (fExtDispReqSupport)
- {
- if (fEnabled)
- {
- if (cx != 0 && cy != 0)
- {
- RTStrPrintf(szCommand, sizeof(szCommand),
- "%s --output VBOX%u --set VBOX_MODE %dx%d",
- pcszXrandr, iDisplay, cx, cy);
- system(szCommand);
- }
- /* Extended Display support possible . Secondary monitor position supported */
- if (cxOrg != 0 || cyOrg != 0)
- {
- RTStrPrintf(szCommand, sizeof(szCommand),
- "%s --output VBOX%u --auto --pos %dx%d",
- pcszXrandr, iDisplay, cxOrg, cyOrg);
- system(szCommand);
- }
- RTStrPrintf(szCommand, sizeof(szCommand),
- "%s --output VBOX%u --preferred",
- pcszXrandr, iDisplay);
- system(szCommand);
- }
- else /* disable the virtual monitor */
- {
- RTStrPrintf(szCommand, sizeof(szCommand),
- "%s --output VBOX%u --off",
- pcszXrandr, iDisplay);
- system(szCommand);
- }
- }
- else /* Extended display support not possible */
- {
- if (cx != 0 && cy != 0)
- {
- RTStrPrintf(szCommand, sizeof(szCommand),
- "%s --output VBOX%u --set VBOX_MODE %dx%d",
- pcszXrandr, iDisplay, cx, cy);
- system(szCommand);
- RTStrPrintf(szCommand, sizeof(szCommand),
- "%s --output VBOX%u --preferred",
- pcszXrandr, iDisplay);
- system(szCommand);
- }
- }
-
- }
}
}
- return VINF_SUCCESS;
}
-class DisplayService : public VBoxClient::Service
+static const char *getPidFilePath()
{
-public:
- virtual const char *getPidFilePath()
- {
- return ".vboxclient-display.pid";
- }
- virtual int run(bool fDaemonised /* = false */)
- {
- Display *pDisplay = XOpenDisplay(NULL);
- if (!pDisplay)
- return VERR_NOT_FOUND;
- int rc = initDisplay(pDisplay);
- if (RT_SUCCESS(rc))
- rc = runDisplay(pDisplay);
- XCloseDisplay(pDisplay);
+ return ".vboxclient-display.pid";
+}
+
+static struct DISPLAYSTATE *getStateFromInterface(struct VBCLSERVICE **ppInterface)
+{
+ struct DISPLAYSTATE *pSelf = (struct DISPLAYSTATE *)ppInterface;
+ if (pSelf->magic != DISPLAYSTATE_MAGIC)
+ VBClFatalError(("Bad display service object!\n"));
+ return pSelf;
+}
+
+static int init(struct VBCLSERVICE **ppInterface)
+{
+ struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
+ int rc;
+
+ if (pSelf->mfInit)
+ return VERR_WRONG_ORDER;
+ rc = initDisplay(pSelf);
+ if (RT_FAILURE(rc))
return rc;
- }
- virtual void cleanup()
- {
- cleanupDisplay();
- }
+ rc = enableEventsAndCaps();
+ if (RT_SUCCESS(rc))
+ pSelf->mfInit = true;
+ return rc;
+}
+
+static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
+{
+ struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
+ int rc;
+
+ if (!pSelf->mfInit)
+ return VERR_WRONG_ORDER;
+ rc = VBClStartVTMonitor();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to start the VT monitor thread: %Rrc\n", rc));
+ runDisplay(pSelf);
+ return VERR_INTERNAL_ERROR; /* "Should never reach here." */
+}
+
+static int pause(struct VBCLSERVICE **ppInterface)
+{
+ struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
+
+ if (!pSelf->mfInit)
+ return VERR_WRONG_ORDER;
+ return disableEventsAndCaps();
+}
+
+static int resume(struct VBCLSERVICE **ppInterface)
+{
+ struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
+
+ if (!pSelf->mfInit)
+ return VERR_WRONG_ORDER;
+ return enableEventsAndCaps();
+}
+
+static void cleanup(struct VBCLSERVICE **ppInterface)
+{
+ NOREF(ppInterface);
+ disableEventsAndCaps();
+ VbglR3Term();
+}
+
+struct VBCLSERVICE vbclDisplayInterface =
+{
+ getPidFilePath,
+ init,
+ run,
+ pause,
+ resume,
+ cleanup
};
-VBoxClient::Service *VBoxClient::GetDisplayService()
+struct VBCLSERVICE **VBClGetDisplayService()
{
- return new DisplayService;
+ struct DISPLAYSTATE *pService = (struct DISPLAYSTATE *)RTMemAlloc(sizeof(*pService));
+
+ if (!pService)
+ VBClFatalError(("Out of memory\n"));
+ pService->pInterface = &vbclDisplayInterface;
+ pService->magic = DISPLAYSTATE_MAGIC;
+ pService->mfInit = false;
+ return &pService->pInterface;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp b/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
index f38a89f..d69d3f8 100644
--- a/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
@@ -417,7 +417,7 @@ public:
*
******************************************************************************/
-class DragAndDropService : public VBoxClient::Service
+class DragAndDropService
{
public:
DragAndDropService()
@@ -428,18 +428,7 @@ public:
, m_pCurDnD(0)
{}
- virtual const char *getPidFilePath() { return ".vboxclient-draganddrop.pid"; }
-
- /** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
- notification stuff, since this is very similar to the VBoxTray code. */
- virtual int run(bool fDaemonised = false);
-
- virtual void cleanup()
- {
- /* Nothing to do, everything should be cleaned up automatically when the
- * user process/X11 client exits. */
- VbglR3DnDTerm();
- };
+ int run(bool fDaemonised = false);
private:
int x11DragAndDropInit();
@@ -1550,6 +1539,10 @@ int DragAndDropService::run(bool fDaemonised /* = false */)
do
{
+ /* Initialise the guest library. */
+ rc = VbglR3InitUser();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
/* Initialize our service */
rc = VbglR3DnDInit();
if (RT_FAILURE(rc))
@@ -1776,8 +1769,62 @@ int DragAndDropService::x11EventThread(RTTHREAD hThread, void *pvUser)
return VINF_SUCCESS;
}
+/** Drag and drop magic number, start of a UUID. */
+#define DRAGANDDROPSERVICE_MAGIC 0x67c97173
+
+/** VBoxClient service class wrapping the logic for the service while
+ * the main VBoxClient code provides the daemon logic needed by all services.
+ */
+struct DRAGANDDROPSERVICE
+{
+ /** The service interface. */
+ struct VBCLSERVICE *pInterface;
+ /** Magic number for sanity checks. */
+ uint32_t magic;
+ /** Service object. */
+ DragAndDropService mDragAndDrop;
+};
+
+static const char *getPidFilePath()
+{
+ return ".vboxclient-draganddrop.pid";
+}
+
+static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
+{
+ struct DRAGANDDROPSERVICE *pSelf = (struct DRAGANDDROPSERVICE *)ppInterface;
+
+ if (pSelf->magic != DRAGANDDROPSERVICE_MAGIC)
+ VBClFatalError(("Bad display service object!\n"));
+ return pSelf->mDragAndDrop.run(fDaemonised);
+}
+
+static void cleanup(struct VBCLSERVICE **ppInterface)
+{
+ NOREF(ppInterface);
+ VbglR3Term();
+}
+
+struct VBCLSERVICE vbclDragAndDropInterface =
+{
+ getPidFilePath,
+ VBClServiceDefaultHandler, /* init */
+ run,
+ VBClServiceDefaultHandler, /* pause */
+ VBClServiceDefaultHandler, /* resume */
+ cleanup
+};
+
/* Static factory */
-VBoxClient::Service *VBoxClient::GetDragAndDropService()
+struct VBCLSERVICE **VBClGetDragAndDropService(void)
{
- return new(DragAndDropService);
+ struct DRAGANDDROPSERVICE *pService =
+ (struct DRAGANDDROPSERVICE *)RTMemAlloc(sizeof(*pService));
+
+ if (!pService)
+ VBClFatalError(("Out of memory\n"));
+ pService->pInterface = &vbclDragAndDropInterface;
+ pService->magic = DRAGANDDROPSERVICE_MAGIC;
+ new(&pService->mDragAndDrop) DragAndDropService();
+ return &pService->pInterface;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/hostversion.cpp b/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
index 5a5f503..ebc111e 100644
--- a/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/hostversion.cpp
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <iprt/assert.h>
#include <iprt/err.h>
+#include <iprt/mem.h>
#include <iprt/ldr.h>
#include <iprt/string.h>
#include <iprt/thread.h>
@@ -31,183 +32,199 @@
#include "VBoxClient.h"
-class HostVersionService : public VBoxClient::Service
+static const char *getPidFilePath()
{
+ return ".vboxclient-hostversion.pid";
+}
-public:
-
- virtual const char *getPidFilePath()
+static int showNotify(const char *pcHeader, const char *pcBody)
+{
+ int rc;
+# ifdef VBOX_WITH_DBUS
+ DBusConnection *conn;
+ DBusMessage* msg = NULL;
+ conn = dbus_bus_get (DBUS_BUS_SESSON, NULL);
+ if (conn == NULL)
{
- return ".vboxclient-hostversion.pid";
+ LogRelFlowFunc(("Could not retrieve D-BUS session bus!\n"));
+ rc = VERR_INVALID_HANDLE;
}
-
- virtual int showNotify(const char *pcHeader, const char *pcBody)
+ else
{
- int rc;
-# ifdef VBOX_WITH_DBUS
- DBusConnection *conn;
- DBusMessage* msg = NULL;
- conn = dbus_bus_get (DBUS_BUS_SESSON, NULL);
- if (conn == NULL)
+ msg = dbus_message_new_method_call("org.freedesktop.Notifications",
+ "/org/freedesktop/Notifications",
+ "org.freedesktop.Notifications",
+ "Notify");
+ if (msg == NULL)
{
- LogRelFlowFunc(("Could not retrieve D-BUS session bus!\n"));
+ LogRel(("Could not create D-BUS message!\n"));
rc = VERR_INVALID_HANDLE;
}
else
+ rc = VINF_SUCCESS;
+ }
+ if (RT_SUCCESS(rc))
+ {
+ uint32_t msg_replace_id = 0;
+ const char *msg_app = "VBoxClient";
+ const char *msg_icon = "";
+ const char *msg_summary = pcHeader;
+ const char *msg_body = pcBody;
+ int32_t msg_timeout = -1; /* Let the notification server decide */
+
+ DBusMessageIter iter;
+ DBusMessageIter array;
+ DBusMessageIter dict;
+ DBusMessageIter value;
+ DBusMessageIter variant;
+ DBusMessageIter data;
+
+ /* Format: UINT32 org.freedesktop.Notifications.Notify
+ * (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body,
+ * ARRAY actions, DICT hints, INT32 expire_timeout)
+ */
+ dbus_message_iter_init_append(msg,&iter);
+ dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_app);
+ dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msg_replace_id);
+ dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_icon);
+ dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_summary);
+ dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_body);
+ dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array);
+ dbus_message_iter_close_container(&iter,&array);
+ dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array);
+ dbus_message_iter_close_container(&iter,&array);
+ dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&msg_timeout);
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ DBusMessage *reply;
+ reply = dbus_connection_send_with_reply_and_block(conn, msg,
+ 30 * 1000 /* 30 seconds timeout */, &err);
+ if (dbus_error_is_set(&err))
{
- msg = dbus_message_new_method_call("org.freedesktop.Notifications",
- "/org/freedesktop/Notifications",
- "org.freedesktop.Notifications",
- "Notify");
- if (msg == NULL)
- {
- LogRel(("Could not create D-BUS message!\n"));
- rc = VERR_INVALID_HANDLE;
- }
- else
- rc = VINF_SUCCESS;
+ LogRel(("D-BUS returned an error while sending the notification: %s", err.message));
}
- if (RT_SUCCESS(rc))
+ else if (reply)
{
- uint32_t msg_replace_id = 0;
- const char *msg_app = "VBoxClient";
- const char *msg_icon = "";
- const char *msg_summary = pcHeader;
- const char *msg_body = pcBody;
- int32_t msg_timeout = -1; /* Let the notification server decide */
-
- DBusMessageIter iter;
- DBusMessageIter array;
- DBusMessageIter dict;
- DBusMessageIter value;
- DBusMessageIter variant;
- DBusMessageIter data;
-
- /* Format: UINT32 org.freedesktop.Notifications.Notify
- * (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body,
- * ARRAY actions, DICT hints, INT32 expire_timeout)
- */
- dbus_message_iter_init_append(msg,&iter);
- dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_app);
- dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msg_replace_id);
- dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_icon);
- dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_summary);
- dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_body);
- dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array);
- dbus_message_iter_close_container(&iter,&array);
- dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array);
- dbus_message_iter_close_container(&iter,&array);
- dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&msg_timeout);
-
- DBusError err;
- dbus_error_init(&err);
-
- DBusMessage *reply;
- reply = dbus_connection_send_with_reply_and_block(conn, msg,
- 30 * 1000 /* 30 seconds timeout */, &err);
- if (dbus_error_is_set(&err))
- {
- LogRel(("D-BUS returned an error while sending the notification: %s", err.message));
- }
- else if (reply)
- {
- dbus_connection_flush(conn);
- dbus_message_unref(reply);
- }
- if (dbus_error_is_set(&err))
- dbus_error_free(&err);
+ dbus_connection_flush(conn);
+ dbus_message_unref(reply);
}
- if (msg != NULL)
- dbus_message_unref(msg);
+ if (dbus_error_is_set(&err))
+ dbus_error_free(&err);
+ }
+ if (msg != NULL)
+ dbus_message_unref(msg);
# else
- /* TODO: Implement me */
- rc = VINF_SUCCESS;
+ /* TODO: Implement me */
+ rc = VINF_SUCCESS;
# endif /* VBOX_WITH_DBUS */
- return rc;
- }
-
- /** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
- notification stuff, since this is very similar to the VBoxTray code. */
- virtual int run(bool fDaemonised /* = false */)
- {
- int rc;
- LogFlowFunc(("\n"));
+ return rc;
+}
- /* Because we need desktop notifications to be displayed, wait
- * some time to make the desktop environment load (as a work around). */
- if (fDaemonised)
- RTThreadSleep(30 * 1000 /* Wait 30 seconds */);
+/** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
+ notification stuff, since this is very similar to the VBoxTray code. */
+static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
+{
+ int rc;
+ LogFlowFunc(("\n"));
+
+ NOREF(ppInterface);
+ /* Initialise the guest library. */
+ rc = VbglR3InitUser();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
+ /* Because we need desktop notifications to be displayed, wait
+ * some time to make the desktop environment load (as a work around). */
+ if (fDaemonised)
+ RTThreadSleep(30 * 1000 /* Wait 30 seconds */);
# ifdef VBOX_WITH_DBUS
- rc = RTDBusLoadLib();
- if (RT_FAILURE(rc))
- LogRel(("VBoxClient: D-Bus seems not to be installed; no host version check/notification done.\n"));
+ rc = RTDBusLoadLib();
+ if (RT_FAILURE(rc))
+ LogRel(("VBoxClient: D-Bus seems not to be installed; no host version check/notification done.\n"));
# else
- rc = VERR_NOT_IMPLEMENTED;
+ rc = VERR_NOT_IMPLEMENTED;
# endif /* VBOX_WITH_DBUS */
# ifdef VBOX_WITH_GUEST_PROPS
- uint32_t uGuestPropSvcClientID;
- if (RT_SUCCESS(rc))
- {
- rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
- if (RT_FAILURE(rc))
- LogRel(("VBoxClient: Cannot connect to guest property service while chcking for host version! rc = %Rrc\n", rc));
- }
+ uint32_t uGuestPropSvcClientID;
+ if (RT_SUCCESS(rc))
+ {
+ rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
+ if (RT_FAILURE(rc))
+ LogRel(("VBoxClient: Cannot connect to guest property service while chcking for host version! rc = %Rrc\n", rc));
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ char *pszHostVersion;
+ char *pszGuestVersion;
+ bool bUpdate;
+ rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &bUpdate, &pszHostVersion, &pszGuestVersion);
if (RT_SUCCESS(rc))
{
- char *pszHostVersion;
- char *pszGuestVersion;
- bool bUpdate;
-
- rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &bUpdate, &pszHostVersion, &pszGuestVersion);
- if (RT_SUCCESS(rc))
+ if (bUpdate)
{
- if (bUpdate)
- {
- char szMsg[1024];
- char szTitle[64];
+ char szMsg[1024];
+ char szTitle[64];
- /** @todo add some translation macros here */
- RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
+ /** @todo add some translation macros here */
+ RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
#ifndef VBOX_OSE
- RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
- "We recommend updating to the latest version (%s) by choosing the "
- "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
+ RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
+ "We recommend updating to the latest version (%s) by choosing the "
+ "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
#else
/* This is the message which appears for non-Oracle builds of the
- * Guest Additions. Distributors are encouraged to customise this. */
- RTStrPrintf(szMsg, sizeof(szMsg), "Your virtual machine is currently running the Guest Additions version %s. Since you are running a version of the Guest Additions provided by the operating system you installed in the virtual machine we recommend that you update it to at least version %s using that system's update features, or alternatively that you remove this version and then install the " VBOX_VENDOR_SHORT " Guest Additions package using the install option from the [...]
+* Guest Additions. Distributors are encouraged to customise this. */
+ RTStrPrintf(szMsg, sizeof(szMsg), "Your virtual machine is currently running the Guest Additions version %s. Since you are running a version of the Guest Additions provided by the operating system you installed in the virtual machine we recommend that you update it to at least version %s using that system's update features, or alternatively that you remove this version and then install the " VBOX_VENDOR_SHORT " Guest Additions package using the install option from the Dev [...]
#endif
- rc = showNotify(szTitle, szMsg);
- LogRel(("VBoxClient: VirtualBox Guest Additions update available!"));
- if (RT_FAILURE(rc))
- LogRel(("VBoxClient: Could not show version notifier tooltip! rc = %d\n", rc));
- }
+ rc = showNotify(szTitle, szMsg);
+ LogRel(("VBoxClient: VirtualBox Guest Additions update available!"));
+ if (RT_FAILURE(rc))
+ LogRel(("VBoxClient: Could not show version notifier tooltip! rc = %d\n", rc));
+ }
- /* Store host version to not notify again */
- rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
+ /* Store host version to not notify again */
+ rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
- VbglR3GuestPropReadValueFree(pszHostVersion);
- VbglR3GuestPropReadValueFree(pszGuestVersion);
- }
- VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
+ VbglR3GuestPropReadValueFree(pszHostVersion);
+ VbglR3GuestPropReadValueFree(pszGuestVersion);
}
-# endif /* VBOX_WITH_GUEST_PROPS */
- LogFlowFunc(("returning %Rrc\n", rc));
- return rc;
+ VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
}
+# endif /* VBOX_WITH_GUEST_PROPS */
+ VbglR3Term();
+ LogFlowFunc(("returning %Rrc\n", rc));
+ return rc;
+}
- virtual void cleanup()
- {
+struct VBCLSERVICE vbclHostVersionInterface =
+{
+ getPidFilePath,
+ VBClServiceDefaultHandler, /* init */
+ run,
+ VBClServiceDefaultHandler, /* pause */
+ VBClServiceDefaultHandler, /* resume */
+ VBClServiceDefaultCleanup
+};
- }
+struct HOSTVERSIONSERVICE
+{
+ struct VBCLSERVICE *pInterface;
};
/* Static factory */
-VBoxClient::Service *VBoxClient::GetHostVersionService()
+struct VBCLSERVICE **VBClGetHostVersionService()
{
- return new HostVersionService;
+ struct HOSTVERSIONSERVICE *pService =
+ (struct HOSTVERSIONSERVICE *)RTMemAlloc(sizeof(*pService));
+
+ if (!pService)
+ VBClFatalError(("Out of memory\n"));
+ pService->pInterface = &vbclHostVersionInterface;
+ return &pService->pInterface;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/main.cpp b/src/VBox/Additions/x11/VBoxClient/main.cpp
index 7846397..b07d833 100644
--- a/src/VBox/Additions/x11/VBoxClient/main.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/main.cpp
@@ -22,77 +22,92 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <poll.h>
#include <signal.h>
#include <X11/Xlib.h>
+#include <X11/Xatom.h>
#include <iprt/critsect.h>
#include <iprt/env.h>
+#include <iprt/file.h>
#include <iprt/initterm.h>
#include <iprt/message.h>
#include <iprt/path.h>
#include <iprt/param.h>
#include <iprt/stream.h>
#include <iprt/string.h>
+#include <iprt/types.h>
#include <VBox/VBoxGuestLib.h>
#include <VBox/log.h>
#include "VBoxClient.h"
-#define TRACE RTPrintf("%s: %d\n", __PRETTY_FUNCTION__, __LINE__); LogRel(("%s: %d\n", __PRETTY_FUNCTION__, __LINE__))
-
static int (*gpfnOldIOErrorHandler)(Display *) = NULL;
/** Object representing the service we are running. This has to be global
* so that the cleanup routine can access it. */
-VBoxClient::Service *g_pService;
+struct VBCLSERVICE **g_pService;
/** The name of our pidfile. It is global for the benefit of the cleanup
* routine. */
static char g_szPidFile[RTPATH_MAX];
/** The file handle of our pidfile. It is global for the benefit of the
* cleanup routine. */
static RTFILE g_hPidFile;
-/** Global critical section used to protect the clean-up routine, which can be
- * called from different threads.
+/** Global critical section held during the clean-up routine (to prevent it
+ * being called on multiple threads at once) or things which may not happen
+ * during clean-up (e.g. pausing and resuming the service).
*/
RTCRITSECT g_critSect;
+/** Counter of how often our deamon has been respawned. */
+unsigned cRespawn = 0;
+
+/** Exit with a fatal error. */
+void vbclFatalError(char *pszMessage)
+{
+ char *pszCommand;
+ if (pszMessage && cRespawn == 0)
+ {
+ pszCommand = RTStrAPrintf2("notify-send -t 5 \"VBoxClient: %s\"",
+ pszMessage);
+ if (pszCommand)
+ system(pszCommand);
+ }
+ _exit(1);
+}
/** Clean up if we get a signal or something. This is extern so that we
* can call it from other compilation units. */
-void VBoxClient::CleanUp()
+void VBClCleanUp()
{
/* We never release this, as we end up with a call to exit(3) which is not
- * async-safe. Until we fix this application properly, we should be sure
+ * async-safe. Unless we fix this application properly, we should be sure
* never to exit from anywhere except from this method. */
int rc = RTCritSectEnter(&g_critSect);
if (RT_FAILURE(rc))
- {
- RTPrintf("VBoxClient: Failure while acquiring the global critical section, rc=%Rrc\n", rc);
- abort();
- }
+ VBClFatalError(("VBoxClient: Failure while acquiring the global critical section, rc=%Rrc\n", rc));
if (g_pService)
- g_pService->cleanup();
+ (*g_pService)->cleanup(g_pService);
if (g_szPidFile[0] && g_hPidFile)
VbglR3ClosePidFile(g_szPidFile, g_hPidFile);
- VbglR3Term();
exit(0);
}
/**
* A standard signal handler which cleans up and exits.
*/
-void vboxClientSignalHandler(int cSignal)
+static void vboxClientSignalHandler(int cSignal)
{
LogRel(("VBoxClient: terminated with signal %d\n", cSignal));
/** Disable seamless mode */
RTPrintf(("VBoxClient: terminating...\n"));
- VBoxClient::CleanUp();
+ VBClCleanUp();
}
/**
* Xlib error handler for certain errors that we can't avoid.
*/
-int vboxClientXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
+static int vboxClientXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
{
char errorText[1024];
@@ -108,7 +123,7 @@ int vboxClientXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
static int vboxClientXLibIOErrorHandler(Display *pDisplay)
{
LogRel(("VBoxClient: a fatal guest X Window error occurred. This may just mean that the Window system was shut down while the client was still running.\n"));
- VBoxClient::CleanUp();
+ VBClCleanUp();
return 0; /* We should never reach this. */
}
@@ -116,7 +131,7 @@ static int vboxClientXLibIOErrorHandler(Display *pDisplay)
* Reset all standard termination signals to call our signal handler, which
* cleans up and exits.
*/
-void vboxClientSetSignalHandlers(void)
+static void vboxClientSetSignalHandlers(void)
{
struct sigaction sigAction;
@@ -135,6 +150,91 @@ void vboxClientSetSignalHandlers(void)
LogRelFlowFunc(("returning\n"));
}
+/** Check whether X.Org has acquired or lost the current virtual terminal and
+ * call the service @a pause() or @a resume() call-back if appropriate.
+ * The functionality is provided by the vboxvideo driver for pre-1.16 X servers
+ * and by 1.16 and later series servers.
+ * This can either be called directly from a service's event loop or the service
+ * can call VBClStartVTMonitor() to start an event loop in a separate thread.
+ * Property notification for the root window should be selected first. Services
+ * are not required to check VT changes if they do not need the information.
+ * @param pEvent an event received on a display connection which will be
+ * checked to see if it is change to the XFree86_has_VT property
+ */
+void VBClCheckXOrgVT(union _XEvent *pEvent)
+{
+ Atom actualType;
+ int actualFormat;
+ unsigned long cItems, cbLeft;
+ bool fHasVT = false;
+ unsigned long *pValue;
+ int rc;
+ Display *pDisplay = pEvent->xany.display;
+ Atom hasVT = XInternAtom(pDisplay, "XFree86_has_VT", False);
+
+ if ( pEvent->type != PropertyNotify
+ || pEvent->xproperty.window != DefaultRootWindow(pDisplay)
+ || pEvent->xproperty.atom != hasVT)
+ return;
+ XGetWindowProperty(pDisplay, DefaultRootWindow(pDisplay), hasVT, 0, 1,
+ False, XA_INTEGER, &actualType, &actualFormat, &cItems,
+ &cbLeft, (unsigned char **)&pValue);
+ if (cItems && actualFormat == 32)
+ {
+ fHasVT = *pValue != 0;
+ XFree(pValue);
+ }
+ else
+ return;
+ if (fHasVT)
+ {
+ rc = (*g_pService)->resume(g_pService);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Error resuming the service: %Rrc\n"));
+ }
+ if (!fHasVT)
+ {
+ rc = (*g_pService)->pause(g_pService);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Error pausing the service: %Rrc\n"));
+ }
+}
+
+/**
+ * Thread which notifies the service when we switch to a different VT or back
+ * and cleans up when the X server exits.
+ * @note runs until programme exit.
+ */
+static int pfnMonitorThread(RTTHREAD self, void *pvUser)
+{
+ Display *pDisplay;
+ bool fHasVT = true;
+
+ pDisplay = XOpenDisplay(NULL);
+ if (!pDisplay)
+ VBClFatalError(("Failed to open the X11 display\n"));
+ XSelectInput(pDisplay, DefaultRootWindow(pDisplay), PropertyChangeMask);
+ while (true)
+ {
+ XEvent event;
+
+ XNextEvent(pDisplay, &event);
+ VBClCheckXOrgVT(&event);
+ }
+ return VINF_SUCCESS; /* Should never be reached. */
+}
+
+/**
+ * Start a thread which notifies the service when we switch to a different
+ * VT or back, and terminates us when the X server exits. This should be called
+ * by most services which do not regularly run an X11 event loop.
+ */
+int VBClStartVTMonitor()
+{
+ return RTThreadCreate(NULL, pfnMonitorThread, NULL, 0,
+ RTTHREADTYPE_INFREQUENT_POLLER, 0, "MONITOR");
+}
+
/**
* Print out a usage message and exit with success.
*/
@@ -167,146 +267,136 @@ void vboxClientUsage(const char *pcszFileName)
/**
* The main loop for the VBoxClient daemon.
+ * @todo Clean up for readability.
*/
int main(int argc, char *argv[])
{
- if (!XInitThreads())
- return 1;
+ bool fDaemonise = true, fRespawn = true;
+ int rc;
+ const char *pcszFileName, *pcszStage;
+
/* Initialise our runtime before all else. */
- int rc = RTR3InitExe(argc, &argv, 0);
+ rc = RTR3InitExe(argc, &argv, 0);
if (RT_FAILURE(rc))
return RTMsgInitFailure(rc);
-
- int rcClipboard;
- const char *pszFileName = RTPathFilename(argv[0]);
- bool fDaemonise = true;
- /* Have any fatal errors occurred yet? */
- bool fSuccess = true;
- /* Do we know which service we wish to run? */
- bool fHaveService = false;
-
- if (NULL == pszFileName)
- pszFileName = "VBoxClient";
-
- /* Initialise our global clean-up critical section */
- rc = RTCritSectInit(&g_critSect);
- if (RT_FAILURE(rc))
- {
- /* Of course, this should never happen. */
- RTPrintf("%s: Failed to initialise the global critical section, rc=%Rrc\n", pszFileName, rc);
- return 1;
- }
+ /* This should never be called twice in one process - in fact one Display
+ * object should probably never be used from multiple threads anyway. */
+ if (!XInitThreads())
+ VBClFatalError(("Failed to initialize X11 threads\n"));
+ /* Get our file name for error output. */
+ pcszFileName = RTPathFilename(argv[0]);
+ if (!pcszFileName)
+ pcszFileName = "VBoxClient";
/* Parse our option(s) */
/** @todo Use RTGetOpt() if the arguments become more complex. */
for (int i = 1; i < argc; ++i)
{
+ rc = VERR_INVALID_PARAMETER;
if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon"))
+ {
+ /* If the user is running in "no daemon" mode anyway, send critical
+ * logging to stdout as well. */
+ PRTLOGGER pReleaseLog = RTLogRelDefaultInstance();
+
+ if (pReleaseLog)
+ rc = RTLogDestinations(pReleaseLog, "stdout");
+ if (pReleaseLog && RT_FAILURE(rc))
+ RTPrintf("%s: failed to redivert error output, rc=%Rrc\n",
+ pcszFileName, rc);
fDaemonise = false;
+ }
+ else if (!strcmp(argv[i], "--no-respawn"))
+ {
+ fRespawn = false;
+ }
else if (!strcmp(argv[i], "--clipboard"))
{
- if (g_pService == NULL)
- g_pService = VBoxClient::GetClipboardService();
- else
- fSuccess = false;
+ if (g_pService)
+ break;
+ g_pService = VBClGetClipboardService();
}
else if (!strcmp(argv[i], "--display"))
{
- if (g_pService == NULL)
- g_pService = VBoxClient::GetDisplayService();
- else
- fSuccess = false;
+ if (g_pService)
+ break;
+ g_pService = VBClGetDisplayService();
}
else if (!strcmp(argv[i], "--seamless"))
{
- if (g_pService == NULL)
- g_pService = VBoxClient::GetSeamlessService();
- else
- fSuccess = false;
+ if (g_pService)
+ break;
+ g_pService = VBClGetSeamlessService();
}
else if (!strcmp(argv[i], "--checkhostversion"))
{
- if (g_pService == NULL)
- g_pService = VBoxClient::GetHostVersionService();
- else
- fSuccess = false;
+ if (g_pService)
+ break;
+ g_pService = VBClGetHostVersionService();
}
#ifdef VBOX_WITH_DRAG_AND_DROP
else if (!strcmp(argv[i], "--draganddrop"))
{
- if (g_pService == NULL)
- g_pService = VBoxClient::GetDragAndDropService();
- else
- fSuccess = false;
+ if (g_pService)
+ break;
+ g_pService = VBClGetDragAndDropService();
}
#endif /* VBOX_WITH_DRAG_AND_DROP */
else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
{
- vboxClientUsage(pszFileName);
+ vboxClientUsage(pcszFileName);
return 0;
}
else
{
- RTPrintf("%s: unrecognized option `%s'\n", pszFileName, argv[i]);
- RTPrintf("Try `%s --help' for more information\n", pszFileName);
+ RTPrintf("%s: unrecognized option `%s'\n", pcszFileName, argv[i]);
+ RTPrintf("Try `%s --help' for more information\n", pcszFileName);
return 1;
}
+ rc = VINF_SUCCESS;
}
- if (!fSuccess || !g_pService)
+ if (RT_FAILURE(rc) || !g_pService)
{
- vboxClientUsage(pszFileName);
+ vboxClientUsage(pcszFileName);
return 1;
}
- /* Get the path for the pidfiles */
+
+ rc = RTCritSectInit(&g_critSect);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Initialising critical section: %Rrc\n", rc));
rc = RTPathUserHome(g_szPidFile, sizeof(g_szPidFile));
if (RT_FAILURE(rc))
- {
- RTPrintf("VBoxClient: failed to get home directory, rc=%Rrc. Exiting.\n", rc);
- LogRel(("VBoxClient: failed to get home directory, rc=%Rrc. Exiting.\n", rc));
- return 1;
- }
- rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile), g_pService->getPidFilePath());
+ VBClFatalError(("Getting home directory for pid-file: %Rrc\n", rc));
+ rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile),
+ (*g_pService)->getPidFilePath());
if (RT_FAILURE(rc))
- {
- RTPrintf("VBoxClient: RTPathAppend failed with rc=%Rrc. Exiting.\n", rc);
- LogRel(("VBoxClient: RTPathAppend failed with rc=%Rrc. Exiting.\n", rc));
- return 1;
- }
-
- /* Initialise the guest library. */
- if (RT_FAILURE(VbglR3InitUser()))
- {
- RTPrintf("Failed to connect to the VirtualBox kernel service\n");
- LogRel(("Failed to connect to the VirtualBox kernel service\n"));
- return 1;
- }
+ VBClFatalError(("Creating pid-file path: %Rrc\n", rc));
if (fDaemonise)
- {
- rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */);
- if (RT_FAILURE(rc))
- {
- RTPrintf("VBoxClient: failed to daemonize. Exiting.\n");
- LogRel(("VBoxClient: failed to daemonize. Exiting.\n"));
-# ifdef DEBUG
- RTPrintf("Error %Rrc\n", rc);
-# endif
- return 1;
- }
- }
- if (g_szPidFile[0] && RT_FAILURE(VbglR3PidFile(g_szPidFile, &g_hPidFile)))
- {
- RTPrintf("Failed to create a pidfile. Exiting.\n");
- LogRel(("Failed to create a pidfile. Exiting.\n"));
- VbglR3Term();
- return 1;
- }
+ rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */, fRespawn, &cRespawn);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Daemonizing: %Rrc\n", rc));
+ if (g_szPidFile[0])
+ rc = VbglR3PidFile(g_szPidFile, &g_hPidFile);
+ if (rc == VERR_FILE_LOCK_VIOLATION) /* Already running. */
+ return 0;
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Creating pid-file: %Rrc\n", rc));
/* Set signal handlers to clean up on exit. */
vboxClientSetSignalHandlers();
- /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */
+#ifndef VBOXCLIENT_WITHOUT_X11
+ /* Set an X11 error handler, so that we don't die when we get unavoidable
+ * errors. */
XSetErrorHandler(vboxClientXLibErrorHandler);
- /* Set an X11 I/O error handler, so that we can shutdown properly on fatal errors. */
+ /* Set an X11 I/O error handler, so that we can shutdown properly on
+ * fatal errors. */
XSetIOErrorHandler(vboxClientXLibIOErrorHandler);
- g_pService->run(fDaemonise);
- VBoxClient::CleanUp();
- return 1; /* We should never get here. */
+#endif
+ rc = (*g_pService)->init(g_pService);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Initialising service: %Rrc\n", rc));
+ rc = (*g_pService)->run(g_pService, fDaemonise);
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Service main loop failed: %Rrc\n", rc));
+ VBClCleanUp();
+ return 0;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-glue.h b/src/VBox/Additions/x11/VBoxClient/seamless-glue.h
deleted file mode 100644
index 6b617b4..0000000
--- a/src/VBox/Additions/x11/VBoxClient/seamless-glue.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file
- *
- * Guest client: seamless mode
- * Proxy between the guest and host components
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#ifndef __Additions_client_seamless_glue_h
-# define __Additions_client_seamless_glue_h
-
-class VBoxGuestSeamlessObserver
-{
-public:
- virtual void notify(void) = 0;
- virtual ~VBoxGuestSeamlessObserver() {}
-};
-
-#endif /* __Additions_client_seamless_glue_h not defined */
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-guest.h b/src/VBox/Additions/x11/VBoxClient/seamless-guest.h
deleted file mode 100644
index e468531..0000000
--- a/src/VBox/Additions/x11/VBoxClient/seamless-guest.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/** @file
- *
- * Guest client: seamless mode
- * Abstract class for interacting with the guest system
- */
-
-/*
- * Copyright (C) 2006-2011 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#ifndef __Additions_client_seamless_guest_h
-# define __Additions_client_seamless_guest_h
-
-#include <iprt/types.h> /* for RTRECT */
-
-#include "seamless-glue.h"
-
-/**
- * Observable to monitor the state of the guest windows. This abstract class definition
- * serves as a template (in the linguistic sense, not the C++ sense) for creating
- * platform-specific child classes.
- */
-class VBoxGuestSeamlessGuest
-{
-public:
- /** Events which can be reported by this class */
- enum meEvent
- {
- /** Empty event */
- NONE,
- /** Seamless mode is now supported */
- CAPABLE,
- /** Seamless mode is no longer supported */
- INCAPABLE
- };
-};
-
-#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
-# include "seamless-x11.h" /* for VBoxGuestSeamlessGuestImpl */
-#else
-# error Port me
-#endif
-
-#endif /* __Additions_client_seamless_guest_h not defined */
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp b/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
deleted file mode 100644
index 81467a3..0000000
--- a/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/** @file
- * X11 Guest client - seamless mode, missing proper description while using the
- * potentially confusing word 'host'.
- */
-
-/*
- * Copyright (C) 2006-2011 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-/*****************************************************************************
-* Header files *
-*****************************************************************************/
-#include <VBox/log.h>
-#include <VBox/VMMDev.h>
-#include <VBox/VBoxGuestLib.h>
-#include <iprt/err.h>
-
-#include "seamless-host.h"
-
-/**
- * Start the service.
- * @returns iprt status value
- */
-int VBoxGuestSeamlessHost::start(void)
-{
- int rc = VERR_NOT_SUPPORTED;
-
- LogRelFlowFunc(("\n"));
- if (mRunning) /* Assertion */
- {
- LogRel(("VBoxClient: seamless service started twice!\n"));
- return VERR_INTERNAL_ERROR;
- }
- rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
- if (RT_FAILURE(rc))
- {
- LogRel(("VBoxClient (seamless): failed to set the guest IRQ filter mask, rc=%Rrc\n", rc));
- }
- rc = VbglR3SeamlessSetCap(true);
- if (RT_SUCCESS(rc))
- {
- LogRel(("VBoxClient: enabled seamless capability on host.\n"));
- rc = mThread.start();
- if (RT_SUCCESS(rc))
- {
- mRunning = true;
- }
- else
- {
- LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc. Disabled seamless capability on host again.\n", rc));
- VbglR3SeamlessSetCap(false);
- }
- }
- if (RT_FAILURE(rc))
- {
- LogRel(("VBoxClient (seamless): failed to enable seamless capability on host, rc=%Rrc\n", rc));
- }
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
-}
-
-/** Stops the service. */
-void VBoxGuestSeamlessHost::stop(RTMSINTERVAL cMillies /* = RT_INDEFINITE_WAIT */)
-{
- LogRelFlowFunc(("returning\n"));
- if (!mRunning) /* Assertion */
- {
- LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
- return;
- }
- mThread.stop(cMillies, 0);
- VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
- VbglR3SeamlessSetCap(false);
- mRunning = false;
- LogRelFlowFunc(("returning\n"));
-}
-
-/**
- * Waits for a seamless state change events from the host and dispatch it.
- *
- * @returns IRPT return code.
- */
-int VBoxGuestSeamlessHost::nextEvent(void)
-{
- VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
-
- LogRelFlowFunc(("\n"));
- int rc = VbglR3SeamlessWaitEvent(&newMode);
- if (RT_SUCCESS(rc))
- {
- switch(newMode)
- {
- case VMMDev_Seamless_Visible_Region:
- /* A simplified seamless mode, obtained by making the host VM window borderless and
- making the guest desktop transparent. */
-#ifdef DEBUG
- LogRelFunc(("VMMDev_Seamless_Visible_Region request received (VBoxClient).\n"));
-#endif
- mState = ENABLE;
- mObserver->notify();
- break;
- case VMMDev_Seamless_Host_Window:
- /* One host window represents one guest window. Not yet implemented. */
- LogRelFunc(("Warning: VMMDev_Seamless_Host_Window request received (VBoxClient).\n"));
- /* fall through to default */
- default:
- LogRelFunc(("Warning: unsupported VMMDev_Seamless request %d received (VBoxClient).\n", newMode));
- /* fall through to case VMMDev_Seamless_Disabled */
- case VMMDev_Seamless_Disabled:
-#ifdef DEBUG
- LogRelFunc(("VMMDev_Seamless_Disabled set (VBoxClient).\n"));
-#endif
- mState = DISABLE;
- mObserver->notify();
- }
- }
- else
- {
- LogRelFunc(("VbglR3SeamlessWaitEvent returned %Rrc (VBoxClient)\n", rc));
- }
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
-}
-
-/**
- * Update the set of visible rectangles in the host.
- */
-void VBoxGuestSeamlessHost::updateRects(RTRECT *pRects, size_t cRects)
-{
- LogRelFlowFunc(("\n"));
- if (cRects && !pRects) /* Assertion */
- {
- LogRelThisFunc(("ERROR: called with null pointer!\n"));
- return;
- }
- VbglR3SeamlessSendRects(cRects, pRects);
- LogRelFlowFunc(("returning\n"));
-}
-
-/**
- * The actual thread function.
- *
- * @returns iprt status code as thread return value
- * @param pParent the VBoxGuestThread running this thread function
- */
-int VBoxGuestSeamlessHostThread::threadFunction(VBoxGuestThread *pThread)
-{
- LogRelFlowFunc(("\n"));
- if (0 != mHost)
- {
- mThread = pThread;
- while (!mThread->isStopping())
- {
- if (RT_FAILURE(mHost->nextEvent()) && !mThread->isStopping())
- {
- /* If we are not stopping, sleep for a bit to avoid using up too
- much CPU while retrying. */
- mThread->yield();
- }
- }
- }
- LogRelFlowFunc(("returning VINF_SUCCESS\n"));
- return VINF_SUCCESS;
-}
-
-/**
- * Send a signal to the thread function that it should exit
- */
-void VBoxGuestSeamlessHostThread::stop(void)
-{
- LogRelFlowFunc(("\n"));
- if (0 != mHost)
- {
- /**
- * @todo is this reasonable? If the thread is in the event loop then the cancelEvent()
- * will cause it to exit. If it enters or exits the event loop it will also
- * notice that we wish it to exit. And if it is somewhere in-between, the
- * yield() should give it time to get to one of places mentioned above.
- */
- for (int i = 0; (i < 5) && mThread->isRunning(); ++i)
- {
- mHost->cancelEvent();
- mThread->yield();
- }
- }
- LogRelFlowFunc(("returning\n"));
-}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-host.h b/src/VBox/Additions/x11/VBoxClient/seamless-host.h
deleted file mode 100644
index 812eb88..0000000
--- a/src/VBox/Additions/x11/VBoxClient/seamless-host.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/** @file
- * X11 Guest client - seamless mode, missing proper description while using the
- * potentially confusing word 'host'.
- */
-
-/*
- * Copyright (C) 2006-2011 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#ifndef __Additions_client_seamless_host_h
-# define __Additions_client_seamless_host_h
-
-#include <VBox/log.h>
-#include <VBox/VBoxGuestLib.h> /* for the R3 guest library functions */
-
-#include "seamless-glue.h" /* for VBoxGuestSeamlessObserver */
-#include "thread.h" /* for VBoxGuestThread */
-
-class VBoxGuestSeamlessHost;
-
-/**
- * Host event (i.e. enter or leave seamless mode) thread function for the main
- * seamless class
- */
-class VBoxGuestSeamlessHostThread : public VBoxGuestThreadFunction
-{
-private:
- // Copying or assigning a thread object is not sensible
- VBoxGuestSeamlessHostThread(const VBoxGuestSeamlessHostThread&);
- VBoxGuestSeamlessHostThread& operator=(const VBoxGuestSeamlessHostThread&);
-
- // Private member variables
- /** The host proxy object */
- VBoxGuestSeamlessHost *mHost;
-
- /** The thread object running us. */
- VBoxGuestThread *mThread;
-public:
- VBoxGuestSeamlessHostThread(VBoxGuestSeamlessHost *pHost)
- {
- mHost = pHost;
- }
- virtual ~VBoxGuestSeamlessHostThread(void) {}
- /**
- * The actual thread function.
- *
- * @returns iprt status code as thread return value
- * @param pParent the VBoxGuestThread running this thread function
- */
- virtual int threadFunction(VBoxGuestThread *pThread);
- /**
- * Send a signal to the thread function that it should exit
- */
- virtual void stop(void);
-};
-
-/**
- * Interface to the host
- */
-class VBoxGuestSeamlessHost
-{
- friend class VBoxGuestSeamlessHostThread;
-public:
- /** Events which can be reported by this class */
- enum meEvent
- {
- /** Empty event */
- NONE,
- /** Request to enable seamless mode */
- ENABLE,
- /** Request to disable seamless mode */
- DISABLE
- };
-
-private:
- // We don't want a copy constructor or assignment operator
- VBoxGuestSeamlessHost(const VBoxGuestSeamlessHost&);
- VBoxGuestSeamlessHost& operator=(const VBoxGuestSeamlessHost&);
-
- /** Observer to connect guest and host and ferry events back and forth. */
- VBoxGuestSeamlessObserver *mObserver;
- /** Host seamless event (i.e. enter and leave) thread function. */
- VBoxGuestSeamlessHostThread mThreadFunction;
- /** Host seamless event thread. */
- VBoxGuestThread mThread;
- /** Is the service running? */
- bool mRunning;
- /** Last request issued by the host. */
- meEvent mState;
-
- /**
- * Waits for a seamless state change events from the host and dispatch it. This is
- * meant to be called by the host event monitor thread exclusively.
- *
- * @returns IRPT return code.
- */
- int nextEvent(void);
-
- /**
- * Interrupt an event wait and cause nextEvent() to return immediately.
- */
- void cancelEvent(void) { VbglR3InterruptEventWaits(); }
-
-public:
- /**
- * Initialise the guest and ensure that it is capable of handling seamless mode
- * @param pObserver Observer class to connect host and guest interfaces
- *
- * @returns iprt status code
- */
- int init(VBoxGuestSeamlessObserver *pObserver)
- {
- LogRelFlowFunc(("\n"));
- if (mObserver != 0) /* Assertion */
- {
- LogRel(("VBoxClient: ERROR: attempt to initialise seamless host object twice!\n"));
- return VERR_INTERNAL_ERROR;
- }
- mObserver = pObserver;
- LogRelFlowFunc(("returning VINF_SUCCESS\n"));
- return VINF_SUCCESS;
- }
-
- /**
- * Start the service.
- * @returns iprt status value
- */
- int start(void);
-
- /**
- * Stops the service.
- * @param cMillies how long to wait for the thread to exit
- */
- void stop(RTMSINTERVAL cMillies = RT_INDEFINITE_WAIT);
-
- /** Returns the current state of the host - i.e. requesting seamless or not. */
- meEvent getState(void) { return mState; }
-
- /**
- * Update the set of visible rectangles in the host.
- */
- void updateRects(RTRECT *pRects, size_t cRects);
-
- VBoxGuestSeamlessHost(void) : mThreadFunction(this),
- mThread(&mThreadFunction, 0, RTTHREADTYPE_MSG_PUMP,
- RTTHREADFLAGS_WAITABLE, "Host events")
- {
- mObserver = 0;
- mRunning = false;
- mState = NONE;
- }
-
- ~VBoxGuestSeamlessHost()
- {
- LogRelFlowFunc(("\n"));
- if (mRunning) /* Assertion */
- {
- LogRel(("VBoxClient: seamless host object still running! Stopping...\n"));
- stop(2000);
- }
- LogRelFlowFunc(("returning\n"));
- }
-};
-
-#endif /* __Additions_xclient_seamless_h not defined */
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp b/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
index 7c7d8a3..8bf275c 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-x11.cpp
@@ -23,7 +23,7 @@
#include <iprt/vector.h>
#include <VBox/log.h>
-#include "seamless-guest.h"
+#include "seamless-x11.h"
#include <X11/Xatom.h>
#include <X11/Xmu/WinUtil.h>
@@ -70,12 +70,12 @@ static unsigned char *XXGetProperty (Display *aDpy, Window aWnd, Atom aPropType,
*
* @returns true if it can handle seamless, false otherwise
*/
-int VBoxGuestSeamlessX11::init(VBoxGuestSeamlessObserver *pObserver)
+int SeamlessX11::init(PFNSENDREGIONUPDATE pHostCallback)
{
int rc = VINF_SUCCESS;
LogRelFlowFunc(("\n"));
- if (0 != mObserver) /* Assertion */
+ if (mHostCallback != NULL) /* Assertion */
{
LogRel(("VBoxClient: ERROR: attempt to initialise seamless guest object twice!\n"));
return VERR_INTERNAL_ERROR;
@@ -85,7 +85,7 @@ int VBoxGuestSeamlessX11::init(VBoxGuestSeamlessObserver *pObserver)
LogRel(("VBoxClient: seamless guest object failed to acquire a connection to the display.\n"));
return VERR_ACCESS_DENIED;
}
- mObserver = pObserver;
+ mHostCallback = pHostCallback;
LogRelFlowFunc(("returning %Rrc\n", rc));
return rc;
}
@@ -95,10 +95,10 @@ int VBoxGuestSeamlessX11::init(VBoxGuestSeamlessObserver *pObserver)
* events about changes to this information.
*
* @note This class does not contain its own event thread, so an external thread must
- * call nextEvent() for as long as events are wished.
+ * call nextConfigurationEvent() for as long as events are wished.
* @todo This function should switch the guest to fullscreen mode.
*/
-int VBoxGuestSeamlessX11::start(void)
+int SeamlessX11::start(void)
{
int rc = VINF_SUCCESS;
/** Dummy values for XShapeQueryExtension */
@@ -115,7 +115,7 @@ int VBoxGuestSeamlessX11::start(void)
/** Stop reporting seamless events to the host. Free information about guest windows
and stop requesting updates. */
-void VBoxGuestSeamlessX11::stop(void)
+void SeamlessX11::stop(void)
{
LogRelFlowFunc(("\n"));
mEnabled = false;
@@ -124,13 +124,13 @@ void VBoxGuestSeamlessX11::stop(void)
LogRelFlowFunc(("returning\n"));
}
-void VBoxGuestSeamlessX11::monitorClientList(void)
+void SeamlessX11::monitorClientList(void)
{
LogRelFlowFunc(("called\n"));
XSelectInput(mDisplay, DefaultRootWindow(mDisplay), SubstructureNotifyMask);
}
-void VBoxGuestSeamlessX11::unmonitorClientList(void)
+void SeamlessX11::unmonitorClientList(void)
{
LogRelFlowFunc(("called\n"));
XSelectInput(mDisplay, DefaultRootWindow(mDisplay), 0);
@@ -140,7 +140,7 @@ void VBoxGuestSeamlessX11::unmonitorClientList(void)
* Recreate the table of toplevel windows of clients on the default root window of the
* X server.
*/
-void VBoxGuestSeamlessX11::rebuildWindowTree(void)
+void SeamlessX11::rebuildWindowTree(void)
{
LogRelFlowFunc(("called\n"));
freeWindowTree();
@@ -155,7 +155,7 @@ void VBoxGuestSeamlessX11::rebuildWindowTree(void)
*
* @param hRoot the virtual root window to be examined
*/
-void VBoxGuestSeamlessX11::addClients(const Window hRoot)
+void SeamlessX11::addClients(const Window hRoot)
{
/** Unused out parameters of XQueryTree */
Window hRealRoot, hParent;
@@ -177,7 +177,7 @@ void VBoxGuestSeamlessX11::addClients(const Window hRoot)
}
-void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
+void SeamlessX11::addClientWindow(const Window hWin)
{
LogRelFlowFunc(("\n"));
XWindowAttributes winAttrib;
@@ -240,7 +240,7 @@ void VBoxGuestSeamlessX11::addClientWindow(const Window hWin)
* @returns true if it is, false otherwise
* @param hWin the window to be examined
*/
-bool VBoxGuestSeamlessX11::isVirtualRoot(Window hWin)
+bool SeamlessX11::isVirtualRoot(Window hWin)
{
unsigned char *windowTypeRaw = NULL;
Atom *windowType;
@@ -274,7 +274,7 @@ DECLCALLBACK(int) VBoxGuestWinFree(VBoxGuestWinInfo *pInfo, void *pvParam)
/**
* Free all information in the tree of visible windows
*/
-void VBoxGuestSeamlessX11::freeWindowTree(void)
+void SeamlessX11::freeWindowTree(void)
{
/* We use post-increment in the operation to prevent the iterator from being invalidated. */
LogRelFlowFunc(("\n"));
@@ -288,7 +288,7 @@ void VBoxGuestSeamlessX11::freeWindowTree(void)
*
* @note Called from the guest event thread.
*/
-void VBoxGuestSeamlessX11::nextEvent(void)
+void SeamlessX11::nextConfigurationEvent(void)
{
XEvent event;
@@ -298,7 +298,7 @@ void VBoxGuestSeamlessX11::nextEvent(void)
if (mChanged)
{
updateRects();
- mObserver->notify();
+ mHostCallback(mpRects, mcRects);
}
mChanged = false;
XNextEvent(mDisplay, &event);
@@ -344,7 +344,7 @@ void VBoxGuestSeamlessX11::nextEvent(void)
*
* @param event the X11 event structure
*/
-void VBoxGuestSeamlessX11::doConfigureEvent(Window hWin)
+void SeamlessX11::doConfigureEvent(Window hWin)
{
VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
if (pInfo)
@@ -380,7 +380,7 @@ void VBoxGuestSeamlessX11::doConfigureEvent(Window hWin)
*
* @param event the X11 event structure
*/
-void VBoxGuestSeamlessX11::doMapEvent(Window hWin)
+void SeamlessX11::doMapEvent(Window hWin)
{
LogRelFlowFunc(("\n"));
VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
@@ -398,7 +398,7 @@ void VBoxGuestSeamlessX11::doMapEvent(Window hWin)
*
* @param event the X11 event structure
*/
-void VBoxGuestSeamlessX11::doShapeEvent(Window hWin)
+void SeamlessX11::doShapeEvent(Window hWin)
{
LogRelFlowFunc(("\n"));
VBoxGuestWinInfo *pInfo = mGuestWindows.find(hWin);
@@ -426,7 +426,7 @@ void VBoxGuestSeamlessX11::doShapeEvent(Window hWin)
*
* @param event the X11 event structure
*/
-void VBoxGuestSeamlessX11::doUnmapEvent(Window hWin)
+void SeamlessX11::doUnmapEvent(Window hWin)
{
LogRelFlowFunc(("\n"));
VBoxGuestWinInfo *pInfo = mGuestWindows.removeWindow(hWin);
@@ -441,7 +441,7 @@ void VBoxGuestSeamlessX11::doUnmapEvent(Window hWin)
/**
* Gets the list of visible rectangles
*/
-RTRECT *VBoxGuestSeamlessX11::getRects(void)
+RTRECT *SeamlessX11::getRects(void)
{
return mpRects;
}
@@ -449,7 +449,7 @@ RTRECT *VBoxGuestSeamlessX11::getRects(void)
/**
* Gets the number of rectangles in the visible rectangle list
*/
-size_t VBoxGuestSeamlessX11::getRectCount(void)
+size_t SeamlessX11::getRectCount(void)
{
return mcRects;
}
@@ -500,7 +500,7 @@ DECLCALLBACK(int) getRectsCallback(VBoxGuestWinInfo *pInfo,
/**
* Updates the list of seamless rectangles
*/
-int VBoxGuestSeamlessX11::updateRects(void)
+int SeamlessX11::updateRects(void)
{
LogRelFlowFunc(("\n"));
unsigned cRects = 0;
@@ -527,7 +527,7 @@ int VBoxGuestSeamlessX11::updateRects(void)
*
* @note This function should only be called from the host event thread.
*/
-bool VBoxGuestSeamlessX11::interruptEvent(void)
+bool SeamlessX11::interruptEventWait(void)
{
bool rc = false;
@@ -535,8 +535,8 @@ bool VBoxGuestSeamlessX11::interruptEvent(void)
/* Message contents set to zero. */
XClientMessageEvent clientMessage = { ClientMessage, 0, 0, 0, 0, 0, 8 };
- if (0 != XSendEvent(mDisplay, DefaultRootWindow(mDisplay), false, PropertyChangeMask,
- reinterpret_cast<XEvent *>(&clientMessage)))
+ if (XSendEvent(mDisplay, DefaultRootWindow(mDisplay), false,
+ SubstructureNotifyMask, (XEvent *)&clientMessage))
{
XFlush(mDisplay);
rc = true;
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless-x11.h b/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
index 68fcad1..46a5d41 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
@@ -22,8 +22,6 @@
#include <VBox/log.h>
#include <iprt/avl.h>
-#include "seamless-guest.h"
-
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
@@ -34,6 +32,14 @@
/* This is defined wrong in my X11 header files! */
#define VBoxShapeNotify 64
+/**
+ * Callback which provides the interface for notifying the host of changes to
+ * the X11 window configuration, mainly split out from @a VBoxGuestSeamlessHost
+ * to simplify the unit test.
+ */
+typedef void FNSENDREGIONUPDATE(RTRECT *pRects, size_t cRects);
+typedef FNSENDREGIONUPDATE *PFNSENDREGIONUPDATE;
+
/** Structure containing information about a guest window's position and visible area.
Used inside of VBoxGuestWindowList. */
struct VBoxGuestWinInfo {
@@ -145,18 +151,16 @@ public:
}
};
-class VBoxGuestSeamlessX11;
-
-class VBoxGuestSeamlessX11 : public VBoxGuestSeamlessGuest
+class SeamlessX11
{
private:
// We don't want a copy constructor or assignment operator
- VBoxGuestSeamlessX11(const VBoxGuestSeamlessX11&);
- VBoxGuestSeamlessX11& operator=(const VBoxGuestSeamlessX11&);
+ SeamlessX11(const SeamlessX11&);
+ SeamlessX11& operator=(const SeamlessX11&);
// Private member variables
- /** Pointer to the observer class. */
- VBoxGuestSeamlessObserver *mObserver;
+ /** Pointer to the host callback. */
+ PFNSENDREGIONUPDATE mHostCallback;
/** Our connection to the X11 display we are running on. */
Display *mDisplay;
/** Class to keep track of visible guest windows. */
@@ -196,22 +200,24 @@ private:
public:
/**
* Initialise the guest and ensure that it is capable of handling seamless mode
- * @param pObserver Observer class to connect host and guest interfaces
+ * @param pHost Host interface callback to notify of window configuration
+ * changes.
*
* @returns iprt status code
*/
- int init(VBoxGuestSeamlessObserver *pObserver);
+ int init(PFNSENDREGIONUPDATE pHostCallback);
/**
* Shutdown seamless event monitoring.
*/
void uninit(void)
{
- if (0 != mObserver)
- {
+ if (mHostCallback)
stop();
- }
- mObserver = 0;
+ mHostCallback = NULL;
+ if (mDisplay)
+ XCloseDisplay(mDisplay);
+ mDisplay = NULL;
}
/**
@@ -228,9 +234,9 @@ public:
size_t getRectCount(void);
/** Process next event in the guest event queue - called by the event thread. */
- void nextEvent(void);
+ void nextConfigurationEvent(void);
/** Wake up the event thread if it is waiting for an event so that it can exit. */
- bool interruptEvent(void);
+ bool interruptEventWait(void);
/* Methods to handle X11 events. These are public so that the unit test
* can call them. */
@@ -239,18 +245,14 @@ public:
void doUnmapEvent(Window hWin);
void doShapeEvent(Window hWin);
- VBoxGuestSeamlessX11(void)
- : mObserver(0), mDisplay(NULL), mpRects(NULL), mcRects(0),
+ SeamlessX11(void)
+ : mHostCallback(NULL), mDisplay(NULL), mpRects(NULL), mcRects(0),
mSupportsShape(false), mEnabled(false), mChanged(false) {}
- ~VBoxGuestSeamlessX11()
+ ~SeamlessX11()
{
uninit();
- if (mDisplay)
- XCloseDisplay(mDisplay);
}
};
-typedef VBoxGuestSeamlessX11 VBoxGuestSeamlessGuestImpl;
-
#endif /* __Additions_linux_seamless_x11_h not defined */
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless.cpp b/src/VBox/Additions/x11/VBoxClient/seamless.cpp
index e3ab64a..d349f1e 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/seamless.cpp
@@ -1,10 +1,11 @@
/** @file
- *
- * Guest client: seamless mode.
+ * X11 Guest client - seamless mode: main logic, communication with the host and
+ * wrapper interface for the main code of the VBoxClient deamon. The
+ * X11-specific parts are split out into their own file for ease of testing.
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -15,41 +16,420 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <unistd.h>
+/*****************************************************************************
+* Header files *
+*****************************************************************************/
#include <X11/Xlib.h>
+#include <VBox/log.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuestLib.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+
#include "VBoxClient.h"
#include "seamless.h"
-class SeamlessService : public VBoxClient::Service
+#include <new>
+
+SeamlessMain::SeamlessMain(void)
+{
+ LogRelFlowFunc(("\n"));
+ mX11MonitorThread = NIL_RTTHREAD;
+ mX11MonitorThreadStopping = false;
+ mMode = VMMDev_Seamless_Disabled;
+ mfPaused = false;
+}
+
+SeamlessMain::~SeamlessMain()
+{
+ LogRelFlowFunc(("\n"));
+ stop();
+}
+
+/**
+ * Update the set of visible rectangles in the host.
+ */
+static void sendRegionUpdate(RTRECT *pRects, size_t cRects)
{
-private:
- VBoxGuestSeamless mSeamless;
-public:
- virtual const char *getPidFilePath()
+ LogRelFlowFunc(("\n"));
+ if (cRects && !pRects) /* Assertion */
{
- return ".vboxclient-seamless.pid";
+ LogRelFunc(("ERROR: called with null pointer!\n"));
+ return;
}
- virtual int run(bool fDaemonised /* = false */)
+ VbglR3SeamlessSendRects(cRects, pRects);
+ LogRelFlowFunc(("returning\n"));
+}
+
+/**
+ * initialise the service.
+ */
+int SeamlessMain::init(void)
+{
+ int rc;
+ const char *pcszStage;
+
+ LogRelFlowFunc(("\n"));
+ do {
+ pcszStage = "Connecting to the X server";
+ rc = mX11Monitor.init(sendRegionUpdate);
+ if (RT_FAILURE(rc))
+ break;
+ pcszStage = "Setting guest IRQ filter mask";
+ rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
+ if (RT_FAILURE(rc))
+ break;
+ pcszStage = "Reporting support for seamless capability";
+ rc = VbglR3SeamlessSetCap(true);
+ if (RT_FAILURE(rc))
+ break;
+ } while(0);
+ if (RT_FAILURE(rc))
+ LogRel(("VBoxClient (seamless): failed to start. Stage: \"%s\" Error: %Rrc\n",
+ pcszStage, rc));
+ return rc;
+}
+
+/**
+ * Run the main service thread which listens for host state change
+ * notifications.
+ * @returns iprt status value. Service will be set to the stopped state on
+ * failure.
+ */
+int SeamlessMain::run(void)
+{
+ int rc = VINF_SUCCESS;
+
+ LogRelFlowFunc(("\n"));
+ /* This will only exit if something goes wrong. */
+ while (RT_SUCCESS(rc) || rc == VERR_INTERRUPTED)
{
- int rc = mSeamless.init();
if (RT_FAILURE(rc))
- return rc;
- /* Stay running as long as X does... */
- Display *pDisplay = XOpenDisplay(NULL);
- XEvent ev;
- while (true)
- XNextEvent(pDisplay, &ev);
- return VERR_INTERRUPTED;
+ /* If we are not stopping, sleep for a bit to avoid using up too
+ much CPU while retrying. */
+ RTThreadYield();
+ rc = nextStateChangeEvent();
+ }
+ if (RT_FAILURE(rc))
+ {
+ LogRel(("VBoxClient (seamless): event loop failed with error: %Rrc\n",
+ rc));
+ stop();
}
- virtual void cleanup()
+ return rc;
+}
+
+/** Stops the service. */
+void SeamlessMain::stop()
+{
+ LogRelFlowFunc(("\n"));
+ VbglR3SeamlessSetCap(false);
+ VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
+ stopX11MonitorThread();
+ mX11Monitor.uninit();
+ LogRelFlowFunc(("returning\n"));
+}
+
+/**
+ * Waits for a seamless state change events from the host and dispatch it.
+ *
+ * @returns IRPT return code.
+ */
+int SeamlessMain::nextStateChangeEvent(void)
+{
+ VMMDevSeamlessMode newMode = VMMDev_Seamless_Disabled;
+
+ LogRelFlowFunc(("\n"));
+ int rc = VbglR3SeamlessWaitEvent(&newMode);
+ if (RT_SUCCESS(rc))
+ {
+ mMode = newMode;
+ switch (newMode)
+ {
+ case VMMDev_Seamless_Visible_Region:
+ /* A simplified seamless mode, obtained by making the host VM window
+ * borderless and making the guest desktop transparent. */
+ LogRelFlowFunc(("\"Visible region\" mode requested (VBoxClient).\n"));
+ break;
+ case VMMDev_Seamless_Disabled:
+ LogRelFlowFunc(("\"Disabled\" mode requested (VBoxClient).\n"));
+ break;
+ case VMMDev_Seamless_Host_Window:
+ /* One host window represents one guest window. Not yet implemented. */
+ LogRelFunc(("Unsupported \"host window\" mode requested (VBoxClient).\n"));
+ return VERR_NOT_SUPPORTED;
+ default:
+ LogRelFunc(("Unsupported mode %d requested (VBoxClient).\n",
+ newMode));
+ return VERR_NOT_SUPPORTED;
+ }
+ }
+ if (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN)
+ {
+ if (mMode == VMMDev_Seamless_Visible_Region && !mfPaused)
+ /* This does it's own logging on failure. */
+ rc = startX11MonitorThread();
+ else
+ /* This does it's own logging on failure. */
+ rc = stopX11MonitorThread();
+ }
+ else
+ {
+ LogRelFunc(("VbglR3SeamlessWaitEvent returned %Rrc (VBoxClient)\n", rc));
+ }
+ LogRelFlowFunc(("returning %Rrc\n", rc));
+ return rc;
+}
+
+int SeamlessMain::cancelEvent(void)
+{
+ return VbglR3InterruptEventWaits();
+}
+
+/**
+ * The actual X11 window configuration change monitor thread function.
+ */
+int SeamlessMain::x11MonitorThread(RTTHREAD self, void *pvUser)
+{
+ SeamlessMain *pHost = (SeamlessMain *)pvUser;
+ int rc = VINF_SUCCESS;
+
+ LogRelFlowFunc(("\n"));
+ rc = pHost->mX11Monitor.start();
+ if (RT_SUCCESS(rc))
+ {
+ while (!pHost->mX11MonitorThreadStopping)
+ pHost->mX11Monitor.nextConfigurationEvent();
+ pHost->mX11Monitor.stop();
+ }
+ LogRelFlowFunc(("returning %Rrc\n", rc));
+ return rc;
+}
+
+/**
+ * Start the X11 window configuration change monitor thread.
+ */
+int SeamlessMain::startX11MonitorThread(void)
+{
+ int rc;
+
+ mX11MonitorThreadStopping = false;
+ if (isX11MonitorThreadRunning())
+ return VINF_SUCCESS;
+ rc = RTThreadCreate(&mX11MonitorThread, x11MonitorThread, this, 0,
+ RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
+ "X11 events");
+ if (RT_FAILURE(rc))
+ LogRelFunc(("Warning: failed to start X11 monitor thread (VBoxClient).\n"));
+ return rc;
+}
+
+/**
+ * Send a signal to the thread function that it should exit
+ */
+int SeamlessMain::stopX11MonitorThread(void)
+{
+ int rc;
+
+ mX11MonitorThreadStopping = true;
+ if (!isX11MonitorThreadRunning())
+ return VINF_SUCCESS;
+ mX11Monitor.interruptEventWait();
+ rc = RTThreadWait(mX11MonitorThread, RT_INDEFINITE_WAIT, NULL);
+ if (RT_SUCCESS(rc))
+ mX11MonitorThread = NIL_RTTHREAD;
+ else
+ LogRelThisFunc(("Failed to stop X11 monitor thread, rc=%Rrc!\n",
+ rc));
+ return rc;
+}
+
+/** Pause the service loop. */
+int SeamlessMain::pause()
+{
+ int rc;
+ const char *pcszStage;
+
+ LogRelFlowFunc(("\n"));
+ mfPaused = true;
+ do {
+ pcszStage = "Reporting end of support for seamless capability";
+ rc = VbglR3SeamlessSetCap(false);
+ if (RT_FAILURE(rc))
+ break;
+ pcszStage = "Interrupting the event loop";
+ rc = cancelEvent();
+ if (RT_FAILURE(rc))
+ break;
+ } while (0);
+ if (RT_FAILURE(rc))
+ LogRelFunc(("Failure. Stage: \"%s\" Error: %Rrc (VBoxClient)\n",
+ pcszStage, rc));
+ return rc;
+}
+
+/** Resume after pausing. */
+int SeamlessMain::resume()
+{
+ int rc;
+ const char *pcszStage;
+
+ LogRelFlowFunc(("\n"));
+ mfPaused = false;
+ do {
+ pcszStage = "Reporting support for seamless capability";
+ rc = VbglR3SeamlessSetCap(true);
+ if (RT_FAILURE(rc))
+ break;
+ pcszStage = "Interrupting the event loop";
+ rc = cancelEvent();
+ if (RT_FAILURE(rc))
+ break;
+ } while (0);
+ if (RT_FAILURE(rc))
+ LogRelFunc(("Failure. Stage: \"%s\" Error: %Rrc (VBoxClient)\n",
+ pcszStage, rc));
+ return rc;
+}
+
+/** @todo Expand this? */
+int SeamlessMain::selfTest()
+{
+ int rc = VERR_INTERNAL_ERROR;
+ const char *pcszStage;
+
+ LogRelFlowFunc(("\n"));
+ do {
+ pcszStage = "Testing event loop cancellation";
+ VbglR3InterruptEventWaits();
+ if (RT_FAILURE(VbglR3WaitEvent(VMMDEV_EVENT_VALID_EVENT_MASK, 0, NULL)))
+ break;
+ if ( VbglR3WaitEvent(VMMDEV_EVENT_VALID_EVENT_MASK, 0, NULL)
+ != VERR_TIMEOUT)
+ break;
+ rc = VINF_SUCCESS;
+ } while(0);
+ if (RT_FAILURE(rc))
+ LogRel(("VBoxClient (seamless): self test failed. Stage: \"%s\"\n",
+ pcszStage));
+ return rc;
+}
+
+/** Service magic number, start of a UUID. */
+#define SEAMLESSSERVICE_MAGIC 0xd28ba727
+
+/** VBoxClient service class wrapping the logic for the seamless service while
+ * the main VBoxClient code provides the daemon logic needed by all services.
+ */
+struct SEAMLESSSERVICE
+{
+ /** The service interface. */
+ struct VBCLSERVICE *pInterface;
+ /** Magic number for sanity checks. */
+ uint32_t magic;
+ /** Seamless service object. */
+ SeamlessMain mSeamless;
+ /** Are we initialised yet? */
+ bool mIsInitialised;
+};
+
+static const char *getPidFilePath(void)
+{
+ return ".vboxclient-seamless.pid";
+}
+
+static struct SEAMLESSSERVICE *getClassFromInterface(struct VBCLSERVICE **
+ ppInterface)
+{
+ struct SEAMLESSSERVICE *pSelf = (struct SEAMLESSSERVICE *)ppInterface;
+ if (pSelf->magic != SEAMLESSSERVICE_MAGIC)
+ VBClFatalError(("Bad seamless service object!\n"));
+ return pSelf;
+}
+
+static int init(struct VBCLSERVICE **ppInterface)
+{
+ struct SEAMLESSSERVICE *pSelf = getClassFromInterface(ppInterface);
+ int rc;
+
+ if (pSelf->mIsInitialised)
+ return VERR_INTERNAL_ERROR;
+ /* Initialise the guest library. */
+ rc = VbglR3InitUser();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
+ rc = pSelf->mSeamless.init();
+ if (RT_FAILURE(rc))
+ return rc;
+ rc = pSelf->mSeamless.selfTest();
+ if (RT_FAILURE(rc))
{
- VbglR3SeamlessSetCap(false);
+ pSelf->mSeamless.stop();
+ return rc;
}
+ pSelf->mIsInitialised = true;
+ return VINF_SUCCESS;
+}
+
+static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
+{
+ struct SEAMLESSSERVICE *pSelf = getClassFromInterface(ppInterface);
+ int rc;
+
+ if (!pSelf->mIsInitialised)
+ return VERR_INTERNAL_ERROR;
+ rc = VBClStartVTMonitor();
+ if (RT_FAILURE(rc))
+ VBClFatalError(("Failed to start the VT monitor thread: %Rrc\n", rc));
+ /* This only exits on error. */
+ rc = pSelf->mSeamless.run();
+ pSelf->mIsInitialised = false;
+ return rc;
+}
+
+static int pause(struct VBCLSERVICE **ppInterface)
+{
+ struct SEAMLESSSERVICE *pSelf = getClassFromInterface(ppInterface);
+
+ return pSelf->mSeamless.pause();
+}
+
+static int resume(struct VBCLSERVICE **ppInterface)
+{
+ struct SEAMLESSSERVICE *pSelf = getClassFromInterface(ppInterface);
+
+ return pSelf->mSeamless.resume();
+}
+
+static void cleanup(struct VBCLSERVICE **ppInterface)
+{
+ NOREF(ppInterface);
+ VbglR3SeamlessSetCap(false);
+ VbglR3Term();
+}
+
+struct VBCLSERVICE vbclSeamlessInterface =
+{
+ getPidFilePath,
+ init,
+ run,
+ pause,
+ resume,
+ cleanup
};
-VBoxClient::Service *VBoxClient::GetSeamlessService()
+struct VBCLSERVICE **VBClGetSeamlessService()
{
- return new SeamlessService;
+ struct SEAMLESSSERVICE *pService =
+ (struct SEAMLESSSERVICE *)RTMemAlloc(sizeof(*pService));
+
+ if (!pService)
+ VBClFatalError(("Out of memory\n"));
+ pService->pInterface = &vbclSeamlessInterface;
+ pService->magic = SEAMLESSSERVICE_MAGIC;
+ new(&pService->mSeamless) SeamlessMain();
+ pService->mIsInitialised = false;
+ return &pService->pInterface;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/seamless.h b/src/VBox/Additions/x11/VBoxClient/seamless.h
index c1ffc27..1a567eb 100644
--- a/src/VBox/Additions/x11/VBoxClient/seamless.h
+++ b/src/VBox/Additions/x11/VBoxClient/seamless.h
@@ -1,6 +1,6 @@
/** @file
- *
- * Guest client: seamless mode.
+ * X11 Guest client - seamless mode, missing proper description while using the
+ * potentially confusing word 'host'.
*/
/*
@@ -15,185 +15,101 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#ifndef __Additions_xclient_seamless_h
-# define __Additions_xclient_seamless_h
+#ifndef __Additions_client_seamless_host_h
+# define __Additions_client_seamless_host_h
+
+#include <iprt/thread.h>
#include <VBox/log.h>
+#include <VBox/VBoxGuestLib.h> /* for the R3 guest library functions */
-#include "seamless-host.h"
-#include "seamless-guest.h"
-#include "seamless-glue.h"
+#include "seamless-x11.h"
-/** Thread function class for VBoxGuestSeamlessGuest. */
-class VBoxGuestSeamlessGuestThread: public VBoxGuestThreadFunction
+/**
+ * Interface to the host
+ */
+class SeamlessMain
{
private:
- /** The guest class "owning" us. */
- VBoxGuestSeamlessGuestImpl *mGuest;
- /** The guest observer monitoring the guest. */
- VBoxGuestSeamlessObserver *mObserver;
- /** Should we exit the thread? */
- bool mExit;
+ // We don't want a copy constructor or assignment operator
+ SeamlessMain(const SeamlessMain&);
+ SeamlessMain& operator=(const SeamlessMain&);
- // Copying or assigning a thread object is not sensible
- VBoxGuestSeamlessGuestThread(const VBoxGuestSeamlessGuestThread&);
- VBoxGuestSeamlessGuestThread& operator=(const VBoxGuestSeamlessGuestThread&);
+ /** X11 event monitor object */
+ SeamlessX11 mX11Monitor;
-public:
- VBoxGuestSeamlessGuestThread(VBoxGuestSeamlessGuestImpl *pGuest,
- VBoxGuestSeamlessObserver *pObserver)
- { mGuest = pGuest; mObserver = pObserver; mExit = false; }
- virtual ~VBoxGuestSeamlessGuestThread(void) {}
- /**
- * The actual thread function.
- *
- * @returns iprt status code as thread return value
- * @param pParent the VBoxGuestThread running this thread function
- */
- virtual int threadFunction(VBoxGuestThread *pThread)
- {
- int rc = VINF_SUCCESS;
-
- LogRelFlowFunc(("\n"));
- rc = mGuest->start();
- if (RT_SUCCESS(rc))
- {
- while (!pThread->isStopping())
- {
- mGuest->nextEvent();
- }
- mGuest->stop();
- }
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
- }
- /**
- * Send a signal to the thread function that it should exit
- */
- virtual void stop(void) { mGuest->interruptEvent(); }
-};
+ /** Thread to start and stop when we enter and leave seamless mode which
+ * monitors X11 windows in the guest. */
+ RTTHREAD mX11MonitorThread;
+ /** Should the X11 monitor thread be stopping? */
+ volatile bool mX11MonitorThreadStopping;
-/** Observer for the host class - start and stop seamless reporting in the guest when the
- host requests. */
-class VBoxGuestSeamlessHostObserver : public VBoxGuestSeamlessObserver
-{
-private:
- VBoxGuestSeamlessHost *mHost;
- VBoxGuestThread *mGuestThread;
+ /** The current seamless mode we are in. */
+ VMMDevSeamlessMode mMode;
+ /** Is the service currently paused? */
+ volatile bool mfPaused;
-public:
- VBoxGuestSeamlessHostObserver(VBoxGuestSeamlessHost *pHost,
- VBoxGuestThread *pGuestThread)
- {
- mHost = pHost;
- mGuestThread = pGuestThread;
- }
+ /**
+ * Waits for a seamless state change events from the host and dispatch it. This is
+ * meant to be called by the host event monitor thread exclusively.
+ *
+ * @returns IRPT return code.
+ */
+ int nextStateChangeEvent(void);
- virtual void notify(void)
+ /**
+ * Interrupt an event wait and cause the current or next
+ * @a nextStateChangeEvent call to return immediately.
+ */
+ int cancelEvent(void);
+
+ /** Thread function to monitor X11 window configuration changes. */
+ static DECLCALLBACK(int) x11MonitorThread(RTTHREAD self, void *pvUser);
+
+ /** Helper to start the X11 monitor thread. */
+ int startX11MonitorThread(void);
+
+ /** Helper to stop the X11 monitor thread again. */
+ int stopX11MonitorThread(void);
+
+ /** Is the service currently actively monitoring X11 windows? */
+ bool isX11MonitorThreadRunning()
{
- switch (mHost->getState())
- {
- case VBoxGuestSeamlessHost::ENABLE:
- mGuestThread->start();
- break;
- case VBoxGuestSeamlessHost::DISABLE:
- mGuestThread->stop(RT_INDEFINITE_WAIT, 0);
- break;
- default:
- break;
- }
+ return mX11MonitorThread != NIL_RTTHREAD;
}
-};
-
-/** Observer for the guest class - send the host updated seamless rectangle information when
- it becomes available. */
-class VBoxGuestSeamlessGuestObserver : public VBoxGuestSeamlessObserver
-{
-private:
- VBoxGuestSeamlessHost *mHost;
- VBoxGuestSeamlessGuestImpl *mGuest;
public:
- VBoxGuestSeamlessGuestObserver(VBoxGuestSeamlessHost *pHost,
- VBoxGuestSeamlessGuestImpl *pGuest)
- {
- mHost = pHost;
- mGuest = pGuest;
- }
+ SeamlessMain(void);
+ virtual ~SeamlessMain();
- virtual void notify(void)
- {
- mHost->updateRects(mGuest->getRects(), mGuest->getRectCount());
- }
-};
-
-class VBoxGuestSeamless
-{
-private:
- VBoxGuestSeamlessHost mHost;
- VBoxGuestSeamlessGuestImpl mGuest;
- VBoxGuestSeamlessGuestThread mGuestFunction;
- VBoxGuestThread mGuestThread;
- VBoxGuestSeamlessHostObserver mHostObs;
- VBoxGuestSeamlessGuestObserver mGuestObs;
-
- bool isInitialised;
-public:
- int init(void)
- {
- int rc = VINF_SUCCESS;
-
- LogRelFlowFunc(("\n"));
- if (isInitialised) /* Assertion */
- {
- LogRelFunc(("error: called a second time! (VBoxClient)\n"));
- rc = VERR_INTERNAL_ERROR;
- }
- if (RT_SUCCESS(rc))
- {
- rc = mHost.init(&mHostObs);
- }
- if (RT_SUCCESS(rc))
- {
- rc = mGuest.init(&mGuestObs);
- }
- if (RT_SUCCESS(rc))
- {
- rc = mHost.start();
- }
- if (RT_SUCCESS(rc))
- {
- isInitialised = true;
- }
- if (RT_FAILURE(rc))
- {
- LogRelFunc(("returning %Rrc (VBoxClient)\n", rc));
- }
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
- }
+ /**
+ * Initialise the service.
+ */
+ int init(void);
- void uninit(RTMSINTERVAL cMillies = RT_INDEFINITE_WAIT)
- {
- LogRelFlowFunc(("\n"));
- if (isInitialised)
- {
- mHost.stop(cMillies);
- mGuestThread.stop(cMillies, 0);
- mGuest.uninit();
- isInitialised = false;
- }
- LogRelFlowFunc(("returning\n"));
- }
+ /**
+ * Run the service.
+ * @returns iprt status value
+ */
+ int run(void);
- VBoxGuestSeamless() : mGuestFunction(&mGuest, &mGuestObs),
- mGuestThread(&mGuestFunction, 0, RTTHREADTYPE_MSG_PUMP,
- RTTHREADFLAGS_WAITABLE, "Guest events"),
- mHostObs(&mHost, &mGuestThread), mGuestObs(&mHost, &mGuest)
- {
- isInitialised = false;
- }
- ~VBoxGuestSeamless() { uninit(); }
+ /**
+ * Stops the service.
+ */
+ void stop();
+
+ /** Pause the service loop. This must be safe to call on a different thread
+ * and potentially before @a run is or after it exits.
+ * This is called by the VT monitoring thread to allow the service to disable
+ * itself when the X server is switched out. If the monitoring functionality
+ * is available then @a pause or @a resume will be called as soon as it starts
+ * up. */
+ int pause();
+ /** Resume after pausing. The same applies here as for @a pause. */
+ int resume();
+
+ /** Run a few tests to be sure everything is working as intended. */
+ int selfTest();
};
#endif /* __Additions_xclient_seamless_h not defined */
diff --git a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
index d79080d..d877ffb 100644
--- a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11-auto.cpp
@@ -296,19 +296,22 @@ int XFlush(Display *display)
AssertFailedReturn(0);
}
-/** Dummy observer class */
-class testObserver: public VBoxGuestSeamlessObserver
+/** Global "received a notification" flag. */
+static bool g_fNotified = false;
+
+/** Dummy host call-back. */
+static void sendRegionUpdate(RTRECT *pRects, size_t cRects)
{
- bool mfNotified;
-public:
- testObserver() : mfNotified(false) {}
- virtual void notify(void)
- {
- mfNotified = true;
- }
- virtual ~testObserver() {}
- bool isNotified(void) { return mfNotified; }
-};
+ g_fNotified = true;
+}
+
+static bool gotNotification(void)
+{
+ if (!g_fNotified)
+ return false;
+ g_fNotified = false;
+ return true;
+}
/*****************************
* The actual tests to be run *
@@ -371,6 +374,8 @@ struct SMLSFIXTURE
unsigned cReportedRects;
/** The onscreen positions of those windows. */
RTRECT *paReportedRects;
+ /** Do we expect notification after the event? */
+ bool fExpectNotification;
};
/*** Test fixture to test the code against X11 configure (move) events ***/
@@ -418,7 +423,8 @@ static SMLSFIXTURE g_testMove =
ConfigureNotify,
20,
RT_ELEMENTS(g_aRects1),
- g_aRects1
+ g_aRects1,
+ true
};
/*** Test fixture to test the code against X11 configure (resize) events ***/
@@ -453,7 +459,8 @@ static SMLSFIXTURE g_testResize =
ConfigureNotify,
20,
RT_ELEMENTS(g_aRects1),
- g_aRects1
+ g_aRects1,
+ true
};
/*** Test fixture to test the code against X11 map events ***/
@@ -483,7 +490,8 @@ static SMLSFIXTURE g_testMap =
MapNotify,
20,
RT_ELEMENTS(g_aRects1),
- g_aRects1
+ g_aRects1,
+ true
};
/*** Test fixtures to test the code against X11 unmap events ***/
@@ -513,7 +521,8 @@ static SMLSFIXTURE g_testUnmap =
UnmapNotify,
20,
0,
- NULL
+ NULL,
+ true
};
/*** A window we are not monitoring has been unmapped. Nothing should
@@ -544,7 +553,8 @@ static SMLSFIXTURE g_testUnmapOther =
UnmapNotify,
21,
RT_ELEMENTS(g_aRects2),
- g_aRects2
+ g_aRects2,
+ false
};
/*** Test fixture to test the code against X11 shape events ***/
@@ -573,7 +583,8 @@ static SMLSFIXTURE g_testShape =
VBoxShapeNotify,
20,
RT_ELEMENTS(g_aRects1),
- g_aRects1
+ g_aRects1,
+ true
};
/*** And the test code proper ***/
@@ -597,11 +608,10 @@ static void smlsPrintDiffRects(RTRECT *pExp, RTRECT *pGot)
/** Run through a test fixture */
static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
{
- VBoxGuestSeamlessX11 subject;
- testObserver observer;
+ SeamlessX11 subject;
unsigned cErrs = 0;
- subject.init(&observer);
+ subject.init(sendRegionUpdate);
smlsSetWindowAttributes(pFixture->paAttribsBefore,
pFixture->pahWindowsBefore,
pFixture->cWindowsBefore,
@@ -618,22 +628,22 @@ static unsigned smlsDoFixture(SMLSFIXTURE *pFixture, const char *pszDesc)
pFixture->cShapeRectsAfter,
pFixture->paShapeRectsAfter);
smlsSetNextEvent(pFixture->x11EventType, pFixture->hEventWindow);
- if (observer.isNotified()) /* Initial window tree rebuild */
+ if (gotNotification()) /* Initial window tree rebuild */
{
RTPrintf("%s: fixture: %s. Notification was set before the first event!!!\n",
g_pszTestName, pszDesc);
++cErrs;
}
- subject.nextEvent();
- if (!observer.isNotified())
+ subject.nextConfigurationEvent();
+ if (!gotNotification())
{
RTPrintf("%s: fixture: %s. No notification was sent for the initial window tree rebuild.\n",
g_pszTestName, pszDesc);
++cErrs;
}
smlsSetNextEvent(0, 0);
- subject.nextEvent();
- if (!observer.isNotified())
+ subject.nextConfigurationEvent();
+ if (pFixture->fExpectNotification && !gotNotification())
{
RTPrintf("%s: fixture: %s. No notification was sent after the event.\n",
g_pszTestName, pszDesc);
diff --git a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
index 638f2cf..d9782dd 100644
--- a/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
+++ b/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
@@ -25,6 +25,18 @@
static RTSEMEVENT eventSem;
+/** Exit with a fatal error. */
+void vbclFatalError(char *pszMessage)
+{
+ RTPrintf("Fatal error: %s", pszMessage);
+ exit(1);
+}
+
+int VBClStartVTMonitor()
+{
+ return VINF_SUCCESS;
+}
+
int VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects)
{
RTPrintf("Received rectangle update (%u rectangles):\n", cRects);
@@ -34,21 +46,21 @@ int VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects)
pRects[i].xLeft, pRects[i].yTop, pRects[i].xRight,
pRects[i].yBottom);
}
- return true;
+ return VINF_SUCCESS;
}
int VbglR3SeamlessSetCap(bool bState)
{
RTPrintf("%s\n", bState ? "Seamless capability set"
: "Seamless capability unset");
- return true;
+ return VINF_SUCCESS;
}
int VbglR3CtlFilterMask(uint32_t u32OrMask, uint32_t u32NotMask)
{
RTPrintf("IRQ filter mask changed. Or mask: 0x%x. Not mask: 0x%x\n",
u32OrMask, u32NotMask);
- return true;
+ return VINF_SUCCESS;
}
int VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode)
@@ -62,14 +74,13 @@ int VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode)
*pMode = VMMDev_Seamless_Visible_Region;
}
else
- {
rc = RTSemEventWait(eventSem, RT_INDEFINITE_WAIT);
- if (RT_SUCCESS(rc))
- {
- rc = VERR_INTERRUPTED;
- }
- }
- return true;
+ return rc;
+}
+
+int VbglR3WaitEvent(uint32_t , uint32_t cMillies, uint32_t *)
+{
+ return RTSemEventWait(eventSem, cMillies);
}
int VbglR3InterruptEventWaits(void)
@@ -77,6 +88,9 @@ int VbglR3InterruptEventWaits(void)
return RTSemEventSignal(eventSem);
}
+VBGLR3DECL(int) VbglR3InitUser(void) { return VINF_SUCCESS; }
+VBGLR3DECL(void) VbglR3Term(void) {}
+
/**
* Xlib error handler for certain errors that we can't avoid.
*/
@@ -115,17 +129,20 @@ int main( int argc, char **argv)
}
/* Set an X11 error handler, so that we don't die when we get unavoidable errors. */
XSetErrorHandler(vboxClientXLibErrorHandler);
- RTPrintf("\nPress <Enter> to exit...\n");
+ RTPrintf("\nType Ctrl-C to exit...\n");
RTSemEventCreate(&eventSem);
/** Our instance of the seamless class. */
- VBoxGuestSeamless seamless;
+ SeamlessMain seamless;
LogRel(("Starting seamless Guest Additions...\n"));
rc = seamless.init();
if (rc != VINF_SUCCESS)
{
- RTPrintf("Failed to initialise seamless Additions, rc = %d\n", rc);
+ RTPrintf("Failed to initialise seamless Additions, rc = %Rrc\n", rc);
+ }
+ rc = seamless.run();
+ if (rc != VINF_SUCCESS)
+ {
+ RTPrintf("Failed to run seamless Additions, rc = %Rrc\n", rc);
}
- RTStrmGetLine(g_pStdIn, ach, sizeof(ach));
- seamless.uninit();
return rc;
}
diff --git a/src/VBox/Additions/x11/VBoxClient/thread.cpp b/src/VBox/Additions/x11/VBoxClient/thread.cpp
deleted file mode 100644
index 4655cb7..0000000
--- a/src/VBox/Additions/x11/VBoxClient/thread.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/** @file
- *
- * VirtualBox additions client application: thread class.
- */
-
-/*
- * Copyright (C) 2006-2011 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include <VBox/log.h>
-
-#include "thread.h"
-
-/** Stop the thread using its stop method and get the exit value. */
-int VBoxGuestThread::stop(RTMSINTERVAL cMillies, int *prc)
-{
- int rc = VINF_SUCCESS;
-
- LogRelFlowFunc(("\n"));
- if (NIL_RTTHREAD == mSelf) /* Assertion */
- {
- LogRelThisFunc(("Attempted to stop thread %s which is not running!\n", mName));
- return VERR_INTERNAL_ERROR;
- }
- mExit = true;
- mFunction->stop();
- if (0 != (mFlags & RTTHREADFLAGS_WAITABLE))
- {
- rc = RTThreadWait(mSelf, cMillies, prc);
- if (RT_SUCCESS(rc))
- {
- mSelf = NIL_RTTHREAD;
- }
- else
- {
- LogRelThisFunc(("Failed to stop thread %s!\n", mName));
- }
- }
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
-}
-
-/** Destroy the class, stopping the thread if necessary. */
-VBoxGuestThread::~VBoxGuestThread(void)
-{
- LogRelFlowFunc(("\n"));
- if (NIL_RTTHREAD != mSelf)
- {
- LogRelThisFunc(("Warning! Stopping thread %s, as it is still running!\n", mName));
- stop(2000, 0);
- }
- LogRelFlowFunc(("returning\n"));
-}
-
-/** Start the thread. */
-int VBoxGuestThread::start(void)
-{
- int rc = VINF_SUCCESS;
-
- LogRelFlowFunc(("returning\n"));
- if (NIL_RTTHREAD != mSelf) /* Assertion */
- {
- LogRelThisFunc(("Attempted to start thread %s twice!\n", mName));
- return VERR_INTERNAL_ERROR;
- }
- mExit = false;
- rc = RTThreadCreate(&mSelf, threadFunction, reinterpret_cast<void *>(this),
- mStack, mType, mFlags, mName);
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
-}
-
-/** Yield the CPU */
-bool VBoxGuestThread::yield(void)
-{
- return RTThreadYield();
-}
-
-/** The "real" thread function for the VBox runtime. */
-int VBoxGuestThread::threadFunction(RTTHREAD self, void *pvUser)
-{
- int rc = VINF_SUCCESS;
-
- LogRelFlowFunc(("\n"));
- PSELF pSelf = reinterpret_cast<PSELF>(pvUser);
- pSelf->mRunning = true;
- rc = pSelf->mFunction->threadFunction(pSelf);
- pSelf->mRunning = false;
- LogRelFlowFunc(("returning %Rrc\n", rc));
- return rc;
-}
diff --git a/src/VBox/Additions/x11/VBoxClient/thread.h b/src/VBox/Additions/x11/VBoxClient/thread.h
deleted file mode 100644
index 8cd118a..0000000
--- a/src/VBox/Additions/x11/VBoxClient/thread.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/** @file
- *
- * VirtualBox additions client application: thread class.
- */
-
-/*
- * Copyright (C) 2006-2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#ifndef __Additions_client_thread_h
-# define __Additions_client_thread_h
-
-#include <iprt/thread.h>
-#include <iprt/err.h>
-
-#include <VBox/log.h>
-
-class VBoxGuestThread;
-
-/** Virtual parent class for thread functions for the VBoxGuestThread class. */
-class VBoxGuestThreadFunction
-{
-public:
- // VBoxGuestThreadFunction(void);
- virtual ~VBoxGuestThreadFunction(void) {}
- /**
- * The actual thread function.
- *
- * @returns iprt status code as thread return value
- * @param pParent the VBoxGuestThread running this thread function
- */
- virtual int threadFunction(VBoxGuestThread *pPThread) = 0;
- /**
- * Send a signal to the thread function that it should exit. This should not block.
- */
- virtual void stop(void) = 0;
-};
-
-/** C++ wrapper for VBox runtime threads. */
-class VBoxGuestThread
-{
-private:
- // Private member variables
- /** The thread function for this thread */
- VBoxGuestThreadFunction *mFunction;
- /** The size of the stack for the new thread. Use 0 for the default stack size. */
- size_t mStack;
- /** The thread type. Used for deciding scheduling attributes of the thread. */
- RTTHREADTYPE mType;
- /** Flags of the RTTHREADFLAGS type (ORed together). */
- unsigned mFlags;
- /** Thread name */
- const char *mName;
- /** The VBox runtime thread handle. */
- RTTHREAD mSelf;
- /** Is the thread currently running? */
- volatile bool mRunning;
- /** Should the thread be stopped? */
- volatile bool mExit;
-
- // Typedefs
- /** Ourselves, for use in the thread function. */
- typedef VBoxGuestThread *PSELF;
-public:
- /**
- * Initialise the class.
- * @param pFunction the thread function for this thread
- * @param cbStack The size of the stack for the new thread.
- * Use 0 for the default stack size.
- * @param enmType The thread type. Used for deciding scheduling attributes
- * of the thread.
- * @param fFlags Flags of the RTTHREADFLAGS type (ORed together).
- * @param pszName Thread name.
- */
- VBoxGuestThread(VBoxGuestThreadFunction *pFunction, size_t cbStack, RTTHREADTYPE enmType,
- unsigned fFlags, const char *pszName)
- {
- mFunction = pFunction;
- mStack = cbStack;
- mType = enmType;
- mFlags = fFlags;
- mName = pszName;
- mSelf = NIL_RTTHREAD;
- mRunning = false;
- mExit = false;
- }
- /** Stop the thread using its stop method and get the exit value.
- * @returns iprt status code
- * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
- * an indefinite wait. Only relevant if the thread is
- * waitable.
- * @param prc Where to store the return code of the thread. Optional.
- */
- int stop(RTMSINTERVAL cMillies, int *prc);
-
- /** Destroy the class, stopping the thread if necessary. */
- ~VBoxGuestThread(void);
-
- /** Return the VBox runtime thread handle. */
- RTTHREAD getSelf(void) { return mSelf; }
-
- /** Start the thread. */
- int start(void);
-
- /** Yield the CPU */
- bool yield(void);
-
- /** Is the thread running? */
- bool isRunning(void) { return mRunning; }
-
- /** Should the thread function exit? */
- bool isStopping(void) { return mExit; }
-private:
- // Copying or assigning a thread object is not sensible
- VBoxGuestThread(const VBoxGuestThread&);
- VBoxGuestThread& operator=(const VBoxGuestThread&);
-
- // Member functions
- /** The "real" thread function for the VBox runtime. */
- static DECLCALLBACK(int) threadFunction(RTTHREAD self, void *pvUser);
-};
-
-#endif /* __Additions_client_thread_h not defined */
diff --git a/src/VBox/Additions/x11/undefined_xorg b/src/VBox/Additions/x11/undefined_xorg
index 7115fa3..ed49272 100644
--- a/src/VBox/Additions/x11/undefined_xorg
+++ b/src/VBox/Additions/x11/undefined_xorg
@@ -8,6 +8,7 @@ chdir
chmod
chown
close
+closedir
__ctype_b_loc
__ctype_mask
__cxa_finalize
@@ -28,6 +29,8 @@ drmDropMaster
drmFreeVersion
drmGetVersion
drmIoctl
+drmModeGetResources
+drmModeFreeResources
drmSetMaster
___errno
__errno_location
@@ -86,6 +89,7 @@ nanosleep
nl_langinfo
open
open64
+opendir
pci_device_map_range
pci_device_unmap_range
posix_memalign
@@ -94,12 +98,15 @@ pthread_sigmask
pthread_yield
putenv
read
+readdir
+readdir64
realloc
realpath
__realpath_chk
__register_frame_info_bases
rename
RRChangeOutputProperty
+RRGetInfo
setenv
ShadowFBInit2
sigdelset
@@ -116,6 +123,8 @@ strchr
strcmp
strcpy
strlen
+__strncat_chk
+strncat
strncmp
strncpy
__strncpy_chk
@@ -141,6 +150,7 @@ vgaHWSetStdFuncs
vsnprintf
__vsnprintf_chk
write
+xf86AddGeneralHandler
xf86CreateCursorInfoRec
xf86CrtcConfigInit
xf86CrtcConfigPrivateIndex
@@ -156,6 +166,7 @@ xf86ModesAdd
xf86OutputCreate
xf86OutputSetEDID
xf86OutputUseScreenMonitor
+xf86RemoveGeneralHandler
xf86SaveScreen
xf86ScreenToScrn
xf86ScrnToScreen
diff --git a/src/VBox/Additions/x11/vboxmouse/Makefile.kmk b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
index ca2f88a..6a3b0d1 100644
--- a/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
@@ -74,9 +74,8 @@ vboxmouse_drv_70_TEMPLATE = VBOXGUESTR3XORGMOD
vboxmouse_drv_70_DEFS = \
XFree86Server IN_MODULE XFree86Module XFree86LOADER XINPUT XORG_7X IN_XF86_MODULE DONT_DEFINE_WRAPPERS NO_ANSIC
vboxmouse_drv_70_INCS := \
- $(VBOX_PATH_X11_XORG_7_0) \
- $(VBOX_PATH_X11_XORG_7_0)/X11 \
- $(VBOX_PATH_X11_XORG_7_0)/xorg \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.0.1 \
$(PATH_SUB_CURRENT)
vboxmouse_drv_70_SOURCES = \
vboxmouse.c
@@ -89,9 +88,8 @@ DLLS += vboxmouse_drv_71
vboxmouse_drv_71_TEMPLATE = VBOXGUESTR3XORGMOD
vboxmouse_drv_71_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
vboxmouse_drv_71_INCS := \
- $(VBOX_PATH_X11_XORG_7_1) \
- $(VBOX_PATH_X11_XORG_7_1)/X11 \
- $(VBOX_PATH_X11_XORG_7_1)/xorg \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.1.0 \
$(PATH_SUB_CURRENT)
vboxmouse_drv_71_SOURCES = \
vboxmouse.c
@@ -147,7 +145,7 @@ vboxmouse_drv_16_TEMPLATE = VBOXGUESTR3XORGMOD
vboxmouse_drv_16_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
vboxmouse_drv_16_INCS := \
$(vboxmouse_xorg_INCS) \
- $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0 \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.5 \
$(PATH_SUB_CURRENT)
vboxmouse_drv_16_SOURCES = \
vboxmouse.c
diff --git a/src/VBox/Additions/x11/vboxmouse/vboxmouse.c b/src/VBox/Additions/x11/vboxmouse/vboxmouse.c
index def915f..7b32aea 100644
--- a/src/VBox/Additions/x11/vboxmouse/vboxmouse.c
+++ b/src/VBox/Additions/x11/vboxmouse/vboxmouse.c
@@ -184,11 +184,8 @@ VBoxProc(DeviceIntPtr device, int what)
if (device->public.on)
break;
/* Tell the host that we want absolute co-ordinates */
- rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
- if (RT_SUCCESS(rc))
- rc = VbglR3SetMouseStatus( fFeatures
- | VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
- | VMMDEV_MOUSE_NEW_PROTOCOL);
+ rc = VbglR3SetMouseStatus( VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
+ | VMMDEV_MOUSE_NEW_PROTOCOL);
if (!RT_SUCCESS(rc)) {
xf86Msg(X_ERROR, "%s: Failed to switch guest mouse into absolute mode\n",
pInfo->name);
diff --git a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
index 7a9a0c8..592d65e 100644
--- a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
@@ -18,13 +18,6 @@
SUB_DEPTH = ../../../../..
include $(KBUILD_PATH)/subheader.kmk
-#
-# Include sub-makefile(s).
-#
-ifndef VBOX_USE_SYSTEM_XORG_HEADERS
- include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk
-endif
-
vboxvideo_70_DEFS := \
IN_MODULE XORG_7X RENDER=1 IN_RT_STATIC
ifeq ($(KBUILD_TARGET),solaris) # don't use .solaris or anything here.
@@ -32,7 +25,7 @@ ifeq ($(KBUILD_TARGET),solaris) # don't use .solaris or anything here.
endif
vboxvideo_13_DEFS := $(vboxvideo_70_DEFS) VBOXVIDEO_13
vboxvideo_15_DEFS := \
- $(vboxvideo_13_DEFS) NO_ANSIC PCIACCESS XSERVER_LIBPCIACCESS
+ $(vboxvideo_13_DEFS) NO_ANSIC PCIACCESS XSERVER_LIBPCIACCESS _XORG_SERVER_H_ _DIX_CONFIG_H_
if1of ($(KBUILD_TARGET), linux solaris)
vboxvideo_15_DEFS += \
VBOX_DRI
@@ -108,9 +101,10 @@ vboxvideo_drv_INCS = \
$(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/Xext
vboxvideo_drv_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_SOURCES = \
+ getmode.c \
+ helpers.c \
pointer.c \
setmode.c \
- vboxutils.c \
vboxvideo.c \
vbva.c \
$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
@@ -141,9 +135,8 @@ ifeq ($(KBUILD_TARGET),solaris) # don't use .solaris or anything here.
vboxvideo_drv_70_CFLAGS += -D_XPG6 -Wno-shadow # Use XPG6 until we have moved the C++ bits into a library.
endif
vboxvideo_drv_70_INCS = \
- $(VBOX_PATH_X11_XORG_7_0) \
- $(VBOX_PATH_X11_XORG_7_0)/X11 \
- $(VBOX_PATH_X11_XORG_7_0)/xorg
+ $(vboxvideo_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.0.1
vboxvideo_drv_70_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_70_SOURCES = $(vboxvideo_drv_SOURCES)
@@ -156,9 +149,8 @@ vboxvideo_drv_71_TEMPLATE = VBOXGUESTR3XORGMOD
vboxvideo_drv_71_CFLAGS := $(vboxvideo_drv_70_CFLAGS)
vboxvideo_drv_71_DEFS := $(vboxvideo_70_DEFS) XORG_VERSION_CURRENT=700100000
vboxvideo_drv_71_INCS = \
- $(VBOX_PATH_X11_XORG_7_1) \
- $(VBOX_PATH_X11_XORG_7_1)/X11 \
- $(VBOX_PATH_X11_XORG_7_1)/xorg
+ $(vboxvideo_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.1.0
vboxvideo_drv_71_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_71_SOURCES = $(vboxvideo_drv_SOURCES)
@@ -226,7 +218,7 @@ if1of ($(KBUILD_TARGET), linux solaris)
endif
vboxvideo_drv_16_INCS = \
$(vboxvideo_xorg_INCS) \
- $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0 \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.5 \
vboxvideo_drv_16_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_16_SOURCES := $(vboxvideo_drv_15_SOURCES)
@@ -375,6 +367,20 @@ vboxvideo_drv_116_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_116_SOURCES := $(vboxvideo_drv_17_SOURCES)
+#
+# vboxvideo_drv_117
+#
+DLLS += vboxvideo_drv_117
+vboxvideo_drv_117_TEMPLATE = VBOXGUESTR3XORGMOD
+vboxvideo_drv_117_CFLAGS := $(vboxvideo_drv_70_CFLAGS)
+vboxvideo_drv_117_DEFS := $(vboxvideo_15_DEFS) XORG_VERSION_CURRENT=101700000
+vboxvideo_drv_117_INCS = \
+ $(vboxvideo_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.17.1
+vboxvideo_drv_117_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
+vboxvideo_drv_117_SOURCES := $(vboxvideo_drv_17_SOURCES)
+
+
ifdef VBOX_USE_SYSTEM_XORG_HEADERS
# Build using local X.Org headers. We assume X.Org Server 1.7 or later.
DLLS := $(filter-out vboxvideo_drv_%,$(DLLS)) vboxvideo_drv_system
@@ -428,7 +434,7 @@ $$(vboxvideo_drv_0_OUTDIR)/tstvboxvideo68.run: $$(vboxvideo_drv_1_STAGE_TARGET)
$$(QUIET)$$(APPEND) -t "$$@" "done"
endef
- $(foreach ver, _70 _71 _13 _14 _15 _16 _17 _18 _19 _110 _111 _112 _113 _114 _115 _116, $(eval $(def_vboxvideo_test)))
+ $(foreach ver, _70 _71 _13 _14 _15 _16 _17 _18 _19 _110 _111 _112 _113 _114 _115 _116 _117, $(eval $(def_vboxvideo_test)))
endif # ! VBOX_ONLY_SDK
endif # eq ($(KBUILD_HOST_ARCH),$(KBUILD_TARGET_ARCH))
diff --git a/src/VBox/Additions/x11/vboxvideo/README.testing b/src/VBox/Additions/x11/vboxvideo/README.testing
new file mode 100644
index 0000000..b478049
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/README.testing
@@ -0,0 +1,20 @@
+This file contains some notes about things to try out to give the X.Org video
+driver a reasonably thorough test. We will add cases of things which have been
+known to fail in the past to this file as we discover them.
+
+ * Test XFree86 guests (CentOS 3), early X.Org (CentOS 5) and recent
+ (CentOS 6 and 7, current Ubuntu/Fedora). Test Solaris guests (10 and 11?).
+ * Dynamic resizing should work, on CentOS 6 and later Linux guests it should
+ work without VBoxClient running.
+ * Disabling and enabling virtual screens (only possible as of 4.4).
+ * Dynamic resizing with one of more virtual screens disabled.
+ * Test switching to virtual terminals and back from windowed, full screen and
+ seamless modes.
+ * Test switching directly between normal, full-screen, seamless and scaled
+ modes.
+ * Test enabling and disabling guest screens from the host.
+ * execute "xprop -root | grep VBOX" after resizing a screen: VBOX_SIZE_HINTS
+ should be set, and VBOX_SIZE_HINTS_MISMATCH should equal 0 on CentOS 6 and
+ later.
+ * Shutting down and re-starting a virtual machine should restore the last size
+ for all monitors (note: currently only after log-in).
diff --git a/src/VBox/Additions/x11/vboxvideo/getmode.c b/src/VBox/Additions/x11/vboxvideo/getmode.c
new file mode 100644
index 0000000..67707c3
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/getmode.c
@@ -0,0 +1,541 @@
+/* $Id: getmode.c $ */
+/** @file
+ * VirtualBox X11 Additions graphics driver dynamic video mode functions.
+ */
+
+/*
+ * Copyright (C) 2006-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "vboxvideo.h"
+#include <VBox/VMMDev.h>
+
+#define NEED_XF86_TYPES
+#include <iprt/string.h>
+
+#include "xf86.h"
+#include "dixstruct.h"
+#ifdef VBOX_GUESTR3XF86MOD
+# define EXTENSION_PROC_ARGS char *name, GCPtr pGC
+#endif
+#include "extnsionst.h"
+#include "windowstr.h"
+#include <X11/extensions/randrproto.h>
+
+#ifdef XORG_7X
+# include <stdio.h>
+# include <stdlib.h>
+#endif
+
+#ifdef VBOXVIDEO_13
+# ifdef RT_OS_LINUX
+# include "randrstr.h"
+# include "xf86_OSproc.h"
+# include <linux/input.h>
+# ifndef EVIOCGRAB
+# define EVIOCGRAB _IOW('E', 0x90, int)
+# endif
+# ifndef KEY_SWITCHVIDEOMODE
+# define KEY_SWITCHVIDEOMODE 227
+# endif
+# include <dirent.h>
+# include <errno.h>
+# include <fcntl.h>
+# include <unistd.h>
+# endif /* RT_OS_LINUX */
+#endif /* VBOXVIDEO_13 */
+/**************************************************************************
+* Main functions *
+**************************************************************************/
+
+/**
+ * Fills a display mode M with a built-in mode of name pszName and dimensions
+ * cx and cy.
+ */
+static void vboxFillDisplayMode(ScrnInfoPtr pScrn, DisplayModePtr m,
+ const char *pszName, unsigned cx, unsigned cy)
+{
+ VBOXPtr pVBox = pScrn->driverPrivate;
+ char szName[256];
+ DisplayModePtr pPrev = m->prev;
+ DisplayModePtr pNext = m->next;
+
+ if (!pszName)
+ {
+ sprintf(szName, "%ux%u", cx, cy);
+ pszName = szName;
+ }
+ TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy);
+ if (m->name)
+ free((void*)m->name);
+ memset(m, '\0', sizeof(*m));
+ m->prev = pPrev;
+ m->next = pNext;
+ m->status = MODE_OK;
+ m->type = M_T_BUILTIN;
+ /* Older versions of VBox only support screen widths which are a multiple
+ * of 8 */
+ if (pVBox->fAnyX)
+ m->HDisplay = cx;
+ else
+ m->HDisplay = cx & ~7;
+ m->HSyncStart = m->HDisplay + 2;
+ m->HSyncEnd = m->HDisplay + 4;
+ m->HTotal = m->HDisplay + 6;
+ m->VDisplay = cy;
+ m->VSyncStart = m->VDisplay + 2;
+ m->VSyncEnd = m->VDisplay + 4;
+ m->VTotal = m->VDisplay + 6;
+ m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */
+ m->name = xnfstrdup(pszName);
+}
+
+/** vboxvideo's list of standard video modes */
+struct
+{
+ /** mode width */
+ uint32_t cx;
+ /** mode height */
+ uint32_t cy;
+} vboxStandardModes[] =
+{
+ { 1600, 1200 },
+ { 1440, 1050 },
+ { 1280, 960 },
+ { 1024, 768 },
+ { 800, 600 },
+ { 640, 480 },
+ { 0, 0 }
+};
+enum
+{
+ vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])
+};
+
+/**
+ * Returns a standard mode which the host likes. Can be called multiple
+ * times with the index returned by the previous call to get a list of modes.
+ * @returns the index of the mode in the list, or 0 if no more modes are
+ * available
+ * @param pScrn the screen information structure
+ * @param pScrn->bitsPerPixel
+ * if this is non-null, only modes with this BPP will be
+ * returned
+ * @param cIndex the index of the last mode queried, or 0 to query the
+ * first mode available. Note: the first index is 1
+ * @param pcx where to store the mode's width
+ * @param pcy where to store the mode's height
+ * @param pcBits where to store the mode's BPP
+ */
+unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
+ uint32_t *pcx, uint32_t *pcy)
+{
+ unsigned i;
+
+ VBVXASSERT(cIndex < vboxNumStdModes,
+ ("cIndex = %d, vboxNumStdModes = %d\n", cIndex,
+ vboxNumStdModes));
+ for (i = cIndex; i < vboxNumStdModes - 1; ++i)
+ {
+ uint32_t cx = vboxStandardModes[i].cx;
+ uint32_t cy = vboxStandardModes[i].cy;
+
+ if (pcx)
+ *pcx = cx;
+ if (pcy)
+ *pcy = cy;
+ return i + 1;
+ }
+ return 0;
+}
+
+/**
+ * Allocates an empty display mode and links it into the doubly linked list of
+ * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated
+ * memory.
+ */
+static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)
+{
+ DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
+
+ TRACE_ENTRY();
+ if (!pScrn->modes)
+ {
+ pScrn->modes = pMode;
+ pMode->next = pMode;
+ pMode->prev = pMode;
+ }
+ else
+ {
+ pMode->next = pScrn->modes;
+ pMode->prev = pScrn->modes->prev;
+ pMode->next->prev = pMode;
+ pMode->prev->next = pMode;
+ }
+ return pMode;
+}
+
+/**
+ * Create display mode entries in the screen information structure for each
+ * of the graphics modes that we wish to support, that is:
+ * - A dynamic mode in first place which will be updated by the RandR code.
+ * - Several standard modes.
+ * - Any modes that the user requested in xorg.conf/XFree86Config.
+ */
+void vboxAddModes(ScrnInfoPtr pScrn)
+{
+ unsigned cx = 0, cy = 0, cIndex = 0;
+ unsigned i;
+ DisplayModePtr pMode;
+
+ /* Add two dynamic mode entries. When we receive a new size hint we will
+ * update whichever of these is not current. */
+ pMode = vboxAddEmptyScreenMode(pScrn);
+ vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768);
+ pMode = vboxAddEmptyScreenMode(pScrn);
+ vboxFillDisplayMode(pScrn, pMode, NULL, 1024, 768);
+ /* Add standard modes supported by the host */
+ for ( ; ; )
+ {
+ cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy);
+ if (cIndex == 0)
+ break;
+ pMode = vboxAddEmptyScreenMode(pScrn);
+ vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy);
+ }
+ /* And finally any modes specified by the user. We assume here that
+ * the mode names reflect the mode sizes. */
+ for (i = 0; pScrn->display->modes && pScrn->display->modes[i]; i++)
+ {
+ if (sscanf(pScrn->display->modes[i], "%ux%u", &cx, &cy) == 2)
+ {
+ pMode = vboxAddEmptyScreenMode(pScrn);
+ vboxFillDisplayMode(pScrn, pMode, pScrn->display->modes[i], cx, cy);
+ }
+ }
+}
+
+/** Set the initial values for the guest screen size hints by reading saved
+ * values from files. */
+/** @todo Actually read the files instead of setting dummies. */
+void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn)
+{
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ DisplayModePtr pMode;
+ unsigned i;
+
+ for (i = 0; i < pVBox->cScreens; ++i)
+ {
+ pVBox->pScreens[i].aPreferredSize.cx = 1024;
+ pVBox->pScreens[i].aPreferredSize.cy = 768;
+ pVBox->pScreens[i].afConnected = true;
+ }
+ /* Set up the first mode correctly to match the requested initial mode. */
+ pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;
+ pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy;
+ /* RandR 1.1 quirk: make sure that the initial resolution is always present
+ * in the mode list as RandR will always advertise a mode of the initial
+ * virtual resolution via GetScreenInfo. */
+ pMode = vboxAddEmptyScreenMode(pScrn);
+ vboxFillDisplayMode(pScrn, pMode, NULL, pVBox->pScreens[0].aPreferredSize.cx,
+ pVBox->pScreens[0].aPreferredSize.cy);
+}
+
+static void updateUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities)
+{
+ if ( !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
+ && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
+ pVBox->fUseHardwareCursor = true;
+ else
+ pVBox->fUseHardwareCursor = false;
+}
+
+# define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS"
+# define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES"
+
+/** Read in information about the most recent size hints requested for the
+ * guest screens. A client application sets the hint information as a root
+ * window property. */
+/* TESTING: dynamic resizing and absolute pointer toggling work on old guest X servers and recent ones on Linux at the log-in screen. */
+/** @note we try to maximise code coverage by typically using all code paths (HGSMI and properties) in a single X session. */
+void VBoxUpdateSizeHints(ScrnInfoPtr pScrn)
+{
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ size_t cModesFromProperty, cDummy;
+ int32_t *paModeHints, *pfCursorCapabilities;
+ unsigned i;
+ uint32_t fCursorCapabilities;
+ bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor;
+
+ if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS)
+ paModeHints = NULL;
+ if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) != VINF_SUCCESS
+ || cDummy != 1)
+ pfCursorCapabilities = NULL;
+#ifdef VBOXVIDEO_13
+ if (!pVBox->fHaveReadHGSMIModeHintData && RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens,
+ pVBox->paVBVAModeHints)))
+ {
+ for (i = 0; i < pVBox->cScreens; ++i)
+ {
+ if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC)
+ {
+ pVBox->pScreens[i].aPreferredSize.cx = pVBox->paVBVAModeHints[i].cx;
+ pVBox->pScreens[i].aPreferredSize.cy = pVBox->paVBVAModeHints[i].cy;
+ pVBox->pScreens[i].afConnected = pVBox->paVBVAModeHints[i].fEnabled;
+ /* Do not re-read this if we have data from HGSMI. */
+ if (paModeHints != NULL && i < cModesFromProperty)
+ pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i];
+ }
+ }
+ }
+ if (!pVBox->fHaveReadHGSMIModeHintData)
+ {
+ if (RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities)))
+ updateUseHardwareCursor(pVBox, fCursorCapabilities);
+ else
+ pVBox->fUseHardwareCursor = false;
+ /* Do not re-read this if we have data from HGSMI. */
+ if (pfCursorCapabilities != NULL)
+ pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities;
+ }
+ pVBox->fHaveReadHGSMIModeHintData = true;
+#endif
+ if (paModeHints != NULL)
+ for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i)
+ {
+ if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty)
+ {
+ if (paModeHints[i] == -1)
+ pVBox->pScreens[i].afConnected = false;
+ else
+ {
+ pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16;
+ pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff;
+ pVBox->pScreens[i].afConnected = true;
+ }
+ pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i];
+ }
+ }
+ if (pfCursorCapabilities != NULL && *pfCursorCapabilities != pVBox->fLastCursorCapabilitiesFromProperty)
+ {
+ updateUseHardwareCursor(pVBox, (uint32_t)*pfCursorCapabilities);
+ pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities;
+ }
+ if (pVBox->fUseHardwareCursor != fOldUseHardwareCursor)
+ vbvxReprobeCursor(pScrn);
+}
+
+#ifndef VBOXVIDEO_13
+
+/** The RandR "proc" vector, which we wrap with our own in order to notice
+ * when a client sends a GetScreenInfo request. */
+static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL;
+/** The swapped RandR "proc" vector. */
+static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL;
+
+/* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */
+static void vboxRandRDispatchCore(ClientPtr pClient)
+{
+ xRRGetScreenInfoReq *pReq = (xRRGetScreenInfoReq *)pClient->requestBuffer;
+ WindowPtr pWin;
+ ScrnInfoPtr pScrn;
+ VBOXPtr pVBox;
+ DisplayModePtr pMode;
+
+ if (pClient->req_len != sizeof(xRRGetScreenInfoReq) >> 2)
+ return;
+ pWin = (WindowPtr)SecurityLookupWindow(pReq->window, pClient,
+ SecurityReadAccess);
+ if (!pWin)
+ return;
+ pScrn = xf86Screens[pWin->drawable.pScreen->myNum];
+ pVBox = VBOXGetRec(pScrn);
+ TRACE_LOG("pVBox->fUseHardwareCursor=%u\n", pVBox->fUseHardwareCursor);
+ VBoxUpdateSizeHints(pScrn);
+ pMode = pScrn->modes;
+ if (pScrn->currentMode == pMode)
+ pMode = pMode->next;
+ pMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;
+ pMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy;
+}
+
+static int vboxRandRDispatch(ClientPtr pClient)
+{
+ xReq *pReq = (xReq *)pClient->requestBuffer;
+
+ if (pReq->data == X_RRGetScreenInfo)
+ vboxRandRDispatchCore(pClient);
+ return g_pfnVBoxRandRProc(pClient);
+}
+
+static int vboxRandRSwappedDispatch(ClientPtr pClient)
+{
+ xReq *pReq = (xReq *)pClient->requestBuffer;
+
+ if (pReq->data == X_RRGetScreenInfo)
+ vboxRandRDispatchCore(pClient);
+ return g_pfnVBoxRandRSwappedProc(pClient);
+}
+
+static Bool vboxRandRCreateScreenResources(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ ExtensionEntry *pExt;
+
+ pScreen->CreateScreenResources = pVBox->pfnCreateScreenResources;
+ if (!pScreen->CreateScreenResources(pScreen))
+ return FALSE;
+ /* I doubt we can be loaded twice - should I fail here? */
+ if (g_pfnVBoxRandRProc)
+ return TRUE;
+ pExt = CheckExtension(RANDR_NAME);
+ if (!pExt)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "RandR extension not found, disabling dynamic resizing.\n");
+ return TRUE;
+ }
+ if ( !ProcVector[pExt->base]
+#if !defined(XF86_VERSION_CURRENT) \
+ || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0)
+ /* SwappedProcVector is not exported in XFree86, so we will not support
+ * swapped byte order clients. I doubt this is a big issue. */
+ || !SwappedProcVector[pExt->base]
+#endif
+ )
+ FatalError("RandR \"proc\" vector not initialised\n");
+ g_pfnVBoxRandRProc = ProcVector[pExt->base];
+ ProcVector[pExt->base] = vboxRandRDispatch;
+#if !defined(XF86_VERSION_CURRENT) \
+ || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0)
+ g_pfnVBoxRandRSwappedProc = SwappedProcVector[pExt->base];
+ SwappedProcVector[pExt->base] = vboxRandRSwappedDispatch;
+#endif
+ return TRUE;
+}
+
+/** Install our private RandR hook procedure, so that we can detect
+ * GetScreenInfo requests from clients to update our dynamic mode. This works
+ * by installing a wrapper around CreateScreenResources(), which will be called
+ * after RandR is initialised. The wrapper then in turn wraps the RandR "proc"
+ * vectors with its own handlers which will get called on any client RandR
+ * request. This should not be used in conjunction with RandR 1.2 or later.
+ * A couple of points of interest in our RandR 1.1 support:
+ * * We use the first two screen modes as dynamic modes. When a new mode hint
+ * arrives we update the first of the two which is not the current mode with
+ * the new size.
+ * * RandR 1.1 always advertises a mode of the size of the initial virtual
+ * resolution via GetScreenInfo(), so we make sure that a mode of that size
+ * is always present in the list.
+ * * RandR adds each new mode it sees to an internal array, but never removes
+ * entries. This array might end up getting rather long given that we can
+ * report a lot more modes than physical hardware.
+ */
+void VBoxSetUpRandR11(ScreenPtr pScreen)
+{
+ VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
+
+ if (!pScreen->CreateScreenResources)
+ FatalError("called to early: CreateScreenResources not yet initialised\n");
+ pVBox->pfnCreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = vboxRandRCreateScreenResources;
+}
+
+#endif /* !VBOXVIDEO_13 */
+
+#ifdef VBOXVIDEO_13
+# ifdef RT_OS_LINUX
+/* TESTING: dynamic resizing works on recent Linux guest X servers at the log-in screen. */
+/** @note to maximise code coverage we only read data from HGSMI once, and only when responding to an ACPI event. */
+static void acpiEventHandler(int fd, void *pvData)
+{
+ ScreenPtr pScreen = (ScreenPtr)pvData;
+ VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
+ struct input_event event;
+ ssize_t rc;
+
+ pVBox->fHaveReadHGSMIModeHintData = false;
+ RRGetInfo(pScreen
+# if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
+ , TRUE
+# endif
+ );
+ VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n"));
+ do
+ rc = read(fd, &event, sizeof(event));
+ while (rc > 0 || (rc == -1 && errno == EINTR));
+ /* Why do they return EAGAIN instead of zero bytes read like everyone else does? */
+ VBVXASSERT(rc != -1 || errno == EAGAIN, ("Reading ACPI input event failed.\n"));
+}
+
+void VBoxSetUpLinuxACPI(ScreenPtr pScreen)
+{
+ VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
+ struct dirent *pDirent;
+ DIR *pDir;
+ int fd = -1;
+
+ if (pVBox->fdACPIDevices != -1 || pVBox->hACPIEventHandler != NULL)
+ FatalError("ACPI input file descriptor not initialised correctly.\n");
+ pDir = opendir("/dev/input");
+ if (pDir == NULL)
+ return;
+ for (pDirent = readdir(pDir); pDirent != NULL; pDirent = readdir(pDir))
+ {
+ if (strncmp(pDirent->d_name, "event", sizeof("event") - 1) == 0)
+ {
+#define BITS_PER_BLOCK (sizeof(unsigned long) * 8)
+ char szFile[64] = "/dev/input/";
+ char szDevice[64] = "";
+ unsigned long afKeys[KEY_MAX / BITS_PER_BLOCK];
+
+ strncat(szFile, pDirent->d_name, sizeof(szFile) - sizeof("/dev/input/"));
+ if (fd != -1)
+ close(fd);
+ fd = open(szFile, O_RDONLY | O_NONBLOCK);
+ if ( fd == -1
+ || ioctl(fd, EVIOCGNAME(sizeof(szDevice)), szDevice) == -1
+ || strcmp(szDevice, "Video Bus") != 0)
+ continue;
+ if ( ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(afKeys)), afKeys) == -1
+ || (( afKeys[KEY_SWITCHVIDEOMODE / BITS_PER_BLOCK]
+ >> KEY_SWITCHVIDEOMODE % BITS_PER_BLOCK) & 1) == 0)
+ break;
+ if (ioctl(fd, EVIOCGRAB, (void *)1) != 0)
+ break;
+ pVBox->hACPIEventHandler
+ = xf86AddGeneralHandler(fd, acpiEventHandler, pScreen);
+ if (pVBox->hACPIEventHandler == NULL)
+ break;
+ pVBox->fdACPIDevices = fd;
+ fd = -1;
+ break;
+#undef BITS_PER_BLOCK
+ }
+ }
+ if (fd != -1)
+ close(fd);
+ closedir(pDir);
+}
+
+void VBoxCleanUpLinuxACPI(ScreenPtr pScreen)
+{
+ VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
+ if (pVBox->fdACPIDevices != -1)
+ close(pVBox->fdACPIDevices);
+ pVBox->fdACPIDevices = -1;
+ xf86RemoveGeneralHandler(pVBox->hACPIEventHandler);
+ pVBox->hACPIEventHandler = NULL;
+}
+# endif /* RT_OS_LINUX */
+#endif /* VBOXVIDEO_13 */
diff --git a/src/VBox/Additions/x11/vboxvideo/helpers.c b/src/VBox/Additions/x11/vboxvideo/helpers.c
new file mode 100644
index 0000000..aa20384
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxvideo/helpers.c
@@ -0,0 +1,91 @@
+/* $Id: helpers.c $ */
+/** @file
+ * VirtualBox X11 Additions graphics driver X server helper functions
+ *
+ * This file contains helpers which call back into the X server. The longer-
+ * term idea is to eliminate X server version dependencies in as many files as
+ * possible inside the driver code. Ideally most files should not directly
+ * depend on X server symbols at all.
+ */
+
+/*
+ * Copyright (C) 2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "vboxvideo.h"
+#include <os.h>
+#include <propertyst.h>
+#include <windowstr.h>
+#include <xf86.h>
+#include <X11/Xatom.h>
+#ifdef XORG_7X
+# include <string.h>
+#endif
+
+void vbvxMsg(const char *pszFormat, ...)
+{
+ va_list args;
+
+ va_start(args, pszFormat);
+ VErrorF(pszFormat, args);
+ va_end(args);
+}
+
+void vbvxMsgV(const char *pszFormat, va_list args)
+{
+ VErrorF(pszFormat, args);
+}
+
+void vbvxAbortServer(void)
+{
+ FatalError("Assertion");
+}
+
+VBOXPtr vbvxGetRec(ScrnInfoPtr pScrn)
+{
+ return ((VBOXPtr)pScrn->driverPrivate);
+}
+
+/* TESTING: if this is broken, dynamic resizing will not work on old X servers (1.2 and older). */
+int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData)
+{
+ Atom atom;
+ PropertyPtr prop;
+
+ /* We can get called early, before the root window is created. */
+ if (!ROOT_WINDOW(pScrn))
+ return VERR_NOT_FOUND;
+ atom = MakeAtom(pszName, strlen(pszName), FALSE);
+ if (atom == BAD_RESOURCE)
+ return VERR_NOT_FOUND;
+ for (prop = wUserProps(ROOT_WINDOW(pScrn));
+ prop != NULL && prop->propertyName != atom; prop = prop->next);
+ if (prop == NULL)
+ return VERR_NOT_FOUND;
+ if (prop->type != XA_INTEGER || prop->format != 32)
+ return VERR_NOT_FOUND;
+ *pcData = prop->size;
+ *ppaData = (int32_t *)prop->data;
+ return VINF_SUCCESS;
+}
+
+void vbvxReprobeCursor(ScrnInfoPtr pScrn)
+{
+ if (ROOT_WINDOW(pScrn) == NULL)
+ return;
+#ifdef XF86_SCRN_INTERFACE
+ pScrn->EnableDisableFBAccess(pScrn, FALSE);
+ pScrn->EnableDisableFBAccess(pScrn, TRUE);
+#else
+ pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+ pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+#endif
+}
diff --git a/src/VBox/Additions/x11/vboxvideo/pointer.c b/src/VBox/Additions/x11/vboxvideo/pointer.c
index 45fceca..1b9be84 100644
--- a/src/VBox/Additions/x11/vboxvideo/pointer.c
+++ b/src/VBox/Additions/x11/vboxvideo/pointer.c
@@ -14,7 +14,6 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <VBox/VMMDev.h>
#include <VBox/VBoxGuestLib.h>
#ifndef PCIACCESS
@@ -111,58 +110,6 @@ vbox_show_shape(unsigned short w, unsigned short h, CARD32 bg, unsigned char *im
#endif
/**************************************************************************
-* Helper functions and macros *
-**************************************************************************/
-
-/* This is called by the X server every time it loads a new cursor to see
- * whether our "cursor hardware" can handle the cursor. This provides us with
- * a mechanism (the only one!) to switch back from a software to a hardware
- * cursor. */
-static Bool
-vbox_host_uses_hwcursor(ScrnInfoPtr pScrn)
-{
- Bool rc = TRUE;
- uint32_t fFeatures = 0;
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- /* We may want to force the use of a software cursor. Currently this is
- * needed if the guest uses a large virtual resolution, as in this case
- * the host and guest tend to disagree about the pointer location. */
- if (pVBox->forceSWCursor)
- rc = FALSE;
- /* Query information about mouse integration from the host. */
- if (rc) {
- int vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
- if (RT_FAILURE(vrc)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unable to determine whether the virtual machine supports mouse pointer integration - request initialization failed with return code %d\n", vrc);
- rc = FALSE;
- }
- }
- /* If we got the information from the host then make sure the host wants
- * to draw the pointer. */
- if (rc)
- {
- if ( (fFeatures & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
-#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
- /* As of this version (server 1.6) all major Linux releases
- * are known to handle USB tablets correctly. */
- || (fFeatures & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
-#endif
- )
- /* Assume this will never be unloaded as long as the X session is
- * running. */
- pVBox->guestCanAbsolute = TRUE;
- if ( (fFeatures & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
- || !pVBox->guestCanAbsolute
- || !(fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
- )
- rc = FALSE;
- }
- return rc;
-}
-
-/**************************************************************************
* Main functions *
**************************************************************************/
@@ -176,40 +123,13 @@ vbox_close(ScrnInfoPtr pScrn, VBOXPtr pVBox)
TRACE_EXIT();
}
-Bool
-vbox_init(int scrnIndex, VBOXPtr pVBox)
-{
- Bool rc = TRUE;
- int vrc;
- uint32_t fMouseFeatures = 0;
-
- TRACE_ENTRY();
- vrc = VbglR3Init();
- if (RT_FAILURE(vrc))
- {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Failed to initialize the VirtualBox device (rc=%d) - make sure that the VirtualBox guest additions are properly installed. If you are not sure, try reinstalling them. The X Window graphics drivers will run in compatibility mode.\n",
- vrc);
- rc = FALSE;
- }
- pVBox->useDevice = rc;
- return rc;
-}
-
static void
vbox_vmm_hide_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
{
int rc;
rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, 0, 0, 0, 0, 0, NULL, 0);
- if (RT_FAILURE(rc))
- {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not hide the virtual mouse pointer, VBox error %d.\n", rc);
- /* Play safe, and disable the hardware cursor until the next mode
- * switch, since obviously something happened that we didn't
- * anticipate. */
- pVBox->forceSWCursor = TRUE;
- }
+ VBVXASSERT(rc == VINF_SUCCESS, ("Could not hide the virtual mouse pointer, VBox error %d.\n", rc));
}
static void
@@ -217,17 +137,11 @@ vbox_vmm_show_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
{
int rc;
- if (!vbox_host_uses_hwcursor(pScrn))
+ if (!pVBox->fUseHardwareCursor)
return;
rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, VBOX_MOUSE_POINTER_VISIBLE,
0, 0, 0, 0, NULL, 0);
- if (RT_FAILURE(rc)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
- /* Play safe, and disable the hardware cursor until the next mode
- * switch, since obviously something happened that we didn't
- * anticipate. */
- pVBox->forceSWCursor = TRUE;
- }
+ VBVXASSERT(rc == VINF_SUCCESS, ("Could not unhide the virtual mouse pointer.\n"));
}
static void
@@ -245,13 +159,7 @@ vbox_vmm_load_cursor_image(ScrnInfoPtr pScrn, VBOXPtr pVBox,
rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, pImage->fFlags,
pImage->cHotX, pImage->cHotY, pImage->cWidth, pImage->cHeight,
pImage->pPixels, pImage->cbLength);
- if (RT_FAILURE(rc)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to set the virtual mouse pointer image.\n");
- /* Play safe, and disable the hardware cursor until the next mode
- * switch, since obviously something happened that we didn't
- * anticipate. */
- pVBox->forceSWCursor = TRUE;
- }
+ VBVXASSERT(rc == VINF_SUCCESS, ("Unable to set the virtual mouse pointer image.\n"));
}
static void
@@ -267,11 +175,10 @@ vbox_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
static void
vbox_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
{
- /* Nothing to do here, as we are telling the guest where the mouse is,
- * not vice versa. */
- NOREF(pScrn);
- NOREF(x);
- NOREF(y);
+ VBOXPtr pVBox = pScrn->driverPrivate;
+
+ /* This currently does nothing. */
+ VBoxHGSMICursorPosition(&pVBox->guestCtx, true, x, y, NULL, NULL);
}
static void
@@ -302,7 +209,8 @@ static Bool
vbox_use_hw_cursor(ScreenPtr pScreen, CursorPtr pCurs)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- return vbox_host_uses_hwcursor(pScrn);
+ VBOXPtr pVBox = pScrn->driverPrivate;
+ return pVBox->fUseHardwareCursor;
}
static unsigned char
@@ -435,23 +343,15 @@ static Bool
vbox_use_hw_cursor_argb(ScreenPtr pScreen, CursorPtr pCurs)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- Bool rc = TRUE;
+ VBOXPtr pVBox = pScrn->driverPrivate;
- if (!vbox_host_uses_hwcursor(pScrn))
- rc = FALSE;
- if ( rc
- && ( (pCurs->bits->height > VBOX_MAX_CURSOR_HEIGHT)
- || (pCurs->bits->width > VBOX_MAX_CURSOR_WIDTH)
- || (pScrn->bitsPerPixel <= 8)
- )
- )
- rc = FALSE;
-#ifndef VBOXVIDEO_13
- /* Evil hack - we use this as another way of poking the driver to update
- * our list of video modes. */
- vboxWriteHostModes(pScrn, pScrn->currentMode);
-#endif
- return rc;
+ if (!pVBox->fUseHardwareCursor)
+ return FALSE;
+ if ( (pCurs->bits->height > VBOX_MAX_CURSOR_HEIGHT)
+ || (pCurs->bits->width > VBOX_MAX_CURSOR_WIDTH)
+ || (pScrn->bitsPerPixel <= 8))
+ return FALSE;
+ return TRUE;
}
@@ -531,8 +431,8 @@ vbox_load_cursor_argb(ScrnInfoPtr pScrn, CursorPtr pCurs)
pm += (w + 7) / 8;
}
- rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, fFlags, bitsp->xhot,
- bitsp->yhot, w, h, p, sizeData);
+ VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, fFlags, bitsp->xhot,
+ bitsp->yhot, w, h, p, sizeData);
free(p);
}
#endif
@@ -546,8 +446,6 @@ vbox_cursor_init(ScreenPtr pScreen)
Bool rc = TRUE;
TRACE_ENTRY();
- if (!pVBox->fHaveHGSMI)
- return FALSE;
pVBox->pCurs = pCurs = xf86CreateCursorInfoRec();
if (!pCurs) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -574,10 +472,6 @@ vbox_cursor_init(ScreenPtr pScreen)
pCurs->LoadCursorARGB = vbox_load_cursor_argb;
#endif
- /* Hide the host cursor before we initialise if we wish to use a
- * software cursor. */
- if (pVBox->forceSWCursor)
- vbox_vmm_hide_cursor(pScrn, pVBox);
rc = xf86InitCursor(pScreen, pCurs);
}
if (!rc)
diff --git a/src/VBox/Additions/x11/vboxvideo/setmode.c b/src/VBox/Additions/x11/vboxvideo/setmode.c
index 7e082f8..2c8cb4e 100644
--- a/src/VBox/Additions/x11/vboxvideo/setmode.c
+++ b/src/VBox/Additions/x11/vboxvideo/setmode.c
@@ -99,6 +99,9 @@ Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
{
VBOXPtr pVBox = VBOXGetRec(pScrn);
uint32_t offStart, cwReal = cWidth;
+ bool fEnabled;
+ uint16_t fFlags;
+ int rc;
TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
@@ -115,21 +118,26 @@ Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
return FALSE;
else
cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x);
- TRACE_LOG("pVBox->afDisabled[%u]=%d\n",
- cDisplay, (int)pVBox->afDisabled[cDisplay]);
+ TRACE_LOG("pVBox->pScreens[%u].fCrtcEnabled=%d, fOutputEnabled=%d\n",
+ cDisplay, (int)pVBox->pScreens[cDisplay].fCrtcEnabled,
+ (int)pVBox->pScreens[cDisplay].fOutputEnabled);
if (cDisplay == 0)
VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth,
vboxBPP(pScrn), 0, x, y);
- /* Tell the host we support graphics */
- if (vbox_device_available(pVBox))
- vboxEnableGraphicsCap(pVBox);
- if (pVBox->fHaveHGSMI)
+ fEnabled = pVBox->pScreens[cDisplay].fCrtcEnabled
+ && pVBox->pScreens[cDisplay].fOutputEnabled;
+ fFlags = VBVA_SCREEN_F_ACTIVE;
+ fFlags |= (pVBox->pScreens[cDisplay].afConnected ? 0
+ : VBVA_SCREEN_F_DISABLED);
+ VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
+ offStart, pVBox->cbLine, cwReal, cHeight,
+ fEnabled ? vboxBPP(pScrn) : 0, fFlags);
+ if (cDisplay == 0)
{
- uint16_t fFlags = VBVA_SCREEN_F_ACTIVE;
- fFlags |= (pVBox->afDisabled[cDisplay] ? VBVA_SCREEN_F_DISABLED : 0);
- VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
- offStart, pVBox->cbLine, cwReal, cHeight,
- vboxBPP(pScrn), fFlags);
+ rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x,
+ 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY);
+ if (RT_FAILURE(rc))
+ FatalError("Failed to update the input mapping.\n");
}
return TRUE;
}
@@ -144,6 +152,7 @@ Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
VBOXPtr pVBox = VBOXGetRec(pScrn);
uint64_t cbLine = vboxLineLength(pScrn, width);
int displayWidth = vboxDisplayPitch(pScrn, cbLine);
+ int rc;
TRACE_LOG("width=%d, height=%d\n", width, height);
if ( width == pScrn->virtualX
@@ -176,14 +185,20 @@ Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
#endif
#ifdef VBOXVIDEO_13
/* Write the new values to the hardware */
+ /** @todo why is this only for VBOXVIDEO_13? */
{
unsigned i;
for (i = 0; i < pVBox->cScreens; ++i)
- VBOXSetMode(pScrn, i, pVBox->aScreenLocation[i].cx,
- pVBox->aScreenLocation[i].cy,
- pVBox->aScreenLocation[i].x,
- pVBox->aScreenLocation[i].y);
+ VBOXSetMode(pScrn, i, pVBox->pScreens[i].aScreenLocation.cx,
+ pVBox->pScreens[i].aScreenLocation.cy,
+ pVBox->pScreens[i].aScreenLocation.x,
+ pVBox->pScreens[i].aScreenLocation.y);
}
+#else
+ rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x,
+ 0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY);
+ if (RT_FAILURE(rc))
+ FatalError("Failed to update the input mapping.\n");
#endif
#ifdef RT_OS_SOLARIS
/* Tell the virtual mouse device about the new virtual desktop size. */
diff --git a/src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk
deleted file mode 100644
index 701c7bf..0000000
--- a/src/VBox/Additions/x11/vboxvideo/testcase/Makefile.kmk
+++ /dev/null
@@ -1,48 +0,0 @@
-# $Id: Makefile.kmk $
-## @file
-# Sub-Makefile for the vboxvideo testcases.
-#
-
-#
-# Copyright (C) 2006-2012 Oracle Corporation
-#
-# This file is part of VirtualBox Open Source Edition (OSE), as
-# available from http://www.virtualbox.org. This file is free software;
-# you can redistribute it and/or modify it under the terms of the GNU
-# General Public License (GPL) as published by the Free Software
-# Foundation, in version 2 as it comes in the "COPYING" file of the
-# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-#
-
-SUB_DEPTH = ../../../..
-include $(KBUILD_PATH)/subheader.kmk
-
-#
-# Target
-#
-ifndef VBOX_ONLY_SDK
- ifndef VBOX_ONLY_ADDITIONS
- if defined(VBOX_WITH_TESTCASES)
- PROGRAMS += \
- tstSetModeXOrg
- endif # !VBOX_WITH_TESTCASES
- endif #!VBOX_ONLY_ADDITIONS
-endif # !VBOX_ONLY_SDK
-
-
-#
-# tstSetModeXOrg
-#
-tstSetModeXOrg_TEMPLATE = VBOXR3TSTEXE
-tstSetModeXOrg_CFLAGS += -std=c99
-tstSetModeXOrg_DEFS = $(filter-out IN_RT_STATIC,$(vboxvideo_drv_15_DEFS)) TESTCASE
-tstSetModeXOrg_SOURCES = \
- tstSetModeXOrg.c \
- ../setmode.c
-tstSetModeXOrg_INCS = $(vboxvideo_drv_15_INCS)
-
-
-# generate rules.
-include $(FILE_KBUILD_SUB_FOOTER)
-
diff --git a/src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c b/src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c
deleted file mode 100644
index b30a35b..0000000
--- a/src/VBox/Additions/x11/vboxvideo/testcase/tstSetModeXOrg.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* $Id: tstSetModeXOrg.c $ */
-/** @file
- * vboxvideo unit test - modesetting.
- */
-
-/*
- * Copyright (C) 2011 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-/*******************************************************************************
-* Header Files *
-*******************************************************************************/
-
-#include "../vboxvideo.h"
-
-#include <VBox/VBoxVideoGuest.h>
-
-#include <iprt/assert.h>
-#include <iprt/err.h>
-#include <iprt/test.h>
-
-#include <xf86.h>
-
-void xf86Msg(MessageType type, const char *format, ...) {}
-void xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...) {}
-
-static ScrnInfoRec scrnInfo[1];
-static ScrnInfoPtr pScrns[1] = { &scrnInfo[0] };
-ScrnInfoPtr *xf86Screens = pScrns;
-
-Bool vbox_device_available(VBOXPtr pVBox)
-{
- return TRUE;
-}
-
-Bool vboxEnableGraphicsCap(VBOXPtr pVBox)
-{
- return TRUE;
-}
-
-void VBOXDRIUpdateStride(ScrnInfoPtr pScrn, VBOXPtr pVBox) {}
-
-static struct
-{
- uint16_t cWidth;
- uint16_t cHeight;
- uint16_t cVirtWidth;
- uint16_t cBPP;
- uint16_t fFlags;
- uint16_t cx;
- uint16_t cy;
-} s_ModeRegs;
-
-RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
- uint16_t cVirtWidth, uint16_t cBPP,
- uint16_t fFlags,
- uint16_t cx, uint16_t cy)
-{
- s_ModeRegs.cWidth = cWidth;
- s_ModeRegs.cHeight = cHeight;
- s_ModeRegs.cVirtWidth = cVirtWidth;
- s_ModeRegs.cBPP = cBPP;
- s_ModeRegs.fFlags = fFlags;
- s_ModeRegs.cx = cx;
- s_ModeRegs.cy = cy;
-}
-
-static struct
-{
- PHGSMIGUESTCOMMANDCONTEXT pCtx;
- uint32_t cDisplay;
- int32_t cOriginX;
- int32_t cOriginY;
- uint32_t offStart;
- uint32_t cbPitch;
- uint32_t cWidth;
- uint32_t cHeight;
- uint16_t cBPP;
- uint16_t fFlags;
-} s_DisplayInfo;
-
-void VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
- uint32_t cDisplay, int32_t cOriginX,
- int32_t cOriginY, uint32_t offStart,
- uint32_t cbPitch, uint32_t cWidth,
- uint32_t cHeight, uint16_t cBPP,
- uint16_t fFlags)
-{
- s_DisplayInfo.pCtx = pCtx;
- s_DisplayInfo.cDisplay = cDisplay;
- s_DisplayInfo.cOriginX = cOriginX;
- s_DisplayInfo.cOriginY = cOriginY;
- s_DisplayInfo.offStart = offStart;
- s_DisplayInfo.cbPitch = cbPitch;
- s_DisplayInfo.cWidth = cWidth;
- s_DisplayInfo.cHeight = cHeight;
- s_DisplayInfo.cBPP = cBPP;
- s_DisplayInfo.fFlags = fFlags;
-}
-
-
-static int setup(void)
-{
- return VINF_SUCCESS;
-}
-
-static void teardown(void)
-{
-}
-
-int main(void)
-{
- /*
- * Init the runtime, test and say hello.
- */
- RTTEST hTest;
- RTEXITCODE rcExit = RTTestInitAndCreate("tstVBoxVideoXOrg", &hTest);
- if (rcExit != RTEXITCODE_SUCCESS)
- return rcExit;
- RTTestBanner(hTest);
-
- /*
- * Run the tests.
- */
- AssertRC(setup());
- teardown();
-
- /*
- * Summary
- */
- return RTTestSummaryAndDestroy(hTest);
-}
-
diff --git a/src/VBox/Additions/x11/vboxvideo/undefined b/src/VBox/Additions/x11/vboxvideo/undefined
index d4413ed..84a570e 100644
--- a/src/VBox/Additions/x11/vboxvideo/undefined
+++ b/src/VBox/Additions/x11/vboxvideo/undefined
@@ -1,3 +1,5 @@
+ChangeWindowProperty
+CheckExtension
DRI2CloseScreen
DRI2ScreenInit
DRICloseScreen
@@ -13,11 +15,16 @@ ErrorF
FatalError
GlxSetVisualConfigs
LoaderRefSymLists
+LookupWindow
MakeAtom
PixmapWidthPaddingInfo
+ProcVector
RRChangeOutputProperty
+SecurityLookupWindow
+SwappedProcVector
ShadowFBInit2
VErrorF
+WindowTable
XNFcalloc
XNFstrdup
Xalloc
@@ -173,6 +180,7 @@ xf86OutputUseScreenMonitor
xf86PrintChipsets
xf86PrintDepthBpp
xf86PrintModes
+xf86RegisterRootWindowProperty
xf86SaveScreen
xf86ScreenToScrn
xf86Screens
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxutils.c b/src/VBox/Additions/x11/vboxvideo/vboxutils.c
deleted file mode 100644
index a18ac10..0000000
--- a/src/VBox/Additions/x11/vboxvideo/vboxutils.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* $Id: vboxutils.c $ */
-/** @file
- * VirtualBox X11 Additions graphics driver utility functions
- */
-
-/*
- * Copyright (C) 2006-2012 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include <VBox/VMMDev.h>
-#include <VBox/VBoxGuestLib.h>
-
-#ifndef PCIACCESS
-# include <xf86Pci.h>
-# include <Pci.h>
-#endif
-
-#include "xf86.h"
-#define NEED_XF86_TYPES
-#include <iprt/string.h>
-#include "compiler.h"
-
-#include "vboxvideo.h"
-
-#ifdef XORG_7X
-# include <stdio.h>
-# include <stdlib.h>
-#endif
-
-/**************************************************************************
-* Main functions *
-**************************************************************************/
-
-/**
- * Inform VBox that we are aware of advanced graphics functions
- * (i.e. dynamic resizing, seamless).
- *
- * @returns TRUE for success, FALSE for failure
- */
-Bool
-vboxEnableGraphicsCap(VBOXPtr pVBox)
-{
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- return FALSE;
- return RT_SUCCESS(VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0));
-}
-
-/**
- * Inform VBox that we are no longer aware of advanced graphics functions
- * (i.e. dynamic resizing, seamless).
- *
- * @returns TRUE for success, FALSE for failure
- */
-Bool
-vboxDisableGraphicsCap(VBOXPtr pVBox)
-{
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- return FALSE;
- return RT_SUCCESS(VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
-}
-
-/**
- * Query the last display change request.
- *
- * @returns boolean success indicator.
- * @param pScrn Pointer to the X screen info structure.
- * @param pcx Where to store the horizontal pixel resolution (0 = do not change).
- * @param pcy Where to store the vertical pixel resolution (0 = do not change).
- * @param pcBits Where to store the bits per pixel (0 = do not change).
- * @param iDisplay Where to store the display number the request was for - 0 for the
- * primary display, 1 for the first secondary, etc.
- */
-Bool
-vboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy,
- uint32_t *pcBits, uint32_t *piDisplay)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- return FALSE;
- int rc = VbglR3GetDisplayChangeRequest(pcx, pcy, pcBits, piDisplay, false);
- if (RT_SUCCESS(rc))
- return TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to obtain the last resolution requested by the guest, rc=%d.\n", rc);
- return FALSE;
-}
-
-
-/**
- * Query the host as to whether it likes a specific video mode.
- *
- * @returns the result of the query
- * @param cx the width of the mode being queried
- * @param cy the height of the mode being queried
- * @param cBits the bpp of the mode being queried
- */
-Bool
-vboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- return TRUE; /* If we can't ask the host then we like everything. */
- return VbglR3HostLikesVideoMode(cx, cy, cBits);
-}
-
-/**
- * Check if any seamless mode is enabled.
- * Seamless is only relevant for the newer Xorg modules.
- *
- * @returns the result of the query
- * (true = seamless enabled, false = seamless not enabled)
- * @param pScrn Screen info pointer.
- */
-Bool
-vboxGuestIsSeamless(ScrnInfoPtr pScrn)
-{
- VMMDevSeamlessMode mode;
- VBOXPtr pVBox = pScrn->driverPrivate;
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- return FALSE;
- if (RT_FAILURE(VbglR3SeamlessGetLastEvent(&mode)))
- return FALSE;
- return (mode != VMMDev_Seamless_Disabled);
-}
-
-/**
- * Save video mode parameters to the registry.
- *
- * @returns iprt status value
- * @param pszName the name to save the mode parameters under
- * @param cx mode width
- * @param cy mode height
- * @param cBits bits per pixel for the mode
- */
-Bool
-vboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- return FALSE;
- return RT_SUCCESS(VbglR3SaveVideoMode("SavedMode", cx, cy, cBits));
-}
-
-/**
- * Retrieve video mode parameters from the registry.
- *
- * @returns iprt status value
- * @param pszName the name under which the mode parameters are saved
- * @param pcx where to store the mode width
- * @param pcy where to store the mode height
- * @param pcBits where to store the bits per pixel for the mode
- */
-Bool
-vboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
- int rc;
- TRACE_ENTRY();
- if (!pVBox->useDevice)
- rc = VERR_NOT_AVAILABLE;
- else
- rc = VbglR3RetrieveVideoMode("SavedMode", pcx, pcy, pcBits);
- if (RT_SUCCESS(rc))
- TRACE_LOG("Retrieved a video mode of %dx%dx%d\n", *pcx, *pcy, *pcBits);
- else
- TRACE_LOG("Failed to retrieve video mode, error %d\n", rc);
- return (RT_SUCCESS(rc));
-}
-
-/**
- * Fills a display mode M with a built-in mode of name pszName and dimensions
- * cx and cy.
- */
-static void vboxFillDisplayMode(ScrnInfoPtr pScrn, DisplayModePtr m,
- const char *pszName, unsigned cx, unsigned cy)
-{
- VBOXPtr pVBox = pScrn->driverPrivate;
- TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy);
- m->status = MODE_OK;
- m->type = M_T_BUILTIN;
- /* Older versions of VBox only support screen widths which are a multiple
- * of 8 */
- if (pVBox->fAnyX)
- m->HDisplay = cx;
- else
- m->HDisplay = cx & ~7;
- m->HSyncStart = m->HDisplay + 2;
- m->HSyncEnd = m->HDisplay + 4;
- m->HTotal = m->HDisplay + 6;
- m->VDisplay = cy;
- m->VSyncStart = m->VDisplay + 2;
- m->VSyncEnd = m->VDisplay + 4;
- m->VTotal = m->VDisplay + 6;
- m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */
- if (pszName)
- {
- if (m->name)
- free((void*)m->name);
- m->name = xnfstrdup(pszName);
- }
-}
-
-/** vboxvideo's list of standard video modes */
-struct
-{
- /** mode width */
- uint32_t cx;
- /** mode height */
- uint32_t cy;
-} vboxStandardModes[] =
-{
- { 1600, 1200 },
- { 1440, 1050 },
- { 1280, 960 },
- { 1024, 768 },
- { 800, 600 },
- { 640, 480 },
- { 0, 0 }
-};
-enum
-{
- vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])
-};
-
-/**
- * Returns a standard mode which the host likes. Can be called multiple
- * times with the index returned by the previous call to get a list of modes.
- * @returns the index of the mode in the list, or 0 if no more modes are
- * available
- * @param pScrn the screen information structure
- * @param pScrn->bitsPerPixel
- * if this is non-null, only modes with this BPP will be
- * returned
- * @param cIndex the index of the last mode queried, or 0 to query the
- * first mode available. Note: the first index is 1
- * @param pcx where to store the mode's width
- * @param pcy where to store the mode's height
- * @param pcBits where to store the mode's BPP
- */
-unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
- uint32_t *pcx, uint32_t *pcy,
- uint32_t *pcBits)
-{
- unsigned i;
-
- XF86ASSERT(cIndex < vboxNumStdModes,
- ("cIndex = %d, vboxNumStdModes = %d\n", cIndex,
- vboxNumStdModes));
- for (i = cIndex; i < vboxNumStdModes - 1; ++i)
- {
- uint32_t cBits = pScrn->bitsPerPixel;
- uint32_t cx = vboxStandardModes[i].cx;
- uint32_t cy = vboxStandardModes[i].cy;
-
- if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits))
- continue;
- if (vboxHostLikesVideoMode(pScrn, cx, cy, 32))
- cBits = 32;
- else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16))
- cBits = 16;
- else
- continue;
- if (pcx)
- *pcx = cx;
- if (pcy)
- *pcy = cy;
- if (pcBits)
- *pcBits = cBits;
- return i + 1;
- }
- return 0;
-}
-
-/**
- * Returns the preferred video mode. The current order of preference is
- * (from highest to least preferred):
- * - The mode corresponding to the last size hint from the host
- * - The video mode saved from the last session
- * - The largest standard mode which the host likes, falling back to
- * 640x480x32 as a worst case
- * - If the host can't be contacted at all, we return 1024x768x32
- *
- * The return type is void as we guarantee we will return some mode.
- */
-void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen, uint32_t *pcx,
- uint32_t *pcy, uint32_t *pcBits)
-{
- /* Query the host for the preferred resolution and colour depth */
- uint32_t cx = 0, cy = 0, iScreenIn = iScreen, cBits = 32;
- VBOXPtr pVBox = pScrn->driverPrivate;
-
- TRACE_LOG("iScreen=%u\n", iScreen);
- bool found = false;
- if ( pVBox->aPreferredSize[iScreen].cx
- && pVBox->aPreferredSize[iScreen].cy)
- {
- cx = pVBox->aPreferredSize[iScreen].cx;
- cy = pVBox->aPreferredSize[iScreen].cy;
- found = true;
- }
- if (pVBox->useDevice)
- {
- if (!found)
- found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits,
- &iScreenIn);
- if ((cx == 0) || (cy == 0) || iScreenIn != iScreen)
- found = false;
- if (!found)
- found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits);
- if ((cx == 0) || (cy == 0))
- found = false;
- if (!found)
- found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0);
- if (!found)
- {
- /* Last resort */
- cx = 640;
- cy = 480;
- cBits = 32;
- }
- }
- else
- {
- cx = 1024;
- cy = 768;
- }
- if (pcx)
- *pcx = cx;
- if (pcy)
- *pcy = cy;
- if (pcBits)
- *pcBits = cBits;
- TRACE_LOG("cx=%u, cy=%u, cBits=%u\n", cx, cy, cBits);
-}
-
-/* Move a screen mode found to the end of the list, so that RandR will give
- * it the highest priority when a mode switch is requested. Returns the mode
- * that was previously before the mode in the list in order to allow the
- * caller to continue walking the list. */
-static DisplayModePtr vboxMoveModeToFront(ScrnInfoPtr pScrn,
- DisplayModePtr pMode)
-{
- DisplayModePtr pPrev = pMode->prev;
- if (pMode != pScrn->modes)
- {
- pMode->prev->next = pMode->next;
- pMode->next->prev = pMode->prev;
- pMode->next = pScrn->modes;
- pMode->prev = pScrn->modes->prev;
- pMode->next->prev = pMode;
- pMode->prev->next = pMode;
- pScrn->modes = pMode;
- }
- return pPrev;
-}
-
-/**
- * Rewrites the first dynamic mode found which is not the current screen mode
- * to contain the host's currently preferred screen size, then moves that
- * mode to the front of the screen information structure's mode list.
- * Additionally, if the current mode is not dynamic, the second dynamic mode
- * will be set to match the current mode and also added to the front. This
- * ensures that the user can always reset the current size to kick the driver
- * to update its mode list.
- */
-void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent)
-{
- uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 0;
- DisplayModePtr pMode;
- bool found = false;
-
- TRACE_ENTRY();
- vboxGetPreferredMode(pScrn, 0, &cx, &cy, &cBits);
-#ifdef DEBUG
- /* Count the number of modes for sanity */
- unsigned cModes = 1, cMode = 0;
- DisplayModePtr pCount;
- for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes)
- if (pCount->next == pScrn->modes)
- break;
-#endif
- for (pMode = pScrn->modes; ; pMode = pMode->next)
- {
-#ifdef DEBUG
- XF86ASSERT (cMode++ < cModes, (NULL));
-#endif
- if ( pMode != pCurrent
- && !strcmp(pMode->name, "VBoxDynamicMode"))
- {
- if (!found)
- vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy);
- else if (pCurrent)
- vboxFillDisplayMode(pScrn, pMode, NULL, pCurrent->HDisplay,
- pCurrent->VDisplay);
- found = true;
- pMode = vboxMoveModeToFront(pScrn, pMode);
- }
- if (pMode->next == pScrn->modes)
- break;
- }
- XF86ASSERT (found,
- ("vboxvideo: no free dynamic mode found. Exiting.\n"));
- XF86ASSERT ( (pScrn->modes->HDisplay == (long) cx)
- || ( (pScrn->modes->HDisplay == pCurrent->HDisplay)
- && (pScrn->modes->next->HDisplay == (long) cx)),
- ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n",
- pScrn->modes->HDisplay, pScrn->modes->next->HDisplay));
- XF86ASSERT ( (pScrn->modes->VDisplay == (long) cy)
- || ( (pScrn->modes->VDisplay == pCurrent->VDisplay)
- && (pScrn->modes->next->VDisplay == (long) cy)),
- ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n",
- pScrn->modes->VDisplay, pScrn->modes->next->VDisplay));
-}
-
-/**
- * Allocates an empty display mode and links it into the doubly linked list of
- * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated
- * memory.
- */
-static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)
-{
- DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
-
- TRACE_ENTRY();
- if (!pScrn->modes)
- {
- pScrn->modes = pMode;
- pMode->next = pMode;
- pMode->prev = pMode;
- }
- else
- {
- pMode->next = pScrn->modes;
- pMode->prev = pScrn->modes->prev;
- pMode->next->prev = pMode;
- pMode->prev->next = pMode;
- }
- return pMode;
-}
-
-/**
- * Create display mode entries in the screen information structure for each
- * of the initial graphics modes that we wish to support. This includes:
- * - An initial mode, of the size requested by the caller
- * - Two dynamic modes, one of which will be updated to match the last size
- * hint from the host on each mode switch, but initially also of the
- * requested size
- * - Several standard modes, if possible ones that the host likes
- * - Any modes that the user requested in xorg.conf/XFree86Config
- */
-void vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit)
-{
- unsigned cx = 0, cy = 0, cIndex = 0;
- unsigned i;
- /* For reasons related to the way RandR 1.1 is implemented, we need to
- * make sure that the initial mode (more precisely, a mode equal to the
- * initial virtual resolution) is always present in the mode list. RandR
- * has the assumption build in that there will either be a mode of that
- * size present at all times, or that the first mode in the list will
- * always be smaller than the initial virtual resolution. Since our
- * approach to dynamic resizing isn't quite the way RandR was intended to
- * be, and breaks the second assumption, we guarantee the first. */
- DisplayModePtr pMode = vboxAddEmptyScreenMode(pScrn);
- vboxFillDisplayMode(pScrn, pMode, "VBoxInitialMode", cxInit, cyInit);
- /* Create our two dynamic modes. */
- pMode = vboxAddEmptyScreenMode(pScrn);
- vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);
- pMode = vboxAddEmptyScreenMode(pScrn);
- vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);
- /* Add standard modes supported by the host */
- for ( ; ; )
- {
- char szName[256];
- cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy, NULL);
- if (cIndex == 0)
- break;
- sprintf(szName, "VBox-%ux%u", cx, cy);
- pMode = vboxAddEmptyScreenMode(pScrn);
- vboxFillDisplayMode(pScrn, pMode, szName, cx, cy);
- }
- /* And finally any modes specified by the user. We assume here that
- * the mode names reflect the mode sizes. */
- for (i = 0; pScrn->display->modes && pScrn->display->modes[i]; i++)
- {
- if (sscanf(pScrn->display->modes[i], "%ux%u", &cx, &cy) == 2)
- {
- pMode = vboxAddEmptyScreenMode(pScrn);
- vboxFillDisplayMode(pScrn, pMode, pScrn->display->modes[i], cx, cy);
- }
- }
-}
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
index d6dab14..43bcf7d 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
@@ -65,6 +65,12 @@
# include "xf86Resources.h"
#endif
+/* This was accepted upstream in X.Org Server 1.16 which bumped the video
+ * driver ABI to 17. */
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 17
+# define SET_HAVE_VT_PROPERTY
+#endif
+
#ifndef PCIACCESS
/* Drivers for PCI hardware need this */
# include "xf86PciInfo.h"
@@ -100,11 +106,15 @@
# define _HAVE_STRING_ARCH_strsep /* bits/string2.h, __strsep_1c. */
# include "xf86Crtc.h"
# include "xf86Modes.h"
-# include <X11/Xatom.h>
#endif
+/* For setting the root window property. */
+#include <X11/Xatom.h>
+#include "property.h"
+
#ifdef VBOX_DRI
# include "xf86drm.h"
+# include "xf86drmMode.h"
#endif
/* Mandatory functions */
@@ -138,7 +148,13 @@ static void VBOXRestoreMode(ScrnInfoPtr pScrn);
static inline void VBOXSetRec(ScrnInfoPtr pScrn)
{
if (!pScrn->driverPrivate)
- pScrn->driverPrivate = calloc(sizeof(VBOXRec), 1);
+ {
+ VBOXPtr pVBox = (VBOXPtr)xnfcalloc(sizeof(VBOXRec), 1);
+ pScrn->driverPrivate = pVBox;
+#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
+ pVBox->fdACPIDevices = -1;
+#endif
+ }
}
enum GenericTypes
@@ -278,8 +294,12 @@ vbox_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
VBOXPtr pVBox = VBOXGetRec(crtc->scrn);
unsigned cDisplay = (uintptr_t)crtc->driver_private;
+ bool fEnabled = (mode != DPMSModeOff);
+
TRACE_LOG("cDisplay=%u, mode=%i\n", cDisplay, mode);
- pVBox->afDisabled[cDisplay] = (mode != DPMSModeOn);
+ if (pVBox->pScreens[cDisplay].fCrtcEnabled == fEnabled)
+ return;
+ pVBox->pScreens[cDisplay].fCrtcEnabled = fEnabled;
/* Don't fiddle with the hardware if we are switched
* to a virtual terminal. */
if (!crtc->scrn->vtSema) {
@@ -287,13 +307,13 @@ vbox_crtc_dpms(xf86CrtcPtr crtc, int mode)
"We do not own the active VT, exiting.\n");
return;
}
- if ( pVBox->aScreenLocation[cDisplay].cx
- && pVBox->aScreenLocation[cDisplay].cy)
+ if ( pVBox->pScreens[cDisplay].aScreenLocation.cx
+ && pVBox->pScreens[cDisplay].aScreenLocation.cy)
VBOXSetMode(crtc->scrn, cDisplay,
- pVBox->aScreenLocation[cDisplay].cx,
- pVBox->aScreenLocation[cDisplay].cy,
- pVBox->aScreenLocation[cDisplay].x,
- pVBox->aScreenLocation[cDisplay].y);
+ pVBox->pScreens[cDisplay].aScreenLocation.cx,
+ pVBox->pScreens[cDisplay].aScreenLocation.cy,
+ pVBox->pScreens[cDisplay].aScreenLocation.x,
+ pVBox->pScreens[cDisplay].aScreenLocation.y);
}
static Bool
@@ -326,16 +346,12 @@ vbox_crtc_mode_set (xf86CrtcPtr crtc, DisplayModePtr mode,
TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name,
adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y);
- pVBox->afDisabled[cDisplay] = false;
- pVBox->aScreenLocation[cDisplay].cx = adjusted_mode->HDisplay;
- pVBox->aScreenLocation[cDisplay].cy = adjusted_mode->VDisplay;
- pVBox->aScreenLocation[cDisplay].x = x;
- pVBox->aScreenLocation[cDisplay].y = y;
- /* Don't remember any modes set while we are seamless, as they are
- * just temporary. */
- if (!vboxGuestIsSeamless(crtc->scrn))
- vboxSaveVideoMode(crtc->scrn, adjusted_mode->HDisplay,
- adjusted_mode->VDisplay, crtc->scrn->bitsPerPixel);
+ pVBox->pScreens[cDisplay].fCrtcEnabled = true;
+ pVBox->pScreens[cDisplay].fOutputEnabled = true;
+ pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay;
+ pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay;
+ pVBox->pScreens[cDisplay].aScreenLocation.x = x;
+ pVBox->pScreens[cDisplay].aScreenLocation.y = y;
/* Don't fiddle with the hardware if we are switched
* to a virtual terminal. */
if (!crtc->scrn->vtSema)
@@ -386,26 +402,35 @@ vbox_output_stub (xf86OutputPtr output)
static void
vbox_output_dpms (xf86OutputPtr output, int mode)
-{ (void) output; (void) mode; }
+{
+ VBOXPtr pVBox = VBOXGetRec(output->scrn);
+ unsigned cDisplay = (uintptr_t)output->driver_private;
+ bool fEnabled = (mode == DPMSModeOn);
+
+ TRACE_LOG("cDisplay=%u, mode=%i\n", cDisplay, mode);
+ if (pVBox->pScreens[cDisplay].fOutputEnabled == fEnabled)
+ return;
+ pVBox->pScreens[cDisplay].fOutputEnabled = fEnabled;
+ /* Don't fiddle with the hardware if we are switched
+ * to a virtual terminal. */
+ if (!output->scrn->vtSema) {
+ xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
+ "We do not own the active VT, exiting.\n");
+ return;
+ }
+ if ( pVBox->pScreens[cDisplay].aScreenLocation.cx
+ && pVBox->pScreens[cDisplay].aScreenLocation.cy)
+ VBOXSetMode(output->scrn, cDisplay,
+ pVBox->pScreens[cDisplay].aScreenLocation.cx,
+ pVBox->pScreens[cDisplay].aScreenLocation.cy,
+ pVBox->pScreens[cDisplay].aScreenLocation.x,
+ pVBox->pScreens[cDisplay].aScreenLocation.y);
+}
static int
vbox_output_mode_valid (xf86OutputPtr output, DisplayModePtr mode)
{
- ScrnInfoPtr pScrn = output->scrn;
- int rc = MODE_OK;
- TRACE_LOG("HDisplay=%d, VDisplay=%d\n", mode->HDisplay, mode->VDisplay);
- /* We always like modes specified by the user in the configuration
- * file and modes requested by the host, as doing otherwise is likely to
- * annoy people. */
- if ( !(mode->type & M_T_USERDEF)
- && !(mode->type & M_T_PREFERRED)
- && vbox_device_available(VBOXGetRec(pScrn))
- && !vboxHostLikesVideoMode(pScrn, mode->HDisplay, mode->VDisplay,
- pScrn->bitsPerPixel)
- )
- rc = MODE_BAD;
- TRACE_LOG("returning %s\n", MODE_OK == rc ? "MODE_OK" : "MODE_BAD");
- return rc;
+ return MODE_OK;
}
static Bool
@@ -422,17 +447,19 @@ vbox_output_mode_set (xf86OutputPtr output, DisplayModePtr mode,
static xf86OutputStatus
vbox_output_detect (xf86OutputPtr output)
{
- (void) output;
- return XF86OutputStatusConnected;
+ ScrnInfoPtr pScrn = output->scrn;
+ VBOXPtr pVBox = VBOXGetRec(pScrn);
+ uint32_t iScreen = (uintptr_t)output->driver_private;
+ return pVBox->pScreens[iScreen].afConnected
+ ? XF86OutputStatusConnected : XF86OutputStatusDisconnected;
}
-static DisplayModePtr
-vbox_output_add_mode (VBOXPtr pVBox, DisplayModePtr *pModes,
- const char *pszName, int x, int y,
- Bool isPreferred, Bool isUserDef)
+static DisplayModePtr vbox_output_add_mode(VBOXPtr pVBox, DisplayModePtr *pModes, const char *pszName, int x, int y,
+ Bool isPreferred, Bool isUserDef)
{
- TRACE_LOG("pszName=%s, x=%d, y=%d\n", pszName, x, y);
+ TRACE_LOG("pszName=%s, x=%d, y=%d\n", pszName ? pszName : "(null)", x, y);
DisplayModePtr pMode = xnfcalloc(1, sizeof(DisplayModeRec));
+ int cRefresh = 60;
pMode->status = MODE_OK;
/* We don't ask the host whether it likes user defined modes,
@@ -453,7 +480,7 @@ vbox_output_add_mode (VBOXPtr pVBox, DisplayModePtr *pModes,
pMode->VSyncStart = pMode->VDisplay + 2;
pMode->VSyncEnd = pMode->VDisplay + 4;
pMode->VTotal = pMode->VDisplay + 6;
- pMode->Clock = pMode->HTotal * pMode->VTotal * 60 / 1000; /* kHz */
+ pMode->Clock = pMode->HTotal * pMode->VTotal * cRefresh / 1000; /* kHz */
if (NULL == pszName) {
xf86SetModeDefaultName(pMode);
} else {
@@ -472,15 +499,16 @@ vbox_output_get_modes (xf86OutputPtr output)
VBOXPtr pVBox = VBOXGetRec(pScrn);
TRACE_ENTRY();
- uint32_t x, y, bpp, iScreen;
+ uint32_t x, y, iScreen;
iScreen = (uintptr_t)output->driver_private;
- vboxGetPreferredMode(pScrn, iScreen, &x, &y, &bpp);
- pMode = vbox_output_add_mode(pVBox, &pModes, NULL, x, y, TRUE, FALSE);
+ VBoxUpdateSizeHints(pScrn);
+ pMode = vbox_output_add_mode(pVBox, &pModes, NULL, pVBox->pScreens[iScreen].aPreferredSize.cx,
+ pVBox->pScreens[iScreen].aPreferredSize.cy, TRUE, FALSE);
VBOXEDIDSet(output, pMode);
/* Add standard modes supported by the host */
for ( ; ; )
{
- cIndex = vboxNextStandardMode(pScrn, cIndex, &x, &y, NULL);
+ cIndex = vboxNextStandardMode(pScrn, cIndex, &x, &y);
if (cIndex == 0)
break;
vbox_output_add_mode(pVBox, &pModes, NULL, x, y, FALSE, FALSE);
@@ -491,57 +519,12 @@ vbox_output_get_modes (xf86OutputPtr output)
for (i = 0; pScrn->display->modes[i] != NULL; i++)
{
if (2 == sscanf(pScrn->display->modes[i], "%ux%u", &x, &y))
- vbox_output_add_mode(pVBox, &pModes, pScrn->display->modes[i], x, y,
- FALSE, TRUE);
+ vbox_output_add_mode(pVBox, &pModes, pScrn->display->modes[i], x, y, FALSE, TRUE);
}
TRACE_EXIT();
return pModes;
}
-#ifdef RANDR_12_INTERFACE
-static Atom
-vboxAtomVBoxMode(void)
-{
- return MakeAtom("VBOX_MODE", sizeof("VBOX_MODE") - 1, TRUE);
-}
-
-static Atom
-vboxAtomEDID(void)
-{
- return MakeAtom("EDID", sizeof("EDID") - 1, TRUE);
-}
-
-/** We use this for receiving information from clients for the purpose of
- * dynamic resizing, and later possibly other things too.
- */
-static Bool
-vbox_output_set_property(xf86OutputPtr output, Atom property,
- RRPropertyValuePtr value)
-{
- ScrnInfoPtr pScrn = output->scrn;
- VBOXPtr pVBox = VBOXGetRec(pScrn);
- TRACE_LOG("property=%d, value->type=%d, value->format=%d, value->size=%ld\n",
- (int)property, (int)value->type, value->format, value->size);
- if (property == vboxAtomVBoxMode())
- {
- uint32_t cDisplay = (uintptr_t)output->driver_private;
- char sz[256] = { 0 };
- int w, h;
-
- if ( value->type != XA_STRING
- || (unsigned) value->size > (sizeof(sz) - 1))
- return FALSE;
- strncpy(sz, value->data, value->size);
- TRACE_LOG("screen=%u, property value=%s\n", cDisplay, sz);
- if (sscanf(sz, "%dx%d", &w, &h) != 2)
- return FALSE;
- pVBox->aPreferredSize[cDisplay].cx = w;
- pVBox->aPreferredSize[cDisplay].cy = h;
- }
- return TRUE;
-}
-#endif
-
static const xf86OutputFuncsRec VBOXOutputFuncs = {
.create_resources = vbox_output_stub,
.dpms = vbox_output_dpms,
@@ -555,7 +538,7 @@ static const xf86OutputFuncsRec VBOXOutputFuncs = {
.detect = vbox_output_detect,
.get_modes = vbox_output_get_modes,
#ifdef RANDR_12_INTERFACE
- .set_property = vbox_output_set_property,
+ .set_property = NULL,
#endif
.destroy = vbox_output_stub
};
@@ -810,9 +793,6 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
if (!pVBox)
return FALSE;
- /* Initialise the guest library */
- vbox_init(pScrn->scrnIndex, pVBox);
-
/* Entity information seems to mean bus information. */
pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
@@ -887,18 +867,9 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->clockRanges->ClockMulFactor = 1;
pScrn->clockRanges->ClockDivFactor = 1;
- /* Query the host for the preferred colour depth */
- {
- uint32_t cx = 0, cy = 0, cBits = 0;
-
- vboxGetPreferredMode(pScrn, 0, &cx, &cy, &cBits);
- /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
- if (cBits != 16)
- cBits = 24;
- if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
- return FALSE;
- vboxAddModes(pScrn, cx, cy);
- }
+ if (!xf86SetDepthBpp(pScrn, 24, 0, 0, Support32bppFb))
+ return FALSE;
+ /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
{
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -906,6 +877,7 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
xf86PrintDepthBpp(pScrn);
+ vboxAddModes(pScrn);
#ifdef VBOXVIDEO_13
/* Work around a bug in the original X server modesetting code, which
@@ -977,6 +949,50 @@ vboxLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
(void)pVisual;
}
+#define HAS_VT_ATOM_NAME "XFree86_has_VT"
+#define VBOXVIDEO_DRIVER_ATOM_NAME "VBOXVIDEO_DRIVER_IN_USE"
+/* The memory storing the initial value of the XFree86_has_VT root window
+ * property. This has to remain available until server start-up, so we just
+ * use a global. */
+static CARD32 InitialPropertyValue = 1;
+
+/** Initialise a flag property on the root window to say whether the server VT
+ * is currently the active one as some clients need to know this. */
+static void initialiseProperties(ScrnInfoPtr pScrn)
+{
+ Atom atom = -1;
+ CARD32 *PropertyValue = &InitialPropertyValue;
+#ifdef SET_HAVE_VT_PROPERTY
+ atom = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, TRUE);
+ if (xf86RegisterRootWindowProperty(pScrn->scrnIndex, atom, XA_INTEGER,
+ 32, 1, PropertyValue) != Success)
+ FatalError("vboxvideo: failed to register VT property\n");
+#endif /* SET_HAVE_VT_PROPERTY */
+ atom = MakeAtom(VBOXVIDEO_DRIVER_ATOM_NAME,
+ sizeof(VBOXVIDEO_DRIVER_ATOM_NAME) - 1, TRUE);
+ if (xf86RegisterRootWindowProperty(pScrn->scrnIndex, atom, XA_INTEGER,
+ 32, 1, PropertyValue) != Success)
+ FatalError("vboxvideo: failed to register driver in use property\n");
+}
+
+#ifdef SET_HAVE_VT_PROPERTY
+/** Update a flag property on the root window to say whether the server VT
+ * is currently the active one as some clients need to know this. */
+static void updateHasVTProperty(ScrnInfoPtr pScrn, Bool hasVT)
+{
+ Atom property_name;
+ int32_t value = hasVT ? 1 : 0;
+ int i;
+
+ property_name = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1,
+ FALSE);
+ if (property_name == BAD_RESOURCE)
+ FatalError("Failed to retrieve \"HAS_VT\" atom\n");
+ ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32,
+ PropModeReplace, 1, &value, TRUE);
+}
+#endif /* SET_HAVE_VT_PROPERTY */
+
/*
* QUOTE from the XFree86 DESIGN document:
*
@@ -1049,10 +1065,13 @@ static Bool VBOXScreenInit(ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
pScrn->vtSema = TRUE;
- if (vbox_open (pScrn, pScreen, pVBox)) {
- vboxEnableVbva(pScrn);
- vboxEnableGraphicsCap(pVBox);
- }
+#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
+ VBoxSetUpLinuxACPI(pScreen);
+#endif
+
+ vbox_open (pScrn, pScreen, pVBox);
+ vboxEnableVbva(pScrn);
+ VBoxInitialiseSizeHints(pScrn);
#ifdef VBOXVIDEO_13
/* Initialise CRTC and output configuration for use with randr1.2. */
@@ -1066,23 +1085,23 @@ static Bool VBOXScreenInit(ScreenPtr pScreen, int argc, char **argv)
char szOutput[256];
/* Setup our virtual CRTCs. */
- pVBox->paCrtcs[i] = xf86CrtcCreate(pScrn, &VBOXCrtcFuncs);
- pVBox->paCrtcs[i]->driver_private = (void *)(uintptr_t)i;
+ pVBox->pScreens[i].paCrtcs = xf86CrtcCreate(pScrn, &VBOXCrtcFuncs);
+ pVBox->pScreens[i].paCrtcs->driver_private = (void *)(uintptr_t)i;
/* Set up our virtual outputs. */
- snprintf(szOutput, sizeof(szOutput), "VBOX%u", i);
- pVBox->paOutputs[i] = xf86OutputCreate(pScrn, &VBOXOutputFuncs,
- szOutput);
+ snprintf(szOutput, sizeof(szOutput), "VGA-%u", i);
+ pVBox->pScreens[i].paOutputs
+ = xf86OutputCreate(pScrn, &VBOXOutputFuncs, szOutput);
/* We are not interested in the monitor section in the
* configuration file. */
- xf86OutputUseScreenMonitor(pVBox->paOutputs[i], FALSE);
- pVBox->paOutputs[i]->possible_crtcs = 1 << i;
- pVBox->paOutputs[i]->possible_clones = 0;
- pVBox->paOutputs[i]->driver_private = (void *)(uintptr_t)i;
+ xf86OutputUseScreenMonitor(pVBox->pScreens[i].paOutputs, FALSE);
+ pVBox->pScreens[i].paOutputs->possible_crtcs = 1 << i;
+ pVBox->pScreens[i].paOutputs->possible_clones = 0;
+ pVBox->pScreens[i].paOutputs->driver_private = (void *)(uintptr_t)i;
TRACE_LOG("Created crtc (%p) and output %s (%p)\n",
- (void *)pVBox->paCrtcs[i], szOutput,
- (void *)pVBox->paOutputs[i]);
+ (void *)pVBox->pScreens[i].paCrtcs, szOutput,
+ (void *)pVBox->pScreens[i].paOutputs);
}
}
@@ -1103,25 +1122,11 @@ static Bool VBOXScreenInit(ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
- /* Create our VBOX_MODE display properties. */
- {
- uint32_t i;
-
- for (i = 0; i < pVBox->cScreens; ++i)
- {
- char csz[] = "0x0";
- RRChangeOutputProperty(pVBox->paOutputs[i]->randr_output,
- vboxAtomVBoxMode(), XA_STRING, 8,
- PropModeReplace, sizeof(csz), csz, TRUE,
- FALSE);
-
- }
- }
-
if (!xf86SetDesiredModes(pScrn)) {
return FALSE;
}
#else /* !VBOXVIDEO_13 */
+ VBoxSetUpRandR11(pScreen);
/* set first video mode */
if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
pScrn->currentMode->VDisplay, pScrn->frameX0,
@@ -1130,13 +1135,10 @@ static Bool VBOXScreenInit(ScreenPtr pScreen, int argc, char **argv)
/* Save the size in case we need to re-set it later. */
pVBox->FBSize.cx = pScrn->currentMode->HDisplay;
pVBox->FBSize.cy = pScrn->currentMode->VDisplay;
- pVBox->aScreenLocation[0].cx = pScrn->currentMode->HDisplay;
- pVBox->aScreenLocation[0].cy = pScrn->currentMode->VDisplay;
- pVBox->aScreenLocation[0].x = pScrn->frameX0;
- pVBox->aScreenLocation[0].y = pScrn->frameY0;
- /* And make sure that a non-current dynamic mode is at the front of the
- * list */
- vboxWriteHostModes(pScrn, pScrn->currentMode);
+ pVBox->pScreens[0].aScreenLocation.cx = pScrn->currentMode->HDisplay;
+ pVBox->pScreens[0].aScreenLocation.cy = pScrn->currentMode->VDisplay;
+ pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0;
+ pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0;
#endif /* !VBOXVIDEO_13 */
/* software cursor */
@@ -1177,6 +1179,9 @@ static Bool VBOXScreenInit(ScreenPtr pScreen, int argc, char **argv)
if (pVBox->useDRI)
pVBox->useDRI = VBOXDRIFinishScreenInit(pScreen);
#endif
+
+ initialiseProperties(pScrn);
+
return (TRUE);
}
@@ -1193,12 +1198,10 @@ static Bool VBOXEnterVT(ScrnInfoPtr pScrn)
if (pVBox->drmFD >= 0)
{
/* Tell the kernel driver, if present, that we are taking over. */
- drmIoctl(pVBox->drmFD, VBOXVIDEO_IOCTL_DISABLE_HGSMI, NULL);
drmSetMaster(pVBox->drmFD);
}
#endif
- if (pVBox->fHaveHGSMI)
- vboxEnableVbva(pScrn);
+ vboxEnableVbva(pScrn);
/* Re-assert this in case we had a change request while switched out. */
if (pVBox->FBSize.cx && pVBox->FBSize.cy)
VBOXAdjustScreenPixmap(pScrn, pVBox->FBSize.cx, pVBox->FBSize.cy);
@@ -1211,6 +1214,9 @@ static Bool VBOXEnterVT(ScrnInfoPtr pScrn)
pScrn->frameY0))
return FALSE;
#endif
+#ifdef SET_HAVE_VT_PROPERTY
+ updateHasVTProperty(pScrn, TRUE);
+#endif
return TRUE;
}
@@ -1219,23 +1225,19 @@ static void VBOXLeaveVT(ScrnInfoPtr pScrn)
VBOXPtr pVBox = VBOXGetRec(pScrn);
TRACE_ENTRY();
- if (pVBox->fHaveHGSMI)
- vboxDisableVbva(pScrn);
+ vboxDisableVbva(pScrn);
vboxClearVRAM(pScrn, 0, 0);
- vboxDisableGraphicsCap(pVBox);
#ifdef VBOX_DRI_OLD
if (pVBox->useDRI)
DRILock(xf86ScrnToScreen(pScrn), 0);
#elif defined(VBOX_DRI) /* DRI2 */
if (pVBox->drmFD >= 0)
drmDropMaster(pVBox->drmFD);
- /* Tell the kernel driver, if present, that it can use the framebuffer
- * driver again. If not, or if that fails, restore the old mode ourselves.
- */
- if ( pVBox->drmFD < 0
- || drmIoctl(pVBox->drmFD, VBOXVIDEO_IOCTL_ENABLE_HGSMI, NULL) < 0)
#endif
- VBOXRestoreMode(pScrn);
+ VBOXRestoreMode(pScrn);
+#ifdef SET_HAVE_VT_PROPERTY
+ updateHasVTProperty(pScrn, FALSE);
+#endif
TRACE_EXIT();
}
@@ -1248,10 +1250,7 @@ static Bool VBOXCloseScreen(ScreenPtr pScreen)
#endif
if (pScrn->vtSema)
{
- if (pVBox->fHaveHGSMI)
- vboxDisableVbva(pScrn);
- if (pScrn->vtSema)
- vboxDisableGraphicsCap(pVBox);
+ vboxDisableVbva(pScrn);
vboxClearVRAM(pScrn, 0, 0);
}
#ifdef VBOX_DRI
@@ -1278,6 +1277,9 @@ static Bool VBOXCloseScreen(ScreenPtr pScreen)
vbox_close(pScrn, pVBox);
pScreen->CloseScreen = pVBox->CloseScreen;
+#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
+ VBoxCleanUpLinuxACPI(pScreen);
+#endif
#ifndef XF86_SCRN_INTERFACE
return pScreen->CloseScreen(pScreen->myNum, pScreen);
#else
@@ -1296,10 +1298,10 @@ static Bool VBOXSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* Save the size in case we need to re-set it later. */
pVBox->FBSize.cx = pMode->HDisplay;
pVBox->FBSize.cy = pMode->VDisplay;
- pVBox->aScreenLocation[0].cx = pMode->HDisplay;
- pVBox->aScreenLocation[0].cy = pMode->VDisplay;
- pVBox->aScreenLocation[0].x = pScrn->frameX0;
- pVBox->aScreenLocation[0].y = pScrn->frameY0;
+ pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay;
+ pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay;
+ pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0;
+ pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0;
#endif
if (!pScrn->vtSema)
{
@@ -1313,14 +1315,6 @@ static Bool VBOXSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay);
rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay,
pScrn->frameX0, pScrn->frameY0);
- if (rc)
- {
- vboxWriteHostModes(pScrn, pMode);
- xf86PrintModes(pScrn);
- }
- if (rc && !vboxGuestIsSeamless(pScrn))
- vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay,
- pScrn->bitsPerPixel);
#endif
TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
return rc;
@@ -1331,8 +1325,8 @@ static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
VBOXPtr pVBox = VBOXGetRec(pScrn);
TRACE_ENTRY();
- pVBox->aScreenLocation[0].x = x;
- pVBox->aScreenLocation[0].y = y;
+ pVBox->pScreens[0].aScreenLocation.x = x;
+ pVBox->pScreens[0].aScreenLocation.y = y;
/* Don't fiddle with the hardware if we are switched
* to a virtual terminal. */
if (!pScrn->vtSema)
@@ -1341,8 +1335,8 @@ static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
"We do not own the active VT, exiting.\n");
return;
}
- VBOXSetMode(pScrn, 0, pVBox->aScreenLocation[0].cx,
- pVBox->aScreenLocation[0].cy, x, y);
+ VBOXSetMode(pScrn, 0, pVBox->pScreens[0].aScreenLocation.cx,
+ pVBox->pScreens[0].aScreenLocation.cy, x, y);
TRACE_EXIT();
}
@@ -1432,8 +1426,21 @@ VBOXRestoreMode(ScrnInfoPtr pScrn)
{
VBOXPtr pVBox = VBOXGetRec(pScrn);
vgaRegPtr vgaReg;
+#ifdef VBOX_DRI
+ drmModeResPtr pRes;
+#endif
TRACE_ENTRY();
+#ifdef VBOX_DRI
+ /* Do not try to re-set the VGA state if a mode-setting driver is loaded. */
+ if ( pVBox->drmFD >= 0
+ && LoaderSymbol("drmModeGetResources") != NULL
+ && (pRes = drmModeGetResources(pVBox->drmFD)) != NULL)
+ {
+ drmModeFreeResources(pRes);
+ return;
+ }
+#endif
vgaReg = &VGAHWPTR(pScrn)->SavedReg;
vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
if (pVBox->fSavedVBEMode)
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.h b/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
index 6fb15c5..381479c 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
@@ -57,45 +57,44 @@
#ifdef DEBUG
-#include <xf86.h>
-
#define TRACE_ENTRY() \
do { \
- xf86Msg(X_INFO, __PRETTY_FUNCTION__); \
- xf86Msg(X_INFO, ": entering\n"); \
+ vbvxMsg(__PRETTY_FUNCTION__); \
+ vbvxMsg(": entering\n"); \
} while(0)
#define TRACE_EXIT() \
do { \
- xf86Msg(X_INFO, __PRETTY_FUNCTION__); \
- xf86Msg(X_INFO, ": leaving\n"); \
+ vbvxMsg(__PRETTY_FUNCTION__); \
+ vbvxMsg(": leaving\n"); \
} while(0)
#define TRACE_LOG(...) \
do { \
- xf86Msg(X_INFO, __PRETTY_FUNCTION__); \
- xf86Msg(X_INFO, __VA_ARGS__); \
+ vbvxMsg("%s: ", __PRETTY_FUNCTION__); \
+ vbvxMsg(__VA_ARGS__); \
} while(0)
# define TRACE_LINE() do \
{ \
- ErrorF ("%s: line %d\n", __FUNCTION__, __LINE__); \
- } while(0)
-# define XF86ASSERT(expr, out) \
-if (!(expr)) \
-{ \
- ErrorF ("\nAssertion failed!\n\n"); \
- ErrorF ("%s\n", #expr); \
- ErrorF ("at %s (%s:%d)\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); \
- ErrorF out; \
- FatalError("Aborting"); \
-}
+ vbvxMsg("%s: line %d\n", __FUNCTION__, __LINE__); \
+} while(0)
#else /* !DEBUG */
#define TRACE_ENTRY() do { } while (0)
#define TRACE_EXIT() do { } while (0)
#define TRACE_LOG(...) do { } while (0)
-#define XF86ASSERT(expr, out) do { } while (0)
#endif /* !DEBUG */
+/* Not just for debug builds. If something is wrong we want to know at once. */
+#define VBVXASSERT(expr, out) \
+if (!(expr)) \
+{ \
+ vbvxMsg("\nAssertion failed!\n\n"); \
+ vbvxMsg("%s\n", #expr); \
+ vbvxMsg("at %s (%s:%d)\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); \
+ vbvxMsg out; \
+ vbvxAbortServer(); \
+}
+
#define BOOL_STR(a) ((a) ? "TRUE" : "FALSE")
#include <VBox/Hardware/VBoxVideoVBE.h>
@@ -132,7 +131,42 @@ extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
#define VBOXPTR(p) ((VBOXPtr)((p)->driverPrivate))
-/*XXX*/
+/** Helper to work round different ways of getting the root window in different
+ * server versions. */
+#if defined(XORG_VERSION_CURRENT) && XORG_VERSION_CURRENT < 700000000 \
+ && XORG_VERSION_CURRENT >= 100900000
+# define ROOT_WINDOW(pScrn) screenInfo.screens[(pScrn)->scrnIndex]->root
+#else
+# define ROOT_WINDOW(pScrn) WindowTable[(pScrn)->scrnIndex]
+#endif
+
+/** Structure containing all virtual monitor-specific information. */
+struct VBoxScreen
+{
+ /** Position information for each virtual screen for the purposes of
+ * sending dirty rectangle information to the right one. */
+ RTRECT2 aScreenLocation;
+ /** Is this CRTC enabled or in DPMS off state? */
+ Bool fCrtcEnabled;
+ /** Is this output enabled or in DPMS low power state? */
+ Bool fOutputEnabled;
+#ifdef VBOXVIDEO_13
+ /** The virtual crtcs. */
+ struct _xf86Crtc *paCrtcs;
+ /** The virtual outputs, logically not distinct from crtcs. */
+ struct _xf86Output *paOutputs;
+#endif
+ /** Offsets of VBVA buffers in video RAM */
+ uint32_t aoffVBVABuffer;
+ /** Context information about the VBVA buffers for each screen */
+ struct VBVABUFFERCONTEXT aVbvaCtx;
+ /** The current preferred resolution for the screen */
+ RTRECTSIZE aPreferredSize;
+ /** Has this screen been enabled by the host? */
+ Bool afConnected;
+ /** The last mode hint data read from the X11 property. */
+ int32_t lastModeHintFromProperty;
+};
typedef struct VBOXRec
{
@@ -161,32 +195,32 @@ typedef struct VBOXRec
OptionInfoPtr Options;
/** @todo we never actually free this */
xf86CursorInfoPtr pCurs;
- Bool useDevice;
- Bool forceSWCursor;
- /** Do we know that the guest can handle absolute co-ordinates? */
- Bool guestCanAbsolute;
- /** Does this host support sending graphics commands using HGSMI? */
- Bool fHaveHGSMI;
+ /** Do we currently want to use the host cursor? */
+ Bool fUseHardwareCursor;
+ /** The last cursor capabilities data read from the X11 property. */
+ int32_t fLastCursorCapabilitiesFromProperty;
/** Number of screens attached */
uint32_t cScreens;
- /** Position information for each virtual screen for the purposes of
- * sending dirty rectangle information to the right one. */
- RTRECT2 aScreenLocation[VBOX_VIDEO_MAX_SCREENS];
+ /** Information about each virtual screen. */
+ struct VBoxScreen *pScreens;
/** The last requested framebuffer size. */
RTRECTSIZE FBSize;
- /** Has this screen been disabled by the guest? */
- Bool afDisabled[VBOX_VIDEO_MAX_SCREENS];
#ifdef VBOXVIDEO_13
- /** The virtual crtcs */
- struct _xf86Crtc *paCrtcs[VBOX_VIDEO_MAX_SCREENS];
- struct _xf86Output *paOutputs[VBOX_VIDEO_MAX_SCREENS];
+ /** Array of structures for receiving mode hints. */
+ VBVAMODEHINT *paVBVAModeHints;
+# ifdef RT_OS_LINUX
+ /** Input device file descriptor for getting ACPI hot-plug events. */
+ int fdACPIDevices;
+ /** Input handler handle for ACPI hot-plug listener. */
+ void *hACPIEventHandler;
+# endif
+ /** Have we read all available HGSMI mode hint data? */
+ bool fHaveReadHGSMIModeHintData;
+#else
+ /** The original CreateScreenResources procedure which we wrap with our own.
+ */
+ CreateScreenResourcesProcPtr pfnCreateScreenResources;
#endif
- /** Offsets of VBVA buffers in video RAM */
- uint32_t aoffVBVABuffer[VBOX_VIDEO_MAX_SCREENS];
- /** Context information about the VBVA buffers for each screen */
- struct VBVABUFFERCONTEXT aVbvaCtx[VBOX_VIDEO_MAX_SCREENS];
- /** The current preferred resolution for the screen */
- RTRECTSIZE aPreferredSize[VBOX_VIDEO_MAX_SCREENS];
/** HGSMI guest heap context */
HGSMIGUESTCOMMANDCONTEXT guestCtx;
/** Unrestricted horizontal resolution flag. */
@@ -202,34 +236,35 @@ typedef struct VBOXRec
#endif
} VBOXRec, *VBOXPtr;
-extern Bool vbox_init(int scrnIndex, VBOXPtr pVBox);
+/* helpers.c */
+extern void vbvxMsg(const char *pszFormat, ...);
+extern void vbvxMsgV(const char *pszFormat, va_list args);
+extern void vbvxAbortServer(void);
+extern VBOXPtr vbvxGetRec(ScrnInfoPtr pScrn);
+#define VBOXGetRec vbvxGetRec /* Temporary */
+extern int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData);
+extern void vbvxReprobeCursor(ScrnInfoPtr pScrn);
+
+/* setmode.c */
extern Bool vbox_cursor_init (ScreenPtr pScreen);
-extern Bool vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox);
+extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox);
extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox);
-extern Bool vbox_device_available(VBOXPtr pVBox);
extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
extern void vboxDisableVbva(ScrnInfoPtr pScrn);
-extern Bool vboxEnableGraphicsCap(VBOXPtr pVBox);
-extern Bool vboxDisableGraphicsCap(VBOXPtr pVBox);
-extern Bool vboxGuestIsSeamless(ScrnInfoPtr pScrn);
-
-extern Bool vboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx,
- uint32_t *pcy, uint32_t *pcBits,
- uint32_t *piDisplay);
-extern Bool vboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits);
-extern Bool vboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits);
-extern Bool vboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits);
+/* getmode.c */
extern unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
- uint32_t *pcx, uint32_t *pcy,
- uint32_t *pcBits);
-extern void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen,
- uint32_t *pcx, uint32_t *pcy,
- uint32_t *pcBits);
-extern void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent);
-extern void vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit,
- uint32_t cyInit);
+ uint32_t *pcx, uint32_t *pcy);
+extern void vboxAddModes(ScrnInfoPtr pScrn);
+extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn);
+extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn);
+#ifndef VBOXVIDEO_13
+extern void VBoxSetUpRandR11(ScreenPtr pScreen);
+#else
+void VBoxSetUpLinuxACPI(ScreenPtr pScreen);
+void VBoxCleanUpLinuxACPI(ScreenPtr pScreen);
+#endif
/* DRI stuff */
extern Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen,
@@ -245,11 +280,6 @@ extern Bool VBOXEDIDSet(struct _xf86Output *output, DisplayModePtr pmode);
/* Utilities */
-static inline VBOXPtr VBOXGetRec(ScrnInfoPtr pScrn)
-{
- return ((VBOXPtr)pScrn->driverPrivate);
-}
-
/** Calculate the BPP from the screen depth */
static inline uint16_t vboxBPP(ScrnInfoPtr pScrn)
{
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri2.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri2.c
index f665df5..639113e 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri2.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri2.c
@@ -53,8 +53,7 @@ const char *devicePaths[] =
#undef PATH
/** As long as we are using our fake DRI driver inside of Mesa, we only want
- * to implement the minimum here to make Mesa load it. Notably we just set
- * "DRI2Info.fd" to -1 as we do not need authentication to work. */
+ * to implement the minimum here to make Mesa load it. */
Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
{
DRI2InfoRec DRI2Info;
diff --git a/src/VBox/Additions/x11/vboxvideo/vbva.c b/src/VBox/Additions/x11/vboxvideo/vbva.c
index 67b0adc..98924ea 100644
--- a/src/VBox/Additions/x11/vboxvideo/vbva.c
+++ b/src/VBox/Additions/x11/vboxvideo/vbva.c
@@ -32,6 +32,10 @@
#include "vboxvideo.h"
+#ifdef XORG_7X
+# include <stdlib.h>
+#endif
+
/**************************************************************************
* Main functions *
**************************************************************************/
@@ -55,24 +59,24 @@ vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
unsigned j;
pVBox = pScrn->driverPrivate;
- if (pVBox->fHaveHGSMI == FALSE || !pScrn->vtSema)
+ if (!pScrn->vtSema)
return;
for (j = 0; j < pVBox->cScreens; ++j)
{
/* Just continue quietly if VBVA is not currently active. */
- struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
+ struct VBVABUFFER *pVBVA = pVBox->pScreens[j].aVbvaCtx.pVBVA;
if ( !pVBVA
|| !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
continue;
for (i = 0; i < iRects; ++i)
{
- if ( aRects[i].x1 > pVBox->aScreenLocation[j].x
- + pVBox->aScreenLocation[j].cx
- || aRects[i].y1 > pVBox->aScreenLocation[j].y
- + pVBox->aScreenLocation[j].cy
- || aRects[i].x2 < pVBox->aScreenLocation[j].x
- || aRects[i].y2 < pVBox->aScreenLocation[j].y)
+ if ( aRects[i].x1 > pVBox->pScreens[j].aScreenLocation.x
+ + pVBox->pScreens[j].aScreenLocation.cx
+ || aRects[i].y1 > pVBox->pScreens[j].aScreenLocation.y
+ + pVBox->pScreens[j].aScreenLocation.cy
+ || aRects[i].x2 < pVBox->pScreens[j].aScreenLocation.x
+ || aRects[i].y2 < pVBox->pScreens[j].aScreenLocation.y)
continue;
cmdHdr.x = (int16_t)aRects[i].x1;
cmdHdr.y = (int16_t)aRects[i].y1;
@@ -84,12 +88,12 @@ vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
#endif
- if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j],
+ if (VBoxVBVABufferBeginUpdate(&pVBox->pScreens[j].aVbvaCtx,
&pVBox->guestCtx))
{
- VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
+ VBoxVBVAWrite(&pVBox->pScreens[j].aVbvaCtx, &pVBox->guestCtx, &cmdHdr,
sizeof(cmdHdr));
- VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
+ VBoxVBVABufferEndUpdate(&pVBox->pScreens[j].aVbvaCtx);
}
}
}
@@ -155,8 +159,6 @@ vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
void *pvGuestHeapMemory;
- if (!pVBox->fHaveHGSMI)
- return FALSE;
VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
NULL);
@@ -175,16 +177,27 @@ vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
}
pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
+ if (pVBox->pScreens == NULL)
+ pVBox->pScreens = calloc(pVBox->cScreens, sizeof(*pVBox->pScreens));
+ if (pVBox->pScreens == NULL)
+ FatalError("Failed to allocate memory for screens array.\n");
+#ifdef VBOXVIDEO_13
+ if (pVBox->paVBVAModeHints == NULL)
+ pVBox->paVBVAModeHints = calloc(pVBox->cScreens,
+ sizeof(*pVBox->paVBVAModeHints));
+ if (pVBox->paVBVAModeHints == NULL)
+ FatalError("Failed to allocate memory for mode hints array.\n");
+#endif
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
pVBox->cScreens);
for (i = 0; i < pVBox->cScreens; ++i)
{
pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
- pVBox->aoffVBVABuffer[i] = pVBox->cbFBMax;
+ pVBox->pScreens[i].aoffVBVABuffer = pVBox->cbFBMax;
TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
(unsigned long) pVBox->cbFBMax);
- VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
- pVBox->aoffVBVABuffer[i],
+ VBoxVBVASetupBufferContext(&pVBox->pScreens[i].aVbvaCtx,
+ pVBox->pScreens[i].aoffVBVABuffer,
VBVA_MIN_BUFFER_SIZE);
}
TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
@@ -200,19 +213,13 @@ vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
return TRUE;
}
-Bool
+void
vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
{
TRACE_ENTRY();
- pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
- return pVBox->fHaveHGSMI;
-}
-
-Bool
-vbox_device_available(VBOXPtr pVBox)
-{
- return pVBox->useDevice;
+ if (!vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox))
+ FatalError("failed to initialise vboxvideo graphics acceleration.\n");
}
/**
@@ -238,8 +245,9 @@ vboxEnableVbva(ScrnInfoPtr pScrn)
struct VBVABUFFER *pVBVA;
pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
- + pVBox->aoffVBVABuffer[i]);
- if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
+ + pVBox->pScreens[i].aoffVBVABuffer);
+ if (!VBoxVBVAEnable(&pVBox->pScreens[i].aVbvaCtx, &pVBox->guestCtx,
+ pVBVA, i))
rc = FALSE;
}
if (!rc)
@@ -249,6 +257,14 @@ vboxEnableVbva(ScrnInfoPtr pScrn)
"Failed to enable screen update reporting for at least one virtual monitor.\n");
vboxDisableVbva(pScrn);
}
+#ifdef VBOXVIDEO_13
+# ifdef RT_OS_LINUX
+ if (rc && pVBox->hACPIEventHandler != NULL)
+ /* We ignore the return value as the fall-back should be active
+ * anyway. */
+ VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION);
+# endif
+#endif
return rc;
}
@@ -269,8 +285,6 @@ vboxDisableVbva(ScrnInfoPtr pScrn)
VBOXPtr pVBox = pScrn->driverPrivate;
TRACE_ENTRY();
- if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */
- return;
for (i = 0; i < pVBox->cScreens; ++i)
- VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
+ VBoxVBVADisable(&pVBox->pScreens[i].aVbvaCtx, &pVBox->guestCtx, i);
}
diff --git a/src/VBox/Debugger/DBGCPlugInDiggers.rc b/src/VBox/Debugger/DBGCPlugInDiggers.rc
new file mode 100644
index 0000000..dd78cfd
--- /dev/null
+++ b/src/VBox/Debugger/DBGCPlugInDiggers.rc
@@ -0,0 +1,50 @@
+/* $Id: DBGCPlugInDiggers.rc $ */
+/** @file
+ * DBGCPlugInDiggers - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Debugger Plug-in\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "DBGCPlugInDiggers\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "DBGCPlugInDiggers.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Debugger/Makefile.kmk b/src/VBox/Debugger/Makefile.kmk
index 7a4df62..3e9d1fd 100644
--- a/src/VBox/Debugger/Makefile.kmk
+++ b/src/VBox/Debugger/Makefile.kmk
@@ -66,6 +66,8 @@ DBGCPlugInDiggers_SOURCES = \
DBGPlugInWinNt.cpp \
DBGPlugInOS2.cpp \
DBGPlugInCommonELF.cpp
+DBGCPlugInDiggers_SOURCES.win = \
+ DBGCPlugInDiggers.rc
DBGCPlugInDiggers_LIBS = \
$(if-expr "$(LIB_VMM)" == "$(VBOX_LIB_VMM_LAZY)",$(LIB_REM),) \
$(VBOX_LIB_VMM_LAZY) \
@@ -107,6 +109,8 @@ VBoxDbg_SOURCES = \
VBoxDbgBase.cpp \
VBoxDbgConsole.cpp \
VBoxDbgStatsQt4.cpp
+VBoxDbg_SOURCES.win = \
+ VBoxDbg.rc
VBoxDbg_LIBS = \
$(VBOX_LIB_VMM_LAZY)
VBoxDbg_LDFLAGS.darwin = \
diff --git a/src/VBox/Debugger/VBoxDbg.rc b/src/VBox/Debugger/VBoxDbg.rc
new file mode 100644
index 0000000..28827e7
--- /dev/null
+++ b/src/VBox/Debugger/VBoxDbg.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxDbg.rc $ */
+/** @file
+ * VBoxDbg - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Debugger\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxDbg\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxDbg.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Debugger/VBoxDbgConsole.cpp b/src/VBox/Debugger/VBoxDbgConsole.cpp
index 77eb8cc..80b5a6d 100644
--- a/src/VBox/Debugger/VBoxDbgConsole.cpp
+++ b/src/VBox/Debugger/VBoxDbgConsole.cpp
@@ -29,6 +29,7 @@
#include <QHBoxLayout>
#include <QAction>
#include <QContextMenuEvent>
+#include <QMenu>
#include <VBox/dbg.h>
#include <VBox/vmm/cfgm.h>
@@ -67,6 +68,109 @@ VBoxDbgConsoleOutput::VBoxDbgConsoleOutput(QWidget *pParent/* = NULL*/, const ch
setTabChangesFocus(true);
setAcceptRichText(false);
+ /*
+ * Font.
+ * Create actions for font menu items.
+ */
+ m_pCourierFontAction = new QAction(tr("Courier"), this);
+ m_pCourierFontAction->setCheckable(true);
+ m_pCourierFontAction->setShortcut(Qt::ControlModifier + Qt::Key_D);
+ connect(m_pCourierFontAction, SIGNAL(triggered()), this, SLOT(setFontCourier()));
+
+ m_pMonospaceFontAction = new QAction(tr("Monospace"), this);
+ m_pMonospaceFontAction->setCheckable(true);
+ m_pMonospaceFontAction->setShortcut(Qt::ControlModifier + Qt::Key_M);
+ connect(m_pMonospaceFontAction, SIGNAL(triggered()), this, SLOT(setFontMonospace()));
+
+ /* Create action group for grouping of exclusive font menu items. */
+ QActionGroup *pActionFontGroup = new QActionGroup(this);
+ pActionFontGroup->addAction(m_pCourierFontAction);
+ pActionFontGroup->addAction(m_pMonospaceFontAction);
+ pActionFontGroup->setExclusive(true);
+
+ /*
+ * Color scheme.
+ * Create actions for color-scheme menu items.
+ */
+ m_pGreenOnBlackAction = new QAction(tr("Green On Black"), this);
+ m_pGreenOnBlackAction->setCheckable(true);
+ m_pGreenOnBlackAction->setShortcut(Qt::ControlModifier + Qt::Key_1);
+ connect(m_pGreenOnBlackAction, SIGNAL(triggered()), this, SLOT(setColorGreenOnBlack()));
+
+ m_pBlackOnWhiteAction = new QAction(tr("Black On White"), this);
+ m_pBlackOnWhiteAction->setCheckable(true);
+ m_pBlackOnWhiteAction->setShortcut(Qt::ControlModifier + Qt::Key_2);
+ connect(m_pBlackOnWhiteAction, SIGNAL(triggered()), this, SLOT(setColorBlackOnWhite()));
+
+ /* Create action group for grouping of exclusive color-scheme menu items. */
+ QActionGroup *pActionColorGroup = new QActionGroup(this);
+ pActionColorGroup->addAction(m_pGreenOnBlackAction);
+ pActionColorGroup->addAction(m_pBlackOnWhiteAction);
+ pActionColorGroup->setExclusive(true);
+
+ /*
+ * Set the defaults (which syncs with the menu item checked state).
+ */
+ setFontCourier();
+ setColorGreenOnBlack();
+
+ NOREF(pszName);
+}
+
+
+VBoxDbgConsoleOutput::~VBoxDbgConsoleOutput()
+{
+ Assert(m_hGUIThread == RTThreadNativeSelf());
+}
+
+
+void
+VBoxDbgConsoleOutput::contextMenuEvent(QContextMenuEvent *pEvent)
+{
+ /*
+ * Create the context menu and add the menu items.
+ */
+ QMenu *pMenu = createStandardContextMenu();
+ QMenu *pColorMenu = pMenu->addMenu(tr("Co&lor Scheme"));
+ pColorMenu->addAction(m_pGreenOnBlackAction);
+ pColorMenu->addAction(m_pBlackOnWhiteAction);
+
+ QMenu *pFontMenu = pMenu->addMenu(tr("&Font Family"));
+ pFontMenu->addAction(m_pCourierFontAction);
+ pFontMenu->addAction(m_pMonospaceFontAction);
+
+ pMenu->exec(pEvent->globalPos());
+ delete pMenu;
+}
+
+
+void
+VBoxDbgConsoleOutput::setColorGreenOnBlack()
+{
+ setStyleSheet("QTextEdit { background-color: black; color: rgb(0, 224, 0) }");
+ m_enmColorScheme = kGreenOnBlack;
+
+ /* This is used both as a trigger as well as called independently from code.
+ When used as a trigger, the checked is done automatically by Qt. */
+ if (!m_pGreenOnBlackAction->isChecked())
+ m_pGreenOnBlackAction->setChecked(true);
+}
+
+
+void
+VBoxDbgConsoleOutput::setColorBlackOnWhite()
+{
+ setStyleSheet("QTextEdit { background-color: white; color: black }");
+ m_enmColorScheme = kBlackOnWhite;
+
+ if (!m_pBlackOnWhiteAction->isChecked())
+ m_pBlackOnWhiteAction->setChecked(true);
+}
+
+
+void
+VBoxDbgConsoleOutput::setFontCourier()
+{
#ifdef Q_WS_MAC
QFont Font("Monaco", 10, QFont::Normal, FALSE);
Font.setStyleStrategy(QFont::NoAntialias);
@@ -77,30 +181,22 @@ VBoxDbgConsoleOutput::VBoxDbgConsoleOutput(QWidget *pParent/* = NULL*/, const ch
#endif
setFont(Font);
- /* green on black */
- QPalette Pal(palette());
- Pal.setColor(QPalette::All, QPalette::Base, QColor(Qt::black));
- setPalette(Pal);
- setTextColor(QColor(qRgb(0, 0xe0, 0)));
-
-#ifdef DEBUG_ramshankar
- /* Solaris host (esp. S10) has illegible Courier font (bad aliasing). */
- Font.setFamily("Monospace [Monotype]");
- setFont(Font);
-
- /* White on black while I'm at it. */
- Pal.setColor(QPalette::All, QPalette::Base, QColor(Qt::white));
- setPalette(Pal);
- setTextColor(QColor(qRgb(0, 0, 0)));
-#endif
-
- NOREF(pszName);
+ if (!m_pCourierFontAction->isChecked())
+ m_pCourierFontAction->setChecked(true);
}
-VBoxDbgConsoleOutput::~VBoxDbgConsoleOutput()
+void
+VBoxDbgConsoleOutput::setFontMonospace()
{
- Assert(m_hGUIThread == RTThreadNativeSelf());
+ QFont Font = font();
+ Font.setStyleHint(QFont::TypeWriter);
+ Font.setStyleStrategy(QFont::PreferAntialias);
+ Font.setFamily("Monospace [Monotype]");
+ setFont(Font);
+
+ if (!m_pMonospaceFontAction->isChecked())
+ m_pMonospaceFontAction->setChecked(true);
}
@@ -365,6 +461,11 @@ VBoxDbgConsole::VBoxDbgConsole(VBoxDbgGui *a_pDbgGui, QWidget *a_pParent/* = NUL
m_pFocusToOutput->setShortcut(QKeySequence("Ctrl+O"));
addAction(m_pFocusToOutput);
connect(m_pFocusToOutput, SIGNAL(triggered(bool)), this, SLOT(actFocusToOutput()));
+
+ addAction(m_pOutput->m_pBlackOnWhiteAction);
+ addAction(m_pOutput->m_pGreenOnBlackAction);
+ addAction(m_pOutput->m_pCourierFontAction);
+ addAction(m_pOutput->m_pMonospaceFontAction);
}
diff --git a/src/VBox/Debugger/VBoxDbgConsole.h b/src/VBox/Debugger/VBoxDbgConsole.h
index f7bf255..f659721 100644
--- a/src/VBox/Debugger/VBoxDbgConsole.h
+++ b/src/VBox/Debugger/VBoxDbgConsole.h
@@ -60,13 +60,56 @@ public:
*/
virtual void appendText(const QString &rStr, bool fClearSelection);
+ /** The action to switch to black-on-white color scheme. */
+ QAction *m_pBlackOnWhiteAction;
+ /** The action to switch to green-on-black color scheme. */
+ QAction *m_pGreenOnBlackAction;
+
+ /** The action to switch to Courier font. */
+ QAction *m_pCourierFontAction;
+ /** The action to switch to Monospace font. */
+ QAction *m_pMonospaceFontAction;
+
protected:
+ typedef enum { kGreenOnBlack, kBlackOnWhite } VBoxDbgConsoleColor;
+
+ /**
+ * Context menu event.
+ * This adds custom menu items for the output view.
+ *
+ * @param pEvent Pointer to the event.
+ */
+ virtual void contextMenuEvent(QContextMenuEvent *pEvent);
+
/** The current line (paragraph) number. */
unsigned m_uCurLine;
/** The position in the current line. */
unsigned m_uCurPos;
/** The handle to the GUI thread. */
RTNATIVETHREAD m_hGUIThread;
+ /** The current color scheme (foreground on background). */
+ VBoxDbgConsoleColor m_enmColorScheme;
+
+private slots:
+ /**
+ * The green-on-black color scheme context-menu item was triggered.
+ */
+ void setColorGreenOnBlack();
+
+ /**
+ * The black-on-white color scheme context-menu item was triggered.
+ */
+ void setColorBlackOnWhite();
+
+ /**
+ * The courier font family context-menu item was triggered.
+ */
+ void setFontCourier();
+
+ /**
+ * The monospace font family context-menu item was triggered.
+ */
+ void setFontMonospace();
};
diff --git a/src/VBox/Devices/Audio/DevIchHdaCodec.cpp b/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
index 6689f92..c746031 100644
--- a/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
+++ b/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
@@ -739,8 +739,19 @@ static SSMFIELD const g_aCodecNodeFieldsV1[] =
SSMFIELD_ENTRY_TERM()
};
+static DECLCALLBACK(void) dbgNodes(PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+ for (int i = 1; i < 12; i++)
+ {
+ PCODECNODE pNode = &pThis->paNodes[i];
+ AMPLIFIER *pAmp = &pNode->dac.B_params;
+ uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) & 0x7f;
+ uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) & 0x7f;
+ pHlp->pfnPrintf(pHlp, "0x%x: lVol=%RU8, rVol=%RU8\n", i, lVol, rVol);
+ }
+}
static int stac9220ResetNode(PHDACODEC pThis, uint8_t nodenum, PCODECNODE pNode)
{
@@ -761,8 +772,8 @@ static int stac9220ResetNode(PHDACODEC pThis, uint8_t nodenum, PCODECNODE pNode)
| CODEC_F00_0C_CAP_TRIGGER_REQUIRED
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//(17 << 8)|RT_BIT(6)|RT_BIT(5)|RT_BIT(2)|RT_BIT(1)|RT_BIT(0);
pNode->node.au32F00_param[0x0B] = CODEC_F00_0B_PCM;
- pNode->node.au32F00_param[0x0D] = CODEC_MAKE_F00_0D(1, 0x5, 0xE, 0);//RT_BIT(31)|(0x5 << 16)|(0xE)<<8;
- pNode->node.au32F00_param[0x12] = RT_BIT(31)|(0x2 << 16)|(0x7f << 8)|0x7f;
+ pNode->node.au32F00_param[0x0D] = CODEC_MAKE_F00_0D(1, 0x0, 0x7F, 0x7F);
+ pNode->node.au32F00_param[0x12] = CODEC_MAKE_F00_12(1, 0x0, 0x7F, 0x7F);
pNode->node.au32F00_param[0x11] = CODEC_MAKE_F00_11(1, 1, 0, 0, 4);//0xc0000004;
pNode->node.au32F00_param[0x0F] = CODEC_F00_0F_D3|CODEC_F00_0F_D2|CODEC_F00_0F_D1|CODEC_F00_0F_D0;
pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2);//0x2 << 4| 0x2; /* PS-Act: D3, PS->Set D3 */
@@ -999,7 +1010,6 @@ static int stac9220ResetNode(PHDACODEC pThis, uint8_t nodenum, PCODECNODE pNode)
| CODEC_F00_09_CAP_OUT_AMP_PRESENT
| CODEC_F00_09_CAP_LSB;//(3<<20)|RT_BIT(8)|RT_BIT(3)|RT_BIT(2)|RT_BIT(0);
pNode->node.au32F00_param[0xe] = CODEC_MAKE_F00_0E(0, 0x7);
- pNode->node.au32F00_param[0x12] = (0x27 << 16)|(0x4 << 8);
/* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplefiers inited with 0*/
memset(pNode->adcmux.B_params, 0, AMPLIFIER_SIZE);
pNode->node.au32F02_param[0] = RT_MAKE_U32_FROM_U8(0xe, 0x15, 0xf, 0xb);
@@ -1009,7 +1019,6 @@ static int stac9220ResetNode(PHDACODEC pThis, uint8_t nodenum, PCODECNODE pNode)
pNode->node.au32F00_param[9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_BEEP_GEN, 0, 0)
| CODEC_F00_09_CAP_AMP_FMT_OVERRIDE
| CODEC_F00_09_CAP_OUT_AMP_PRESENT;//(7 << 20) | RT_BIT(3) | RT_BIT(2);
- pNode->node.au32F00_param[0x12] = (0x17 << 16)|(0x3 << 8)| 0x3;
pNode->pcbeep.u32F0a_param = 0;
memset(pNode->pcbeep.B_params, 0, AMPLIFIER_SIZE);
break;
@@ -1087,6 +1096,7 @@ static int stac9220Construct(PHDACODEC pThis)
{
unconst(pThis->cTotalNodes) = 0x1C;
pThis->pfnCodecNodeReset = stac9220ResetNode;
+ pThis->pfnCodecDbgListNodes = dbgNodes;
pThis->u16VendorId = 0x8384;
pThis->u16DeviceId = 0x7680;
pThis->u8BSKU = 0x76;
@@ -1179,6 +1189,9 @@ static int hdaCodecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt)
mute &= 0x1;
uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f;
uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f;
+
+ LogFlowFunc(("mt=%ld, lVol=%RU8, rVol=%RU8\n", mt, lVol, rVol));
+
AUD_set_volume(mt, &mute, &lVol, &rVol);
return VINF_SUCCESS;
}
@@ -1318,6 +1331,8 @@ static DECLCALLBACK(int) vrbProcSetAmplifier(PHDACODEC pThis, uint32_t cmd, uint
hdaCodecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
if (fIsRight)
hdaCodecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
+
+ hdaCodecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
}
if (fIsOut)
{
@@ -1325,11 +1340,10 @@ static DECLCALLBACK(int) vrbProcSetAmplifier(PHDACODEC pThis, uint32_t cmd, uint
hdaCodecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
if (fIsRight)
hdaCodecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
- }
- if (CODEC_NID(cmd) == pThis->u8DacLineOut)
+
hdaCodecToAudVolume(pAmplifier, AUD_MIXER_VOLUME);
- if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn) /* Microphone */
- hdaCodecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN);
+ }
+
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/Audio/DevSB16.cpp b/src/VBox/Devices/Audio/DevSB16.cpp
index d0570f0..6c3f4be 100644
--- a/src/VBox/Devices/Audio/DevSB16.cpp
+++ b/src/VBox/Devices/Audio/DevSB16.cpp
@@ -1145,7 +1145,7 @@ static IO_READ_PROTO (dsp_read)
retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
if (s->mixer_regs[0x82] & 1) {
ack = 1;
- s->mixer_regs[0x82] &= 1;
+ s->mixer_regs[0x82] &= ~1;
#ifndef VBOX
qemu_irq_lower (s->pic[s->irq]);
#else
@@ -1158,7 +1158,7 @@ static IO_READ_PROTO (dsp_read)
retval = 0xff;
if (s->mixer_regs[0x82] & 2) {
ack = 1;
- s->mixer_regs[0x82] &= 2;
+ s->mixer_regs[0x82] &= ~2;
#ifndef VBOX
qemu_irq_lower (s->pic[s->irq]);
#else
diff --git a/src/VBox/Devices/Audio/dsound_template.h b/src/VBox/Devices/Audio/dsound_template.h
index de7b04b..c64e40d 100644
--- a/src/VBox/Devices/Audio/dsound_template.h
+++ b/src/VBox/Devices/Audio/dsound_template.h
@@ -1,4 +1,17 @@
+/* $Id: dsound_template.h $ */
+
/*
+ * Copyright (C) 2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
* QEMU DirectSound audio driver header
*
* Copyright (c) 2005 Vassili Karpov (malc)
@@ -145,16 +158,18 @@ static int glue (dsound_lock_, TYPE) (
#ifdef DSBTYPE_IN
static void dsound_fini_in (HWVoiceIn *hw)
+{
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+ dsoundCaptureClose (ds);
+ ds->last_read_pos = 0;
+ ds->capture_buffer_size = 0;
+ memset (&ds->as, 0, sizeof(ds->as));
+}
#else
static void dsound_fini_out (HWVoiceOut *hw)
-#endif
{
HRESULT hr;
-#ifdef DSBTYPE_IN
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
-#else
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
-#endif
if (ds->FIELD) {
hr = glue (IFACE, _Stop) (ds->FIELD);
@@ -169,52 +184,48 @@ static void dsound_fini_out (HWVoiceOut *hw)
ds->FIELD = NULL;
}
}
+#endif
#ifdef DSBTYPE_IN
static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
+{
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+
+ ds->last_read_pos = 0;
+ ds->capture_buffer_size = 0;
+ ds->dsound_capture_buffer = NULL;
+ ds->as = *as;
+
+ /* Init default settings. */
+ audio_pcm_init_info (&hw->info, &ds->as);
+ hw->samples = conf.bufsize_in >> hw->info.shift;
+
+ /* Try to open capture in case the device is already there. */
+ dsoundCaptureOpen (ds);
+
+ return 0;
+}
#else
static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
-#endif
{
int err;
HRESULT hr;
dsound *s = &glob_dsound;
WAVEFORMATEX wfx;
audsettings_t obt_as;
-#ifdef DSBTYPE_IN
- const char *typ = "ADC";
- DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- DSCBUFFERDESC bd;
- DSCBCAPS bc;
-#else
const char *typ = "DAC";
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
DSBUFFERDESC bd;
DSBCAPS bc;
-#endif
err = waveformat_from_audio_settings (&wfx, as);
if (err) {
return -1;
}
-#ifdef DSBTYPE_IN
- if (!s->dsound_capture)
- return -1;
-#endif
-
memset (&bd, 0, sizeof (bd));
bd.dwSize = sizeof (bd);
bd.lpwfxFormat = &wfx;
-#ifdef DSBTYPE_IN
- bd.dwBufferBytes = conf.bufsize_in;
- hr = IDirectSoundCapture_CreateCaptureBuffer (
- s->dsound_capture,
- &bd,
- &ds->dsound_capture_buffer,
- NULL
- );
-#else
bd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
bd.dwBufferBytes = conf.bufsize_out;
hr = IDirectSound_CreateSoundBuffer (
@@ -223,7 +234,6 @@ static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
&ds->dsound_buffer,
NULL
);
-#endif
if (FAILED (hr)) {
dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
@@ -284,6 +294,7 @@ static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
glue (dsound_fini_, TYPE) (hw);
return -1;
}
+#endif
#undef NAME
#undef TYPE
diff --git a/src/VBox/Devices/Audio/dsoundaudio.c b/src/VBox/Devices/Audio/dsoundaudio.c
index 0c745d5..e6a1d6e 100644
--- a/src/VBox/Devices/Audio/dsoundaudio.c
+++ b/src/VBox/Devices/Audio/dsoundaudio.c
@@ -1,4 +1,20 @@
+/* $Id: dsoundaudio.c $ */
+/** @file
+ * DirectSound Windows Host Audio Backend.
+ */
+
/*
+ * Copyright (C) 2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
* QEMU DirectSound audio driver
*
* Copyright (c) 2005 Vassili Karpov (malc)
@@ -45,6 +61,19 @@
/* #define DEBUG_DSOUND */
+#define DSLOGF(a) do { LogRel2(a); } while(0)
+#define DSLOGREL(a) \
+ do { \
+ static int8_t scLogged = 0; \
+ if (scLogged < 8) { \
+ ++scLogged; \
+ LogRel(a); \
+ } \
+ else { \
+ DSLOGF(a); \
+ } \
+ } while (0)
+
static struct {
int lock_retries;
int restore_retries;
@@ -78,6 +107,8 @@ typedef struct {
LPDIRECTSOUNDCAPTURE dsound_capture;
LPDIRECTSOUNDBUFFER dsound_primary_buffer;
audsettings_t settings;
+ RTUUID devguid_capture;
+ LPCGUID devguidp_capture;
} dsound;
static dsound glob_dsound;
@@ -96,8 +127,11 @@ typedef struct {
typedef struct {
HWVoiceIn hw;
- int first_time;
+ int last_read_pos;
+ int capture_buffer_size;
LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+ audsettings_t as;
+ HRESULT hr_last_run_in;
} DSoundVoiceIn;
static void dsound_log_hresult (HRESULT hr)
@@ -409,6 +443,221 @@ static int waveformat_to_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
return 0;
}
+static void dsoundCaptureInterfaceRelease (dsound *s)
+{
+ if (s->dsound_capture) {
+ HRESULT hr = IDirectSoundCapture_Release (s->dsound_capture);
+ if (FAILED (hr)) {
+ DSLOGF(("DSound: DirectSoundCapture release %Rhrc\n", hr));
+ }
+ s->dsound_capture = NULL;
+ }
+}
+
+static int dsoundCaptureInterfaceCreate (dsound *s)
+{
+ HRESULT hr;
+
+ if (s->dsound_capture != NULL) {
+ DSLOGF(("DSound: DirectSoundCapture instance already exists\n"));
+ return -1;
+ }
+
+ hr = CoCreateInstance (&CLSID_DirectSoundCapture, NULL, CLSCTX_ALL,
+ &IID_IDirectSoundCapture, (void **) &s->dsound_capture);
+ if (FAILED (hr)) {
+ DSLOGREL(("DSound: DirectSoundCapture create instance %Rhrc\n", hr));
+ }
+ else {
+ hr = IDirectSoundCapture_Initialize (s->dsound_capture, s->devguidp_capture);
+ if (FAILED (hr)) {
+ if (hr == DSERR_NODRIVER) {
+ DSLOGREL(("DSound: DirectSoundCapture not available\n"));
+ }
+ else {
+ DSLOGREL(("DSound: DirectSoundCapture initialize %Rhrc\n", hr));
+ }
+ dsoundCaptureInterfaceRelease (s);
+ }
+ }
+
+ return SUCCEEDED (hr)? 0: -1;
+}
+
+static void dsoundCaptureClose (DSoundVoiceIn *ds)
+{
+ dsound *s = &glob_dsound;
+
+ DSLOGF(("DSound: capture close %p buffer %p\n", ds, ds->dsound_capture_buffer));
+
+ if (ds->dsound_capture_buffer) {
+ HRESULT hr = IDirectSoundCaptureBuffer_Stop (ds->dsound_capture_buffer);
+ if (FAILED (hr)) {
+ DSLOGF(("DSound: close capture buffer stop %Rhrc\n", hr));
+ }
+
+ hr = IDirectSoundCaptureBuffer_Release (ds->dsound_capture_buffer);
+ if (FAILED (hr)) {
+ DSLOGF(("DSound: close capture buffer release %Rhrc\n", hr));
+ }
+ ds->dsound_capture_buffer = NULL;
+ }
+
+ dsoundCaptureInterfaceRelease (s);
+}
+
+static int dsoundCaptureOpen (DSoundVoiceIn *ds)
+{
+ dsound *s = &glob_dsound;
+
+ int err;
+ HRESULT hr;
+ WAVEFORMATEX wfx;
+ DSCBUFFERDESC bd;
+ DSCBCAPS bc;
+ DWORD cpos;
+
+ DSLOGF(("DSound: capture open %p size %d samples, freq %d, chan %d, bits %d, sign %d\n",
+ ds,
+ ds->hw.samples,
+ ds->hw.info.freq,
+ ds->hw.info.nchannels,
+ ds->hw.info.bits,
+ ds->hw.info.sign));
+
+ if (ds->dsound_capture_buffer != NULL) {
+ /* Should not happen but be forgiving. */
+ DSLOGREL(("DSound: DirectSoundCaptureBuffer already exists\n"));
+ dsoundCaptureClose (ds);
+ }
+
+ err = waveformat_from_audio_settings (&wfx, &ds->as);
+ if (err) {
+ return err;
+ }
+
+ err = dsoundCaptureInterfaceCreate (s);
+ if (err) {
+ return err;
+ }
+
+ memset (&bd, 0, sizeof (bd));
+ bd.dwSize = sizeof (bd);
+ bd.lpwfxFormat = &wfx;
+ bd.dwBufferBytes = ds->hw.samples << ds->hw.info.shift;
+ hr = IDirectSoundCapture_CreateCaptureBuffer (s->dsound_capture,
+ &bd, &ds->dsound_capture_buffer, NULL);
+
+ if (FAILED (hr)) {
+ DSLOGREL(("DSound: create capture buffer %Rhrc\n", hr));
+ ds->dsound_capture_buffer = NULL;
+ goto fail0;
+ }
+
+ /* Query the actual parameters. */
+
+ hr = IDirectSoundCaptureBuffer_GetCurrentPosition (ds->dsound_capture_buffer, &cpos, NULL);
+ if (FAILED (hr)) {
+ cpos = 0;
+ DSLOGF(("DSound: open GetCurrentPosition %Rhrc\n", hr));
+ }
+
+ memset (&wfx, 0, sizeof (wfx));
+ hr = IDirectSoundCaptureBuffer_GetFormat (ds->dsound_capture_buffer, &wfx, sizeof (wfx), NULL);
+ if (FAILED (hr)) {
+ DSLOGREL(("DSound: capture buffer GetFormat %Rhrc\n", hr));
+ goto fail0;
+ }
+
+ memset (&bc, 0, sizeof (bc));
+ bc.dwSize = sizeof (bc);
+ hr = IDirectSoundCaptureBuffer_GetCaps (ds->dsound_capture_buffer, &bc);
+ if (FAILED (hr)) {
+ DSLOGREL(("DSound: capture buffer GetCaps %Rhrc\n", hr));
+ goto fail0;
+ }
+
+ DSLOGF(("DSound: capture buffer format: size %d bytes\n"
+ " tag = %d\n"
+ " nChannels = %d\n"
+ " nSamplesPerSec = %d\n"
+ " nAvgBytesPerSec = %d\n"
+ " nBlockAlign = %d\n"
+ " wBitsPerSample = %d\n"
+ " cbSize = %d\n",
+ bc.dwBufferBytes,
+ wfx.wFormatTag,
+ wfx.nChannels,
+ wfx.nSamplesPerSec,
+ wfx.nAvgBytesPerSec,
+ wfx.nBlockAlign,
+ wfx.wBitsPerSample,
+ wfx.cbSize));
+
+ if (bc.dwBufferBytes & ds->hw.info.align) {
+ DSLOGREL(("DSound: GetCaps returned misaligned buffer size %ld, alignment %d\n",
+ bc.dwBufferBytes, ds->hw.info.align + 1));
+ }
+
+ if (ds->hw.samples != 0 && ds->hw.samples != (bc.dwBufferBytes >> ds->hw.info.shift)) {
+ DSLOGREL(("DSound: buffer size mismatch dsound %d, hw %d bytes\n",
+ bc.dwBufferBytes, ds->hw.samples << ds->hw.info.shift));
+ }
+
+ /* Initial state: reading at the initial capture position. */
+ ds->hw.wpos = 0;
+ ds->last_read_pos = cpos >> ds->hw.info.shift;
+ ds->capture_buffer_size = bc.dwBufferBytes >> ds->hw.info.shift;
+ DSLOGF(("DSound: open last_read_pos %d, capture_buffer_size %d\n", ds->last_read_pos, ds->capture_buffer_size));
+
+ ds->hr_last_run_in = S_OK;
+
+ return 0;
+
+ fail0:
+ dsoundCaptureClose (ds);
+ return -1;
+}
+
+static void dsoundCaptureStop (DSoundVoiceIn *ds)
+{
+ if (ds->dsound_capture_buffer) {
+ HRESULT hr = IDirectSoundCaptureBuffer_Stop (ds->dsound_capture_buffer);
+ if (FAILED (hr)) {
+ DSLOGF(("DSound: stop capture buffer %Rhrc\n", hr));
+ }
+ }
+}
+
+static int dsoundCaptureStart (DSoundVoiceIn *ds)
+{
+ HRESULT hr;
+ DWORD status;
+
+ if (ds->dsound_capture_buffer != NULL) {
+ hr = IDirectSoundCaptureBuffer_GetStatus (ds->dsound_capture_buffer, &status);
+ if (FAILED (hr)) {
+ DSLOGF(("DSound: start GetStatus %Rhrc\n", hr));
+ }
+ else {
+ if (status & DSCBSTATUS_CAPTURING) {
+ DSLOGF(("DSound: already capturing\n"));
+ }
+ else {
+ hr = IDirectSoundCaptureBuffer_Start (ds->dsound_capture_buffer, DSCBSTART_LOOPING);
+ if (FAILED (hr)) {
+ DSLOGREL(("DSound: start %Rhrc\n", hr));
+ }
+ }
+ }
+ }
+ else {
+ hr = E_FAIL;
+ }
+
+ return SUCCEEDED (hr)? 0: -1;
+}
+
#include "dsound_template.h"
#define DSBTYPE_IN
#include "dsound_template.h"
@@ -832,51 +1081,23 @@ static int dsound_run_out (HWVoiceOut *hw)
static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
{
- HRESULT hr;
- DWORD status;
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
- LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
-
- if (!dscb) {
- dolog ("Attempt to control capture voice without a buffer\n");
- return -1;
- }
switch (cmd) {
case VOICE_ENABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- dolog ("warning: Voice is already capturing\n");
- return 0;
- }
-
- /* clear ?? */
+ /* Try to start capture. If it fails, then reopen and try again. */
+ if (dsoundCaptureStart (ds)) {
+ dsoundCaptureClose (ds);
+ dsoundCaptureOpen (ds);
- hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not start capturing\n");
- return -1;
+ if (dsoundCaptureStart (ds)) {
+ return -1;
+ }
}
break;
case VOICE_DISABLE:
- if (dsound_get_status_in (dscb, &status)) {
- return -1;
- }
-
- if (status & DSCBSTATUS_CAPTURING) {
- hr = IDirectSoundCaptureBuffer_Stop (dscb);
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not stop capturing\n");
- return -1;
- }
- }
- else {
- dolog ("warning: Voice is not capturing\n");
- }
+ dsoundCaptureStop (ds);
break;
}
return 0;
@@ -894,15 +1115,16 @@ static int dsound_run_in (HWVoiceIn *hw)
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
int live, len, dead;
+ int ltmp;
DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD cpos, rpos;
+ int len1, len2;
+ int decr;
+ DWORD cpos;
LPVOID p1, p2;
int hwshift;
if (!dscb) {
- dolog ("Attempt to run without capture buffer\n");
+ DSLOGF(("DSound: run_in no capture buffer\n"));
return 0;
}
@@ -917,29 +1139,25 @@ static int dsound_run_in (HWVoiceIn *hw)
hr = IDirectSoundCaptureBuffer_GetCurrentPosition (
dscb,
&cpos,
- ds->first_time ? &rpos : NULL
+ NULL
);
if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer position\n");
- return 0;
- }
-
- if (ds->first_time) {
- ds->first_time = 0;
- if (rpos & hw->info.align) {
- ldebug ("warning: Misaligned capture read position %ld(%d)\n",
- rpos, hw->info.align);
+ if (hr != ds->hr_last_run_in) {
+ DSLOGREL(("DSound: run_in GetCurrentPosition %Rhrc\n", hr));
}
- hw->wpos = rpos >> hwshift;
+ ds->hr_last_run_in = hr;
+ return 0;
}
+ ds->hr_last_run_in = hr;
if (cpos & hw->info.align) {
- ldebug ("warning: Misaligned capture position %ld(%d)\n",
- cpos, hw->info.align);
+ DSLOGF(("DSound: run_in misaligned capture position %ld(%d)\n", cpos, hw->info.align));
}
+
cpos >>= hwshift;
- len = audio_ring_dist (cpos, hw->wpos, hw->samples);
+ /* Number of samples available in the capture buffer. */
+ len = audio_ring_dist (cpos, ds->last_read_pos, ds->capture_buffer_size);
if (!len) {
return 0;
}
@@ -948,7 +1166,7 @@ static int dsound_run_in (HWVoiceIn *hw)
err = dsound_lock_in (
dscb,
&hw->info,
- hw->wpos << hwshift,
+ ds->last_read_pos << hwshift,
len << hwshift,
&p1,
&p2,
@@ -964,26 +1182,26 @@ static int dsound_run_in (HWVoiceIn *hw)
len2 = blen2 >> hwshift;
decr = len1 + len2;
-#ifndef VBOX
if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
- }
-
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
- }
-#else
- if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1, &pcm_in_volume);
+ ltmp = audio_MIN(len1, hw->samples - hw->wpos);
+ hw->conv (hw->conv_buf + hw->wpos, p1, ltmp, &pcm_in_volume);
+ if (len1 > ltmp) {
+ hw->conv (hw->conv_buf, (void *)((uintptr_t)p1 + (ltmp << hwshift)), len1 - ltmp, &pcm_in_volume);
+ }
+ hw->wpos = (hw->wpos + len1) % hw->samples;
}
if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2, &pcm_in_volume);
+ ltmp = audio_MIN(len2, hw->samples - hw->wpos);
+ hw->conv (hw->conv_buf + hw->wpos, p2, ltmp, &pcm_in_volume);
+ if (len2 > ltmp) {
+ hw->conv (hw->conv_buf, (void *)((uintptr_t)p2 + (ltmp << hwshift)), len2 - ltmp, &pcm_in_volume);
+ }
+ hw->wpos = (hw->wpos + len2) % hw->samples;
}
-#endif
dsound_unlock_in (dscb, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
+ ds->last_read_pos = (ds->last_read_pos + decr) % ds->capture_buffer_size;
return decr;
}
@@ -1080,47 +1298,14 @@ static void *dsound_audio_init (void)
return NULL;
}
- hr = CoCreateInstance (
- &CLSID_DirectSoundCapture,
- NULL,
- CLSCTX_ALL,
- &IID_IDirectSoundCapture,
- (void **) &s->dsound_capture
- );
- if (FAILED (hr)) {
-#ifndef VBOX
- dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
-#else
- LogRel(("DSound: Could not create DirectSoundCapture instance\n"));
- dsound_log_hresult(hr);
-#endif
- }
- else {
- if (conf.device_guid_in) {
- hr = RTUuidFromStr(&devguid, conf.device_guid_in);
- if (FAILED (hr)) {
- LogRel(("DSound: Could not parse DirectSound input device GUID\n"));
- }
- devguidp = (LPCGUID)&devguid;
- } else {
- devguidp = NULL;
- }
- hr = IDirectSoundCapture_Initialize (s->dsound_capture, devguidp);
- if (FAILED (hr)) {
-#ifndef VBOX
- dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
-#else
- LogRel(("DSound: Could not initialize DirectSoundCapture\n"));
- dsound_log_hresult(hr);
-#endif
-
- hr = IDirectSoundCapture_Release (s->dsound_capture);
- if (FAILED (hr)) {
- dsound_logerr (hr,
- "Could not release DirectSoundCapture\n");
- }
- s->dsound_capture = NULL;
+ if (conf.device_guid_in) {
+ int rc = RTUuidFromStr(&s->devguid_capture, conf.device_guid_in);
+ if (RT_FAILURE(rc)) {
+ LogRel(("DSound: Could not parse DirectSound input device GUID\n"));
}
+ s->devguidp_capture = (LPCGUID)&s->devguid_capture;
+ } else {
+ s->devguidp_capture = NULL;
}
err = dsound_open (s);
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyEfiCompressor/setup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyUtility/setup.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/C/PyUtility/setup.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/AutoGen.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/AutoGen.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/BuildEngine.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/BuildEngine.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenC.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenC.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenDepex.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenDepex.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenMake.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/GenMake.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/StrGather.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/StrGather.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/UniClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/AutoGen/UniClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/BPDG.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/BPDG.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/GenVpd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/GenVpd.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/StringTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/BPDG/StringTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Database.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Database.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DecClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DecClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Dictionary.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Dictionary.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DscClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/DscClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspace.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspace.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkIIWorkspaceBuild.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkLogger.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/EdkLogger.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Expression.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Expression.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/FdfClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/FdfClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/InfClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/InfClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/MigrationUtilities.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/MigrationUtilities.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Misc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Misc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Parsing.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Parsing.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/String.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/String.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/TargetTxtClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/TargetTxtClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/ToolDefClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/ToolDefClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/ModuleClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/ModuleClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PackageClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PackageClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PlatformClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/CommonDataClass/PlatformClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CLexer.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CLexer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Check.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Check.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/CodeFragmentCollector.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Configuration.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Configuration.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Database.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Database.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Ecc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Ecc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Exception.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Exception.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/FileProfile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/FileProfile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaDataParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaDataParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaDataTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Xml/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/Xml/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/c.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Ecc/c.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CLexer.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CLexer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CodeFragmentCollector.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/CodeFragmentCollector.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Database.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Database.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Eot.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Eot.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/EotGlobalData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/EotGlobalData.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FileProfile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FileProfile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FvImage.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/FvImage.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/InfParserLite.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/InfParserLite.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Parser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/Parser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Eot/c.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/AprioriSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/AprioriSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Capsule.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Capsule.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CapsuleData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CapsuleData.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/ComponentStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/ComponentStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CompressSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/CompressSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DataSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DataSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DepexSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/DepexSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/EfiSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/EfiSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fd.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FdfParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FdfParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Ffs.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Ffs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsFileStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FfsInfStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fv.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Fv.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FvImageSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/FvImageSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFds.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFds.py
old mode 100644
new mode 100755
index 6068331..6bfa08a
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFds.py
@@ -468,7 +468,7 @@ class GenFds :
if TotalFound and UsedFound and FreeFound:
FvSpaceInfoList.append((FvName, Total, Used, Free))
- GenFdsGlobalVariable.InfLogger('\nFV Space Information')
+ GenFdsGlobalVariable.QuietLogger('\nFV Space Information')
for FvSpaceInfo in FvSpaceInfoList:
Name = FvSpaceInfo[0]
TotalSizeValue = long(FvSpaceInfo[1], 0)
@@ -479,7 +479,7 @@ class GenFds :
else:
Percentage = str((UsedSizeValue+0.0)/TotalSizeValue)[0:4].lstrip('0.')
- GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')
+ GenFdsGlobalVariable.QuietLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')
## PreprocessImage()
#
@@ -522,7 +522,7 @@ class GenFds :
GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))
if GuidXRefFile.getvalue():
SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)
- GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)
+ GenFdsGlobalVariable.QuietLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)
elif os.path.exists(GuidXRefFileName):
os.remove(GuidXRefFileName)
GuidXRefFile.close()
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
old mode 100644
new mode 100755
index 49a79ba..1500e3c
--- a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -610,6 +610,9 @@ class GenFdsGlobalVariable:
def InfLogger (msg):
EdkLogger.info(msg)
+ def QuietLogger (msg):
+ EdkLogger.quiet(msg)
+
def ErrorLogger (msg, File = None, Line = None, ExtraData = None):
EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
@@ -702,6 +705,7 @@ class GenFdsGlobalVariable:
VerboseLogger = staticmethod(VerboseLogger)
InfLogger = staticmethod(InfLogger)
ErrorLogger = staticmethod(ErrorLogger)
+ QuietLogger = staticmethod(QuietLogger)
DebugLogger = staticmethod(DebugLogger)
MacroExtend = staticmethod (MacroExtend)
GetPcdValue = staticmethod(GetPcdValue)
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomFileStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptRomInfStatement.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptionRom.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/OptionRom.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Region.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Region.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Rule.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Rule.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleComplexFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleComplexFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleSimpleFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/RuleSimpleFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Section.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Section.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/UiSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/UiSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/VerSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/VerSection.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Vtf.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/Vtf.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDataModel.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDataModel.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDec.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDec.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDsc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableDsc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableEotReport.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableEotReport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFdf.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFdf.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFunction.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableFunction.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableIdentifier.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableIdentifier.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableInf.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableInf.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TablePcd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TablePcd.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableQuery.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableQuery.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableReport.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Table/TableReport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/TargetTool/TargetTool.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/TargetTool/TargetTool.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Trim/Trim.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Trim/Trim.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/BuildVersion.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/BuildVersion.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DependencyRules.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/IpiDb.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/IpiDb.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/PackageFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/PackageFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Core/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/InstallPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/InstallPkg.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentGenerating.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentGenerating.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentParsing.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/CommentParsing.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/DataType.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/DataType.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/GlobalData.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/GlobalData.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Misc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Misc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ParserValidate.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/ParserValidate.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Parsing.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Parsing.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/String.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/String.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/Xml/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Library/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/Log.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/Log.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/StringTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/StringTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Logger/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/MkPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/MkPkg.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/POM/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/Parser/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Object/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Parser/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/PomAdapter/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/CommonXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/CommonXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/IniToXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/IniToXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PcdXml.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/PcdXml.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/Xml/__init__.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/BuildClassObject.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/BuildClassObject.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaDataTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaDataTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileParser.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileParser.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileTable.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/MetaFileTable.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/BuildReport.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/BuildReport.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/build.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/build/build.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd
index 6d4d015..44a2ac3 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI32.fd differ
diff --git a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd
index 9eeb19c..7ef4975 100644
Binary files a/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd and b/src/VBox/Devices/EFI/FirmwareBin/VBoxEFI64.fd differ
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
index a247557..afcc5c7 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.asm
@@ -6781,7 +6781,7 @@ vesa_pm_end: ; 0xc4714 LB 0x1
section _DATA progbits vstart=0x4800 align=1 ; size=0x36e1 class=DATA group=DGROUP
_msg_vga_init: ; 0xc4800 LB 0x2f
- db 'Oracle VM VirtualBox Version 4.3.20 VGA BIOS', 00dh, 00ah, 000h
+ db 'Oracle VM VirtualBox Version 4.3.22 VGA BIOS', 00dh, 00ah, 000h
_vga_modes: ; 0xc482f LB 0x80
db 000h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 001h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
db 002h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h, 003h, 000h, 000h, 004h, 000h, 0b8h, 0ffh, 002h
@@ -7669,7 +7669,7 @@ _vbebios_vendor_name: ; 0xc7e35 LB 0x13
_vbebios_product_name: ; 0xc7e48 LB 0x21
db 'Oracle VM VirtualBox VBE Adapter', 000h
_vbebios_product_revision: ; 0xc7e69 LB 0x24
- db 'Oracle VM VirtualBox Version 4.3.20', 000h
+ db 'Oracle VM VirtualBox Version 4.3.22', 000h
_vbebios_info_string: ; 0xc7e8d LB 0x2b
db 'VirtualBox VBE Display Adapter enabled', 00dh, 00ah, 00dh, 00ah, 000h
_no_vbebios_info_string: ; 0xc7eb8 LB 0x29
@@ -7700,4 +7700,4 @@ section CONST2 progbits vstart=0x7ee2 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, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 066h
+ db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 062h
diff --git a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
index bca723d..618c8a3 100644
--- a/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
+++ b/src/VBox/Devices/Graphics/BIOS/VBoxVgaBiosAlternative.md5sum
@@ -1 +1 @@
-f0c2efede19d504be4e738110eed5820 *VBoxVgaBios.rom
+c9b5281c79cc70a72c6e4cb1591d673e *VBoxVgaBios.rom
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
index df3b92c..c91c013 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
@@ -1,8 +1,17 @@
+/* $Id: DevVGA-SVGA.cpp $ */
/** @file
- * VMWare SVGA device
+ * VMWare SVGA device.
+ *
+ * Logging levels guidelines for this and related files:
+ * - Log() for normal bits.
+ * - LogFlow() for more info.
+ * - Log2 for hex dump of cursor data.
+ * - Log3 for hex dump of shader code.
+ * - Log4 for hex dumps of 3D data.
*/
+
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,17 +27,24 @@
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
+#define VMSVGA_USE_EMT_HALT_CODE
#include <VBox/vmm/pdmdev.h>
#include <VBox/version.h>
#include <VBox/err.h>
#include <VBox/log.h>
#include <VBox/vmm/pgm.h>
+#ifdef VMSVGA_USE_EMT_HALT_CODE
+# include <VBox/vmm/vmapi.h>
+# include <VBox/vmm/vmcpuset.h>
+# include <VBox/vmm/vm.h> /* Need VMCPU::idCpu. */
+#endif
+#include <VBox/sup.h>
#include <iprt/assert.h>
#include <iprt/semaphore.h>
#include <iprt/uuid.h>
#ifdef IN_RING3
-#include <iprt/mem.h>
+# include <iprt/mem.h>
#endif
#include <VBox/VMMDev.h>
@@ -40,14 +56,11 @@
#ifdef DEBUG
/* Enable to log FIFO register accesses. */
-//#define DEBUG_FIFO_ACCESS
+//# define DEBUG_FIFO_ACCESS
/* Enable to log GMR page accesses. */
-//#define DEBUG_GMR_ACCESS
+//# define DEBUG_GMR_ACCESS
#endif
-/** Converts a display port interface pointer to a vga state pointer. */
-#define IDISPLAYPORT_2_VGASTATE(pInterface) ( (PVGASTATE)((uintptr_t)pInterface - RT_OFFSETOF(VGASTATE, IPort)) )
-
#include "DevVGA-SVGA.h"
#include "vmsvga/svga_reg.h"
#include "vmsvga/svga_escape.h"
@@ -55,10 +68,24 @@
#include "vmsvga/svga3d_reg.h"
#include "vmsvga/svga3d_caps.h"
#ifdef VBOX_WITH_VMSVGA3D
-#include "DevVGA-SVGA3d.h"
+# include "DevVGA-SVGA3d.h"
#endif
/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/**
+ * Macro for checking if a fixed FIFO register is valid according to the
+ * current FIFO configuration.
+ *
+ * @returns true / false.
+ * @param a_iIndex The fifo register index (like SVGA_FIFO_CAPABILITIES).
+ * @param a_offFifoMin A valid SVGA_FIFO_MIN value.
+ */
+#define VMSVGA_IS_VALID_FIFO_REG(a_iIndex, a_offFifoMin) ( ((a_iIndex) + 1) * sizeof(uint32_t) <= (a_offFifoMin) )
+
+
+/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/* 64-bit GMR descriptor */
@@ -98,9 +125,33 @@ typedef struct
void *pData;
} Cursor;
SVGAColorBGRX colorAnnotation;
+
+#ifdef VMSVGA_USE_EMT_HALT_CODE
+ /** Number of EMTs in BusyDelayedEmts (quicker than scanning the set). */
+ uint32_t volatile cBusyDelayedEmts;
+ /** Set of EMTs that are */
+ VMCPUSET BusyDelayedEmts;
+#else
+ /** Number of EMTs waiting on hBusyDelayedEmts. */
+ uint32_t volatile cBusyDelayedEmts;
+ /** Semaphore that EMTs wait on when reading SVGA_REG_BUSY and the FIFO is
+ * busy (ugly). */
+ RTSEMEVENTMULTI hBusyDelayedEmts;
+#endif
+ /** Tracks how much time we waste reading SVGA_REG_BUSY with a busy FIFO. */
+ STAMPROFILE StatBusyDelayEmts;
+
STAMPROFILE StatR3CmdPresent;
STAMPROFILE StatR3CmdDrawPrimitive;
STAMPROFILE StatR3CmdSurfaceDMA;
+
+ STAMCOUNTER StatFifoCommands;
+ STAMCOUNTER StatFifoErrors;
+ STAMCOUNTER StatFifoUnkCmds;
+ STAMCOUNTER StatFifoTodoTimeout;
+ STAMCOUNTER StatFifoTodoWoken;
+ STAMPROFILE StatFifoStalls;
+
} VMSVGASTATE, *PVMSVGASTATE;
#ifdef IN_RING3
@@ -142,9 +193,22 @@ static SSMFIELD const g_aVMSVGASTATEFields[] =
SSMFIELD_ENTRY( VMSVGASTATE, Cursor.cbData),
SSMFIELD_ENTRY_IGN_HCPTR( VMSVGASTATE, Cursor.pData),
SSMFIELD_ENTRY( VMSVGASTATE, colorAnnotation),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, cBusyDelayedEmts),
+#ifdef VMSVGA_USE_EMT_HALT_CODE
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, BusyDelayedEmts),
+#else
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, hBusyDelayedEmts),
+#endif
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatBusyDelayEmts),
SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatR3CmdPresent),
SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatR3CmdDrawPrimitive),
SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatR3CmdSurfaceDMA),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatFifoCommands),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatFifoErrors),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatFifoUnkCmds),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatFifoTodoTimeout),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatFifoTodoWoken),
+ SSMFIELD_ENTRY_IGNORE( VMSVGASTATE, StatFifoStalls),
SSMFIELD_ENTRY_TERM()
};
@@ -177,6 +241,7 @@ static SSMFIELD const g_aVGAStateSVGAFields[] =
SSMFIELD_ENTRY( VMSVGAState, u32RegCaps),
SSMFIELD_ENTRY_IGNORE( VMSVGAState, BasePort),
SSMFIELD_ENTRY( VMSVGAState, u32IndexReg),
+ SSMFIELD_ENTRY_IGNORE( VMSVGAState, pSupDrvSession),
SSMFIELD_ENTRY_IGNORE( VMSVGAState, FIFORequestSem),
SSMFIELD_ENTRY_IGNORE( VMSVGAState, FIFOExtCmdSem),
SSMFIELD_ENTRY_IGN_HCPTR( VMSVGAState, pFIFOIOThread),
@@ -192,15 +257,10 @@ static SSMFIELD const g_aVGAStateSVGAFields[] =
SSMFIELD_ENTRY_IGNORE( VMSVGAState, u8FIFOExtCommand),
SSMFIELD_ENTRY_TERM()
};
-#endif /* IN_RING3 */
-
-RT_C_DECLS_BEGIN
-#ifdef IN_RING3
static void vmsvgaSetTraces(PVGASTATE pThis, bool fTraces);
-#endif
-RT_C_DECLS_END
+#endif /* IN_RING3 */
#ifdef LOG_ENABLED
@@ -316,11 +376,10 @@ static const char *vmsvgaIndexToString(PVGASTATE pThis)
return "SVGA_REG_NUM_DISPLAYS";
default:
- if ( pThis->svga.u32IndexReg >= SVGA_SCRATCH_BASE
- && pThis->svga.u32IndexReg < SVGA_SCRATCH_BASE + pThis->svga.cScratchRegion)
- {
+ if (pThis->svga.u32IndexReg - (uint32_t)SVGA_SCRATCH_BASE < pThis->svga.cScratchRegion)
return "SVGA_SCRATCH_BASE reg";
- }
+ if (pThis->svga.u32IndexReg - (uint32_t)SVGA_PALETTE_BASE < (uint32_t)SVGA_NUM_PALETTE_REGS)
+ return "SVGA_PALETTE_BASE reg";
return "UNKNOWN";
}
}
@@ -459,7 +518,7 @@ static const char *vmsvgaFIFOCmdToString(uint32_t u32Cmd)
*/
DECLCALLBACK(void) vmsvgaPortSetViewPort(PPDMIDISPLAYPORT pInterface, uint32_t uScreenId, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy)
{
- PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
+ PVGASTATE pThis = RT_FROM_MEMBER(pInterface, VGASTATE, IPort);
Log(("vmsvgaPortSetViewPort: screen %d (%d,%d)(%d,%d)\n", uScreenId, x, y, cx, cy));
@@ -733,14 +792,56 @@ PDMBOTHCBDECL(int) vmsvgaReadPort(PVGASTATE pThis, uint32_t *pu32)
if (pThis->svga.fBusy)
{
#ifndef IN_RING3
+ /* Go to ring-3 and halt the CPU. */
rc = VINF_IOM_R3_IOPORT_READ;
break;
+#elif defined(VMSVGA_USE_EMT_HALT_CODE)
+ /* The guest is basically doing a HLT via the device here, but with
+ a special wake up condition on FIFO completion. */
+ PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+ STAM_REL_PROFILE_START(&pSVGAState->StatBusyDelayEmts, EmtDelay);
+ PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
+ VMCPUID idCpu = PDMDevHlpGetVMCPU(pThis->pDevInsR3)->idCpu; /** @todo add a separate dev helper for this. */
+ VMCPUSET_ATOMIC_ADD(&pSVGAState->BusyDelayedEmts, idCpu);
+ ASMAtomicIncU32(&pSVGAState->cBusyDelayedEmts);
+ if (pThis->svga.fBusy)
+ rc = VMR3WaitForDeviceReady(pVM, idCpu);
+ ASMAtomicDecU32(&pSVGAState->cBusyDelayedEmts);
+ VMCPUSET_ATOMIC_DEL(&pSVGAState->BusyDelayedEmts, idCpu);
#else
- /* @todo bit crude */
- RTThreadSleep(50);
+
+ /* Delay the EMT a bit so the FIFO and others can get some work done.
+ This used to be a crude 50 ms sleep. The current code tries to be
+ more efficient, but the consept is still very crude. */
+ PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
+ STAM_REL_PROFILE_START(&pSVGAState->StatBusyDelayEmts, EmtDelay);
+ RTThreadYield();
+ if (pThis->svga.fBusy)
+ {
+ uint32_t cRefs = ASMAtomicIncU32(&pSVGAState->cBusyDelayedEmts);
+
+ if (pThis->svga.fBusy && cRefs == 1)
+ RTSemEventMultiReset(pSVGAState->hBusyDelayedEmts);
+ if (pThis->svga.fBusy)
+ {
+ /** @todo If this code is going to stay, we need to call into the halt/wait
+ * code in VMEmt.cpp here, otherwise all kind of EMT interaction will
+ * suffer when the guest is polling on a busy FIFO. */
+ uint64_t cNsMaxWait = TMVirtualSyncGetNsToDeadline(PDMDevHlpGetVM(pThis->pDevInsR3));
+ if (cNsMaxWait >= RT_NS_100US)
+ RTSemEventMultiWaitEx(pSVGAState->hBusyDelayedEmts,
+ RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NORESUME,
+ RT_MIN(cNsMaxWait, RT_NS_10MS));
+ }
+
+ ASMAtomicDecU32(&pSVGAState->cBusyDelayedEmts);
+ }
+ STAM_REL_PROFILE_STOP(&pSVGAState->StatBusyDelayEmts, EmtDelay);
#endif
+ *pu32 = pThis->svga.fBusy != 0;
}
- *pu32 = pThis->svga.fBusy;
+ else
+ *pu32 = false;
break;
case SVGA_REG_GUEST_ID: /* Set guest OS identifier */
@@ -839,7 +940,7 @@ PDMBOTHCBDECL(int) vmsvgaReadPort(PVGASTATE pThis, uint32_t *pu32)
}
break;
}
- Log(("vmsvgaReadPort index=%s (%d) val=%x rc=%x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, *pu32, rc));
+ Log(("vmsvgaReadPort index=%s (%d) val=%#x rc=%x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, *pu32, rc));
return rc;
}
@@ -912,6 +1013,31 @@ int vmsvgaChangeMode(PVGASTATE pThis)
}
#endif /* IN_RING3 */
+#if defined(IN_RING0) || defined(IN_RING3)
+/**
+ * Safely updates the SVGA_FIFO_BUSY register (in shared memory).
+ *
+ * @param pThis The VMSVGA state.
+ * @param fState The busy state.
+ */
+DECLINLINE(void) vmsvgaSafeFifoBusyRegUpdate(PVGASTATE pThis, bool fState)
+{
+ ASMAtomicWriteU32(&pThis->svga.CTX_SUFF(pFIFO)[SVGA_FIFO_BUSY], fState);
+
+ if (RT_UNLIKELY(fState != (pThis->svga.fBusy != 0)))
+ {
+ /* Race / unfortunately scheduling. Highly unlikly. */
+ uint32_t cLoops = 64;
+ do
+ {
+ ASMNopPause();
+ fState = (pThis->svga.fBusy != 0);
+ ASMAtomicWriteU32(&pThis->svga.CTX_SUFF(pFIFO)[SVGA_FIFO_BUSY], fState != 0);
+ } while (cLoops-- > 0 && fState != (pThis->svga.fBusy != 0));
+ }
+}
+#endif
+
/**
* Write port register
*
@@ -924,7 +1050,7 @@ PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
int rc = VINF_SUCCESS;
- Log(("vmsvgaWritePort index=%s (%d) val=%x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, u32));
+ Log(("vmsvgaWritePort index=%s (%d) val=%#x\n", vmsvgaIndexToString(pThis), pThis->svga.u32IndexReg, u32));
switch (pThis->svga.u32IndexReg)
{
case SVGA_REG_ID:
@@ -1000,58 +1126,64 @@ PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
break;
case SVGA_REG_WIDTH:
- if (pThis->svga.uWidth == u32)
- break; /* nop */
-
- pThis->svga.uWidth = u32;
- if (pThis->svga.fEnabled)
+ if (pThis->svga.uWidth != u32)
{
+ if (pThis->svga.fEnabled)
+ {
#ifdef IN_RING3
- rc = vmsvgaChangeMode(pThis);
- AssertRCReturn(rc, rc);
+ pThis->svga.uWidth = u32;
+ rc = vmsvgaChangeMode(pThis);
+ AssertRCReturn(rc, rc);
#else
- rc = VINF_IOM_R3_IOPORT_WRITE;
- break;
+ rc = VINF_IOM_R3_IOPORT_WRITE;
#endif
+ }
+ else
+ pThis->svga.uWidth = u32;
}
+ /* else: nop */
break;
case SVGA_REG_HEIGHT:
- if (pThis->svga.uHeight == u32)
- break; /* nop */
-
- pThis->svga.uHeight = u32;
- if (pThis->svga.fEnabled)
+ if (pThis->svga.uHeight != u32)
{
+ if (pThis->svga.fEnabled)
+ {
#ifdef IN_RING3
- rc = vmsvgaChangeMode(pThis);
- AssertRCReturn(rc, rc);
+ pThis->svga.uHeight = u32;
+ rc = vmsvgaChangeMode(pThis);
+ AssertRCReturn(rc, rc);
#else
- rc = VINF_IOM_R3_IOPORT_WRITE;
- break;
+ rc = VINF_IOM_R3_IOPORT_WRITE;
#endif
+ }
+ else
+ pThis->svga.uHeight = u32;
}
+ /* else: nop */
break;
case SVGA_REG_DEPTH:
- /* @todo read-only?? */
+ /** @todo read-only?? */
break;
case SVGA_REG_BITS_PER_PIXEL: /* Current bpp in the guest */
- if (pThis->svga.uBpp == u32)
- break; /* nop */
-
- pThis->svga.uBpp = u32;
- if (pThis->svga.fEnabled)
+ if (pThis->svga.uBpp != u32)
{
+ if (pThis->svga.fEnabled)
+ {
#ifdef IN_RING3
- rc = vmsvgaChangeMode(pThis);
- AssertRCReturn(rc, rc);
+ pThis->svga.uBpp = u32;
+ rc = vmsvgaChangeMode(pThis);
+ AssertRCReturn(rc, rc);
#else
- rc = VINF_IOM_R3_IOPORT_WRITE;
- break;
+ rc = VINF_IOM_R3_IOPORT_WRITE;
#endif
+ }
+ else
+ pThis->svga.uBpp = u32;
}
+ /* else: nop */
break;
case SVGA_REG_PSEUDOCOLOR:
@@ -1075,13 +1207,14 @@ PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
if ( pThis->svga.fEnabled
&& pThis->svga.fConfigured)
{
-#ifdef IN_RING3
- Log(("SVGA_REG_SYNC: SVGA_FIFO_BUSY=%d\n", pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
- pThis->svga.fBusy = true;
- pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
+#if defined(IN_RING3) || defined(IN_RING0)
+ Log(("SVGA_REG_SYNC: SVGA_FIFO_BUSY=%d\n", pThis->svga.CTX_SUFF(pFIFO)[SVGA_FIFO_BUSY]));
+ ASMAtomicWriteU32(&pThis->svga.fBusy, VMSVGA_BUSY_F_EMT_FORCE | VMSVGA_BUSY_F_FIFO);
+ if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_BUSY, pThis->svga.CTX_SUFF(pFIFO)[SVGA_FIFO_MIN]))
+ vmsvgaSafeFifoBusyRegUpdate(pThis, true);
/* Kick the FIFO thread to start processing commands again. */
- RTSemEventSignal(pThis->svga.FIFORequestSem);
+ SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
#else
rc = VINF_IOM_R3_IOPORT_WRITE;
#endif
@@ -1145,10 +1278,10 @@ PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
break;
case SVGA_REG_GMR_DESCRIPTOR:
-#ifndef IN_RING3
+# ifndef IN_RING3
rc = VINF_IOM_R3_IOPORT_WRITE;
break;
-#else
+# else /* IN_RING3 */
{
SVGAGuestMemDescriptor desc;
RTGCPHYS GCPhys = (RTGCPHYS)u32 << PAGE_SHIFT;
@@ -1216,7 +1349,7 @@ PDMBOTHCBDECL(int) vmsvgaWritePort(PVGASTATE pThis, uint32_t u32)
AssertRC(rc);
break;
}
-#endif
+# endif /* IN_RING3 */
#endif // VBOX_WITH_VMSVGA3D
case SVGA_REG_TRACES: /* Enable trace-based updates even when FIFO is on */
@@ -1739,8 +1872,9 @@ static DECLCALLBACK(int) vmsvgaR3FIFOAccessHandler(PVM pVM, RTGCPHYS GCPhys, voi
AssertMsg(rc <= VINF_SUCCESS, ("rc=%Rrc\n", rc));
return rc;
}
+
# endif /* IN_RING3 */
-#endif /* DEBUG */
+#endif /* DEBUG_FIFO_ACCESS */
#ifdef DEBUG_GMR_ACCESS
/**
@@ -1790,7 +1924,8 @@ end:
return VINF_PGM_HANDLER_DO_DEFAULT;
}
-#ifdef IN_RING3
+# ifdef IN_RING3
+
/* Callback handler for VMR3ReqCallWait */
static DECLCALLBACK(int) vmsvgaRegisterGMR(PPDMDEVINS pDevIns, uint32_t gmrId)
{
@@ -1848,71 +1983,201 @@ static DECLCALLBACK(int) vmsvgaResetGMRHandlers(PVGASTATE pThis)
}
return VINF_SUCCESS;
}
-#endif /* IN_RING3 */
-
+# endif /* IN_RING3 */
#endif /* DEBUG_GMR_ACCESS */
/* -=-=-=-=-=- Ring 3 -=-=-=-=-=- */
#ifdef IN_RING3
-#include <iprt/mem.h>
-
-static void *vmsvgaFIFOGetCmdBuffer(PPDMTHREAD pThread, uint32_t *pFIFO, uint32_t cbCmd, uint32_t *pSize, void **ppfBounceBuffer)
+/**
+ * Marks the FIFO non-busy, notifying any waiting EMTs.
+ *
+ * @param pThis The VGA state.
+ * @param pSVGAState Pointer to the ring-3 only SVGA state data.
+ * @param offFifoMin The start byte offset of the command FIFO.
+ */
+static void vmsvgaFifoSetNotBusy(PVGASTATE pThis, PVMSVGASTATE pSVGAState, uint32_t offFifoMin)
{
- uint32_t cbLeft;
- uint32_t cbFIFOCmd = pFIFO[SVGA_FIFO_MAX] - pFIFO[SVGA_FIFO_MIN];
- uint32_t u32Current = pFIFO[SVGA_FIFO_STOP] + sizeof(uint32_t); /* skip command dword */
- uint8_t *pCmdBuffer;
+ ASMAtomicAndU32(&pThis->svga.fBusy, ~VMSVGA_BUSY_F_FIFO);
+ if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_BUSY, offFifoMin))
+ vmsvgaSafeFifoBusyRegUpdate(pThis, pThis->svga.fBusy != 0);
- Assert(ppfBounceBuffer);
- /* Commands bigger than the fifo buffer are invalid. */
- AssertReturn(cbCmd <= cbFIFOCmd, NULL);
+ /* Wake up any waiting EMTs. */
+ if (pSVGAState->cBusyDelayedEmts > 0)
+ {
+#ifdef VMSVGA_USE_EMT_HALT_CODE
+ PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3);
+ VMCPUID idCpu = VMCpuSetFindLastPresentInternal(&pSVGAState->BusyDelayedEmts);
+ if (idCpu != NIL_VMCPUID)
+ {
+ VMR3NotifyCpuDeviceReady(pVM, idCpu);
+ while (idCpu-- > 0)
+ if (VMCPUSET_IS_PRESENT(&pSVGAState->BusyDelayedEmts, idCpu))
+ VMR3NotifyCpuDeviceReady(pVM, idCpu);
+ }
+#else
+ int rc2 = RTSemEventMultiSignal(pSVGAState->hBusyDelayedEmts);
+ AssertRC(rc2);
+#endif
+ }
+}
- *pSize += cbCmd;
- *ppfBounceBuffer = NULL;
+/**
+ * Reads (more) payload into the command buffer.
+ *
+ * @returns pbBounceBuf on success
+ * @retval (void *)1 if the thread was requested to stop.
+ * @retval NULL on FIFO error.
+ *
+ * @param cbPayloadReq The number of bytes of payload requested.
+ * @param pFIFO The FIFO.
+ * @param offCurrentCmd The FIFO byte offset of the current command.
+ * @param offFifoMin The start byte offset of the command FIFO.
+ * @param offFifoMax The end byte offset of the command FIFO.
+ * @param pbBounceBuf The bounch buffer. Same size as the entire FIFO, so
+ * always sufficient size.
+ * @param pcbAlreadyRead How much payload we've already read into the bounce
+ * buffer. (We will NEVER re-read anything.)
+ * @param pThread The calling PDM thread handle.
+ * @param pThis The VGA state.
+ * @param pSVGAState Pointer to the ring-3 only SVGA state data. For
+ * statistics collection.
+ */
+static void *vmsvgaFIFOGetCmdPayload(uint32_t cbPayloadReq, uint32_t volatile *pFIFO,
+ uint32_t offCurrentCmd, uint32_t offFifoMin, uint32_t offFifoMax,
+ uint8_t *pbBounceBuf, uint32_t *pcbAlreadyRead,
+ PPDMTHREAD pThread, PVGASTATE pThis, PVMSVGASTATE pSVGAState)
+{
+ Assert(pbBounceBuf);
+ Assert(pcbAlreadyRead);
+ Assert(offFifoMin < offFifoMax);
+ Assert(offCurrentCmd >= offFifoMin && offCurrentCmd < offFifoMax);
+ Assert(offFifoMax <= VMSVGA_FIFO_SIZE);
- while (pThread->enmState == PDMTHREADSTATE_RUNNING)
+ /*
+ * Check if the requested payload size has already been satisfied .
+ * .
+ * When called to read more, the caller is responsible for making sure the .
+ * new command size (cbRequsted) never is smaller than what has already .
+ * been read.
+ */
+ uint32_t cbAlreadyRead = *pcbAlreadyRead;
+ if (cbPayloadReq <= cbAlreadyRead)
{
- Assert(pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP]);
-
- if (pFIFO[SVGA_FIFO_NEXT_CMD] >= u32Current)
- cbLeft = pFIFO[SVGA_FIFO_NEXT_CMD] - u32Current;
- else
- cbLeft = cbFIFOCmd - (u32Current - pFIFO[SVGA_FIFO_NEXT_CMD]);
+ AssertLogRelReturn(cbPayloadReq == cbAlreadyRead, NULL);
+ return pbBounceBuf;
+ }
- if (cbCmd <= cbLeft)
- break;
+ /*
+ * Commands bigger than the fifo buffer are invalid.
+ */
+ uint32_t const cbFifoCmd = offFifoMax - offFifoMin;
+ AssertMsgReturnStmt(cbPayloadReq <= cbFifoCmd, ("cbPayloadReq=%#x cbFifoCmd=%#x\n", cbPayloadReq, cbFifoCmd),
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors),
+ NULL);
- /* Guest still busy copying into the FIFO; wait a bit. */
- Log(("Guest still copying (%x vs %x) current %x next %x stop %x; sleep a bit\n", cbCmd, cbLeft, u32Current, pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
- RTThreadSleep(2);
- }
+ /*
+ * Move offCurrentCmd past the command dword.
+ */
+ offCurrentCmd += sizeof(uint32_t);
+ if (offCurrentCmd >= offFifoMax)
+ offCurrentCmd = offFifoMin;
- if (u32Current + cbCmd <= pFIFO[SVGA_FIFO_MAX])
+ /*
+ * Do we have sufficient payload data available already?
+ */
+ uint32_t cbAfter, cbBefore;
+ uint32_t offNextCmd = pFIFO[SVGA_FIFO_NEXT_CMD];
+ if (offNextCmd > offCurrentCmd)
{
- pCmdBuffer = (uint8_t *)pFIFO + u32Current;
+ if (RT_LIKELY(offNextCmd < offFifoMax))
+ cbAfter = offNextCmd - offCurrentCmd;
+ else
+ {
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
+ LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
+ offNextCmd, offFifoMin, offFifoMax));
+ /** @todo release counter. */
+ cbAfter = offFifoMax - offCurrentCmd;
+ }
+ cbBefore = 0;
}
else
{
- /* command data split; allocate memory and copy. */
- uint8_t *pFIFOMin = (uint8_t *)pFIFO + pFIFO[SVGA_FIFO_MIN];
- uint32_t cbPart1 = pFIFO[SVGA_FIFO_MAX] - u32Current;
- uint32_t cbPart2 = cbCmd - cbPart1;
-
- LogFlow(("Split data buffer at %x (%d-%d)\n", u32Current, cbPart1, cbPart2));
- pCmdBuffer = (uint8_t *)RTMemAlloc(cbCmd);
- AssertReturn(pCmdBuffer, NULL);
- *ppfBounceBuffer = (void *)pCmdBuffer;
-
- memcpy(pCmdBuffer, (uint8_t *)pFIFO + u32Current, cbPart1);
- memcpy(pCmdBuffer + cbPart1, pFIFOMin, cbPart2);
+ cbAfter = offFifoMax - offCurrentCmd;
+ if (offNextCmd >= offFifoMin)
+ cbBefore = offNextCmd - offFifoMin;
+ else
+ {
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
+ LogRelMax(16, ("vmsvgaFIFOGetCmdPayload: Invalid offNextCmd=%#x (offFifoMin=%#x offFifoMax=%#x)\n",
+ offNextCmd, offFifoMin, offFifoMax));
+ /** @todo release counter. */
+ cbBefore = 0;
+ }
}
+ if (cbAfter + cbBefore < cbPayloadReq)
+ {
+ /*
+ * Insufficient, must wait for it to arrive.
+ */
+ STAM_REL_PROFILE_START(&pSVGAState->StatFifoStalls, Stall);
+ for (uint32_t i = 0;; i++)
+ {
+ if (pThread->enmState != PDMTHREADSTATE_RUNNING)
+ {
+ STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoStalls, Stall);
+ return (void *)(uintptr_t)1;
+ }
+ Log(("Guest still copying (%x vs %x) current %x next %x stop %x loop %u; sleep a bit\n",
+ cbPayloadReq, cbAfter + cbBefore, offCurrentCmd, offNextCmd, pFIFO[SVGA_FIFO_STOP], i));
- return pCmdBuffer;
-}
+ SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, i < 16 ? 1 : 2);
+
+ offNextCmd = pFIFO[SVGA_FIFO_NEXT_CMD];
+ if (offNextCmd > offCurrentCmd)
+ {
+ cbAfter = RT_MIN(offNextCmd, offFifoMax) - offCurrentCmd;
+ cbBefore = 0;
+ }
+ else
+ {
+ cbAfter = offFifoMax - offCurrentCmd;
+ cbBefore = RT_MAX(offNextCmd, offFifoMin) - offFifoMin;
+ }
+
+ if (cbAfter + cbBefore >= cbPayloadReq)
+ break;
+ }
+ STAM_REL_PROFILE_STOP(&pSVGAState->StatFifoStalls, Stall);
+ }
+ /*
+ * Copy out the memory and update what pcbAlreadyRead points to.
+ */
+ if (cbAfter >= cbPayloadReq)
+ memcpy(pbBounceBuf + cbAlreadyRead,
+ (uint8_t *)pFIFO + offCurrentCmd + cbAlreadyRead,
+ cbPayloadReq - cbAlreadyRead);
+ else
+ {
+ LogFlow(("Split data buffer at %x (%u-%u)\n", offCurrentCmd, cbAfter, cbBefore));
+ if (cbAlreadyRead < cbAfter)
+ {
+ memcpy(pbBounceBuf + cbAlreadyRead,
+ (uint8_t *)pFIFO + offCurrentCmd + cbAlreadyRead,
+ cbAfter - cbAlreadyRead);
+ cbAlreadyRead += cbAfter - cbAlreadyRead;
+ }
+ memcpy(pbBounceBuf + cbAlreadyRead,
+ (uint8_t *)pFIFO + offFifoMin + cbAlreadyRead - cbAfter,
+ cbPayloadReq - cbAlreadyRead);
+ }
+ *pcbAlreadyRead = cbPayloadReq;
+ return pbBounceBuf;
+}
/* The async FIFO handling thread. */
static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
@@ -1924,70 +2189,92 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
return VINF_SUCCESS;
+ /*
+ * Signal the semaphore to make sure we don't wait for 250 after a
+ * suspend & resume scenario (see vmsvgaFIFOGetCmdPayload).
+ */
+ SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
+
+ /*
+ * Allocate a bounce buffer for command we get from the FIFO.
+ * (All code must return via the end of the function to free this buffer.)
+ */
+ uint8_t *pbBounceBuf = (uint8_t *)RTMemAllocZ(VMSVGA_FIFO_SIZE);
+ AssertReturn(pbBounceBuf, VERR_NO_MEMORY);
+
LogFlow(("vmsvgaFIFOLoop: started loop\n"));
+ uint32_t volatile * const pFIFO = pThis->svga.pFIFOR3;
while (pThread->enmState == PDMTHREADSTATE_RUNNING)
{
- uint32_t *pFIFO = pThis->svga.pFIFOR3;
- /* Wait for at most 250 ms to start polling. */
- rc = RTSemEventWait(pThis->svga.FIFORequestSem, 250);
- AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);
+ /*
+ * Wait for at most 250 ms to start polling.
+ */
+ rc = SUPSemEventWaitNoResume(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem, 250);
+ AssertBreak(RT_SUCCESS(rc) || rc == VERR_TIMEOUT || rc == VERR_INTERRUPTED);
if (pThread->enmState != PDMTHREADSTATE_RUNNING)
{
LogFlow(("vmsvgaFIFOLoop: thread state %x\n", pThread->enmState));
- return VINF_SUCCESS;
+ break;
}
if (rc == VERR_TIMEOUT)
{
if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
continue;
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoTimeout);
Log(("vmsvgaFIFOLoop: timeout\n"));
}
+ else if (pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoTodoWoken);
+
Log(("vmsvgaFIFOLoop: enabled=%d configured=%d busy=%d\n", pThis->svga.fEnabled, pThis->svga.fConfigured, pThis->svga.pFIFOR3[SVGA_FIFO_BUSY]));
Log(("vmsvgaFIFOLoop: min %x max %x\n", pFIFO[SVGA_FIFO_MIN], pFIFO[SVGA_FIFO_MAX]));
Log(("vmsvgaFIFOLoop: next %x stop %x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
+ /*
+ * Handle external commands.
+ */
if (pThis->svga.u8FIFOExtCommand != VMSVGA_FIFO_EXTCMD_NONE)
{
switch (pThis->svga.u8FIFOExtCommand)
{
case VMSVGA_FIFO_EXTCMD_RESET:
Log(("vmsvgaFIFOLoop: reset the fifo thread.\n"));
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
if (pThis->svga.f3DEnabled)
{
/* The 3d subsystem must be reset from the fifo thread. */
vmsvga3dReset(pThis);
}
-#endif
+# endif
break;
case VMSVGA_FIFO_EXTCMD_TERMINATE:
Log(("vmsvgaFIFOLoop: terminate the fifo thread.\n"));
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
if (pThis->svga.f3DEnabled)
{
/* The 3d subsystem must be shut down from the fifo thread. */
vmsvga3dTerminate(pThis);
}
-#endif
+# endif
break;
case VMSVGA_FIFO_EXTCMD_SAVESTATE:
Log(("vmsvgaFIFOLoop: VMSVGA_FIFO_EXTCMD_SAVESTATE.\n"));
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
vmsvga3dSaveExec(pThis, (PSSMHANDLE)pThis->svga.pFIFOExtCmdParam);
-#endif
+# endif
break;
case VMSVGA_FIFO_EXTCMD_LOADSTATE:
{
Log(("vmsvgaFIFOLoop: VMSVGA_FIFO_EXTCMD_LOADSTATE.\n"));
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
PVMSVGA_STATE_LOAD pLoadState = (PVMSVGA_STATE_LOAD)pThis->svga.pFIFOExtCmdParam;
vmsvga3dLoadExec(pThis, pLoadState->pSSM, pLoadState->uVersion, pLoadState->uPass);
-#endif
+# endif
break;
}
}
@@ -2002,59 +2289,105 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
if ( !pThis->svga.fEnabled
|| !pThis->svga.fConfigured)
{
- pThis->svga.fBusy = false;
- pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
+ vmsvgaFifoSetNotBusy(pThis, pSVGAState, pFIFO[SVGA_FIFO_MIN]);
continue; /* device not enabled. */
}
- if (pFIFO[SVGA_FIFO_STOP] >= pFIFO[SVGA_FIFO_MAX])
+ /*
+ * Get and check the min/max values. We ASSUME that they will remain
+ * unchanged while we process requests. A further ASSUMPTION is that
+ * the guest won't mess with SVGA_FIFO_NEXT_CMD while we're busy, so
+ * we don't read it back while in the loop.
+ */
+ uint32_t const offFifoMin = pFIFO[SVGA_FIFO_MIN];
+ uint32_t const offFifoMax = pFIFO[SVGA_FIFO_MAX];
+ uint32_t offCurrentCmd = pFIFO[SVGA_FIFO_STOP];
+ if (RT_UNLIKELY( !VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_STOP, offFifoMin)
+ || offFifoMax <= offFifoMin
+ || offFifoMax > VMSVGA_FIFO_SIZE
+ || (offFifoMax & 3) != 0
+ || (offFifoMin & 3) != 0
+ || offCurrentCmd < offFifoMin
+ || offCurrentCmd > offFifoMax))
{
- Log(("vmsvgaFIFOLoop: Invalid stop %x max=%x\n", pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MAX]));
- continue; /* invalid. */
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
+ LogRelMax(8, ("vmsvgaFIFOLoop: Bad fifo: min=%#x stop=%#x max=%#x\n", offFifoMin, offCurrentCmd, offFifoMax));
+ vmsvgaFifoSetNotBusy(pThis, pSVGAState, offFifoMin);
+ continue;
}
-
- if (pFIFO[SVGA_FIFO_MAX] < VMSVGA_FIFO_SIZE)
+ if (RT_UNLIKELY(offCurrentCmd & 3))
{
- Log(("vmsvgaFIFOLoop: Invalid max %x fifo max=%x\n", pFIFO[SVGA_FIFO_MAX], VMSVGA_FIFO_SIZE));
- continue; /* invalid. */
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoErrors);
+ LogRelMax(8, ("vmsvgaFIFOLoop: Misaligned offCurrentCmd=%#x?\n", offCurrentCmd));
+ offCurrentCmd = ~UINT32_C(3);
}
- if (pFIFO[SVGA_FIFO_STOP] < pFIFO[SVGA_FIFO_MIN])
- {
- Log(("vmsvgaFIFOLoop: Invalid stop %x min=%x\n", pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MIN]));
- continue; /* invalid. */
- }
- pThis->svga.fBusy = true;
- pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
+/**
+ * Macro for shortening calls to vmsvgaFIFOGetCmdPayload.
+ *
+ * Will break out of the switch on failure.
+ * Will restart and quit the loop if the thread was requested to stop.
+ *
+ * @param a_cbPayloadReq How much payload to fetch.
+ * @remarks Access a bunch of variables in the current scope!
+ */
+# define VMSVGAFIFO_GET_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq) \
+ if (1) { \
+ (a_PtrVar) = (a_Type *)vmsvgaFIFOGetCmdPayload((a_cbPayloadReq), pFIFO, offCurrentCmd, offFifoMin, offFifoMax, \
+ pbBounceBuf, &cbPayload, pThread, pThis, pSVGAState); \
+ if (RT_UNLIKELY((uintptr_t)(a_PtrVar) < 2)) { if ((uintptr_t)(a_PtrVar) == 1) continue; break; } \
+ } else do {} while (0)
+/**
+ * Macro for shortening calls to vmsvgaFIFOGetCmdPayload for refetching the
+ * buffer after figuring out the actual command size.
+ * Will break out of the switch on failure.
+ * @param a_cbPayloadReq How much payload to fetch.
+ * @remarks Access a bunch of variables in the current scope!
+ */
+# define VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq) \
+ if (1) { \
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(a_PtrVar, a_Type, a_cbPayloadReq); \
+ } else do {} while (0)
+
+ /*
+ * Mark the FIFO as busy.
+ */
+ ASMAtomicWriteU32(&pThis->svga.fBusy, VMSVGA_BUSY_F_FIFO);
+ if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_BUSY, offFifoMin))
+ ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_BUSY], true);
- /* Execute all queued FIFO commands. */
- while ( pThread->enmState == PDMTHREADSTATE_RUNNING
- && pFIFO[SVGA_FIFO_NEXT_CMD] != pFIFO[SVGA_FIFO_STOP])
+ /*
+ * Execute all queued FIFO commands.
+ * Quit if pending external command or changes in the thread state.
+ */
+ bool fDone = false;
+ while ( !(fDone = pFIFO[SVGA_FIFO_NEXT_CMD] == offCurrentCmd)
+ && pThread->enmState == PDMTHREADSTATE_RUNNING)
{
- uint32_t u32Cmd;
- uint32_t u32Current, size;
+ uint32_t cbPayload = 0;
uint32_t u32IrqStatus = 0;
bool fTriggerIrq = false;
- void *pBounceBuffer = NULL;
+
+ Assert(offCurrentCmd < offFifoMax && offCurrentCmd >= offFifoMin);
/* First check any pending actions. */
if (ASMBitTestAndClear(&pThis->svga.u32ActionFlags, VMSVGA_ACTION_CHANGEMODE_BIT))
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
vmsvga3dChangeMode(pThis);
-#else
- {}
-#endif
+# else
+ {/*nothing*/}
+# endif
/* Check for pending external commands. */
if (pThis->svga.u8FIFOExtCommand != VMSVGA_FIFO_EXTCMD_NONE)
break;
- u32Current = pFIFO[SVGA_FIFO_STOP];
-
- u32Cmd = u32Current / sizeof(uint32_t);
- LogFlow(("vmsvgaFIFOLoop: FIFO command (iCmd=0x%x) %s 0x%x\n", u32Cmd, vmsvgaFIFOCmdToString(pFIFO[u32Cmd]), pFIFO[u32Cmd]));
- size = sizeof(uint32_t); /* command dword */
-
- switch (pFIFO[u32Cmd])
+ /*
+ * Process the command.
+ */
+ SVGAFifoCmdId const enmCmdId = (SVGAFifoCmdId)pFIFO[offCurrentCmd / sizeof(uint32_t)];
+ LogFlow(("vmsvgaFIFOLoop: FIFO command (iCmd=0x%x) %s 0x%x\n",
+ offCurrentCmd / sizeof(uint32_t), vmsvgaFIFOCmdToString(enmCmdId), enmCmdId));
+ switch (enmCmdId)
{
case SVGA_CMD_INVALID_CMD:
/* Nothing to do. */
@@ -2062,29 +2395,36 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_FENCE:
{
- SVGAFifoCmdFence *pCmdFence = (SVGAFifoCmdFence *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdFence), &size, &pBounceBuffer);
-
- Log(("vmsvgaFIFOLoop: SVGA_CMD_FENCE %x\n", pCmdFence->fence));
- pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence;
- if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
+ SVGAFifoCmdFence *pCmdFence;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmdFence, SVGAFifoCmdFence, sizeof(*pCmdFence));
+ if (VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE, offFifoMin))
{
- Log(("vmsvgaFIFOLoop: any fence irq\n"));
- u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
+ Log(("vmsvgaFIFOLoop: SVGA_CMD_FENCE %x\n", pCmdFence->fence));
+ pFIFO[SVGA_FIFO_FENCE] = pCmdFence->fence;
+
+ if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_ANY_FENCE)
+ {
+ Log(("vmsvgaFIFOLoop: any fence irq\n"));
+ u32IrqStatus |= SVGA_IRQFLAG_ANY_FENCE;
+ }
+ else
+ if ( VMSVGA_IS_VALID_FIFO_REG(SVGA_FIFO_FENCE_GOAL, offFifoMin)
+ && (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL)
+ && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence)
+ {
+ Log(("vmsvgaFIFOLoop: fence goal reached irq (fence=%x)\n", pCmdFence->fence));
+ u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
+ }
}
else
- if ( (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FENCE_GOAL)
- && pFIFO[SVGA_FIFO_FENCE_GOAL] == pCmdFence->fence)
- {
- Log(("vmsvgaFIFOLoop: fence goal reached irq (fence=%x)\n", pCmdFence->fence));
- u32IrqStatus |= SVGA_IRQFLAG_FENCE_GOAL;
- }
+ Log(("SVGA_CMD_FENCE is bogus when offFifoMin is %#x!\n", offFifoMin));
break;
}
case SVGA_CMD_UPDATE:
case SVGA_CMD_UPDATE_VERBOSE:
{
- SVGAFifoCmdUpdate *pUpdate = (SVGAFifoCmdUpdate *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdUpdate), &size, &pBounceBuffer);
-
+ SVGAFifoCmdUpdate *pUpdate;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pUpdate, SVGAFifoCmdUpdate, sizeof(*pUpdate));
Log(("vmsvgaFIFOLoop: UPDATE (%d,%d)(%d,%d)\n", pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height));
vgaR3UpdateDisplay(pThis, pUpdate->x, pUpdate->y, pUpdate->width, pUpdate->height);
break;
@@ -2093,31 +2433,31 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_DEFINE_CURSOR:
{
/* Followed by bitmap data. */
- SVGAFifoCmdDefineCursor *pCursor = (SVGAFifoCmdDefineCursor *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineCursor), &size, &pBounceBuffer);
-
- AssertFailed();
+ SVGAFifoCmdDefineCursor *pCursor;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineCursor, sizeof(*pCursor));
+ AssertFailed(); /** @todo implement when necessary. */
break;
}
case SVGA_CMD_DEFINE_ALPHA_CURSOR:
{
/* Followed by bitmap data. */
- SVGAFifoCmdDefineAlphaCursor *pCursor = (SVGAFifoCmdDefineAlphaCursor *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineAlphaCursor), &size, &pBounceBuffer);
uint32_t cbCursorShape, cbAndMask;
uint8_t *pCursorCopy;
uint32_t cbCmd;
+ SVGAFifoCmdDefineAlphaCursor *pCursor;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineAlphaCursor, sizeof(*pCursor));
+
Log(("vmsvgaFIFOLoop: ALPHA_CURSOR id=%d size (%d,%d) hotspot (%d,%d)\n", pCursor->id, pCursor->width, pCursor->height, pCursor->hotspotX, pCursor->hotspotY));
/* Check against a reasonable upper limit to prevent integer overflows in the sanity checks below. */
- AssertReturn(pCursor->height < 2048 && pCursor->width < 2048, VERR_INVALID_PARAMETER);
+ AssertBreak(pCursor->height < 2048 && pCursor->width < 2048);
- /* Refetch the command buffer with the added bitmap data; undo size increase (ugly) */
+ /* Refetch the bitmap data as well. */
cbCmd = sizeof(SVGAFifoCmdDefineAlphaCursor) + pCursor->width * pCursor->height * sizeof(uint32_t) /* 32-bit BRGA format */;
- size = sizeof(uint32_t); /* command dword */
- if (pBounceBuffer)
- RTMemFree(pBounceBuffer);
- pCursor = (SVGAFifoCmdDefineAlphaCursor *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
+ VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCursor, SVGAFifoCmdDefineAlphaCursor, cbCmd);
+ /** @todo Would be more efficient to copy the data straight into pCursorCopy (memcpy below). */
/* The mouse pointer interface always expects an AND mask followed by the color data (XOR mask). */
cbAndMask = (pCursor->width + 7) / 8 * pCursor->height; /* size of the AND mask */
@@ -2127,7 +2467,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
pCursorCopy = (uint8_t *)RTMemAlloc(cbCursorShape);
AssertBreak(pCursorCopy);
- LogFlow(("Cursor data:\n%.*Rhxd\n", pCursor->width * pCursor->height * sizeof(uint32_t), pCursor+1));
+ Log2(("Cursor data:\n%.*Rhxd\n", pCursor->width * pCursor->height * sizeof(uint32_t), pCursor+1));
/* Transparency is defined by the alpha bytes, so make the whole bitmap visible. */
memset(pCursorCopy, 0xff, cbAndMask);
@@ -2160,19 +2500,17 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_ESCAPE:
{
/* Followed by nsize bytes of data. */
- SVGAFifoCmdEscape *pEscape = (SVGAFifoCmdEscape *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdEscape), &size, &pBounceBuffer);
- uint32_t cbCmd;
+ SVGAFifoCmdEscape *pEscape;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pEscape, SVGAFifoCmdEscape, sizeof(*pEscape));
/* Refetch the command buffer with the variable data; undo size increase (ugly) */
- cbCmd = sizeof(SVGAFifoCmdEscape) + pEscape->size;
- size = sizeof(uint32_t); /* command dword */
- if (pBounceBuffer)
- RTMemFree(pBounceBuffer);
- pEscape = (SVGAFifoCmdEscape *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
+ AssertBreak(pEscape->size < VMSVGA_FIFO_SIZE);
+ uint32_t cbCmd = sizeof(SVGAFifoCmdEscape) + pEscape->size;
+ VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pEscape, SVGAFifoCmdEscape, cbCmd);
if (pEscape->nsid == SVGA_ESCAPE_NSID_VMWARE)
{
- Assert(pEscape->size >= sizeof(uint32_t));
+ AssertBreak(pEscape->size >= sizeof(uint32_t));
uint32_t cmd = *(uint32_t *)(pEscape + 1);
Log(("vmsvgaFIFOLoop: ESCAPE (%x %x) VMWARE cmd=%x\n", pEscape->nsid, pEscape->size, cmd));
@@ -2181,6 +2519,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS:
{
SVGAEscapeVideoSetRegs *pVideoCmd = (SVGAEscapeVideoSetRegs *)(pEscape + 1);
+ AssertBreak(pEscape->size >= sizeof(pVideoCmd->header));
uint32_t cRegs = (pEscape->size - sizeof(pVideoCmd->header)) / sizeof(pVideoCmd->items[0]);
Log(("SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS: stream %x\n", pVideoCmd->header.streamId));
@@ -2193,6 +2532,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_ESCAPE_VMWARE_VIDEO_FLUSH:
SVGAEscapeVideoFlush *pVideoCmd = (SVGAEscapeVideoFlush *)(pEscape + 1);
+ AssertBreak(pEscape->size >= sizeof(*pVideoCmd));
Log(("SVGA_ESCAPE_VMWARE_VIDEO_FLUSH: stream %x\n", pVideoCmd->streamId));
break;
}
@@ -2202,10 +2542,11 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
break;
}
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
case SVGA_CMD_DEFINE_GMR2:
{
- SVGAFifoCmdDefineGMR2 *pCmd = (SVGAFifoCmdDefineGMR2 *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineGMR2), &size, &pBounceBuffer);
+ SVGAFifoCmdDefineGMR2 *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineGMR2, sizeof(*pCmd));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_GMR2 id=%x %x pages\n", pCmd->gmrId, pCmd->numPages));
/* Validate current GMR id. */
@@ -2227,15 +2568,17 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_REMAP_GMR2:
{
- /* Followed by page descriptors. */
- SVGAFifoCmdRemapGMR2 *pCmd = (SVGAFifoCmdRemapGMR2 *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdRemapGMR2), &size, &pBounceBuffer);
+ /* Followed by page descriptors or guest ptr. */
+ SVGAFifoCmdRemapGMR2 *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRemapGMR2, sizeof(*pCmd));
uint32_t cbPageDesc = (pCmd->flags & SVGA_REMAP_GMR2_PPN64) ? sizeof(uint64_t) : sizeof(uint32_t);
uint32_t cbCmd;
uint64_t *paNewPage64 = NULL;
Log(("vmsvgaFIFOLoop: SVGA_CMD_REMAP_GMR2 id=%x flags=%x offset=%x npages=%x\n", pCmd->gmrId, pCmd->flags, pCmd->offsetPages, pCmd->numPages));
+ AssertBreak(pCmd->gmrId < VMSVGA_MAX_GMR_IDS);
- /* Refetch the command buffer with the variable data; undo size increase (ugly) */
+ /* Calculate the size of what comes after next and fetch it. */
cbCmd = sizeof(SVGAFifoCmdRemapGMR2);
if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
cbCmd += sizeof(SVGAGuestPtr);
@@ -2246,20 +2589,17 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
pCmd->numPages = 1;
}
else
+ {
+ AssertBreak(pCmd->numPages <= VMSVGA_FIFO_SIZE);
cbCmd += cbPageDesc * pCmd->numPages;
- size = sizeof(uint32_t); /* command dword */
-
- if (pBounceBuffer)
- RTMemFree(pBounceBuffer);
- pCmd = (SVGAFifoCmdRemapGMR2 *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
- AssertReturn(pCmd, VERR_INTERNAL_ERROR);
-
- PGMR pGMR = &pSVGAState->aGMR[pCmd->gmrId];
+ }
+ VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdRemapGMR2, cbCmd);
/* Validate current GMR id. */
AssertBreak(pCmd->gmrId < VMSVGA_MAX_GMR_IDS);
+ PGMR pGMR = &pSVGAState->aGMR[pCmd->gmrId];
AssertBreak(pCmd->offsetPages + pCmd->numPages <= pGMR->cMaxPages);
- AssertBreak(!pCmd->offsetPages || pGMR->paDesc); /* @todo */
+ AssertBreak(!pCmd->offsetPages || pGMR->paDesc); /** @todo */
/* Save the old page descriptors as an array of page addresses (>> PAGE_SHIFT) */
if (pGMR->paDesc)
@@ -2288,7 +2628,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
if (pCmd->flags & SVGA_REMAP_GMR2_VIA_GMR)
{
- /* @todo */
+ /** @todo */
AssertFailed();
}
else
@@ -2356,17 +2696,20 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
if (paNewPage64)
RTMemFree(paNewPage64);
-#ifdef DEBUG_GMR_ACCESS
+# ifdef DEBUG_GMR_ACCESS
VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaRegisterGMR, 2, pThis->pDevInsR3, pCmd->gmrId);
-#endif
+# endif
break;
}
-#endif // VBOX_WITH_VMSVGA3D
+# endif // VBOX_WITH_VMSVGA3D
case SVGA_CMD_DEFINE_SCREEN:
{
- /* @note optional size depending on the capabilities */
+ /* Note! The size of this command is specified by the guest and depends on capabilities. */
Assert(!(pThis->svga.pFIFOR3[SVGA_FIFO_CAPABILITIES] & SVGA_FIFO_CAP_SCREEN_OBJECT));
- SVGAFifoCmdDefineScreen *pCmd = (SVGAFifoCmdDefineScreen *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineScreen), &size, &pBounceBuffer);
+ SVGAFifoCmdDefineScreen *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineScreen, sizeof(pCmd->screen.structSize));
+ RT_BZERO(&pCmd->screen.id, sizeof(*pCmd) - RT_OFFSETOF(SVGAFifoCmdDefineScreen, screen.structSize));
+ VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineScreen, RT_MAX(sizeof(pCmd->screen.structSize), pCmd->screen.structSize));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN id=%x flags=%x size=(%d,%d) root=(%d,%d)\n", pCmd->screen.id, pCmd->screen.flags, pCmd->screen.size.width, pCmd->screen.size.height, pCmd->screen.root.x, pCmd->screen.root.y));
if (pCmd->screen.flags & SVGA_SCREEN_HAS_ROOT)
@@ -2380,6 +2723,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
if (pCmd->screen.flags & SVGA_SCREEN_BLANKING)
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_SCREEN flags SVGA_SCREEN_BLANKING\n"));
+ /** @todo multi monitor support and screen object capabilities. */
pThis->svga.uWidth = pCmd->screen.size.width;
pThis->svga.uHeight = pCmd->screen.size.height;
vmsvgaChangeMode(pThis);
@@ -2388,15 +2732,17 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_DESTROY_SCREEN:
{
- SVGAFifoCmdDestroyScreen *pCmd = (SVGAFifoCmdDestroyScreen *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDestroyScreen), &size, &pBounceBuffer);
+ SVGAFifoCmdDestroyScreen *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDestroyScreen, sizeof(*pCmd));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DESTROY_SCREEN id=%x\n", pCmd->screenId));
break;
}
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
case SVGA_CMD_DEFINE_GMRFB:
{
- SVGAFifoCmdDefineGMRFB *pCmd = (SVGAFifoCmdDefineGMRFB *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdDefineGMRFB), &size, &pBounceBuffer);
+ SVGAFifoCmdDefineGMRFB *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdDefineGMRFB, sizeof(*pCmd));
Log(("vmsvgaFIFOLoop: SVGA_CMD_DEFINE_GMRFB gmr=%x offset=%x bytesPerLine=%x bpp=%d color depth=%d\n", pCmd->ptr.gmrId, pCmd->ptr.offset, pCmd->bytesPerLine, pCmd->format.s.bitsPerPixel, pCmd->format.s.colorDepth));
pSVGAState->GMRFB.ptr = pCmd->ptr;
@@ -2407,12 +2753,13 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
{
- SVGAFifoCmdBlitGMRFBToScreen *pCmd = (SVGAFifoCmdBlitGMRFBToScreen *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdBlitGMRFBToScreen), &size, &pBounceBuffer);
uint32_t width, height;
+ SVGAFifoCmdBlitGMRFBToScreen *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdBlitGMRFBToScreen, sizeof(*pCmd));
Log(("vmsvgaFIFOLoop: SVGA_CMD_BLIT_GMRFB_TO_SCREEN src=(%d,%d) dest id=%d (%d,%d)(%d,%d)\n", pCmd->srcOrigin.x, pCmd->srcOrigin.y, pCmd->destScreenId, pCmd->destRect.left, pCmd->destRect.top, pCmd->destRect.right, pCmd->destRect.bottom));
- /* @todo */
+ /** @todo Support GMRFB.format.s.bitsPerPixel != pThis->svga.uBpp */
AssertBreak(pSVGAState->GMRFB.format.s.bitsPerPixel == pThis->svga.uBpp);
AssertBreak(pCmd->destScreenId == 0);
@@ -2442,7 +2789,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
unsigned offsetDest = (pCmd->destRect.left * RT_ALIGN(pThis->svga.uBpp, 8)) / 8 + pThis->svga.cbScanline * pCmd->destRect.top;
unsigned cbCopyWidth = (width * RT_ALIGN(pThis->svga.uBpp, 8)) / 8;
- AssertReturn(offsetDest < pThis->vram_size, VERR_INVALID_PARAMETER);
+ AssertBreak(offsetDest < pThis->vram_size);
rc = vmsvgaGMRTransfer(pThis, SVGA3D_WRITE_HOST_VRAM, pThis->CTX_SUFF(vram_ptr) + offsetDest, pThis->svga.cbScanline, pSVGAState->GMRFB.ptr, offsetSource, pSVGAState->GMRFB.bytesPerLine, cbCopyWidth, height);
AssertRC(rc);
@@ -2452,17 +2799,19 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
{
- SVGAFifoCmdBlitScreenToGMRFB *pCmd = (SVGAFifoCmdBlitScreenToGMRFB *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdBlitScreenToGMRFB), &size, &pBounceBuffer);
+ SVGAFifoCmdBlitScreenToGMRFB *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdBlitScreenToGMRFB, sizeof(*pCmd));
- /* @note this can fetch 3d render results as well!! */
+ /* Note! This can fetch 3d render results as well!! */
Log(("vmsvgaFIFOLoop: SVGA_CMD_BLIT_SCREEN_TO_GMRFB dest=(%d,%d) src id=%d (%d,%d)(%d,%d)\n", pCmd->destOrigin.x, pCmd->destOrigin.y, pCmd->srcScreenId, pCmd->srcRect.left, pCmd->srcRect.top, pCmd->srcRect.right, pCmd->srcRect.bottom));
AssertFailed();
break;
}
-#endif // VBOX_WITH_VMSVGA3D
+# endif // VBOX_WITH_VMSVGA3D
case SVGA_CMD_ANNOTATION_FILL:
{
- SVGAFifoCmdAnnotationFill *pCmd = (SVGAFifoCmdAnnotationFill *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdAnnotationFill), &size, &pBounceBuffer);
+ SVGAFifoCmdAnnotationFill *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdAnnotationFill, sizeof(*pCmd));
Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_FILL red=%x green=%x blue=%x\n", pCmd->color.s.r, pCmd->color.s.g, pCmd->color.s.b));
pSVGAState->colorAnnotation = pCmd->color;
@@ -2471,48 +2820,55 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_CMD_ANNOTATION_COPY:
{
- SVGAFifoCmdAnnotationCopy *pCmd = (SVGAFifoCmdAnnotationCopy*)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGAFifoCmdAnnotationCopy), &size, &pBounceBuffer);
+ SVGAFifoCmdAnnotationCopy *pCmd;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pCmd, SVGAFifoCmdAnnotationCopy, sizeof(*pCmd));
Log(("vmsvgaFIFOLoop: SVGA_CMD_ANNOTATION_COPY\n"));
AssertFailed();
break;
}
+ /** @todo SVGA_CMD_RECT_COPY - see with ubuntu */
+
default:
-#ifdef VBOX_WITH_VMSVGA3D
- if ( pFIFO[u32Cmd] >= SVGA_3D_CMD_BASE
- && pFIFO[u32Cmd] < SVGA_3D_CMD_MAX)
+# ifdef VBOX_WITH_VMSVGA3D
+ if ( enmCmdId >= SVGA_3D_CMD_BASE
+ && enmCmdId < SVGA_3D_CMD_MAX)
{
/* All 3d commands start with a common header, which defines the size of the command. */
- SVGA3dCmdHeader *pHdr = (SVGA3dCmdHeader *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, sizeof(SVGA3dCmdHeader), &size, &pBounceBuffer);
- uint32_t cbCmd;
+ SVGA3dCmdHeader *pHdr;
+ VMSVGAFIFO_GET_CMD_BUFFER_BREAK(pHdr, SVGA3dCmdHeader, sizeof(*pHdr));
+ AssertBreak(pHdr->size < VMSVGA_FIFO_SIZE);
+ uint32_t cbCmd = sizeof(SVGA3dCmdHeader) + pHdr->size;
+ VMSVGAFIFO_GET_MORE_CMD_BUFFER_BREAK(pHdr, SVGA3dCmdHeader, cbCmd);
- /* Refetch the command buffer with the variable data; undo size increase (ugly) */
- cbCmd = sizeof(SVGA3dCmdHeader) + pHdr->size;
- size = sizeof(uint32_t); /* command dword */
- if (pBounceBuffer)
- RTMemFree(pBounceBuffer);
- pHdr = (SVGA3dCmdHeader *)vmsvgaFIFOGetCmdBuffer(pThread, pFIFO, cbCmd, &size, &pBounceBuffer);
-
- switch (pFIFO[u32Cmd])
+/**
+ * Check that the 3D command has at least a_cbMin of payload bytes after the
+ * header. Will break out of the switch if it doesn't.
+ */
+# define VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(a_cbMin) \
+ AssertMsgBreak((a_cbMin) <= pHdr->size, ("size=%#x a_cbMin=%#zx\n", pHdr->size, (size_t)(a_cbMin)))
+ switch ((int)enmCmdId)
{
case SVGA_3D_CMD_SURFACE_DEFINE:
{
- SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)(pHdr + 1);
uint32_t cMipLevels;
+ SVGA3dCmdDefineSurface *pCmd = (SVGA3dCmdDefineSurface *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cMipLevels = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dSize);
rc = vmsvga3dSurfaceDefine(pThis, pCmd->sid, (uint32_t)pCmd->surfaceFlags, pCmd->format, pCmd->face, 0, SVGA3D_TEX_FILTER_NONE, cMipLevels, (SVGA3dSize *)(pCmd + 1));
-#ifdef DEBUG_GMR_ACCESS
+# ifdef DEBUG_GMR_ACCESS
VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaResetGMRHandlers, 1, pThis);
-#endif
+# endif
break;
}
case SVGA_3D_CMD_SURFACE_DEFINE_V2:
{
- SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)(pHdr + 1);
uint32_t cMipLevels;
+ SVGA3dCmdDefineSurface_v2 *pCmd = (SVGA3dCmdDefineSurface_v2 *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cMipLevels = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dSize);
rc = vmsvga3dSurfaceDefine(pThis, pCmd->sid, pCmd->surfaceFlags, pCmd->format, pCmd->face, pCmd->multisampleCount, pCmd->autogenFilter, cMipLevels, (SVGA3dSize *)(pCmd + 1));
@@ -2522,14 +2878,16 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SURFACE_DESTROY:
{
SVGA3dCmdDestroySurface *pCmd = (SVGA3dCmdDestroySurface *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceDestroy(pThis, pCmd->sid);
break;
}
case SVGA_3D_CMD_SURFACE_COPY:
{
- SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)(pHdr + 1);
uint32_t cCopyBoxes;
+ SVGA3dCmdSurfaceCopy *pCmd = (SVGA3dCmdSurfaceCopy *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cCopyBoxes = (pHdr->size - sizeof(pCmd)) / sizeof(SVGA3dCopyBox);
rc = vmsvga3dSurfaceCopy(pThis, pCmd->dest, pCmd->src, cCopyBoxes, (SVGA3dCopyBox *)(pCmd + 1));
@@ -2539,6 +2897,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SURFACE_STRETCHBLT:
{
SVGA3dCmdSurfaceStretchBlt *pCmd = (SVGA3dCmdSurfaceStretchBlt *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSurfaceStretchBlt(pThis, pCmd->dest, pCmd->boxDest, pCmd->src, pCmd->boxSrc, pCmd->mode);
break;
@@ -2546,8 +2905,9 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SURFACE_DMA:
{
- SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)(pHdr + 1);
uint32_t cCopyBoxes;
+ SVGA3dCmdSurfaceDMA *pCmd = (SVGA3dCmdSurfaceDMA *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cCopyBoxes = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dCopyBox);
STAM_PROFILE_START(&pSVGAState->StatR3CmdSurfaceDMA, a);
@@ -2558,8 +2918,9 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN:
{
- SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)(pHdr + 1);
uint32_t cRects;
+ SVGA3dCmdBlitSurfaceToScreen *pCmd = (SVGA3dCmdBlitSurfaceToScreen *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGASignedRect);
rc = vmsvga3dSurfaceBlitToScreen(pThis, pCmd->destScreenId, pCmd->destRect, pCmd->srcImage, pCmd->srcRect, cRects, (SVGASignedRect *)(pCmd + 1));
@@ -2569,14 +2930,16 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_CONTEXT_DEFINE:
{
SVGA3dCmdDefineContext *pCmd = (SVGA3dCmdDefineContext *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
- rc = vmsvga3dContextDefine(pThis, pCmd->cid);
+ rc = vmsvga3dContextDefine(pThis, pCmd->cid, false /*fOtherProfile*/);
break;
}
case SVGA_3D_CMD_CONTEXT_DESTROY:
{
SVGA3dCmdDestroyContext *pCmd = (SVGA3dCmdDestroyContext *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dContextDestroy(pThis, pCmd->cid);
break;
@@ -2585,6 +2948,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETTRANSFORM:
{
SVGA3dCmdSetTransform *pCmd = (SVGA3dCmdSetTransform *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetTransform(pThis, pCmd->cid, pCmd->type, pCmd->matrix);
break;
@@ -2593,6 +2957,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETZRANGE:
{
SVGA3dCmdSetZRange *pCmd = (SVGA3dCmdSetZRange *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetZRange(pThis, pCmd->cid, pCmd->zRange);
break;
@@ -2600,8 +2965,9 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETRENDERSTATE:
{
- SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)(pHdr + 1);
uint32_t cRenderStates;
+ SVGA3dCmdSetRenderState *pCmd = (SVGA3dCmdSetRenderState *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cRenderStates = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dRenderState);
rc = vmsvga3dSetRenderState(pThis, pCmd->cid, cRenderStates, (SVGA3dRenderState *)(pCmd + 1));
@@ -2611,6 +2977,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETRENDERTARGET:
{
SVGA3dCmdSetRenderTarget *pCmd = (SVGA3dCmdSetRenderTarget *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetRenderTarget(pThis, pCmd->cid, pCmd->type, pCmd->target);
break;
@@ -2618,8 +2985,9 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETTEXTURESTATE:
{
- SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)(pHdr + 1);
uint32_t cTextureStates;
+ SVGA3dCmdSetTextureState *pCmd = (SVGA3dCmdSetTextureState *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
cTextureStates = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dTextureState);
rc = vmsvga3dSetTextureState(pThis, pCmd->cid, cTextureStates, (SVGA3dTextureState *)(pCmd + 1));
@@ -2629,6 +2997,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETMATERIAL:
{
SVGA3dCmdSetMaterial *pCmd = (SVGA3dCmdSetMaterial *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetMaterial(pThis, pCmd->cid, pCmd->face, &pCmd->material);
break;
@@ -2637,6 +3006,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETLIGHTDATA:
{
SVGA3dCmdSetLightData *pCmd = (SVGA3dCmdSetLightData *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetLightData(pThis, pCmd->cid, pCmd->index, &pCmd->data);
break;
@@ -2645,6 +3015,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETLIGHTENABLED:
{
SVGA3dCmdSetLightEnabled *pCmd = (SVGA3dCmdSetLightEnabled *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetLightEnabled(pThis, pCmd->cid, pCmd->index, pCmd->enabled);
break;
@@ -2653,6 +3024,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETVIEWPORT:
{
SVGA3dCmdSetViewport *pCmd = (SVGA3dCmdSetViewport *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetViewPort(pThis, pCmd->cid, &pCmd->rect);
break;
@@ -2661,6 +3033,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETCLIPPLANE:
{
SVGA3dCmdSetClipPlane *pCmd = (SVGA3dCmdSetClipPlane *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetClipPlane(pThis, pCmd->cid, pCmd->index, pCmd->plane);
break;
@@ -2669,6 +3042,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_CLEAR:
{
SVGA3dCmdClear *pCmd = (SVGA3dCmdClear *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
uint32_t cRects;
cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dRect);
@@ -2679,6 +3053,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_PRESENT:
{
SVGA3dCmdPresent *pCmd = (SVGA3dCmdPresent *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
uint32_t cRects;
cRects = (pHdr->size - sizeof(*pCmd)) / sizeof(SVGA3dCopyRect);
@@ -2692,6 +3067,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SHADER_DEFINE:
{
SVGA3dCmdDefineShader *pCmd = (SVGA3dCmdDefineShader *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
uint32_t cbData;
cbData = (pHdr->size - sizeof(*pCmd));
@@ -2702,6 +3078,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SHADER_DESTROY:
{
SVGA3dCmdDestroyShader *pCmd = (SVGA3dCmdDestroyShader *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dShaderDestroy(pThis, pCmd->cid, pCmd->shid, pCmd->type);
break;
@@ -2710,6 +3087,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SET_SHADER:
{
SVGA3dCmdSetShader *pCmd = (SVGA3dCmdSetShader *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dShaderSet(pThis, pCmd->cid, pCmd->type, pCmd->shid);
break;
@@ -2718,6 +3096,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SET_SHADER_CONST:
{
SVGA3dCmdSetShaderConst *pCmd = (SVGA3dCmdSetShaderConst *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
uint32_t cRegisters = (pHdr->size - sizeof(*pCmd)) / sizeof(pCmd->values) + 1;
rc = vmsvga3dShaderSetConst(pThis, pCmd->cid, pCmd->reg, pCmd->type, pCmd->ctype, cRegisters, pCmd->values);
@@ -2727,6 +3106,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_DRAW_PRIMITIVES:
{
SVGA3dCmdDrawPrimitives *pCmd = (SVGA3dCmdDrawPrimitives *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
uint32_t cVertexDivisor;
cVertexDivisor = (pHdr->size - sizeof(*pCmd) - sizeof(SVGA3dVertexDecl) * pCmd->numVertexDecls - sizeof(SVGA3dPrimitiveRange) * pCmd->numRanges);
@@ -2747,6 +3127,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_SETSCISSORRECT:
{
SVGA3dCmdSetScissorRect *pCmd = (SVGA3dCmdSetScissorRect *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dSetScissorRect(pThis, pCmd->cid, &pCmd->rect);
break;
@@ -2755,6 +3136,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_BEGIN_QUERY:
{
SVGA3dCmdBeginQuery *pCmd = (SVGA3dCmdBeginQuery *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dQueryBegin(pThis, pCmd->cid, pCmd->type);
break;
@@ -2763,6 +3145,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_END_QUERY:
{
SVGA3dCmdEndQuery *pCmd = (SVGA3dCmdEndQuery *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dQueryEnd(pThis, pCmd->cid, pCmd->type, pCmd->guestResult);
break;
@@ -2771,6 +3154,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_WAIT_FOR_QUERY:
{
SVGA3dCmdWaitForQuery *pCmd = (SVGA3dCmdWaitForQuery *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dQueryWait(pThis, pCmd->cid, pCmd->type, pCmd->guestResult);
break;
@@ -2779,6 +3163,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_GENERATE_MIPMAPS:
{
SVGA3dCmdGenerateMipmaps *pCmd = (SVGA3dCmdGenerateMipmaps *)(pHdr + 1);
+ VMSVGAFIFO_CHECK_3D_CMD_MIN_SIZE_BREAK(sizeof(*pCmd));
rc = vmsvga3dGenerateMipmaps(pThis, pCmd->sid, pCmd->filter);
break;
@@ -2788,20 +3173,32 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
case SVGA_3D_CMD_DEACTIVATE_SURFACE:
/* context id + surface id? */
break;
+
+ default:
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoUnkCmds);
+ AssertFailed();
+ break;
}
}
else
-#endif // VBOX_WITH_VMSVGA3D
+# endif // VBOX_WITH_VMSVGA3D
+ {
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoUnkCmds);
AssertFailed();
+ }
}
- if (pBounceBuffer)
- RTMemFree(pBounceBuffer);
/* Go to the next slot */
- if (u32Current + size >= pFIFO[SVGA_FIFO_MAX])
- ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], pFIFO[SVGA_FIFO_MIN] + u32Current + size - pFIFO[SVGA_FIFO_MAX]);
- else
- ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], u32Current + size);
+ Assert(cbPayload + sizeof(uint32_t) <= offFifoMax - offFifoMin);
+ offCurrentCmd += RT_ALIGN_32(cbPayload + sizeof(uint32_t), sizeof(uint32_t));
+ if (offCurrentCmd >= offFifoMax)
+ {
+ offCurrentCmd -= offFifoMax - offFifoMin;
+ Assert(offCurrentCmd >= offFifoMin);
+ Assert(offCurrentCmd < offFifoMax);
+ }
+ ASMAtomicWriteU32(&pFIFO[SVGA_FIFO_STOP], offCurrentCmd);
+ STAM_REL_COUNTER_INC(&pSVGAState->StatFifoCommands);
/* FIFO progress might trigger an interrupt. */
if (pThis->svga.u32IrqMask & SVGA_IRQFLAG_FIFO_PROGRESS)
@@ -2818,14 +3215,20 @@ static DECLCALLBACK(int) vmsvgaFIFOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
PDMDevHlpPCISetIrqNoWait(pDevIns, 0, 1);
}
}
- /* Done? */
- if (pFIFO[SVGA_FIFO_NEXT_CMD] == pFIFO[SVGA_FIFO_STOP])
+
+ /* If really done, clear the busy flag. */
+ if (fDone)
{
- Log(("vmsvgaFIFOLoop: emptied the FIFO next=%x stop=%x\n", pFIFO[SVGA_FIFO_NEXT_CMD], pFIFO[SVGA_FIFO_STOP]));
- pThis->svga.fBusy = false;
- pThis->svga.pFIFOR3[SVGA_FIFO_BUSY] = pThis->svga.fBusy;
+ Log(("vmsvgaFIFOLoop: emptied the FIFO next=%x stop=%x\n", pFIFO[SVGA_FIFO_NEXT_CMD], offCurrentCmd));
+ vmsvgaFifoSetNotBusy(pThis, pSVGAState, offFifoMin);
}
}
+
+ /*
+ * Free the bounce buffer. (There are no returns above!)
+ */
+ RTMemFree(pbBounceBuf);
+
return VINF_SUCCESS;
}
@@ -2843,9 +3246,9 @@ void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR)
if (pSVGAState->aGMR[idGMR].numDescriptors)
{
PGMR pGMR = &pSVGAState->aGMR[idGMR];
-#ifdef DEBUG_GMR_ACCESS
+# ifdef DEBUG_GMR_ACCESS
VMR3ReqCallWait(PDMDevHlpGetVM(pThis->pDevInsR3), VMCPUID_ANY, (PFNRT)vmsvgaUnregisterGMR, 2, pThis->pDevInsR3, idGMR);
-#endif
+# endif
Assert(pGMR->paDesc);
RTMemFree(pGMR->paDesc);
@@ -2862,61 +3265,69 @@ void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR)
*
* @returns VBox status code.
* @param pThis VGA device instance data.
- * @param transfer Transfer type (read/write)
- * @param pDest Host destination pointer
+ * @param enmTransferType Transfer type (read/write)
+ * @param pbDst Host destination pointer
* @param cbDestPitch Destination buffer pitch
* @param src GMR description
- * @param cbSrcOffset Source buffer offset
+ * @param offSrc Source buffer offset
* @param cbSrcPitch Source buffer pitch
* @param cbWidth Source width in bytes
* @param cHeight Source height
*/
-int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType transfer, uint8_t *pDest, int32_t cbDestPitch, SVGAGuestPtr src, uint32_t cbSrcOffset, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight)
+int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pbDst, int32_t cbDestPitch,
+ SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight)
{
PVMSVGASTATE pSVGAState = (PVMSVGASTATE)pThis->svga.pSVGAState;
PGMR pGMR;
int rc;
PVMSVGAGMRDESCRIPTOR pDesc;
- unsigned uDescOffset = 0;
+ unsigned offDesc = 0;
- Log(("vmsvgaGMRTransfer: gmr=%x offset=%x pitch=%d cbWidth=%d cHeight=%d; src offset=%d src pitch=%d\n", src.gmrId, src.offset, cbDestPitch, cbWidth, cHeight, cbSrcOffset, cbSrcPitch));
+ Log(("vmsvgaGMRTransfer: gmr=%x offset=%x pitch=%d cbWidth=%d cHeight=%d; src offset=%d src pitch=%d\n",
+ src.gmrId, src.offset, cbDestPitch, cbWidth, cHeight, offSrc, cbSrcPitch));
Assert(cbWidth && cHeight);
/* Shortcut for the framebuffer. */
if (src.gmrId == SVGA_GMR_FRAMEBUFFER)
{
- cbSrcOffset += src.offset;
- AssertReturn(src.offset < pThis->vram_size, VERR_INVALID_PARAMETER);
- AssertReturn(cbSrcOffset + cbSrcPitch * (cHeight - 1) + cbWidth <= pThis->vram_size, VERR_INVALID_PARAMETER);
-
- uint8_t *pSrc = pThis->CTX_SUFF(vram_ptr) + cbSrcOffset;
-
- if (transfer == SVGA3D_READ_HOST_VRAM)
+ offSrc += src.offset;
+ AssertMsgReturn(src.offset < pThis->vram_size,
+ ("src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x vram_size=%#x\n",
+ src.offset, offSrc, cbSrcPitch, cHeight, cbWidth, pThis->vram_size),
+ VERR_INVALID_PARAMETER);
+ AssertMsgReturn(offSrc + cbSrcPitch * (cHeight - 1) + cbWidth <= pThis->vram_size,
+ ("src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x vram_size=%#x\n",
+ src.offset, offSrc, cbSrcPitch, cHeight, cbWidth, pThis->vram_size),
+ VERR_INVALID_PARAMETER);
+
+ uint8_t *pSrc = pThis->CTX_SUFF(vram_ptr) + offSrc;
+
+ if (enmTransferType == SVGA3D_READ_HOST_VRAM)
{
/* switch src & dest */
- uint8_t *pTemp = pDest;
+ uint8_t *pTemp = pbDst;
int32_t cbTempPitch = cbDestPitch;
- pDest = pSrc;
+ pbDst = pSrc;
pSrc = pTemp;
cbDestPitch = cbSrcPitch;
cbSrcPitch = cbTempPitch;
}
- if ( pThis->svga.cbScanline == cbDestPitch
- && cbWidth == cbDestPitch
- && cbSrcPitch == cbDestPitch)
+ if ( pThis->svga.cbScanline == (uint32_t)cbDestPitch
+ && cbWidth == (uint32_t)cbDestPitch
+ && cbSrcPitch == cbDestPitch)
{
- memcpy(pDest, pSrc, cbWidth * cHeight);
+ memcpy(pbDst, pSrc, cbWidth * cHeight);
}
else
{
for(uint32_t i = 0; i < cHeight; i++)
{
- memcpy(pDest, pSrc, cbWidth);
+ memcpy(pbDst, pSrc, cbWidth);
- pDest += cbDestPitch;
+ pbDst += cbDestPitch;
pSrc += cbSrcPitch;
}
}
@@ -2927,60 +3338,66 @@ int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType transfer, uint8_
pGMR = &pSVGAState->aGMR[src.gmrId];
pDesc = pGMR->paDesc;
- cbSrcOffset += src.offset;
- AssertReturn(src.offset < pGMR->cbTotal, VERR_INVALID_PARAMETER);
- AssertReturn(cbSrcOffset + cbSrcPitch * (cHeight - 1) + cbWidth <= pGMR->cbTotal, VERR_INVALID_PARAMETER);
+ offSrc += src.offset;
+ AssertMsgReturn(src.offset < pGMR->cbTotal,
+ ("src.gmrId=%#x src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x\n",
+ src.gmrId, src.offset, offSrc, cbSrcPitch, cHeight, cbWidth, pGMR->cbTotal),
+ VERR_INVALID_PARAMETER);
+ AssertMsgReturn(offSrc + cbSrcPitch * (cHeight - 1) + cbWidth <= pGMR->cbTotal,
+ ("src.gmrId=%#x src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x cbTotal=%#x\n",
+ src.gmrId, src.offset, offSrc, cbSrcPitch, cHeight, cbWidth, pGMR->cbTotal),
+ VERR_INVALID_PARAMETER);
- for (unsigned i = 0; i < cHeight; i++)
+ for (uint32_t i = 0; i < cHeight; i++)
{
- unsigned cbCurrentWidth = cbWidth;
- unsigned uCurrentOffset = cbSrcOffset;
- uint8_t *pCurrentDest = pDest;
+ uint32_t cbCurrentWidth = cbWidth;
+ uint32_t offCurrent = offSrc;
+ uint8_t *pCurrentDest = pbDst;
/* Find the right descriptor */
- while (uDescOffset + pDesc->numPages * PAGE_SIZE <= uCurrentOffset)
+ while (offDesc + pDesc->numPages * PAGE_SIZE <= offCurrent)
{
- uDescOffset += pDesc->numPages * PAGE_SIZE;
- AssertReturn(uDescOffset < pGMR->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
+ offDesc += pDesc->numPages * PAGE_SIZE;
+ AssertReturn(offDesc < pGMR->cbTotal, VERR_INTERNAL_ERROR); /* overflow protection */
pDesc++;
}
while (cbCurrentWidth)
{
- unsigned cbToCopy;
-
- if (uCurrentOffset + cbCurrentWidth <= uDescOffset + pDesc->numPages * PAGE_SIZE)
+ uint32_t cbToCopy;
+
+ if (offCurrent + cbCurrentWidth <= offDesc + pDesc->numPages * PAGE_SIZE)
{
cbToCopy = cbCurrentWidth;
}
else
{
- cbToCopy = (uDescOffset + pDesc->numPages * PAGE_SIZE - uCurrentOffset);
+ cbToCopy = (offDesc + pDesc->numPages * PAGE_SIZE - offCurrent);
AssertReturn(cbToCopy <= cbCurrentWidth, VERR_INVALID_PARAMETER);
}
- LogFlow(("vmsvgaGMRTransfer: %s phys=%RGp\n", (transfer == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", pDesc->GCPhys + uCurrentOffset - uDescOffset));
+ LogFlow(("vmsvgaGMRTransfer: %s phys=%RGp\n", (enmTransferType == SVGA3D_WRITE_HOST_VRAM) ? "READ" : "WRITE", pDesc->GCPhys + offCurrent - offDesc));
- if (transfer == SVGA3D_WRITE_HOST_VRAM)
- rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + uCurrentOffset - uDescOffset, pCurrentDest, cbToCopy);
+ if (enmTransferType == SVGA3D_WRITE_HOST_VRAM)
+ rc = PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + offCurrent - offDesc, pCurrentDest, cbToCopy);
else
- rc = PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + uCurrentOffset - uDescOffset, pCurrentDest, cbToCopy);
+ rc = PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), pDesc->GCPhys + offCurrent - offDesc, pCurrentDest, cbToCopy);
AssertRCBreak(rc);
cbCurrentWidth -= cbToCopy;
- uCurrentOffset += cbToCopy;
+ offCurrent += cbToCopy;
pCurrentDest += cbToCopy;
/* Go to the next descriptor if there's anything left. */
if (cbCurrentWidth)
{
- uDescOffset += pDesc->numPages * PAGE_SIZE;
+ offDesc += pDesc->numPages * PAGE_SIZE;
pDesc++;
}
}
- cbSrcOffset += cbSrcPitch;
- pDest += cbDestPitch;
+ offSrc += cbSrcPitch;
+ pbDst += cbDestPitch;
}
return VINF_SUCCESS;
@@ -2997,7 +3414,7 @@ static DECLCALLBACK(int) vmsvgaFIFOLoopWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pTh
{
PVGASTATE pThis = (PVGASTATE)pThread->pvUser;
Log(("vmsvgaFIFOLoopWakeUp\n"));
- return RTSemEventSignal(pThis->svga.FIFORequestSem);
+ return SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
}
/**
@@ -3072,9 +3489,24 @@ DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS
if (enmType == PCI_ADDRESS_SPACE_IO)
{
AssertReturn(iRegion == 0, VERR_INTERNAL_ERROR);
- rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0, vmsvgaIOWrite, vmsvgaIORead, NULL /* OutStr */, NULL /* InStr */, "VMSVGA");
+ rc = PDMDevHlpIOPortRegister(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0,
+ vmsvgaIOWrite, vmsvgaIORead, NULL /* OutStr */, NULL /* InStr */, "VMSVGA");
if (RT_FAILURE(rc))
return rc;
+ if (pThis->fR0Enabled)
+ {
+ rc = PDMDevHlpIOPortRegisterR0(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0,
+ "vmsvgaIOWrite", "vmsvgaIORead", NULL, NULL, "VMSVGA");
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+ if (pThis->fGCEnabled)
+ {
+ rc = PDMDevHlpIOPortRegisterRC(pDevIns, (RTIOPORT)GCPhysAddress, cb, 0,
+ "vmsvgaIOWrite", "vmsvgaIORead", NULL, NULL, "VMSVGA");
+ if (RT_FAILURE(rc))
+ return rc;
+ }
pThis->svga.BasePort = GCPhysAddress;
Log(("vmsvgaR3IORegionMap: base port = %x\n", pThis->svga.BasePort));
@@ -3090,7 +3522,7 @@ DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS
rc = PDMDevHlpMMIO2Map(pDevIns, iRegion, GCPhysAddress);
AssertRC(rc);
-#ifdef DEBUG_FIFO_ACCESS
+# ifdef DEBUG_FIFO_ACCESS
if (RT_SUCCESS(rc))
{
rc = PGMR3HandlerPhysicalRegister(PDMDevHlpGetVM(pDevIns),
@@ -3102,7 +3534,7 @@ DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS
"VMSVGA FIFO");
AssertRC(rc);
}
-#endif
+# endif
if (RT_SUCCESS(rc))
{
pThis->svga.GCPhysFIFO = GCPhysAddress;
@@ -3112,10 +3544,10 @@ DECLCALLBACK(int) vmsvgaR3IORegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS
else
{
Assert(pThis->svga.GCPhysFIFO);
-#ifdef DEBUG_FIFO_ACCESS
+# ifdef DEBUG_FIFO_ACCESS
rc = PGMHandlerPhysicalDeregister(PDMDevHlpGetVM(pDevIns), pThis->svga.GCPhysFIFO);
AssertRC(rc);
-#endif
+# endif
pThis->svga.GCPhysFIFO = 0;
}
@@ -3178,7 +3610,7 @@ int vmsvgaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint3
}
}
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
if (pThis->svga.f3DEnabled)
{
VMSVGA_STATE_LOAD loadstate;
@@ -3194,13 +3626,13 @@ int vmsvgaLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint3
* The PowerOff notification isn't working, so not an option in this case.
*/
PDMR3ThreadResume(pThis->svga.pFIFOIOThread);
- RTSemEventSignal(pThis->svga.FIFORequestSem);
+ SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
/* Wait for the end of the command. */
rc = RTSemEventWait(pThis->svga.FIFOExtCmdSem, RT_INDEFINITE_WAIT);
AssertRC(rc);
PDMR3ThreadSuspend(pThis->svga.pFIFOIOThread);
}
-#endif
+# endif
return VINF_SUCCESS;
}
@@ -3275,7 +3707,7 @@ int vmsvgaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
}
}
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
if (pThis->svga.f3DEnabled)
{
/* Save the 3d state in the FIFO thread. */
@@ -3285,13 +3717,13 @@ int vmsvgaSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
* The PowerOff notification isn't working, so not an option in this case.
*/
PDMR3ThreadResume(pThis->svga.pFIFOIOThread);
- RTSemEventSignal(pThis->svga.FIFORequestSem);
+ SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
/* Wait for the end of the external command. */
rc = RTSemEventWait(pThis->svga.FIFOExtCmdSem, RT_INDEFINITE_WAIT);
AssertRC(rc);
PDMR3ThreadSuspend(pThis->svga.pFIFOIOThread);
}
-#endif
+# endif
return VINF_SUCCESS;
}
@@ -3316,7 +3748,7 @@ int vmsvgaReset(PPDMDEVINS pDevIns)
/* Reset the FIFO thread. */
pThis->svga.u8FIFOExtCommand = VMSVGA_FIFO_EXTCMD_RESET;
- RTSemEventSignal(pThis->svga.FIFORequestSem);
+ SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
/* Wait for the end of the termination sequence. */
int rc = RTSemEventWait(pThis->svga.FIFOExtCmdSem, 10000);
AssertRC(rc);
@@ -3328,9 +3760,9 @@ int vmsvgaReset(PPDMDEVINS pDevIns)
/* Register caps. */
pThis->svga.u32RegCaps = SVGA_CAP_GMR | SVGA_CAP_GMR2 | SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 | SVGA_CAP_EXTENDED_FIFO | SVGA_CAP_IRQMASK | SVGA_CAP_PITCHLOCK | SVGA_CAP_TRACES | SVGA_CAP_SCREEN_OBJECT_2 | SVGA_CAP_ALPHA_CURSOR;
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
pThis->svga.u32RegCaps |= SVGA_CAP_3D;
-#endif
+# endif
/* Setup FIFO capabilities. */
pThis->svga.pFIFOR3[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE | SVGA_FIFO_CAP_CURSOR_BYPASS_3 | SVGA_FIFO_CAP_GMR2 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED | SVGA_FIFO_CAP_SCREEN_OBJECT_2;
@@ -3369,7 +3801,8 @@ int vmsvgaDestruct(PPDMDEVINS pDevIns)
* The PowerOff notification isn't working, so not an option in this case.
*/
PDMR3ThreadResume(pThis->svga.pFIFOIOThread);
- RTSemEventSignal(pThis->svga.FIFORequestSem);
+ SUPSemEventSignal(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
+
/* Wait for the end of the termination sequence. */
rc = RTSemEventWait(pThis->svga.FIFOExtCmdSem, 10000);
AssertRC(rc);
@@ -3377,6 +3810,13 @@ int vmsvgaDestruct(PPDMDEVINS pDevIns)
if (pSVGAState)
{
+# ifndef VMSVGA_USE_EMT_HALT_CODE
+ if (pSVGAState->hBusyDelayedEmts != NIL_RTSEMEVENTMULTI)
+ {
+ RTSemEventMultiDestroy(pSVGAState->hBusyDelayedEmts);
+ pSVGAState->hBusyDelayedEmts = NIL_RTSEMEVENT;
+ }
+# endif
if (pSVGAState->Cursor.fActive)
RTMemFree(pSVGAState->Cursor.pData);
@@ -3389,10 +3829,16 @@ int vmsvgaDestruct(PPDMDEVINS pDevIns)
}
if (pThis->svga.pFrameBufferBackup)
RTMemFree(pThis->svga.pFrameBufferBackup);
- if (pThis->svga.FIFOExtCmdSem)
+ if (pThis->svga.FIFOExtCmdSem != NIL_RTSEMEVENT)
+ {
RTSemEventDestroy(pThis->svga.FIFOExtCmdSem);
- if (pThis->svga.FIFORequestSem)
- RTSemEventDestroy(pThis->svga.FIFORequestSem);
+ pThis->svga.FIFOExtCmdSem = NIL_RTSEMEVENT;
+ }
+ if (pThis->svga.FIFORequestSem != NIL_SUPSEMEVENT)
+ {
+ SUPSemEventClose(pThis->svga.pSupDrvSession, pThis->svga.FIFORequestSem);
+ pThis->svga.FIFORequestSem = NIL_SUPSEMEVENT;
+ }
return VINF_SUCCESS;
}
@@ -3422,7 +3868,9 @@ int vmsvgaInit(PPDMDEVINS pDevIns)
AssertReturn(pThis->svga.pFrameBufferBackup, VERR_NO_MEMORY);
/* Create event semaphore. */
- rc = RTSemEventCreate(&pThis->svga.FIFORequestSem);
+ pThis->svga.pSupDrvSession = PDMDevHlpGetSupDrvSession(pDevIns);
+
+ rc = SUPSemEventCreate(pThis->svga.pSupDrvSession, &pThis->svga.FIFORequestSem);
if (RT_FAILURE(rc))
{
Log(("%s: Failed to create event semaphore for FIFO handling.\n", __FUNCTION__));
@@ -3437,11 +3885,17 @@ int vmsvgaInit(PPDMDEVINS pDevIns)
return rc;
}
+# ifndef VMSVGA_USE_EMT_HALT_CODE
+ /* Create semaphore for delaying EMTs wait for the FIFO to stop being busy. */
+ rc = RTSemEventMultiCreate(&pSVGAState->hBusyDelayedEmts);
+ AssertRCReturn(rc, rc);
+# endif
+
/* Register caps. */
pThis->svga.u32RegCaps = SVGA_CAP_GMR | SVGA_CAP_GMR2 | SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 | SVGA_CAP_EXTENDED_FIFO | SVGA_CAP_IRQMASK | SVGA_CAP_PITCHLOCK | SVGA_CAP_TRACES | SVGA_CAP_SCREEN_OBJECT_2 | SVGA_CAP_ALPHA_CURSOR;
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
pThis->svga.u32RegCaps |= SVGA_CAP_3D;
-#endif
+# endif
/* Setup FIFO capabilities. */
pThis->svga.pFIFOR3[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE | SVGA_FIFO_CAP_CURSOR_BYPASS_3 | SVGA_FIFO_CAP_GMR2 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED | SVGA_FIFO_CAP_SCREEN_OBJECT_2;
@@ -3450,14 +3904,17 @@ int vmsvgaInit(PPDMDEVINS pDevIns)
pThis->svga.pFIFOR3[SVGA_FIFO_CURSOR_SCREEN_ID] = SVGA_ID_INVALID;
pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION] = pThis->svga.pFIFOR3[SVGA_FIFO_3D_HWVERSION_REVISED] = 0; /* no 3d available. */
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
if (pThis->svga.f3DEnabled)
{
rc = vmsvga3dInit(pThis);
if (RT_FAILURE(rc))
+ {
+ LogRel(("VMSVGA3d: 3D support disabled! (vmsvga3dInit -> %Rrc)\n", rc));
pThis->svga.f3DEnabled = false;
+ }
}
-#endif
+# endif
/* VRAM tracking is enabled by default during bootup. */
pThis->svga.fVRAMTracking = true;
@@ -3488,13 +3945,111 @@ int vmsvgaInit(PPDMDEVINS pDevIns)
/*
* Statistics.
*/
- STAM_REG(pVM, &pSVGAState->StatR3CmdPresent, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/Present", STAMUNIT_TICKS_PER_CALL, "Profiling of Present.");
- STAM_REG(pVM, &pSVGAState->StatR3CmdDrawPrimitive, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/DrawPrimitive", STAMUNIT_TICKS_PER_CALL, "Profiling of DrawPrimitive.");
- STAM_REG(pVM, &pSVGAState->StatR3CmdSurfaceDMA, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/SurfaceDMA", STAMUNIT_TICKS_PER_CALL, "Profiling of SurfaceDMA.");
+ STAM_REG(pVM, &pSVGAState->StatR3CmdPresent, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/Present", STAMUNIT_TICKS_PER_CALL, "Profiling of Present.");
+ STAM_REG(pVM, &pSVGAState->StatR3CmdDrawPrimitive, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/DrawPrimitive", STAMUNIT_TICKS_PER_CALL, "Profiling of DrawPrimitive.");
+ STAM_REG(pVM, &pSVGAState->StatR3CmdSurfaceDMA, STAMTYPE_PROFILE, "/Devices/VMSVGA/3d/Cmd/SurfaceDMA", STAMUNIT_TICKS_PER_CALL, "Profiling of SurfaceDMA.");
+ STAM_REL_REG(pVM, &pSVGAState->StatBusyDelayEmts, STAMTYPE_PROFILE, "/Devices/VMSVGA/EmtDelayOnBusyFifo", STAMUNIT_TICKS_PER_CALL, "Time we've delayed EMTs because of busy FIFO thread.");
+ STAM_REL_REG(pVM, &pSVGAState->StatFifoCommands, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoCommands", STAMUNIT_OCCURENCES, "FIFO command counter.");
+ STAM_REL_REG(pVM, &pSVGAState->StatFifoErrors, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoErrors", STAMUNIT_OCCURENCES, "FIFO error counter.");
+ STAM_REL_REG(pVM, &pSVGAState->StatFifoUnkCmds, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoUnknownCommands", STAMUNIT_OCCURENCES, "FIFO unknown command counter.");
+ STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoTimeout, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoTimeout", STAMUNIT_OCCURENCES, "Number of times we discovered pending work after a wait timeout.");
+ STAM_REL_REG(pVM, &pSVGAState->StatFifoTodoWoken, STAMTYPE_COUNTER, "/Devices/VMSVGA/FifoTodoWoken", STAMUNIT_OCCURENCES, "Number of times we discovered pending work after being woken up.");
+ STAM_REL_REG(pVM, &pSVGAState->StatFifoStalls, STAMTYPE_PROFILE, "/Devices/VMSVGA/FifoStalls", STAMUNIT_TICKS_PER_CALL, "Profiling of FIFO stalls (waiting for guest to finish copying data).");
return VINF_SUCCESS;
}
+# ifdef VBOX_WITH_VMSVGA3D
+/** Names for the vmsvga 3d capabilities, prefixed with format type hint char. */
+static const char * const g_apszVmSvgaDevCapNames[] =
+{
+ "x3D", /* = 0 */
+ "xMAX_LIGHTS",
+ "xMAX_TEXTURES",
+ "xMAX_CLIP_PLANES",
+ "xVERTEX_SHADER_VERSION",
+ "xVERTEX_SHADER",
+ "xFRAGMENT_SHADER_VERSION",
+ "xFRAGMENT_SHADER",
+ "xMAX_RENDER_TARGETS",
+ "xS23E8_TEXTURES",
+ "xS10E5_TEXTURES",
+ "xMAX_FIXED_VERTEXBLEND",
+ "xD16_BUFFER_FORMAT",
+ "xD24S8_BUFFER_FORMAT",
+ "xD24X8_BUFFER_FORMAT",
+ "xQUERY_TYPES",
+ "xTEXTURE_GRADIENT_SAMPLING",
+ "rMAX_POINT_SIZE",
+ "xMAX_SHADER_TEXTURES",
+ "xMAX_TEXTURE_WIDTH",
+ "xMAX_TEXTURE_HEIGHT",
+ "xMAX_VOLUME_EXTENT",
+ "xMAX_TEXTURE_REPEAT",
+ "xMAX_TEXTURE_ASPECT_RATIO",
+ "xMAX_TEXTURE_ANISOTROPY",
+ "xMAX_PRIMITIVE_COUNT",
+ "xMAX_VERTEX_INDEX",
+ "xMAX_VERTEX_SHADER_INSTRUCTIONS",
+ "xMAX_FRAGMENT_SHADER_INSTRUCTIONS",
+ "xMAX_VERTEX_SHADER_TEMPS",
+ "xMAX_FRAGMENT_SHADER_TEMPS",
+ "xTEXTURE_OPS",
+ "xSURFACEFMT_X8R8G8B8",
+ "xSURFACEFMT_A8R8G8B8",
+ "xSURFACEFMT_A2R10G10B10",
+ "xSURFACEFMT_X1R5G5B5",
+ "xSURFACEFMT_A1R5G5B5",
+ "xSURFACEFMT_A4R4G4B4",
+ "xSURFACEFMT_R5G6B5",
+ "xSURFACEFMT_LUMINANCE16",
+ "xSURFACEFMT_LUMINANCE8_ALPHA8",
+ "xSURFACEFMT_ALPHA8",
+ "xSURFACEFMT_LUMINANCE8",
+ "xSURFACEFMT_Z_D16",
+ "xSURFACEFMT_Z_D24S8",
+ "xSURFACEFMT_Z_D24X8",
+ "xSURFACEFMT_DXT1",
+ "xSURFACEFMT_DXT2",
+ "xSURFACEFMT_DXT3",
+ "xSURFACEFMT_DXT4",
+ "xSURFACEFMT_DXT5",
+ "xSURFACEFMT_BUMPX8L8V8U8",
+ "xSURFACEFMT_A2W10V10U10",
+ "xSURFACEFMT_BUMPU8V8",
+ "xSURFACEFMT_Q8W8V8U8",
+ "xSURFACEFMT_CxV8U8",
+ "xSURFACEFMT_R_S10E5",
+ "xSURFACEFMT_R_S23E8",
+ "xSURFACEFMT_RG_S10E5",
+ "xSURFACEFMT_RG_S23E8",
+ "xSURFACEFMT_ARGB_S10E5",
+ "xSURFACEFMT_ARGB_S23E8",
+ "xMISSING62",
+ "xMAX_VERTEX_SHADER_TEXTURES",
+ "xMAX_SIMULTANEOUS_RENDER_TARGETS",
+ "xSURFACEFMT_V16U16",
+ "xSURFACEFMT_G16R16",
+ "xSURFACEFMT_A16B16G16R16",
+ "xSURFACEFMT_UYVY",
+ "xSURFACEFMT_YUY2",
+ "xMULTISAMPLE_NONMASKABLESAMPLES",
+ "xMULTISAMPLE_MASKABLESAMPLES",
+ "xALPHATOCOVERAGE",
+ "xSUPERSAMPLE",
+ "xAUTOGENMIPMAPS",
+ "xSURFACEFMT_NV12",
+ "xSURFACEFMT_AYUV",
+ "xMAX_CONTEXT_IDS",
+ "xMAX_SURFACE_IDS",
+ "xSURFACEFMT_Z_DF16",
+ "xSURFACEFMT_Z_DF24",
+ "xSURFACEFMT_Z_D24S8_INT",
+ "xSURFACEFMT_BC4_UNORM",
+ "xSURFACEFMT_BC5_UNORM", /* 83 */
+};
+# endif
+
/**
* Power On notification.
@@ -3509,13 +4064,14 @@ DECLCALLBACK(void) vmsvgaR3PowerOn(PPDMDEVINS pDevIns)
PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
int rc;
-#ifdef VBOX_WITH_VMSVGA3D
+# ifdef VBOX_WITH_VMSVGA3D
if (pThis->svga.f3DEnabled)
{
rc = vmsvga3dPowerOn(pThis);
if (RT_SUCCESS(rc))
{
+ bool fSavedBuffering = RTLogRelSetBuffering(true);
SVGA3dCapsRecord *pCaps;
SVGA3dCapPair *pData;
uint32_t idxCap = 0;
@@ -3539,16 +4095,25 @@ DECLCALLBACK(void) vmsvgaR3PowerOn(PPDMDEVINS pDevIns)
pData[idxCap][0] = i;
pData[idxCap][1] = val;
idxCap++;
+ if (g_apszVmSvgaDevCapNames[i][0] == 'x')
+ LogRel(("VMSVGA3d: cap[%u]=%#010x {%s}\n", i, val, &g_apszVmSvgaDevCapNames[i][1]));
+ else
+ LogRel(("VMSVGA3d: cap[%u]=%d.%04u {%s}\n", i, (int)(float)val, (unsigned)((float)val * 10000) % 10000,
+ &g_apszVmSvgaDevCapNames[i][1]));
}
+ else
+ LogRel(("VMSVGA3d: cap[%u]=failed rc=%Rrc! {%s}\n", i, rc, &g_apszVmSvgaDevCapNames[i][1]));
}
pCaps->header.length = (sizeof(pCaps->header) + idxCap * sizeof(SVGA3dCapPair)) / sizeof(uint32_t);
pCaps = (SVGA3dCapsRecord *)((uint32_t *)pCaps + pCaps->header.length);
/* Mark end of record array. */
pCaps->header.length = 0;
+
+ RTLogRelSetBuffering(fSavedBuffering);
}
}
-#endif // VBOX_WITH_VMSVGA3D
+# endif // VBOX_WITH_VMSVGA3D
}
#endif /* IN_RING3 */
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h
index b75778e..cb1dc01 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.h
@@ -23,18 +23,28 @@
RT_C_DECLS_BEGIN
+#ifndef ___renderspu_cocoa_helper_h
ADD_COCOA_NATIVE_REF(NSView);
ADD_COCOA_NATIVE_REF(NSOpenGLContext);
-
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pShareCtx);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtrx);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaDestroyView(NativeNSViewRef pView);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx);
-__attribute__ ((visibility("default"))) void vmsvga3dCocoaSwapBuffers(NativeNSOpenGLContextRef pCtx);
+#endif
+
+#ifdef IN_VMSVGA3D
+# define VMSVGA3D_DECL(type) DECLEXPORT(type)
+#else
+# define VMSVGA3D_DECL(type) DECLIMPORT(type)
+#endif
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx,
+ bool fOtherProfile);
+VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx);
+VMSVGA3D_DECL(void) vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView);
+VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyView(NativeNSViewRef pView);
+VMSVGA3D_DECL(void) vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y);
+VMSVGA3D_DECL(void) vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h);
+VMSVGA3D_DECL(void) vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx);
+VMSVGA3D_DECL(void) vmsvga3dCocoaSwapBuffers(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx);
RT_C_DECLS_END
#endif /* !__DevVGA_SVGA3d_cocoa_h */
+
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
index b39b455..c789c04 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-cocoa.m
@@ -1,5 +1,7 @@
/** @file
- * VirtualBox OpenGL Cocoa Window System Helper Implementation.
+ * VirtualBox OpenGL Cocoa Window System Helper Implementation.
+ *
+ * @remarks Inspired by HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m.
*/
/*
@@ -20,19 +22,63 @@
#include <iprt/thread.h>
+/* Debug macros */
+#if 0 /*def DEBUG_VERBOSE*/
+/*# error "should be disabled!"*/
+# define DEBUG_INFO(text) do { \
+ crWarning text ; \
+ Assert(0); \
+ } while (0)
+
# define DEBUG_MSG(text) \
- do {} while (0)
-#ifdef DEBUG_VERBOSE
+ printf text
+
+# define DEBUG_WARN(text) do { \
+ crWarning text ; \
+ Assert(0); \
+ } while (0)
+
# define DEBUG_MSG_1(text) \
DEBUG_MSG(text)
+
+# define DEBUG_FUNC_ENTER() \
+ int cchDebugFuncEnter = printf("==>%s\n", __PRETTY_FUNCTION__)
+
+#define DEBUG_FUNC_LEAVE() do { \
+ DEBUG_MSG(("<==%s\n", __PRETTY_FUNCTION__)); \
+ } while (0)
+
+#define DEBUG_FUNC_RET(valuefmtnl) do { \
+ DEBUG_MSG(("<==%s returns", __PRETTY_FUNCTION__)); \
+ DEBUG_MSG(valuefmtnl); \
+ } while (0)
+
#else
+
+# define DEBUG_INFO(text) do { \
+ crInfo text ; \
+ } while (0)
+
+# define DEBUG_MSG(text) \
+ do {} while (0)
+
+# define DEBUG_WARN(text) do { \
+ crWarning text ; \
+ } while (0)
+
# define DEBUG_MSG_1(text) \
do {} while (0)
+
+# define DEBUG_FUNC_ENTER() int cchDebugFuncEnter = 0
+# define DEBUG_FUNC_LEAVE() NOREF(cchDebugFuncEnter)
+# define DEBUG_FUNC_RET(valuefmtnl) DEBUG_FUNC_LEAVE()
+
#endif
# define CHECK_GL_ERROR()\
do {} while (0)
+
/** Custom OpenGL context class.
*
* This implementation doesn't allow to set a view to the
@@ -55,7 +101,7 @@
NSOpenGLContext *m_pGLCtx;
- /* position/size */
+ /* Position/Size tracking */
NSPoint m_Pos;
NSSize m_Size;
@@ -121,6 +167,8 @@
-(id)initWithFormat:(NSOpenGLPixelFormat*)format shareContext:(NSOpenGLContext*)share
{
+ DEBUG_FUNC_ENTER();
+
m_pPixelFormat = NULL;
m_pView = NULL;
@@ -129,48 +177,65 @@
m_pPixelFormat = format;
DEBUG_MSG(("OCTX(%p): init VMSVGA3DOpenGLContext\n", (void*)self));
-
+ DEBUG_FUNC_RET(("%p\n", (void *)self));
return self;
}
- (void)dealloc
{
+ DEBUG_FUNC_ENTER();
DEBUG_MSG(("OCTX(%p): dealloc VMSVGA3DOpenGLContext\n", (void*)self));
[m_pPixelFormat release];
+m_pPixelFormat = NULL;
+m_pView = NULL;
+
[super dealloc];
+ DEBUG_FUNC_LEAVE();
}
-(bool)isDoubleBuffer
{
+ DEBUG_FUNC_ENTER();
GLint val;
[m_pPixelFormat getValues:&val forAttribute:NSOpenGLPFADoubleBuffer forVirtualScreen:0];
+ DEBUG_FUNC_RET(("%d\n", val == 1 ? YES : NO));
return val == 1 ? YES : NO;
}
-(void)setView:(NSView*)view
{
+ DEBUG_FUNC_ENTER();
DEBUG_MSG(("OCTX(%p): setView: new view: %p\n", (void*)self, (void*)view));
m_pView = view;
+
+ DEBUG_FUNC_LEAVE();
}
-(NSView*)view
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_FUNC_RET(("%p\n", (void *)m_pView));
return m_pView;
}
-(void)clearDrawable
{
+ DEBUG_FUNC_ENTER();
DEBUG_MSG(("OCTX(%p): clearDrawable\n", (void*)self));
- m_pView = NULL;;
+ m_pView = NULL;
[super clearDrawable];
+
+ DEBUG_FUNC_LEAVE();
}
-(NSOpenGLPixelFormat*)openGLPixelFormat
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_FUNC_RET(("%p\n", (void *)m_pPixelFormat));
return m_pPixelFormat;
}
@@ -178,11 +243,156 @@
+/********************************************************************************
+*
+* VMSVGA3DOverlayHelperView class implementation
+*
+********************************************************************************/
+ at implementation VMSVGA3DOverlayHelperView
+
+-(id)initWithOverlayWindow:(VMSVGA3DOverlayWindow*)pOverlayWindow
+{
+ DEBUG_FUNC_ENTER();
+
+ self = [super initWithFrame:NSZeroRect];
+
+ m_pOverlayWindow = pOverlayWindow;
+
+ DEBUG_MSG(("OHVW(%p): init OverlayHelperView\n", (void*)self));
+ DEBUG_FUNC_RET(("%p\n", (void *)self));
+ return self;
+}
+
+-(void)viewDidMoveToWindow
+{
+ DEBUG_FUNC_ENTER();
+ DEBUG_MSG(("OHVW(%p): viewDidMoveToWindow: new win: %p\n", (void*)self, (void*)[self window]));
+
+ [m_pOverlayWindow parentWindowChanged:[self window]];
+
+ DEBUG_FUNC_LEAVE();
+}
+
+ at end
+
+/********************************************************************************
+*
+* VMSVGA3DOverlayWindow class implementation
+*
+********************************************************************************/
+ at implementation VMSVGA3DOverlayWindow
+
+- (id)initWithParentView:(NSView*)pParentView overlayView:(VMSVGA3DOverlayView*)pOverlayView
+{
+ DEBUG_FUNC_ENTER();
+ NSWindow *pParentWin = nil;
+
+ if((self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]))
+ {
+ m_pParentView = pParentView;
+ m_pOverlayView = pOverlayView;
+ m_Thread = [NSThread currentThread];
+
+ [m_pOverlayView setOverlayWin: self];
+
+ m_pOverlayHelperView = [[VMSVGA3DOverlayHelperView alloc] initWithOverlayWindow:self];
+ /* Add the helper view as a child of the parent view to get notifications */
+ [pParentView addSubview:m_pOverlayHelperView];
+
+ /* Make sure this window is transparent */
+#ifdef SHOW_WINDOW_BACKGROUND
+ /* For debugging */
+ [self setBackgroundColor:[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.7]];
+#else
+ [self setBackgroundColor:[NSColor clearColor]];
+#endif
+ [self setOpaque:NO];
+ [self setAlphaValue:.999];
+ /* Disable mouse events for this window */
+ [self setIgnoresMouseEvents:YES];
+
+ pParentWin = [m_pParentView window];
+
+ /* Initial set the position to the parents view top/left (Compiz fix). */
+ [self setFrameOrigin:
+ [pParentWin convertBaseToScreen:
+ [m_pParentView convertPoint:NSZeroPoint toView:nil]]];
+
+ /* Set the overlay view as our content view */
+ [self setContentView:m_pOverlayView];
+
+ /* Add ourself as a child to the parent views window. Note: this has to
+ * be done last so that everything else is setup in
+ * parentWindowChanged. */
+ [pParentWin addChildWindow:self ordered:NSWindowAbove];
+ }
+ DEBUG_MSG(("OWIN(%p): init OverlayWindow\n", (void*)self));
+ DEBUG_FUNC_RET(("%p\n", (void *)self));
+ return self;
+}
+
+- (void)dealloc
+{
+ DEBUG_FUNC_ENTER();
+ DEBUG_MSG(("OWIN(%p): dealloc OverlayWindow\n", (void*)self));
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [m_pOverlayHelperView removeFromSuperview];
+ [m_pOverlayHelperView release];
+
+ [super dealloc];
+ DEBUG_FUNC_LEAVE();
+}
+
+- (void)parentWindowFrameChanged:(NSNotification*)pNote
+{
+ DEBUG_FUNC_ENTER();
+ DEBUG_MSG(("OWIN(%p): parentWindowFrameChanged\n", (void*)self));
+
+ [m_pOverlayView reshape];
+
+ DEBUG_FUNC_LEAVE();
+}
+
+- (void)parentWindowChanged:(NSWindow*)pWindow
+{
+ DEBUG_FUNC_ENTER();
+ DEBUG_MSG(("OWIN(%p): parentWindowChanged\n", (void*)self));
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ if(pWindow != nil)
+ {
+ /* Ask to get notifications when our parent window frame changes. */
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(parentWindowFrameChanged:)
+ name:NSWindowDidResizeNotification
+ object:pWindow];
+ /* Add us self as child window */
+ [pWindow addChildWindow:self ordered:NSWindowAbove];
+ [m_pOverlayView reshape];
+ }
+
+ DEBUG_FUNC_LEAVE();
+}
+
+ at end
+
+/********************************************************************************
+*
+* VMSVGA3DOverlayView class implementation
+*
+********************************************************************************/
@implementation VMSVGA3DOverlayView
- (id)initWithFrame:(NSRect) frame parentView:(NSView*)pParentView
{
+ DEBUG_FUNC_ENTER();
+
m_pParentView = pParentView;
+ /* Make some reasonable defaults */
m_pGLCtx = nil;
m_Pos = NSZeroPoint;
m_Size = NSMakeSize(1, 1);
@@ -191,68 +401,149 @@
self = [super initWithFrame: frame];
+ DEBUG_MSG(("OVIW(%p): init VMSVGA3DOverlayView\n", (void*)self));
+ DEBUG_FUNC_RET(("%p\n", (void *)self));
return self;
}
+- (void)cleanupData
+{
+ DEBUG_FUNC_ENTER();
+
+ /*[self deleteDockTile];*/
+
+ [self setGLCtx:nil];
+
+#if 0
+ if (m_pSharedGLCtx)
+ {
+ if ([m_pSharedGLCtx view] == self)
+ [m_pSharedGLCtx clearDrawable];
+
+ [m_pSharedGLCtx release];
+
+ m_pSharedGLCtx = nil;
+
+ CrBltTerm(m_pBlitter);
+
+ RTMemFree(m_pBlitter);
+
+ m_pBlitter = nil;
+ }
+#endif
+
+ /*[self clearVisibleRegions];*/
+
+ DEBUG_FUNC_LEAVE();
+}
+
+- (void)dealloc
+{
+ DEBUG_FUNC_ENTER();
+ DEBUG_MSG(("OVIW(%p): dealloc OverlayView\n", (void*)self));
+
+ [self cleanupData];
+
+ [super dealloc];
+
+ DEBUG_FUNC_LEAVE();
+}
+
+
- (void)setGLCtx:(NSOpenGLContext*)pCtx
{
+ DEBUG_FUNC_ENTER();
+
+ DEBUG_MSG(("OVIW(%p): setGLCtx: new ctx: %p (old: %p)\n", (void*)self, (void*)pCtx, (void *)m_pGLCtx));
if (m_pGLCtx == pCtx)
+ {
+ DEBUG_FUNC_LEAVE();
return;
+ }
+
+ /* ensure the context drawable is cleared to avoid holding a reference to inexistent view */
if (m_pGLCtx)
+ {
[m_pGLCtx clearDrawable];
+ [m_pGLCtx release];
+ /*[m_pGLCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
+ }
m_pGLCtx = pCtx;
+ if (pCtx)
+ [pCtx retain];
+
+ DEBUG_FUNC_LEAVE();
}
- (NSOpenGLContext*)glCtx
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_FUNC_RET(("%p\n", (void *)m_pGLCtx));
return m_pGLCtx;
}
- (void)setOverlayWin:(NSWindow*)pWin
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_MSG(("OVIW(%p): setOverlayWin: new win: %p\n", (void*)self, (void*)pWin));
m_pOverlayWin = pWin;
+ DEBUG_FUNC_LEAVE();
}
- (NSWindow*)overlayWin
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_FUNC_RET(("%p\n", (void *)m_pOverlayWin));
return m_pOverlayWin;
}
- (void)setPos:(NSPoint)pos
{
+ DEBUG_FUNC_ENTER();
+
m_Pos = pos;
[self reshape];
+ DEBUG_FUNC_LEAVE();
}
- (NSPoint)pos
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_FUNC_RET(("%f,%f\n", m_Pos.x, m_Pos.y));
return m_Pos;
}
- (void)setSize:(NSSize)size
{
+ DEBUG_FUNC_ENTER();
m_Size = size;
[self reshape];
+ DEBUG_FUNC_LEAVE();
}
- (NSSize)size
{
+ DEBUG_FUNC_ENTER();
+ DEBUG_FUNC_RET(("%f,%f\n", m_Size.width, m_Size.height));
return m_Size;
}
- (void)updateViewportCS
{
+ DEBUG_FUNC_ENTER();
DEBUG_MSG(("OVIW(%p): updateViewport\n", (void*)self));
/* Update the viewport for our OpenGL view */
/* [m_pSharedGLCtx update]; */
/* Clear background to transparent */
-// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+/* glClearColor(0.0f, 0.0f, 0.0f, 0.0f);*/
+ DEBUG_FUNC_LEAVE();
}
- (void)reshape
{
+ DEBUG_FUNC_ENTER();
NSRect parentFrame = NSZeroRect;
NSPoint parentPos = NSZeroPoint;
NSPoint childPos = NSZeroPoint;
@@ -264,6 +555,7 @@
/* Getting the right screen coordinates of the parents frame is a little bit
* complicated. */
parentFrame = [m_pParentView frame];
+ DEBUG_MSG(("FIXED parentFrame [%f:%f], [%f:%f]\n", parentFrame.origin.x, parentFrame.origin.y, parentFrame.size.width, parentFrame.size.height));
parentPos = [[m_pParentView window] convertBaseToScreen:[[m_pParentView superview] convertPointToBase:NSMakePoint(parentFrame.origin.x, parentFrame.origin.y + parentFrame.size.height)]];
parentFrame.origin.x = parentPos.x;
parentFrame.origin.y = parentPos.y;
@@ -271,25 +563,27 @@
/* Calculate the new screen coordinates of the overlay window. */
childPos = NSMakePoint(m_Pos.x, m_Pos.y + m_Size.height);
childPos = [[m_pParentView window] convertBaseToScreen:[[m_pParentView superview] convertPointToBase:childPos]];
+ DEBUG_MSG(("FIXED childPos(screen) [%f:%f]\n", childPos.x, childPos.y));
/* Make a frame out of it. */
childFrame = NSMakeRect(childPos.x, childPos.y, m_Size.width, m_Size.height);
+ DEBUG_MSG(("FIXED childFrame [%f:%f], [%f:%f]\n", childFrame.origin.x, childFrame.origin.y, childFrame.size.width, childFrame.size.height));
/* We have to make sure that the overlay window will not be displayed out
* of the parent window. So intersect both frames & use the result as the new
* frame for the window. */
newFrame = NSIntersectionRect(parentFrame, childFrame);
- DEBUG_MSG(("[%#p]: parentFrame pos[%f : %f] size[%f : %f]\n",
+ DEBUG_MSG(("[%p]: parentFrame pos[%f : %f] size[%f : %f]\n",
(void*)self,
parentFrame.origin.x, parentFrame.origin.y,
parentFrame.size.width, parentFrame.size.height));
- DEBUG_MSG(("[%#p]: childFrame pos[%f : %f] size[%f : %f]\n",
+ DEBUG_MSG(("[%p]: childFrame pos[%f : %f] size[%f : %f]\n",
(void*)self,
childFrame.origin.x, childFrame.origin.y,
childFrame.size.width, childFrame.size.height));
- DEBUG_MSG(("[%#p]: newFrame pos[%f : %f] size[%f : %f]\n",
+ DEBUG_MSG(("[%p]: newFrame pos[%f : %f] size[%f : %f]\n",
(void*)self,
newFrame.origin.x, newFrame.origin.y,
newFrame.size.width, newFrame.size.height));
@@ -301,7 +595,7 @@
m_RootRect.size = newFrame.size;
m_yInvRootOffset = newFrame.origin.y - childFrame.origin.y;
- DEBUG_MSG(("[%#p]: m_RootRect pos[%f : %f] size[%f : %f]\n",
+ DEBUG_MSG(("[%p]: m_RootRect pos[%f : %f] size[%f : %f]\n",
(void*)self,
m_RootRect.origin.x, m_RootRect.origin.y,
m_RootRect.size.width, m_RootRect.size.height));
@@ -322,140 +616,21 @@
vboxCtxLeave(&CtxInfo);
}
#endif
-}
-
- at end
-
-/********************************************************************************
-*
-* VMSVGA3DOverlayHelperView class implementation
-*
-********************************************************************************/
- at implementation VMSVGA3DOverlayHelperView
-
--(id)initWithOverlayWindow:(VMSVGA3DOverlayWindow*)pOverlayWindow
-{
- self = [super initWithFrame:NSZeroRect];
-
- m_pOverlayWindow = pOverlayWindow;
-
- return self;
-}
-
--(void)viewDidMoveToWindow
-{
- DEBUG_MSG(("OHVW(%p): viewDidMoveToWindow: new win: %p\n", (void*)self, (void*)[self window]));
-
- [m_pOverlayWindow parentWindowChanged:[self window]];
-}
-
- at end
-
-
-/********************************************************************************
-*
-* VMSVGA3DOverlayWindow class implementation
-*
-********************************************************************************/
- at implementation VMSVGA3DOverlayWindow
-
-- (id)initWithParentView:(NSView*)pParentView overlayView:(VMSVGA3DOverlayView*)pOverlayView
-{
- NSWindow *pParentWin = nil;
-
- if((self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]))
- {
- m_pParentView = pParentView;
- m_pOverlayView = pOverlayView;
- m_Thread = [NSThread currentThread];
-
- [m_pOverlayView setOverlayWin: self];
-
- m_pOverlayHelperView = [[VMSVGA3DOverlayHelperView alloc] initWithOverlayWindow:self];
- /* Add the helper view as a child of the parent view to get notifications */
- [pParentView addSubview:m_pOverlayHelperView];
-
- /* Make sure this window is transparent */
-#ifdef SHOW_WINDOW_BACKGROUND
- /* For debugging */
- [self setBackgroundColor:[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.7]];
-#else
- [self setBackgroundColor:[NSColor clearColor]];
-#endif
- [self setOpaque:NO];
- [self setAlphaValue:.999];
- /* Disable mouse events for this window */
- [self setIgnoresMouseEvents:YES];
-
- pParentWin = [m_pParentView window];
-
- /* Initial set the position to the parents view top/left (Compiz fix). */
- [self setFrameOrigin:
- [pParentWin convertBaseToScreen:
- [m_pParentView convertPoint:NSZeroPoint toView:nil]]];
-
- /* Set the overlay view as our content view */
- [self setContentView:m_pOverlayView];
-
- /* Add ourself as a child to the parent views window. Note: this has to
- * be done last so that everything else is setup in
- * parentWindowChanged. */
- [pParentWin addChildWindow:self ordered:NSWindowAbove];
- }
- DEBUG_MSG(("OWIN(%p): init OverlayWindow\n", (void*)self));
-
- return self;
-}
-
-- (void)dealloc
-{
- DEBUG_MSG(("OWIN(%p): dealloc OverlayWindow\n", (void*)self));
-
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- [m_pOverlayHelperView removeFromSuperview];
- [m_pOverlayHelperView release];
-
- [super dealloc];
-}
-
-- (void)parentWindowFrameChanged:(NSNotification*)pNote
-{
- DEBUG_MSG(("OWIN(%p): parentWindowFrameChanged\n", (void*)self));
-
- [m_pOverlayView reshape];
-}
-
-- (void)parentWindowChanged:(NSWindow*)pWindow
-{
- DEBUG_MSG(("OWIN(%p): parentWindowChanged\n", (void*)self));
-
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- if(pWindow != nil)
- {
- /* Ask to get notifications when our parent window frame changes. */
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(parentWindowFrameChanged:)
- name:NSWindowDidResizeNotification
- object:pWindow];
- /* Add us self as child window */
- [pWindow addChildWindow:self ordered:NSWindowAbove];
- [m_pOverlayView reshape];
- }
+ DEBUG_FUNC_LEAVE();
}
@end
-void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pShareCtx)
+void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pShareCtx, bool fOtherProfile)
{
+ DEBUG_FUNC_ENTER();
NSOpenGLPixelFormat *pFmt = nil;
-
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
#if 1
+ // @todo galitsyn: NSOpenGLPFAWindow was deprecated starting from OSX 10.9.
+ // Consider to remove it and check if it's harmless.
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFAWindow,
@@ -484,21 +659,26 @@ void vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLC
if (pFmt)
{
*ppCtx = [[VMSVGA3DOpenGLContext alloc] initWithFormat:pFmt shareContext:pShareCtx];
- DEBUG_MSG(("New context %X\n", (uint)*ppCtx));
+ DEBUG_MSG(("New context %p\n", (void *)*ppCtx));
}
[pPool release];
+
+ DEBUG_FUNC_LEAVE();
}
void vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx)
{
+ DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
[pCtx release];
[pPool release];
+ DEBUG_FUNC_LEAVE();
}
void vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView)
{
+ DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
/* Create our worker view */
@@ -513,10 +693,12 @@ void vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentVie
}
[pPool release];
+ DEBUG_FUNC_LEAVE();
}
void vmsvga3dCocoaDestroyView(NativeNSViewRef pView)
{
+ DEBUG_FUNC_ENTER();
NSWindow *pWin = nil;
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
@@ -524,11 +706,14 @@ void vmsvga3dCocoaDestroyView(NativeNSViewRef pView)
[pWin release];
[pView release];
+
[pPool release];
+ DEBUG_FUNC_LEAVE();
}
void vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y)
{
+ DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
[(VMSVGA3DOverlayView*)pView setPos:NSMakePoint(x, y)];
@@ -538,15 +723,18 @@ void vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParent
void vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h)
{
+ DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
[(VMSVGA3DOverlayView*)pView setSize:NSMakeSize(w, h)];
[pPool release];
+ DEBUG_FUNC_LEAVE();
}
void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
{
+ DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
DEBUG_MSG(("cocoaViewMakeCurrentContext(%p, %p)\n", (void*)pView, (void*)pCtx));
@@ -554,7 +742,7 @@ void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLCo
if (pView)
{
[(VMSVGA3DOverlayView*)pView setGLCtx:pCtx];
-// [(VMSVGA3DOverlayView*)pView makeCurrentFBO];
+/* [(VMSVGA3DOverlayView*)pView makeCurrentFBO];*/
[pCtx makeCurrentContext];
}
else
@@ -563,13 +751,16 @@ void vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLCo
}
[pPool release];
+ DEBUG_FUNC_LEAVE();
}
-void vmsvga3dCocoaSwapBuffers(NativeNSOpenGLContextRef pCtx)
+void vmsvga3dCocoaSwapBuffers(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
{
+ DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
[pCtx flushBuffer];
[pPool release];
+ DEBUG_FUNC_LEAVE();
}
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
index 3feacd7..9a7cfb9 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2013-2014 Oracle Corporation
+ * Copyright (C) 2013-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -76,8 +76,7 @@ typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname,
# include <GL/gl.h>
# include <GL/glx.h>
# include <GL/glext.h>
-//HACK FOR NOW
-typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103
#endif
#include "vmsvga_glext/glext.h"
@@ -87,20 +86,50 @@ typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
#include <math.h>
#include <float.h>
+
+/* Generated by VBoxDef2LazyLoad from the VBoxSVGA3D.def and VBoxSVGA3DObjC.def files. */
+extern "C" int ExplicitlyLoadVBoxSVGA3D(bool fResolveAllImports, PRTERRINFO pErrInfo);
+#ifdef RT_OS_DARWIN
+extern "C" int ExplicitlyLoadVBoxSVGA3DObjC(bool fResolveAllImports, PRTERRINFO pErrInfo);
+#endif
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
+ * Turns out that on Linux gl.h may often define the first 2-4 OpenGL versions
+ * worth of extensions, but missing out on a function pointer of fifteen. This
+ * causes headache for us when we use the function pointers below. This hack
+ * changes the code to call the known problematic functions directly.
+ * The value is ((x)<<16 | (y)) where x and y are taken from the GL_VERSION_x_y.
+ */
+#ifndef VBOX_VMSVGA3D_GL_HACK_LEVEL
+# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0
+#endif
+
+#ifndef VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE
+# define VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE 1.0
+#endif
+
#ifdef RT_OS_WINDOWS
-#define OGLGETPROCADDRESS wglGetProcAddress
+# define OGLGETPROCADDRESS wglGetProcAddress
+
#elif defined(RT_OS_DARWIN)
-#include <dlfcn.h>
-void *MyNSGLGetProcAddress(const char *name)
+# include <dlfcn.h>
+# define OGLGETPROCADDRESS MyNSGLGetProcAddress
+/** Resolves an OpenGL symbol. */
+static void *MyNSGLGetProcAddress(const char *pszSymbol)
{
- static void *s_image = NULL;
- if (s_image == NULL)
- s_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
- return (s_image ? dlsym(s_image, name) : NULL);
+ /* Another copy in shaderapi.c. */
+ static void *s_pvImage = NULL;
+ if (s_pvImage == NULL)
+ s_pvImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
+ return s_pvImage ? dlsym(s_pvImage, pszSymbol) : NULL;
}
-# define OGLGETPROCADDRESS MyNSGLGetProcAddress
+
#else
-#define OGLGETPROCADDRESS(x) glXGetProcAddress((const GLubyte *)x)
+# define OGLGETPROCADDRESS(x) glXGetProcAddress((const GLubyte *)x)
#endif
/* Invert y-coordinate for OpenGL's bottom left origin. */
@@ -113,18 +142,20 @@ void *MyNSGLGetProcAddress(const char *name)
/* Enable to render the result of DrawPrimitive in a seperate window. */
//#define DEBUG_GFX_WINDOW
-/*******************************************************************************
-* Structures and Typedefs *
-*******************************************************************************/
#define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState) \
do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0)
+/** @def VMSVGA3D_SET_CURRENT_CONTEXT
+ * Makes sure the @a pContext is the active OpenGL context.
+ * @parm pState The VMSVGA3d state.
+ * @parm pContext The new context.
+ */
#ifdef RT_OS_WINDOWS
# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
if ((pState)->idActiveContext != pContext->id) \
{ \
- BOOL makecurret = wglMakeCurrent((pContext)->hdc, (pContext)->hglrc); \
- Assert(makecurret == TRUE); \
+ BOOL fMakeCurrentRc = wglMakeCurrent((pContext)->hdc, (pContext)->hglrc); \
+ Assert(fMakeCurrentRc == TRUE); \
pState->idActiveContext = (pContext)->id; \
} else do { } while (0)
@@ -139,24 +170,47 @@ void *MyNSGLGetProcAddress(const char *name)
# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
if ((pState)->idActiveContext != (pContext)->id) \
{ \
- Bool makecurret = glXMakeCurrent((pState)->display, \
- (pContext)->window, \
- (pContext)->glxContext); \
- Assert(makecurret == True); \
+ Bool fMakeCurrentRc = glXMakeCurrent((pState)->display, \
+ (pContext)->window, \
+ (pContext)->glxContext); \
+ Assert(fMakeCurrentRc == True); \
(pState)->idActiveContext = (pContext)->id; \
} else do { } while (0)
#endif
+/** @def VMSVGA3D_CHECK_LAST_ERROR
+ * Checks that the last OpenGL error code indicates success.
+ *
+ * Will assert and return VERR_INTERNAL_ERROR in strict builds, in other
+ * builds it will do nothing and is a NOOP.
+ *
+ * @parm pState The VMSVGA3d state.
+ * @parm pContext The new context.
+ *
+ * @todo Revamp this to include the OpenGL operation so we can see what went
+ * wrong. Maybe include a few of the first occurances in the release
+ * log of regular builds.
+ */
#ifdef VBOX_STRICT
# define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { \
Assert((pState)->idActiveContext == (pContext)->id); \
(pContext)->lastError = glGetError(); \
- AssertMsgReturn((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError), VERR_INTERNAL_ERROR); \
+ AssertMsgReturn((pContext)->lastError == GL_NO_ERROR, \
+ ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError), \
+ VERR_INTERNAL_ERROR); \
} while (0)
#else
# define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { } while (0)
#endif
+/** @def VMSVGA3D_CHECK_LAST_ERROR_WARN
+ * Checks that the last OpenGL error code indicates success.
+ *
+ * Will assert in strict builds, otherwise it's a NOOP.
+ *
+ * @parm pState The VMSVGA3d state.
+ * @parm pContext The new context.
+ */
#ifdef VBOX_STRICT
# define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { \
Assert((pState)->idActiveContext == (pContext)->id); \
@@ -167,6 +221,53 @@ void *MyNSGLGetProcAddress(const char *name)
# define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { } while (0)
#endif
+
+/**
+ * Macro for doing something and then checking for errors during initialization.
+ * Uses AssertLogRelMsg.
+ */
+#define VMSVGA3D_INIT_CHECKED(a_Expr) \
+ do \
+ { \
+ a_Expr; \
+ GLenum iGlError = glGetError(); \
+ AssertLogRelMsg(iGlError == GL_NO_ERROR, ("VMSVGA3d: %s -> %#x\n", #a_Expr, iGlError)); \
+ } while (0)
+
+/**
+ * Macro for doing something and then checking for errors during initialization,
+ * doing the same in the other context when enabled.
+ *
+ * This will try both profiles in dual profile builds. Caller must be in the
+ * default context.
+ *
+ * Uses AssertLogRelMsg to indicate trouble.
+ */
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+# define VMSVGA3D_INIT_CHECKED_BOTH(a_pState, a_pContext, a_pOtherCtx, a_Expr) \
+ do \
+ { \
+ for (uint32_t i = 0; i < 64; i++) if (glGetError() == GL_NO_ERROR) break; Assert(glGetError() == GL_NO_ERROR); \
+ a_Expr; \
+ GLenum iGlError = glGetError(); \
+ if (iGlError != GL_NO_ERROR) \
+ { \
+ VMSVGA3D_SET_CURRENT_CONTEXT(a_pState, a_pOtherCtx); \
+ for (uint32_t i = 0; i < 64; i++) if (glGetError() == GL_NO_ERROR) break; Assert(glGetError() == GL_NO_ERROR); \
+ a_Expr; \
+ GLenum iGlError2 = glGetError(); \
+ AssertLogRelMsg(iGlError2 == GL_NO_ERROR, ("VMSVGA3d: %s -> %#x / %#x\n", #a_Expr, iGlError, iGlError2)); \
+ VMSVGA3D_SET_CURRENT_CONTEXT(a_pState, a_pContext); \
+ } \
+ } while (0)
+#else
+# define VMSVGA3D_INIT_CHECKED_BOTH(a_pState, a_pContext, a_pOtherCtx, a_Expr) VMSVGA3D_INIT_CHECKED(a_Expr)
+#endif
+
+
+/*******************************************************************************
+* Structures, Typedefs and Globals. *
+*******************************************************************************/
typedef struct
{
SVGA3dSize size;
@@ -330,6 +431,7 @@ typedef struct
/* OpenGL rendering context */
NativeNSOpenGLContextRef cocoaContext;
NativeNSViewRef cocoaView;
+ bool fOtherProfile;
#else
/** XGL rendering context handle */
GLXContext glxContext;
@@ -428,7 +530,12 @@ static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
SSMFIELD_ENTRY_TERM()
};
-typedef struct
+/**
+ * VMSVGA3d state data.
+ *
+ * Allocated on the heap and pointed to by VMSVGAState::p3dState.
+ */
+typedef struct VMSVGA3DSTATE
{
#ifdef RT_OS_WINDOWS
/** Window Thread. */
@@ -471,12 +578,14 @@ typedef struct
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
PFNGLPOINTPARAMETERFPROC glPointParameterf;
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
+ PFNGLBLENDCOLORPROC glBlendColor;
PFNGLBLENDEQUATIONPROC glBlendEquation;
+#endif
PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
- PFNGLBLENDCOLORPROC glBlendColor;
PFNGLBINDBUFFERPROC glBindBuffer;
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
PFNGLGENBUFFERSPROC glGenBuffers;
@@ -490,7 +599,9 @@ typedef struct
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
PFNGLACTIVETEXTUREPROC glActiveTexture;
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
+#endif
PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
PFNGLPROVOKINGVERTEXPROC glProvokingVertex;
bool fEXT_stencil_two_side;
@@ -522,7 +633,25 @@ typedef struct
#ifdef DEBUG_GFX_WINDOW_TEST_CONTEXT
uint32_t idTestContext;
#endif
-} VMSVGA3DSTATE, *PVMSVGA3DSTATE;
+ /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
+ * Free with RTStrFree. */
+ R3PTRTYPE(char *) pszExtensions;
+
+ /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
+ * Free with RTStrFree.
+ *
+ * This is used to detect shader model version since some implementations
+ * (darwin) hides extensions that have made it into core and probably a
+ * bunch of others when using a OpenGL core profile instead of a legacy one */
+ R3PTRTYPE(char *) pszOtherExtensions;
+ /** The version of the other GL profile. */
+ float fOtherGLVersion;
+
+ /** Shader talk back interface. */
+ VBOXVMSVGASHADERIF ShaderIf;
+} VMSVGA3DSTATE;
+/** Pointer to the VMSVGA3d state. */
+typedef VMSVGA3DSTATE *PVMSVGA3DSTATE;
/**
* SSM descriptor table for the VMSVGA3DSTATE structure.
@@ -576,60 +705,459 @@ static int vmsvga3dCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContex
static void vmsvgaColor2GLFloatArray(uint32_t color, GLfloat *pRed, GLfloat *pGreen, GLfloat *pBlue, GLfloat *pAlpha);
RT_C_DECLS_END
-static bool vmsvga3dCheckGLExtension(const char *pExtensionName)
+
+/**
+ * Checks if the given OpenGL extension is supported.
+ *
+ * @returns true if supported, false if not.
+ * @param pState The VMSVGA3d state.
+ * @param fActualGLVersion The actual OpenGL version we're working against.
+ * @param fMinGLVersion The OpenGL version that introduced this feature
+ * into the core.
+ * @param pszWantedExtension The name of the OpenGL extension we want padded
+ * with one space at each end.
+ * @remarks Init time only.
+ */
+static bool vmsvga3dCheckGLExtension(PVMSVGA3DSTATE pState, float fMinGLVersion, const char *pszWantedExtension)
+{
+ /* check padding. */
+ Assert(pszWantedExtension[0] == ' ');
+ Assert(pszWantedExtension[1] != ' ');
+ Assert(strchr(&pszWantedExtension[1], ' ') + 1 == strchr(pszWantedExtension, '\0'));
+
+ /* Look it up. */
+ bool fRet = false;
+ if (strstr(pState->pszExtensions, pszWantedExtension))
+ fRet = true;
+
+ /* Temporarily. Later start if (fMinGLVersion != 0.0 && fActualGLVersion >= fMinGLVersion) return true; */
+#ifdef RT_OS_DARWIN
+ AssertMsg( fMinGLVersion == 0.0
+ || fRet == (pState->fGLVersion >= fMinGLVersion)
+ || VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE == 2.1,
+ ("%s actual:%d min:%d fRet=%d\n",
+ pszWantedExtension, (int)(pState->fGLVersion * 10), (int)(fMinGLVersion * 10), fRet));
+#else
+ AssertMsg(fMinGLVersion == 0.0 || fRet == (pState->fGLVersion >= fMinGLVersion),
+ ("%s actual:%d min:%d fRet=%d\n",
+ pszWantedExtension, (int)(pState->fGLVersion * 10), (int)(fMinGLVersion * 10), fRet));
+#endif
+ return fRet;
+}
+
+
+/**
+ * Outputs GL_EXTENSIONS list to the release log.
+ */
+static void vmsvga3dLogRelExtensions(const char *pszPrefix, const char *pszExtensions)
{
- char *pSupportedExtensions = (char *)glGetString(GL_EXTENSIONS);
- char *pExtensionSupported = pSupportedExtensions;
- size_t cbExtension = strlen(pExtensionName);
+ /* OpenGL 3.0 interface (glGetString(GL_EXTENSIONS) return NULL). */
+ bool fBuffered = RTLogRelSetBuffering(true);
+
+ /*
+ * Determin the column widths first.
+ */
+ size_t acchWidths[4] = { 1, 1, 1, 1 };
+ uint32_t i;
+ const char *psz = pszExtensions;
+ for (i = 0; ; i++)
+ {
+ while (*psz == ' ')
+ psz++;
+ if (!*psz)
+ break;
+
+ const char *pszEnd = strchr(psz, ' ');
+ AssertBreak(pszEnd);
+ size_t cch = pszEnd - psz;
+
+ uint32_t iColumn = i % RT_ELEMENTS(acchWidths);
+ if (acchWidths[iColumn] < cch)
+ acchWidths[iColumn] = cch;
+
+ psz = pszEnd;
+ }
- while (true)
+ /*
+ * Output it.
+ */
+ LogRel(("VMSVGA3d: %sOpenGL extensions (%d):", pszPrefix, i));
+ psz = pszExtensions;
+ for (i = 0; ; i++)
{
- pExtensionSupported = strstr(pExtensionSupported, pExtensionName);
- if (pExtensionSupported == NULL)
+ while (*psz == ' ')
+ psz++;
+ if (!*psz)
break;
- if ( ( pExtensionSupported == pSupportedExtensions
- || *(pExtensionSupported-1) == ' ')
- && ( pExtensionSupported[cbExtension] == ' '
- || pExtensionSupported[cbExtension] == 0)
- )
- return true;
+ const char *pszEnd = strchr(psz, ' ');
+ AssertBreak(pszEnd);
+ size_t cch = pszEnd - psz;
+
+ uint32_t iColumn = i % RT_ELEMENTS(acchWidths);
+ if (iColumn == 0)
+ LogRel(("\nVMSVGA3d: %-*.*s", acchWidths[iColumn], cch, psz));
+ else if (iColumn != RT_ELEMENTS(acchWidths) - 1)
+ LogRel((" %-*.*s", acchWidths[iColumn], cch, psz));
+ else
+ LogRel((" %.*s", cch, psz));
- pExtensionSupported += cbExtension;
+ psz = pszEnd;
}
- return false;
+
+ RTLogRelSetBuffering(fBuffered);
+ LogRel(("\n"));
}
-int vmsvga3dInit(PVGASTATE pThis)
+/**
+ * Gathers the GL_EXTENSIONS list, storing it as a space padded list at
+ * @a ppszExtensions.
+ *
+ * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY
+ * @param ppszExtensions Pointer to the string pointer. Free with RTStrFree.
+ * @param fGLProfileVersion The OpenGL profile version.
+ */
+static int vmsvga3dGatherExtensions(char **ppszExtensions, float fGLProfileVersion)
{
- PVMSVGA3DSTATE pState;
- int rc;
+ int rc;
+ *ppszExtensions = NULL;
+
+ /*
+ * Try the old glGetString interface first.
+ */
+ const char *pszExtensions = (const char *)glGetString(GL_EXTENSIONS);
+ if (pszExtensions)
+ {
+ rc = RTStrAAppendExN(ppszExtensions, 3, " ", (size_t)1, pszExtensions, RTSTR_MAX, " ", (size_t)1);
+ AssertLogRelRCReturn(rc, rc);
+ }
+ else
+ {
+ /*
+ * The new interface where each extension string is retrieved separately.
+ * Note! Cannot use VMSVGA3D_INIT_CHECKED_GL_GET_INTEGER_VALUE here because
+ * the above GL_EXTENSIONS error lingers on darwin. sucks.
+ */
+#ifndef GL_NUM_EXTENSIONS
+# define GL_NUM_EXTENSIONS 0x821D
+#endif
+ GLint cExtensions = 1024;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &cExtensions);
+ Assert(cExtensions != 1024);
+
+ PFNGLGETSTRINGIPROC pfnGlGetStringi = (PFNGLGETSTRINGIPROC)OGLGETPROCADDRESS("glGetStringi");
+ AssertLogRelReturn(pfnGlGetStringi, VERR_NOT_SUPPORTED);
+
+ rc = RTStrAAppend(ppszExtensions, " ");
+ for (GLint i = 0; RT_SUCCESS(rc) && i < cExtensions; i++)
+ {
+ const char *pszExt = (const char *)pfnGlGetStringi(GL_EXTENSIONS, i);
+ if (pszExt)
+ rc = RTStrAAppendExN(ppszExtensions, 2, pfnGlGetStringi(GL_EXTENSIONS, i), RTSTR_MAX, " ", (size_t)1);
+ }
+ AssertRCReturn(rc, rc);
+ }
+
+#if 1
+ /*
+ * Add extensions promoted into the core OpenGL profile.
+ */
+ static const struct
+ {
+ float fGLVersion;
+ const char *pszzExtensions;
+ } s_aPromotedExtensions[] =
+ {
+ {
+ 1.1f,
+ " GL_EXT_vertex_array \0"
+ " GL_EXT_polygon_offset \0"
+ " GL_EXT_blend_logic_op \0"
+ " GL_EXT_texture \0"
+ " GL_EXT_copy_texture \0"
+ " GL_EXT_subtexture \0"
+ " GL_EXT_texture_object \0"
+ " GL_ARB_framebuffer_object \0"
+ " GL_ARB_map_buffer_range \0"
+ " GL_ARB_vertex_array_object \0"
+ "\0"
+ },
+ {
+ 1.2f,
+ " EXT_texture3D \0"
+ " EXT_bgra \0"
+ " EXT_packed_pixels \0"
+ " EXT_rescale_normal \0"
+ " EXT_separate_specular_color \0"
+ " SGIS_texture_edge_clamp \0"
+ " SGIS_texture_lod \0"
+ " EXT_draw_range_elements \0"
+ "\0"
+ },
+ {
+ 1.3f,
+ " GL_ARB_texture_compression \0"
+ " GL_ARB_texture_cube_map \0"
+ " GL_ARB_multisample \0"
+ " GL_ARB_multitexture \0"
+ " GL_ARB_texture_env_add \0"
+ " GL_ARB_texture_env_combine \0"
+ " GL_ARB_texture_env_dot3 \0"
+ " GL_ARB_texture_border_clamp \0"
+ " GL_ARB_transpose_matrix \0"
+ "\0"
+ },
+ {
+ 1.5f,
+ " GL_SGIS_generate_mipmap \0"
+ /*" GL_NV_blend_equare \0"*/
+ " GL_ARB_depth_texture \0"
+ " GL_ARB_shadow \0"
+ " GL_EXT_fog_coord \0"
+ " GL_EXT_multi_draw_arrays \0"
+ " GL_ARB_point_parameters \0"
+ " GL_EXT_secondary_color \0"
+ " GL_EXT_blend_func_separate \0"
+ " GL_EXT_stencil_wrap \0"
+ " GL_ARB_texture_env_crossbar \0"
+ " GL_EXT_texture_lod_bias \0"
+ " GL_ARB_texture_mirrored_repeat \0"
+ " GL_ARB_window_pos \0"
+ "\0"
+ },
+ {
+ 1.6f,
+ " GL_ARB_vertex_buffer_object \0"
+ " GL_ARB_occlusion_query \0"
+ " GL_EXT_shadow_funcs \0"
+ },
+ {
+ 2.0f,
+ " GL_ARB_shader_objects \0" /*??*/
+ " GL_ARB_vertex_shader \0" /*??*/
+ " GL_ARB_fragment_shader \0" /*??*/
+ " GL_ARB_shading_language_100 \0" /*??*/
+ " GL_ARB_draw_buffers \0"
+ " GL_ARB_texture_non_power_of_two \0"
+ " GL_ARB_point_sprite \0"
+ " GL_ATI_separate_stencil \0"
+ " GL_EXT_stencil_two_side \0"
+ "\0"
+ },
+ {
+ 2.1f,
+ " GL_ARB_pixel_buffer_object \0"
+ " GL_EXT_texture_sRGB \0"
+ "\0"
+ },
+ {
+ 3.0f,
+ " GL_ARB_framebuffer_object \0"
+ " GL_ARB_map_buffer_range \0"
+ " GL_ARB_vertex_array_object \0"
+ "\0"
+ },
+ {
+ 3.1f,
+ " GL_ARB_copy_buffer \0"
+ " GL_ARB_uniform_buffer_object \0"
+ "\0"
+ },
+ {
+ 3.2f,
+ " GL_ARB_vertex_array_bgra \0"
+ " GL_ARB_draw_elements_base_vertex \0"
+ " GL_ARB_fragment_coord_conventions \0"
+ " GL_ARB_provoking_vertex \0"
+ " GL_ARB_seamless_cube_map \0"
+ " GL_ARB_texture_multisample \0"
+ " GL_ARB_depth_clamp \0"
+ " GL_ARB_sync \0"
+ " GL_ARB_geometry_shader4 \0" /*??*/
+ "\0"
+ },
+ {
+ 3.3f,
+ " GL_ARB_blend_func_extended \0"
+ " GL_ARB_sampler_objects \0"
+ " GL_ARB_explicit_attrib_location \0"
+ " GL_ARB_occlusion_query2 \0"
+ " GL_ARB_shader_bit_encoding \0"
+ " GL_ARB_texture_rgb10_a2ui \0"
+ " GL_ARB_texture_swizzle \0"
+ " GL_ARB_timer_query \0"
+ " GL_ARB_vertex_type_2_10_10_10_rev \0"
+ "\0"
+ },
+ {
+ 4.0f,
+ " GL_ARB_texture_query_lod \0"
+ " GL_ARB_draw_indirect \0"
+ " GL_ARB_gpu_shader5 \0"
+ " GL_ARB_gpu_shader_fp64 \0"
+ " GL_ARB_shader_subroutine \0"
+ " GL_ARB_tessellation_shader \0"
+ " GL_ARB_texture_buffer_object_rgb32 \0"
+ " GL_ARB_texture_cube_map_array \0"
+ " GL_ARB_texture_gather \0"
+ " GL_ARB_transform_feedback2 \0"
+ " GL_ARB_transform_feedback3 \0"
+ "\0"
+ },
+ {
+ 4.1f,
+ " GL_ARB_ES2_compatibility \0"
+ " GL_ARB_get_program_binary \0"
+ " GL_ARB_separate_shader_objects \0"
+ " GL_ARB_shader_precision \0"
+ " GL_ARB_vertex_attrib_64bit \0"
+ " GL_ARB_viewport_array \0"
+ "\0"
+ }
+ };
+
+ uint32_t cPromoted = 0;
+ for (uint32_t i = 0; i < RT_ELEMENTS(s_aPromotedExtensions) && s_aPromotedExtensions[i].fGLVersion <= fGLProfileVersion; i++)
+ {
+ const char *pszExt = s_aPromotedExtensions[i].pszzExtensions;
+ while (*pszExt)
+ {
+ size_t cchExt = strlen(pszExt);
+ Assert(cchExt > 3);
+ Assert(pszExt[0] == ' ');
+ Assert(pszExt[1] != ' ');
+ Assert(pszExt[cchExt - 2] != ' ');
+ Assert(pszExt[cchExt - 1] == ' ');
+
+ if (strstr(*ppszExtensions, pszExt) == NULL)
+ {
+ if (cPromoted++ == 0)
+ {
+ rc = RTStrAAppend(ppszExtensions, " <promoted-extensions:> <promoted-extensions:> <promoted-extensions:> ");
+ AssertRCReturn(rc, rc);
+ }
+
+ rc = RTStrAAppend(ppszExtensions, pszExt);
+ AssertRCReturn(rc, rc);
+ }
+
+ pszExt = strchr(pszExt, '\0') + 1;
+ }
+ }
+#endif
+ return VINF_SUCCESS;
+}
+
+/**
+ * @interface_method_impl{VBOXVMSVGASHADERIF, pfnSwitchInitProfile}
+ */
+static DECLCALLBACK(void) vmsvga3dShaderIfSwitchInitProfile(PVBOXVMSVGASHADERIF pThis, bool fOtherProfile)
+{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
+ VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->paContext[fOtherProfile ? 2 : 1]);
+#else
+ NOREF(pThis);
+ NOREF(fOtherProfile);
+#endif
+}
+
+
+/**
+ * @interface_method_impl{VBOXVMSVGASHADERIF, pfnGetNextExtension}
+ */
+static DECLCALLBACK(bool) vmsvga3dShaderIfGetNextExtension(PVBOXVMSVGASHADERIF pThis, void **ppvEnumCtx,
+ char *pszBuf, size_t cbBuf, bool fOtherProfile)
+{
+ PVMSVGA3DSTATE pState = RT_FROM_MEMBER(pThis, VMSVGA3DSTATE, ShaderIf);
+ const char *pszCur = *ppvEnumCtx ? (const char *)*ppvEnumCtx
+ : fOtherProfile ? pState->pszOtherExtensions : pState->pszExtensions;
+ while (*pszCur == ' ')
+ pszCur++;
+ if (!*pszCur)
+ return false;
+
+ const char *pszEnd = strchr(pszCur, ' ');
+ AssertReturn(pszEnd, false);
+ size_t cch = pszEnd - pszCur;
+ if (cch < cbBuf)
+ {
+ memcpy(pszBuf, pszCur, cch);
+ pszBuf[cch] = '\0';
+ }
+ else if (cbBuf > 0)
+ {
+ memcpy(pszBuf, "<overflow>", RT_MIN(sizeof("<overflow>"), cbBuf));
+ pszBuf[cbBuf - 1] = '\0';
+ }
+
+ *ppvEnumCtx = (void *)pszEnd;
+ return true;
+}
+
+
+/**
+ * Initializes the VMSVGA3D state during VGA device construction.
+ *
+ * Failure are generally not fatal, 3D support will just be disabled.
+ *
+ * @returns VBox status code.
+ * @param pThis The VGA device state where svga.p3dState will be modified.
+ */
+int vmsvga3dInit(PVGASTATE pThis)
+{
AssertCompile(GL_TRUE == 1);
AssertCompile(GL_FALSE == 0);
- pThis->svga.p3dState = RTMemAllocZ(sizeof(VMSVGA3DSTATE));
- AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
- pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
-
-#ifdef RT_OS_WINDOWS
- /* Create event semaphore. */
- rc = RTSemEventCreate(&pState->WndRequestSem);
+ /*
+ * Load and resolve imports from the external shared libraries.
+ */
+ RTERRINFOSTATIC ErrInfo;
+ int rc = ExplicitlyLoadVBoxSVGA3D(true /*fResolveAllImports*/, RTErrInfoInitStatic(&ErrInfo));
if (RT_FAILURE(rc))
{
- Log(("%s: Failed to create event semaphore for window handling.\n", __FUNCTION__));
+ LogRel(("VMSVGA3d: Error loading VBoxSVGA3D and resolving necessary functions: %Rrc - %s\n", rc, ErrInfo.Core.pszMsg));
return rc;
}
-
- /* Create the async IO thread. */
- rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dWindowThread, pState->WndRequestSem, 0, RTTHREADTYPE_GUI, 0, "VMSVGA3DWND");
+#ifdef RT_OS_DARWIN
+ rc = ExplicitlyLoadVBoxSVGA3DObjC(true /*fResolveAllImports*/, RTErrInfoInitStatic(&ErrInfo));
if (RT_FAILURE(rc))
{
- AssertMsgFailed(("%s: Async IO Thread creation for 3d window handling failed rc=%d\n", __FUNCTION__, rc));
+ LogRel(("VMSVGA3d: Error loading VBoxSVGA3DObjC and resolving necessary functions: %Rrc - %s\n", rc, ErrInfo.Core.pszMsg));
return rc;
}
#endif
+
+ /*
+ * Allocate the state.
+ */
+ pThis->svga.p3dState = RTMemAllocZ(sizeof(VMSVGA3DSTATE));
+ AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
+
+#ifdef RT_OS_WINDOWS
+ /* Create event semaphore and async IO thread. */
+ PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
+ rc = RTSemEventCreate(&pState->WndRequestSem);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dWindowThread, pState->WndRequestSem, 0, RTTHREADTYPE_GUI, 0,
+ "VMSVGA3DWND");
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+
+ /* bail out. */
+ LogRel(("VMSVGA3d: RTThreadCreate failed: %Rrc\n", rc));
+ RTSemEventDestroy(pState->WndRequestSem);
+ }
+ else
+ LogRel(("VMSVGA3d: RTSemEventCreate failed: %Rrc\n", rc));
+ RTMemFree(pThis->svga.p3dState);
+ pThis->svga.p3dState = NULL;
+ return rc;
+#else
return VINF_SUCCESS;
+#endif
}
/* We must delay window creation until the PowerOn phase. Init is too early and will cause failures. */
@@ -638,24 +1166,70 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
PVMSVGA3DCONTEXT pContext;
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ PVMSVGA3DCONTEXT pOtherCtx;
+#endif
int rc;
if (pState->fGLVersion != 0.0)
return VINF_SUCCESS; /* already initialized (load state) */
- /* OpenGL function calls aren't possible without a valid current context, so create a fake one here. */
- rc = vmsvga3dContextDefine(pThis, 1);
+ /*
+ * OpenGL function calls aren't possible without a valid current context, so create a fake one here.
+ */
+ rc = vmsvga3dContextDefine(pThis, 1, false /*fOtherProfile*/);
AssertRCReturn(rc, rc);
pContext = &pState->paContext[1];
VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
- LogRel(("VMSVGA3d: OpenGL version: %s\nOpenGL Vendor: %s\nOpenGL Renderer: %s\n", glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER)));
- LogRel(("VMSVGA3d: OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)));
- LogRel(("VMSVGA3d: OpenGL extensions: %s\n\n", glGetString(GL_EXTENSIONS)));
- pState->fGLVersion = atof((const char *)glGetString(GL_VERSION));
+ LogRel(("VMSVGA3d: OpenGL version: %s\n"
+ "VMSVGA3d: OpenGL Vendor: %s\n"
+ "VMSVGA3d: OpenGL Renderer: %s\n"
+ "VMSVGA3d: OpenGL shader language version: %s\n",
+ glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER),
+ glGetString(GL_SHADING_LANGUAGE_VERSION)));
+
+ rc = vmsvga3dGatherExtensions(&pState->pszExtensions, VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE);
+ AssertRCReturn(rc, rc);
+ vmsvga3dLogRelExtensions("", pState->pszExtensions);
+
+ pState->fGLVersion = atof((const char *)glGetString(GL_VERSION));
+
+
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ /*
+ * Get the extension list for the alternative profile so we can better
+ * figure out the shader model and stuff.
+ */
+ rc = vmsvga3dContextDefine(pThis, 2, true /*fOtherProfile*/);
+ AssertLogRelRCReturn(rc, rc);
+ pContext = &pState->paContext[1]; /* Array may have been reallocated. */
+
+ pOtherCtx = &pState->paContext[2];
+ VMSVGA3D_SET_CURRENT_CONTEXT(pState, pOtherCtx);
+
+ LogRel(("VMSVGA3d: Alternative OpenGL version: %s\n"
+ "VMSVGA3d: Alternative OpenGL Vendor: %s\n"
+ "VMSVGA3d: Alternative OpenGL Renderer: %s\n"
+ "VMSVGA3d: Alternative OpenGL shader language version: %s\n",
+ glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER),
+ glGetString(GL_SHADING_LANGUAGE_VERSION)));
+
+ rc = vmsvga3dGatherExtensions(&pState->pszOtherExtensions, VBOX_VMSVGA3D_OTHER_OGL_PROFILE);
+ AssertRCReturn(rc, rc);
+ vmsvga3dLogRelExtensions("Alternative ", pState->pszOtherExtensions);
+
+ pState->fOtherGLVersion = atof((const char *)glGetString(GL_VERSION));
+
+ VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
+#else
+ pState->pszOtherExtensions = (char *)"";
+ pState->fOtherGLVersion = pState->fGLVersion;
+#endif
+
- if (vmsvga3dCheckGLExtension("GL_ARB_framebuffer_object"))
+ if (vmsvga3dCheckGLExtension(pState, 3.0, " GL_ARB_framebuffer_object "))
{
pState->ext.glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)OGLGETPROCADDRESS("glIsRenderbuffer");
pState->ext.glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)OGLGETPROCADDRESS("glBindRenderbuffer");
@@ -680,8 +1254,12 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
}
pState->ext.glPointParameterf = (PFNGLPOINTPARAMETERFPROC)OGLGETPROCADDRESS("glPointParameterf");
AssertMsgReturn(pState->ext.glPointParameterf, ("glPointParameterf missing"), VERR_NOT_IMPLEMENTED);
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
+ pState->ext.glBlendColor = (PFNGLBLENDCOLORPROC)OGLGETPROCADDRESS("glBlendColor");
+ AssertMsgReturn(pState->ext.glBlendColor, ("glBlendColor missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glBlendEquation = (PFNGLBLENDEQUATIONPROC)OGLGETPROCADDRESS("glBlendEquation");
AssertMsgReturn(pState->ext.glBlendEquation, ("glBlendEquation missing"), VERR_NOT_IMPLEMENTED);
+#endif
pState->ext.glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)OGLGETPROCADDRESS("glBlendEquationSeparate");
AssertMsgReturn(pState->ext.glBlendEquationSeparate, ("glBlendEquationSeparate missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)OGLGETPROCADDRESS("glBlendFuncSeparate");
@@ -690,8 +1268,6 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
AssertMsgReturn(pState->ext.glStencilOpSeparate, ("glStencilOpSeparate missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)OGLGETPROCADDRESS("glStencilFuncSeparate");
AssertMsgReturn(pState->ext.glStencilFuncSeparate, ("glStencilFuncSeparate missing"), VERR_NOT_IMPLEMENTED);
- pState->ext.glBlendColor = (PFNGLBLENDCOLORPROC)OGLGETPROCADDRESS("glBlendColor");
- AssertMsgReturn(pState->ext.glBlendColor, ("glBlendColor missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glBindBuffer = (PFNGLBINDBUFFERPROC)OGLGETPROCADDRESS("glBindBuffer");
AssertMsgReturn(pState->ext.glBindBuffer, ("glBindBuffer missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)OGLGETPROCADDRESS("glDeleteBuffers");
@@ -714,13 +1290,15 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
AssertMsgReturn(pState->ext.glFogCoordPointer, ("glFogCoordPointer missing"), VERR_NOT_IMPLEMENTED);
pState->ext.glActiveTexture = (PFNGLACTIVETEXTUREPROC)OGLGETPROCADDRESS("glActiveTexture");
AssertMsgReturn(pState->ext.glActiveTexture, ("glActiveTexture missing"), VERR_NOT_IMPLEMENTED);
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
pState->ext.glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)OGLGETPROCADDRESS("glClientActiveTexture");
AssertMsgReturn(pState->ext.glClientActiveTexture, ("glClientActiveTexture missing"), VERR_NOT_IMPLEMENTED);
+#endif
pState->ext.glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)OGLGETPROCADDRESS("glGetProgramivARB");
AssertMsgReturn(pState->ext.glGetProgramivARB, ("glGetProgramivARB missing"), VERR_NOT_IMPLEMENTED);
/* OpenGL 3.2 core */
- if (vmsvga3dCheckGLExtension("GL_ARB_draw_elements_base_vertex"))
+ if (vmsvga3dCheckGLExtension(pState, 3.2f, " GL_ARB_draw_elements_base_vertex "))
{
pState->ext.glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsBaseVertex");
pState->ext.glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)OGLGETPROCADDRESS("glDrawElementsInstancedBaseVertex");
@@ -729,7 +1307,7 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
LogRel(("VMSVGA3d: missing extension GL_ARB_draw_elements_base_vertex\n"));
/* OpenGL 3.2 core */
- if (vmsvga3dCheckGLExtension("GL_ARB_provoking_vertex"))
+ if (vmsvga3dCheckGLExtension(pState, 3.2f, " GL_ARB_provoking_vertex "))
{
pState->ext.glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)OGLGETPROCADDRESS("glProvokingVertex");
}
@@ -737,9 +1315,16 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
LogRel(("VMSVGA3d: missing extension GL_ARB_provoking_vertex\n"));
/* Extension support */
- pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension("GL_EXT_stencil_two_side");
+#if defined(RT_OS_DARWIN)
+ /** @todo OpenGL version history suggest this, verify... */
+ pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 2.0, " GL_EXT_stencil_two_side ");
+#else
+ pState->ext.fEXT_stencil_two_side = vmsvga3dCheckGLExtension(pState, 0.0, " GL_EXT_stencil_two_side ");
+#endif
- /* First set sensible defaults. */
+ /*
+ * Initialize the capabilities with sensible defaults.
+ */
pState->caps.maxActiveLights = 1;
pState->caps.maxTextureBufferSize = 65536;
pState->caps.maxTextures = 1;
@@ -751,40 +1336,37 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
pState->caps.maxFragmentShaderInstructions = 1024;
pState->caps.vertexShaderVersion = SVGA3DVSVERSION_NONE;
pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_NONE;
+ pState->caps.flPointSize[0] = 1;
+ pState->caps.flPointSize[1] = 1;
- /* Query capabilities */
- glGetIntegerv(GL_MAX_LIGHTS, &pState->caps.maxActiveLights);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &pState->caps.maxTextureBufferSize);
-#ifdef DEBUG_bird
- if (pState->fGLVersion >= 3.1) /* darwin: Requires GL 3.1, so triggers on older mac os x versions. */
-#endif
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &pState->caps.maxTextures);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetIntegerv(GL_MAX_CLIP_DISTANCES, &pState->caps.maxClipDistances);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &pState->caps.maxColorAttachments);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, &pState->caps.maxRectangleTextureSize);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &pState->caps.maxTextureAnisotropy);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
+ /*
+ * Query capabilities
+ */
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_LIGHTS, &pState->caps.maxActiveLights));
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &pState->caps.maxTextureBufferSize));
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &pState->caps.maxTextures));
+ VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_CLIP_DISTANCES, &pState->caps.maxClipDistances));
+ VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &pState->caps.maxColorAttachments));
+ VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, &pState->caps.maxRectangleTextureSize));
+ VMSVGA3D_INIT_CHECKED(glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &pState->caps.maxTextureAnisotropy));
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx, glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pState->caps.flPointSize));
if (pState->ext.glGetProgramivARB)
{
- pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &pState->caps.maxFragmentShaderTemps);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &pState->caps.maxFragmentShaderInstructions);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &pState->caps.maxVertexShaderTemps);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &pState->caps.maxVertexShaderInstructions);
- VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
- }
- pState->caps.fS3TCSupported = vmsvga3dCheckGLExtension("GL_EXT_texture_compression_s3tc");
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+ pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
+ &pState->caps.maxFragmentShaderTemps));
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+ pState->ext.glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
+ &pState->caps.maxFragmentShaderInstructions));
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+ pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
+ &pState->caps.maxVertexShaderTemps));
+ VMSVGA3D_INIT_CHECKED_BOTH(pState, pContext, pOtherCtx,
+ pState->ext.glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB,
+ &pState->caps.maxVertexShaderInstructions));
+ }
+ pState->caps.fS3TCSupported = vmsvga3dCheckGLExtension(pState, 0.0, " GL_EXT_texture_compression_s3tc ");
/* http://http://www.opengl.org/wiki/Detecting_the_Shader_Model
* ARB Assembly Language
@@ -794,22 +1376,27 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
* GL_ARB_fragment_program: SM 2.0 or better.
* ATI does not support higher than SM 2.0 functionality in assembly shaders.
*
- * @todo: distinguish between vertex and pixel shaders???
*/
- if (vmsvga3dCheckGLExtension("GL_NV_gpu_program4"))
+ /** @todo: distinguish between vertex and pixel shaders??? */
+ if ( vmsvga3dCheckGLExtension(pState, 0.0, " GL_NV_gpu_program4 ")
+ || strstr(pState->pszOtherExtensions, " GL_NV_gpu_program4 "))
{
pState->caps.vertexShaderVersion = SVGA3DVSVERSION_40;
pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_40;
}
else
- if ( vmsvga3dCheckGLExtension("GL_NV_vertex_program3")
- || vmsvga3dCheckGLExtension("GL_ARB_shader_texture_lod")) /* Wine claims this suggests SM 3.0 support */
+ if ( vmsvga3dCheckGLExtension(pState, 0.0, " GL_NV_vertex_program3 ")
+ || strstr(pState->pszOtherExtensions, " GL_NV_vertex_program3 ")
+ || vmsvga3dCheckGLExtension(pState, 0.0, " GL_ARB_shader_texture_lod ") /* Wine claims this suggests SM 3.0 support */
+ || strstr(pState->pszOtherExtensions, " GL_ARB_shader_texture_lod ")
+ )
{
pState->caps.vertexShaderVersion = SVGA3DVSVERSION_30;
pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_30;
}
else
- if (vmsvga3dCheckGLExtension("GL_ARB_fragment_program"))
+ if ( vmsvga3dCheckGLExtension(pState, 0.0, " GL_ARB_fragment_program ")
+ || strstr(pState->pszOtherExtensions, " GL_ARB_fragment_program "))
{
pState->caps.vertexShaderVersion = SVGA3DVSVERSION_20;
pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_20;
@@ -821,9 +1408,9 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
pState->caps.fragmentShaderVersion = SVGA3DPSVERSION_11;
}
- if (!vmsvga3dCheckGLExtension("GL_ARB_vertex_array_bgra"))
+ if (!vmsvga3dCheckGLExtension(pState, 3.2f, " GL_ARB_vertex_array_bgra "))
{
- /* @todo Intel drivers don't support this extension! */
+ /** @todo Intel drivers don't support this extension! */
LogRel(("VMSVGA3D: WARNING: Missing required extension GL_ARB_vertex_array_bgra (d3dcolor)!!!\n"));
}
#if 0
@@ -892,22 +1479,43 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM = 83,
#endif
+ LogRel(("VMSVGA3d: Capabilities:\n"));
+ LogRel(("VMSVGA3d: maxActiveLights=%-2d maxTextures=%-2d maxTextureBufferSize=%d\n",
+ pState->caps.maxActiveLights, pState->caps.maxTextures, pState->caps.maxTextureBufferSize));
+ LogRel(("VMSVGA3d: maxClipDistances=%-2d maxColorAttachments=%-2d maxClipDistances=%d\n",
+ pState->caps.maxClipDistances, pState->caps.maxColorAttachments, pState->caps.maxClipDistances));
+ LogRel(("VMSVGA3d: maxColorAttachments=%-2d maxTextureAnisotropy=%-2d maxRectangleTextureSize=%d\n",
+ pState->caps.maxColorAttachments, pState->caps.maxTextureAnisotropy, pState->caps.maxRectangleTextureSize));
+ LogRel(("VMSVGA3d: maxVertexShaderTemps=%-2d maxVertexShaderInstructions=%d maxFragmentShaderInstructions=%d\n",
+ pState->caps.maxVertexShaderTemps, pState->caps.maxVertexShaderInstructions, pState->caps.maxFragmentShaderInstructions));
+ LogRel(("VMSVGA3d: maxFragmentShaderTemps=%d flPointSize={%d.%02u, %d.%02u}\n",
+ pState->caps.maxFragmentShaderTemps,
+ (int)pState->caps.flPointSize[0], (int)(pState->caps.flPointSize[0] * 100) % 100,
+ (int)pState->caps.flPointSize[1], (int)(pState->caps.flPointSize[1] * 100) % 100));
+ LogRel(("VMSVGA3d: fragmentShaderVersion=%-2d vertexShaderVersion=%-2d fS3TCSupported=%d\n",
+ pState->caps.fragmentShaderVersion, pState->caps.vertexShaderVersion, pState->caps.fS3TCSupported));
+
+
/* Initialize the shader library. */
- rc = ShaderInitLib();
+ pState->ShaderIf.pfnSwitchInitProfile = vmsvga3dShaderIfSwitchInitProfile;
+ pState->ShaderIf.pfnGetNextExtension = vmsvga3dShaderIfGetNextExtension;
+ rc = ShaderInitLib(&pState->ShaderIf);
AssertRC(rc);
/* Cleanup */
rc = vmsvga3dContextDestroy(pThis, 1);
AssertRC(rc);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ rc = vmsvga3dContextDestroy(pThis, 2);
+ AssertRC(rc);
+#endif
-#ifndef RT_OS_DARWIN
- /* on the Mac, OpenGL 3 came very late so we have a capable 2.1 implementation */
- if (pState->fGLVersion < 3.0)
+ if ( pState->fGLVersion < 3.0
+ && pState->fOtherGLVersion < 3.0 /* darwin: legacy profile hack */)
{
LogRel(("VMSVGA3d: unsupported OpenGL version; minimum is 3.0\n"));
return VERR_NOT_IMPLEMENTED;
}
-#endif
if ( !pState->ext.glIsRenderbuffer
|| !pState->ext.glBindRenderbuffer
|| !pState->ext.glDeleteRenderbuffers
@@ -963,7 +1571,7 @@ int vmsvga3dReset(PVGASTATE pThis)
int vmsvga3dTerminate(PVGASTATE pThis)
{
PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
- AssertReturn(pThis->svga.p3dState, VERR_NO_MEMORY);
+ AssertReturn(pState, VERR_WRONG_ORDER);
int rc;
rc = vmsvga3dReset(pThis);
@@ -990,6 +1598,13 @@ int vmsvga3dTerminate(PVGASTATE pThis)
XCloseDisplay(pState->display);
#endif
+ RTStrFree(pState->pszExtensions);
+ pState->pszExtensions = NULL;
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ RTStrFree(pState->pszOtherExtensions);
+#endif
+ pState->pszOtherExtensions = NULL;
+
return VINF_SUCCESS;
}
@@ -1618,8 +2233,9 @@ D3DMULTISAMPLE_TYPE vmsvga3dMultipeSampleCount2D3D(uint32_t multisampleCount)
}
#endif
-int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format, SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES],
- uint32_t multisampleCount, SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *pMipLevelSize)
+int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,
+ SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,
+ SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *pMipLevelSize)
{
PVMSVGA3DSURFACE pSurface;
PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
@@ -1735,7 +2351,7 @@ int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags,
pSurface->flags = surfaceFlags;
pSurface->format = format;
- memcpy(pSurface->faces, face, sizeof(face));
+ memcpy(pSurface->faces, face, sizeof(pSurface->faces));
pSurface->cFaces = 1; /* check for cube maps later */
pSurface->multiSampleCount = multisampleCount;
pSurface->autogenFilter = autogenFilter;
@@ -2168,20 +2784,20 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
pBufferStart = (uint8_t *)pMipLevel->pSurfaceData + uDestOffset;
#endif
rc = vmsvgaGMRTransfer(pThis,
- transfer,
- pBufferStart,
+ transfer,
+ pBufferStart,
#ifdef MANUAL_FLIP_SURFACE_DATA
- -(int32_t)pMipLevel->cbSurfacePitch,
+ -(int32_t)pMipLevel->cbSurfacePitch,
#else
- (int32_t)pMipLevel->cbSurfacePitch,
+ (int32_t)pMipLevel->cbSurfacePitch,
#endif
- guest.ptr,
- pBoxes[i].srcx * pSurface->cbBlock + (pBoxes[i].srcy + pBoxes[i].srcz * pBoxes[i].h) * cbSrcPitch,
- cbSrcPitch,
- pBoxes[i].w * pSurface->cbBlock,
- pBoxes[i].d * pBoxes[i].h);
+ guest.ptr,
+ pBoxes[i].srcx * pSurface->cbBlock + (pBoxes[i].srcy + pBoxes[i].srcz * pBoxes[i].h) * cbSrcPitch,
+ cbSrcPitch,
+ pBoxes[i].w * pSurface->cbBlock,
+ pBoxes[i].d * pBoxes[i].h);
- LogFlow(("first line:\n%.*Rhxd\n", pMipLevel->cbSurface, pMipLevel->pSurfaceData));
+ Log4(("first line:\n%.*Rhxd\n", pMipLevel->cbSurface, pMipLevel->pSurfaceData));
AssertRC(rc);
}
@@ -2342,10 +2958,11 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
glBindTexture(GL_TEXTURE_2D, activeTexture);
VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
}
+
+ Log4(("first line:\n%.*Rhxd\n", pBoxes[i].w * pSurface->cbBlock, pDoubleBuffer));
+
/* Free the double buffer. */
RTMemFree(pDoubleBuffer);
-
- LogFlow(("first line:\n%.*Rhxd\n", pBoxes[i].w * pSurface->cbBlock, pDoubleBuffer));
break;
}
@@ -2384,7 +3001,7 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
pBoxes[i].h);
AssertRC(rc);
- LogFlow(("first line:\n%.*Rhxd\n", cbSrcPitch, pData));
+ Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pData));
pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
@@ -2813,7 +3430,7 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
BOOL ret = SwapBuffers(pContext->hdc);
AssertMsg(ret, ("SwapBuffers failed with %d\n", GetLastError()));
#elif defined(RT_OS_DARWIN)
- vmsvga3dCocoaSwapBuffers(pContext->cocoaContext);
+ vmsvga3dCocoaSwapBuffers(pContext->cocoaView, pContext->cocoaContext);
#else
/* show the window if not already done */
if (!pContext->fMapped)
@@ -2864,8 +3481,12 @@ DECLCALLBACK(int) vmsvga3dXEventThread(RTTHREAD ThreadSelf, void *pvUser)
* @returns VBox status code.
* @param pThis VGA device instance data.
* @param cid Context id
+ * @param fOtherProfile When clear, the context is created using the default
+ * OpenGL profile. When set, it's created using the
+ * alternative profile. The latter is only allowed if
+ * the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set.
*/
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
{
int rc;
PVMSVGA3DCONTEXT pContext;
@@ -2873,13 +3494,16 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
AssertReturn(pState, VERR_NO_MEMORY);
AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
+#if !defined(VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE) || !(defined(RT_OS_DARWIN))
+ AssertReturn(!fOtherProfile, VERR_INTERNAL_ERROR_3);
+#endif
Log(("vmsvga3dContextDefine id %x\n", cid));
#ifdef DEBUG_DEBUG_GFX_WINDOW_TEST_CONTEXT
if (pState->idTestContext == SVGA_ID_INVALID)
{
pState->idTestContext = 207;
- rc = vmsvga3dContextDefine(pThis, pState->idTestContext);
+ rc = vmsvga3dContextDefine(pThis, pState->idTestContext, false /*fOtherProfile*/);
AssertRCReturn(rc, rc);
}
#endif
@@ -2999,21 +3623,25 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
}
#elif defined(RT_OS_DARWIN)
+ pContext->fOtherProfile = fOtherProfile;
+
/* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */
NativeNSOpenGLContextRef shareContext = NULL;
for (uint32_t i = 0; i < pState->cContexts; i++)
{
if ( pState->paContext[i].id != SVGA3D_INVALID_ID
- && i != pContext->id)
+ && i != pContext->id
+ && pState->paContext[i].fOtherProfile == fOtherProfile)
{
Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));
shareContext = pState->paContext[i].cocoaContext;
break;
}
}
- vmsvga3dCocoaCreateContext(&pContext->cocoaContext, shareContext);
- NativeNSViewRef pHostView = (NativeNSViewRef*)pThis->svga.u64HostWindowId;
+ vmsvga3dCocoaCreateContext(&pContext->cocoaContext, shareContext, fOtherProfile);
+ NativeNSViewRef pHostView = (NativeNSViewRef)pThis->svga.u64HostWindowId;
vmsvga3dCocoaCreateView(&pContext->cocoaView, pHostView);
+
#else
Window hostWindow = (Window)pThis->svga.u64HostWindowId;
@@ -3027,7 +3655,7 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
AssertMsgReturn(ret && glxMajor == 1 && glxMinor >= 3, ("glX >=1.3 not present"), VERR_INTERNAL_ERROR);
/* start our X event handling thread */
rc = RTThreadCreate(&pState->pWindowThread, vmsvga3dXEventThread, pState, 0, RTTHREADTYPE_GUI, RTTHREADFLAGS_WAITABLE, "VMSVGA3DXEVENT");
- if (RT_FAILURE(rc))
+ if (RT_FAILURE(rc))
{
AssertMsgFailed(("%s: Async IO Thread creation for 3d window handling failed rc=%d\n", __FUNCTION__, rc));
return rc;
@@ -3862,7 +4490,13 @@ int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates
pState->ext.glBlendEquationSeparate(vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATION].uintValue),
vmsvga3dBlendEquation2GL(pContext->state.aRenderState[SVGA3D_RS_BLENDEQUATIONALPHA].uintValue));
else
+ {
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x102
+ glBlendEquation(vmsvga3dBlendEquation2GL(pRenderState[i].uintValue));
+#else
pState->ext.glBlendEquation(vmsvga3dBlendEquation2GL(pRenderState[i].uintValue));
+#endif
+ }
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
@@ -3872,7 +4506,11 @@ int vmsvga3dSetRenderState(PVGASTATE pThis, uint32_t cid, uint32_t cRenderStates
vmsvgaColor2GLFloatArray(pRenderState[i].uintValue, &red, &green, &blue, &alpha);
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x102
+ glBlendColor(red, green, blue, alpha);
+#else
pState->ext.glBlendColor(red, green, blue, alpha);
+#endif
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
}
@@ -5189,9 +5827,9 @@ int vmsvga3dSetClipPlane(PVGASTATE pThis, uint32_t cid, uint32_t index, float p
/* Store for vm state save/restore. */
pContext->state.aClipPlane[index].fValid = true;
- memcpy(pContext->state.aClipPlane[index].plane, plane, sizeof(plane));
+ memcpy(pContext->state.aClipPlane[index].plane, plane, sizeof(pContext->state.aClipPlane[index].plane));
- /* @todo clip plane affected by model view in OpenGL & view in D3D + vertex shader -> not transformed (see Wine; state.c clipplane) */
+ /** @todo clip plane affected by model view in OpenGL & view in D3D + vertex shader -> not transformed (see Wine; state.c clipplane) */
oglPlane[0] = (double)plane[0];
oglPlane[1] = (double)plane[1];
oglPlane[2] = (double)plane[2];
@@ -5503,7 +6141,8 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
/* Use numbered vertex arrays when shaders are active. */
pState->ext.glEnableVertexAttribArray(index);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
- pState->ext.glVertexAttribPointer(index, size, type, normalized, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
+ pState->ext.glVertexAttribPointer(index, size, type, normalized, pVertexDecl[iVertex].array.stride,
+ (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
/* case SVGA3D_DECLUSAGE_COLOR: @todo color component order not identical!! test GL_BGRA!! */
}
@@ -5515,7 +6154,8 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
case SVGA3D_DECLUSAGE_POSITION:
glEnableClientState(GL_VERTEX_ARRAY);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
- glVertexPointer(size, type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
+ glVertexPointer(size, type, pVertexDecl[iVertex].array.stride,
+ (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
case SVGA3D_DECLUSAGE_BLENDWEIGHT:
@@ -5527,7 +6167,8 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
case SVGA3D_DECLUSAGE_NORMAL:
glEnableClientState(GL_NORMAL_ARRAY);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
- glNormalPointer(type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
+ glNormalPointer(type, pVertexDecl[iVertex].array.stride,
+ (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
case SVGA3D_DECLUSAGE_PSIZE:
@@ -5535,10 +6176,15 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
break;
case SVGA3D_DECLUSAGE_TEXCOORD:
/* Specify the affected texture unit. */
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x103
+ glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
+#else
pState->ext.glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
+#endif
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
- glTexCoordPointer(size, type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
+ glTexCoordPointer(size, type, pVertexDecl[iVertex].array.stride,
+ (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
case SVGA3D_DECLUSAGE_TANGENT:
@@ -5553,16 +6199,18 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
case SVGA3D_DECLUSAGE_POSITIONT:
AssertFailed(); /* see position_transformed in Wine */
break;
- case SVGA3D_DECLUSAGE_COLOR: /* @todo color component order not identical!! test GL_BGRA!! */
+ case SVGA3D_DECLUSAGE_COLOR: /** @todo color component order not identical!! test GL_BGRA!! */
glEnableClientState(GL_COLOR_ARRAY);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
- glColorPointer(size, type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
+ glColorPointer(size, type, pVertexDecl[iVertex].array.stride,
+ (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
case SVGA3D_DECLUSAGE_FOG:
glEnableClientState(GL_FOG_COORD_ARRAY);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
- pState->ext.glFogCoordPointer(type, pVertexDecl[iVertex].array.stride, (const GLvoid *)pVertexDecl[iVertex].array.offset);
+ pState->ext.glFogCoordPointer(type, pVertexDecl[iVertex].array.stride,
+ (const GLvoid *)(uintptr_t)pVertexDecl[iVertex].array.offset);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
case SVGA3D_DECLUSAGE_DEPTH:
@@ -5616,7 +6264,11 @@ int vmsvga3dDrawPrimitivesCleanupVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
break;
case SVGA3D_DECLUSAGE_TEXCOORD:
/* Specify the affected texture unit. */
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL >= 0x103
+ glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
+#else
pState->ext.glClientActiveTexture(GL_TEXTURE0 + pVertexDecl[iVertex].identity.usageIndex);
+#endif
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
break;
@@ -5788,18 +6440,16 @@ int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecl
/* Render with an index buffer */
Log(("DrawIndexedPrimitive %x cPrimitives=%d cVertices=%d hint.first=%d hint.last=%d index offset=%d primitivecount=%d index width=%d index bias=%d\n", modeDraw, pRange[iPrimitive].primitiveCount, cVertices, pVertexDecl[0].rangeHint.first, pVertexDecl[0].rangeHint.last, pRange[iPrimitive].indexArray.offset, pRange[iPrimitive].primitiveCount, pRange[iPrimitive].indexWidth, pRange[iPrimitive].indexBias));
if (pRange[iPrimitive].indexBias == 0)
- {
glDrawElements(modeDraw,
cVertices,
(pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
- (GLvoid *)(pRange[iPrimitive].indexArray.offset)); /* byte offset in indices buffer */
- }
+ (GLvoid *)(uintptr_t)pRange[iPrimitive].indexArray.offset); /* byte offset in indices buffer */
else
pState->ext.glDrawElementsBaseVertex(modeDraw,
cVertices,
(pRange[iPrimitive].indexWidth == sizeof(uint16_t)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
- (GLvoid *)(pRange[iPrimitive].indexArray.offset), /* byte offset in indices buffer */
- pRange[iPrimitive].indexBias); /* basevertex */
+ (GLvoid *)(uintptr_t)pRange[iPrimitive].indexArray.offset, /* byte offset in indices buffer */
+ pRange[iPrimitive].indexBias); /* basevertex */
/* Unbind the index buffer after usage. */
pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -5880,7 +6530,7 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
int rc;
Log(("vmsvga3dShaderDefine cid=%x shid=%x type=%s cbData=%x\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cbData));
- LogFlow(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
+ Log3(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
if ( cid >= pState->cContexts
|| pState->paContext[cid].id != cid)
@@ -6193,6 +6843,3 @@ int vmsvga3dQueryWait(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type, SVGAG
return VERR_NOT_IMPLEMENTED;
}
-
-
-
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
index 8f59416..8b31d66 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h
@@ -48,7 +48,7 @@ int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32
{
uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
- rc = vmsvga3dContextDefine(pThis, cid);
+ rc = vmsvga3dContextDefine(pThis, cid, false /*fOtherProfile*/);
AssertRCReturn(rc, rc);
pContext = &pState->paContext[i];
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
index d943216..ad7a2c5 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win.cpp
@@ -502,7 +502,13 @@ int vmsvga3dPowerOn(PVGASTATE pThis)
pState->pD3D9 = Direct3DCreate9(D3D_SDK_VERSION);
AssertReturn(pState->pD3D9, VERR_INTERNAL_ERROR);
#else
- hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &pState->pD3D9);
+ /* Direct3DCreate9Ex was introduced in Vista, so resolve it dynamically. */
+ typedef HRESULT (WINAPI *PFNDIRECT3DCREATE9EX)(UINT, IDirect3D9Ex **);
+ PFNDIRECT3DCREATE9EX pfnDirect3dCreate9Ex = (PFNDIRECT3DCREATE9EX)RTLdrGetSystemSymbol("d3d9.dll", "Direct3DCreate9Ex");
+ if (!pfnDirect3dCreate9Ex)
+ return PDMDevHlpVMSetError(pThis->CTX_SUFF(pDevIns), VERR_SYMBOL_NOT_FOUND, RT_SRC_POS,
+ "vmsvga3d: Unable to locate Direct3DCreate9Ex. This feature requires Vista and later.");
+ hr = pfnDirect3dCreate9Ex(D3D_SDK_VERSION, &pState->pD3D9);
AssertReturn(hr == D3D_OK, VERR_INTERNAL_ERROR);
#endif
hr = pState->pD3D9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &pState->caps);
@@ -2298,7 +2304,8 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
return VINF_SUCCESS;
}
-int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer, uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
+int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer,
+ uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes)
{
PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
PVMSVGA3DSURFACE pSurface;
@@ -2363,7 +2370,7 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
pBoxes[i].w * pSurface->cbBlock,
pBoxes[i].d * pBoxes[i].h);
- LogFlow(("first line:\n%.*Rhxd\n", pMipLevel->cbSurfacePitch, pMipLevel->pSurfaceData));
+ Log4(("first line:\n%.*Rhxd\n", pMipLevel->cbSurfacePitch, pMipLevel->pSurfaceData));
AssertRC(rc);
}
@@ -2500,7 +2507,7 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
pBoxes[i].h);
AssertRC(rc);
- LogFlow(("first line:\n%.*Rhxd\n", pBoxes[i].w * pSurface->cbBlock, LockedRect.pBits));
+ Log4(("first line:\n%.*Rhxd\n", pBoxes[i].w * pSurface->cbBlock, LockedRect.pBits));
if (fTexture)
{
@@ -2552,7 +2559,7 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
uDestOffset = pBoxes[i].x * pSurface->cbBlock + pBoxes[i].y * pSurface->pMipmapLevels[host.mipmap].cbSurfacePitch;
AssertReturn(uDestOffset + pBoxes[i].w * pSurface->cbBlock + (pBoxes[i].h - 1) * pSurface->pMipmapLevels[host.mipmap].cbSurfacePitch <= pSurface->pMipmapLevels[host.mipmap].cbSurface, VERR_INTERNAL_ERROR);
- /* @todo lock only as much as we really need */
+ /** @todo lock only as much as we really need */
if (fVertex)
hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pData, dwFlags);
else
@@ -2572,7 +2579,7 @@ int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceIma
pBoxes[i].h);
AssertRC(rc);
- LogFlow(("first line:\n%.*Rhxd\n", cbSrcPitch, pData));
+ Log4(("first line:\n%.*Rhxd\n", cbSrcPitch, pData));
if (fVertex)
hr = pSurface->u.pVertexBuffer->Unlock();
@@ -2895,8 +2902,9 @@ int vmsvga3dCommandPresent(PVGASTATE pThis, uint32_t sid, uint32_t cRects, SVGA3
* @returns VBox status code.
* @param pThis VGA device instance data.
* @param cid Context id
+ * @param fOtherProfile OpenGL(+darwin) specific argument, ignored.
*/
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile)
{
int rc;
PVMSVGA3DCONTEXT pContext;
@@ -2906,6 +2914,7 @@ int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid)
AssertReturn(pState, VERR_NO_MEMORY);
AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);
+ NOREF(fOtherProfile);
Log(("vmsvga3dContextDefine id %x\n", cid));
@@ -5347,7 +5356,9 @@ int vmsvga3dDrawPrimitivesProcessVertexDecls(PVMSVGA3DSTATE pState, PVMSVGA3DCON
return VINF_SUCCESS;
}
-int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl, uint32_t numRanges, SVGA3dPrimitiveRange *pRange, uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
+int vmsvga3dDrawPrimitives(PVGASTATE pThis, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
+ uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
+ uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
{
PVMSVGA3DCONTEXT pContext;
PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)pThis->svga.p3dState;
@@ -5688,7 +5699,7 @@ int vmsvga3dShaderDefine(PVGASTATE pThis, uint32_t cid, uint32_t shid, SVGA3dSha
AssertReturn(pState, VERR_NO_MEMORY);
Log(("vmsvga3dShaderDefine %x shid=%x type=%s cbData=%x\n", cid, shid, (type == SVGA3D_SHADERTYPE_VS) ? "VERTEX" : "PIXEL", cbData));
- LogFlow(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
+ Log3(("shader code:\n%.*Rhxd\n", cbData, pShaderData));
if ( cid >= pState->cContexts
|| pState->paContext[cid].id != cid)
@@ -5997,6 +6008,8 @@ int vmsvga3dQueryWait(PVGASTATE pThis, uint32_t cid, SVGA3dQueryType type, SVGAG
static void vmsvgaDumpD3DCaps(D3DCAPS9 *pCaps)
{
+ bool const fBufferingSaved = RTLogRelSetBuffering(true /*fBuffered*/);
+
LogRel(("\nD3D device caps: DevCaps2:\n"));
if (pCaps->DevCaps2 & D3DDEVCAPS2_ADAPTIVETESSRTPATCH)
LogRel((" - D3DDEVCAPS2_ADAPTIVETESSRTPATCH\n"));
@@ -6281,5 +6294,13 @@ static void vmsvgaDumpD3DCaps(D3DCAPS9 *pCaps)
if (pCaps->TextureOpCaps & D3DTEXOPCAPS_LERP)
LogRel((" - D3DTEXOPCAPS_LERP\n"));
+ LogRel(("\n"));
+ LogRel(("PixelShaderVersion: %#x (%u.%u)\n", pCaps->PixelShaderVersion,
+ D3DSHADER_VERSION_MAJOR(pCaps->PixelShaderVersion), D3DSHADER_VERSION_MINOR(pCaps->PixelShaderVersion)));
+ LogRel(("VertexShaderVersion: %#x (%u.%u)\n", pCaps->VertexShaderVersion,
+ D3DSHADER_VERSION_MAJOR(pCaps->VertexShaderVersion), D3DSHADER_VERSION_MINOR(pCaps->VertexShaderVersion)));
+
+ LogRel(("\n"));
+ RTLogRelSetBuffering(fBufferingSaved);
}
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h b/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
index 6e7cbd3..2ea3767 100644
--- a/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d.h
@@ -1,8 +1,9 @@
/** @file
- * DevVMWare - VMWare SVGA device - 3D part
+ * DevVMWare - VMWare SVGA device - 3D part.
*/
+
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -13,8 +14,8 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#ifndef __DEVVMWARE3D_H__
-#define __DEVVMWARE3D_H__
+#ifndef ___DEVVMWARE3D_H___
+#define ___DEVVMWARE3D_H___
#include "vmsvga/svga_reg.h"
#include "vmsvga/svga3d_reg.h"
@@ -22,28 +23,29 @@
#include "vmsvga/svga_overlay.h"
#if defined(RT_OS_WINDOWS) && defined(IN_RING3)
-#include <windows.h>
+# include <Windows.h>
-#define WM_VMSVGA3D_WAKEUP (WM_APP+1)
-#define WM_VMSVGA3D_CREATEWINDOW (WM_APP+2)
-#define WM_VMSVGA3D_DESTROYWINDOW (WM_APP+3)
-#define WM_VMSVGA3D_RESIZEWINDOW (WM_APP+4)
-#define WM_VMSVGA3D_EXIT (WM_APP+5)
+# define WM_VMSVGA3D_WAKEUP (WM_APP+1)
+# define WM_VMSVGA3D_CREATEWINDOW (WM_APP+2)
+# define WM_VMSVGA3D_DESTROYWINDOW (WM_APP+3)
+# define WM_VMSVGA3D_RESIZEWINDOW (WM_APP+4)
+# define WM_VMSVGA3D_EXIT (WM_APP+5)
DECLCALLBACK(int) vmsvga3dWindowThread(RTTHREAD ThreadSelf, void *pvUser);
int vmsvga3dSendThreadMessage(RTTHREAD pWindowThread, RTSEMEVENT WndRequestSem, UINT msg, WPARAM wParam, LPARAM lParam);
#endif
-/* Arbitrary limit */
+/** Arbitrary limit */
#define SVGA3D_MAX_SHADER_IDS 0x100
-/* D3D allows up to 8 texture stages. */
+/** D3D allows up to 8 texture stages. */
#define SVGA3D_MAX_TEXTURE_STAGE 8
-/* Arbitrary upper limit; seen 8 so far. */
+/** Arbitrary upper limit; seen 8 so far. */
#define SVGA3D_MAX_LIGHTS 32
void vmsvgaGMRFree(PVGASTATE pThis, uint32_t idGMR);
-int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType transfer, uint8_t *pDest, int32_t cbDestPitch, SVGAGuestPtr src, uint32_t cbSrcOffset, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight);
+int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pDest, int32_t cbDestPitch,
+ SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight);
int vmsvga3dInit(PVGASTATE pThis);
int vmsvga3dPowerOn(PVGASTATE pThis);
@@ -60,7 +62,7 @@ int vmsvga3dSurfaceStretchBlt(PVGASTATE pThis, SVGA3dSurfaceImageId dest, SVGA3d
int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer, uint32_t cCopyBoxes, SVGA3dCopyBox *pBoxes);
int vmsvga3dSurfaceBlitToScreen(PVGASTATE pThis, uint32_t dest, SVGASignedRect destRect, SVGA3dSurfaceImageId src, SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *pRect);
-int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid);
+int vmsvga3dContextDefine(PVGASTATE pThis, uint32_t cid, bool fOtherProfile);
int vmsvga3dContextDestroy(PVGASTATE pThis, uint32_t cid);
int vmsvga3dChangeMode(PVGASTATE pThis);
@@ -106,4 +108,5 @@ const char *vmsvgaSurfaceType2String(SVGA3dSurfaceFormat format);
const char *vmsvga3dPrimitiveType2String(SVGA3dPrimitiveType PrimitiveType);
#endif
-#endif /* __DEVVMWARE3D_H__ */
+#endif /* !___DEVVMWARE3D_H___ */
+
diff --git a/src/VBox/Devices/Graphics/DevVGA.cpp b/src/VBox/Devices/Graphics/DevVGA.cpp
index d29f950..8a99693 100644
--- a/src/VBox/Devices/Graphics/DevVGA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA.cpp
@@ -111,7 +111,7 @@
#include <VBox/vmm/pdmdev.h>
#include <VBox/vmm/pgm.h>
#ifdef IN_RING3
-# include <iprt/alloc.h>
+# include <iprt/mem.h>
# include <iprt/ctype.h>
#endif /* IN_RING3 */
#include <iprt/assert.h>
@@ -2031,7 +2031,7 @@ static int vga_resize_graphic(PVGASTATE pThis, int cx, int cy,
AssertReturn(pThis->line_offset, VERR_INTERNAL_ERROR);
#if 0 //def VBOX_WITH_VDMA
- /* @todo: we get a second resize here when VBVA is on, while we actually should not */
+ /** @todo: we get a second resize here when VBVA is on, while we actually should not */
/* do not do pfnResize in case VBVA is on since all mode changes are performed over VBVA
* we are checking for VDMA state here to ensure this code works only for WDDM driver,
* although we should avoid calling pfnResize for XPDM as well, since pfnResize is actually an extra resize
@@ -2094,7 +2094,7 @@ int vgaR3UpdateDisplay(VGAState *s, unsigned xStart, unsigned yStart, unsigned w
s->pDrv->pfnUpdateRect(s->pDrv, xStart, yStart, width, height);
return VINF_SUCCESS;
}
- /* @todo might crash if a blit follows a resolution change very quickly (seen this many times!) */
+ /** @todo might crash if a blit follows a resolution change very quickly (seen this many times!) */
if ( s->svga.uWidth == VMSVGA_VAL_UNINITIALIZED
|| s->svga.uHeight == VMSVGA_VAL_UNINITIALIZED
@@ -5767,7 +5767,8 @@ static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
LogFlow(("vgaR3Destruct:\n"));
# ifdef VBOX_WITH_VDMA
- vboxVDMADestruct(pThis->pVdma);
+ if (pThis->pVdma)
+ vboxVDMADestruct(pThis->pVdma);
# endif
#ifdef VBOX_WITH_VMSVGA
@@ -5998,6 +5999,11 @@ static DECLCALLBACK(int) vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCF
#ifdef VBOX_WITH_VMSVGA
pThis->IPort.pfnSetViewPort = vmsvgaPortSetViewPort;
#endif
+ pThis->IPort.pfnSendModeHint = vbvaPortSendModeHint;
+ pThis->IPort.pfnReportHostCursorCapabilities
+ = vbvaPortReportHostCursorCapabilities;
+ pThis->IPort.pfnReportHostCursorPosition
+ = vbvaPortReportHostCursorPosition;
#if defined(VBOX_WITH_HGSMI)
# if defined(VBOX_WITH_VIDEOHWACCEL)
diff --git a/src/VBox/Devices/Graphics/DevVGA.h b/src/VBox/Devices/Graphics/DevVGA.h
index f5ac821..7e48186 100644
--- a/src/VBox/Devices/Graphics/DevVGA.h
+++ b/src/VBox/Devices/Graphics/DevVGA.h
@@ -253,8 +253,11 @@ typedef struct
uint32_t fEnabled;
/** SVGA memory area configured status. */
uint32_t fConfigured;
- /** Device is busy handling FIFO requests. */
- uint32_t fBusy;
+ /** Device is busy handling FIFO requests (VMSVGA_BUSY_F_FIFO,
+ * VMSVGA_BUSY_F_EMT_FORCE). */
+ uint32_t volatile fBusy;
+#define VMSVGA_BUSY_F_FIFO RT_BIT_32(0) /**< The normal true/false busy FIFO bit. */
+#define VMSVGA_BUSY_F_EMT_FORCE RT_BIT_32(1) /**< Bit preventing race status flickering when EMT kicks the FIFO thread. */
/** Traces (dirty page detection) enabled or not. */
uint32_t fTraces;
/** Guest OS identifier. */
@@ -278,10 +281,12 @@ typedef struct
RTIOPORT BasePort;
/** Port io index register. */
uint32_t u32IndexReg;
+ /** The support driver session handle for use with FIFORequestSem. */
+ R3R0PTRTYPE(PSUPDRVSESSION) pSupDrvSession;
/** FIFO request semaphore. */
- RTSEMEVENT FIFORequestSem;
+ SUPSEMEVENT FIFORequestSem;
/** FIFO external command semaphore. */
- RTSEMEVENT FIFOExtCmdSem;
+ R3PTRTYPE(RTSEMEVENT) FIFOExtCmdSem;
/** FIFO IO Thread. */
R3PTRTYPE(PPDMTHREAD) pFIFOIOThread;
uint32_t uWidth;
@@ -308,7 +313,7 @@ typedef struct
bool fVRAMTracking;
/** External command to be executed in the FIFO thread. */
uint8_t u8FIFOExtCommand;
- bool Padding6[HC_ARCH_BITS == 64 ? 1 : 5];
+ bool Padding6;
} VMSVGAState;
#endif /* VBOX_WITH_VMSVGA */
@@ -391,6 +396,9 @@ typedef struct VGAState {
PDMIBASE IBase;
/** LUN\#0: The display port interface. */
PDMIDISPLAYPORT IPort;
+# if HC_ARCH_BITS == 32
+ uint32_t PaddingIPort;
+# endif
# if defined(VBOX_WITH_HGSMI) && (defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_CRHGSMI))
/** LUN\#0: VBVA callbacks interface */
PDMIDISPLAYVBVACALLBACKS IVBVACallbacks;
@@ -543,7 +551,7 @@ typedef struct VGAState {
* adapter, the way it can handle async HGSMI command completion, etc. */
uint32_t fGuestCaps;
uint32_t fScanLineCfg;
- uint8_t Padding10[4];
+ uint32_t fHostCursorCapabilities;
# else
uint8_t Padding10[14];
# endif
@@ -673,6 +681,14 @@ int vboxVBVALoadStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Vers
int vboxVBVALoadStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
int vgaUpdateDisplayAll(PVGASTATE pThis);
+DECLCALLBACK(int) vbvaPortSendModeHint(PPDMIDISPLAYPORT pInterface, uint32_t cx,
+ uint32_t cy, uint32_t cBPP,
+ uint32_t cDisplay, uint32_t dx,
+ uint32_t dy, uint32_t fEnabled,
+ uint32_t fNotifyGuest);
+DECLCALLBACK(void) vbvaPortReportHostCursorCapabilities(PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
+ uint32_t fCapabilitiesRemoved);
+DECLCALLBACK(void) vbvaPortReportHostCursorPosition(PPDMIDISPLAYPORT pInterface, uint32_t x, uint32_t y);
# ifdef VBOX_WITH_VDMA
typedef struct VBOXVDMAHOST *PVBOXVDMAHOST;
diff --git a/src/VBox/Devices/Graphics/DevVGASavedState.h b/src/VBox/Devices/Graphics/DevVGASavedState.h
index 7caecd5..183d223 100644
--- a/src/VBox/Devices/Graphics/DevVGASavedState.h
+++ b/src/VBox/Devices/Graphics/DevVGASavedState.h
@@ -22,7 +22,8 @@
#ifndef Graphics_DevVGASavedState_h
#define Graphics_DevVGASavedState_h
-#define VGA_SAVEDSTATE_VERSION 14
+#define VGA_SAVEDSTATE_VERSION 15
+#define VGA_SAVEDSTATE_VERSION_MODE_HINTS 15
#define VGA_SAVEDSTATE_VERSION_FIXED_PENDVHWA 14
#define VGA_SAVEDSTATE_VERSION_3D 13
#define VGA_SAVEDSTATE_VERSION_HGSMIMA 12 /* HGSMI memory allocator. */
diff --git a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
index ca12aab..71b0385 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
@@ -82,6 +82,9 @@ typedef struct VBVACONTEXT
VBVAVIEW aViews[64 /* @todo SchemaDefs::MaxGuestMonitors*/];
VBVAMOUSESHAPEINFO mouseShapeInfo;
bool fPaused;
+ uint32_t xCursor;
+ uint32_t yCursor;
+ VBVAMODEHINT aModeHints[VBOX_VIDEO_MAX_SCREENS];
} VBVACONTEXT;
@@ -1598,6 +1601,16 @@ int vboxVBVASaveDevStateExec (PVGASTATE pVGAState, PSSMHANDLE pSSM)
rc = SSMR3PutU32 (pSSM, 0);
AssertRCReturn(rc, rc);
#endif
+ rc = SSMR3PutU32 (pSSM, RT_ELEMENTS(pCtx->aModeHints));
+ AssertRCReturn(rc, rc);
+ rc = SSMR3PutU32 (pSSM, sizeof(VBVAMODEHINT));
+ AssertRCReturn(rc, rc);
+ for (unsigned i = 0; i < RT_ELEMENTS(pCtx->aModeHints); ++i)
+ {
+ rc = SSMR3PutMem (pSSM, &pCtx->aModeHints[i],
+ sizeof(VBVAMODEHINT));
+ AssertRCReturn(rc, rc);
+ }
}
}
@@ -1808,6 +1821,7 @@ int vboxVBVALoadStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Vers
{
rc = SSMR3GetU32 (pSSM, &pVGAState->fGuestCaps);
AssertRCReturn(rc, rc);
+ pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv, pVGAState->fGuestCaps);
cbExtra -= 4;
}
#endif
@@ -1816,6 +1830,27 @@ int vboxVBVALoadStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Vers
rc = SSMR3Skip(pSSM, cbExtra);
AssertRCReturn(rc, rc);
}
+
+ if (u32Version >= VGA_SAVEDSTATE_VERSION_MODE_HINTS)
+ {
+ uint32_t cModeHints, cbModeHints;
+ rc = SSMR3GetU32 (pSSM, &cModeHints);
+ AssertRCReturn(rc, rc);
+ rc = SSMR3GetU32 (pSSM, &cbModeHints);
+ AssertRCReturn(rc, rc);
+ memset(&pCtx->aModeHints, ~0, sizeof(pCtx->aModeHints));
+ unsigned iHint;
+ for (iHint = 0; iHint < cModeHints; ++iHint)
+ {
+ if ( cbModeHints <= sizeof(VBVAMODEHINT)
+ && iHint < RT_ELEMENTS(pCtx->aModeHints))
+ rc = SSMR3GetMem(pSSM, &pCtx->aModeHints[iHint],
+ cbModeHints);
+ else
+ rc = SSMR3Skip(pSSM, cbModeHints);
+ AssertRCReturn(rc, rc);
+ }
+ }
}
pCtx->cViews = iView;
@@ -2146,6 +2181,15 @@ static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16Channe
/* @todo a value calculated from the vram size */
pConf32->u32Value = 64*_1K;
}
+ else if ( pConf32->u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING
+ || pConf32->u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING)
+ {
+ pConf32->u32Value = VINF_SUCCESS;
+ }
+ else if (pConf32->u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES)
+ {
+ pConf32->u32Value = pVGAState->fHostCursorCapabilities;
+ }
else
{
Log(("Unsupported VBVA_QUERY_CONF32 index %d!!!\n",
@@ -2397,6 +2441,8 @@ static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16Channe
VBVACAPS *pCaps = (VBVACAPS*)pvBuffer;
pVGAState->fGuestCaps = pCaps->fCaps;
+ pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv,
+ pCaps->fCaps);
pCaps->rc = VINF_SUCCESS;
} break;
#endif
@@ -2412,6 +2458,73 @@ static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16Channe
pVGAState->fScanLineCfg = pCfg->fFlags;
pCfg->rc = VINF_SUCCESS;
} break;
+
+ case VBVA_QUERY_MODE_HINTS:
+ {
+ if (cbBuffer < sizeof(VBVAQUERYMODEHINTS))
+ {
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+ VBVAQUERYMODEHINTS *pModeHintQuery = (VBVAQUERYMODEHINTS*)pvBuffer;
+ LogRelFlowFunc(("VBVA_QUERY_MODE_HINTS: cHintsQueried=%u, cbHintStructureGuest=%u\n",
+ (unsigned)pModeHintQuery->cHintsQueried,
+ (unsigned)pModeHintQuery->cbHintStructureGuest));
+ if (cbBuffer < sizeof (VBVAQUERYMODEHINTS)
+ + (uint64_t)pModeHintQuery->cHintsQueried
+ * pModeHintQuery->cbHintStructureGuest)
+ {
+ pModeHintQuery->rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+ pModeHintQuery->rc = VINF_SUCCESS;
+ uint8_t *pbHint = (uint8_t *)pvBuffer + sizeof(VBVAQUERYMODEHINTS);
+ memset(pbHint, ~0, cbBuffer - sizeof(VBVAQUERYMODEHINTS));
+ unsigned iHint;
+ for (iHint = 0; iHint < pModeHintQuery->cHintsQueried
+ && iHint < VBOX_VIDEO_MAX_SCREENS; ++iHint)
+ {
+ memcpy(pbHint, &pCtx->aModeHints[iHint],
+ RT_MIN(pModeHintQuery->cbHintStructureGuest,
+ sizeof(VBVAMODEHINT)));
+ pbHint += pModeHintQuery->cbHintStructureGuest;
+ Assert(pbHint - (uint8_t *)pvBuffer <= cbBuffer);
+ }
+ } break;
+
+ case VBVA_REPORT_INPUT_MAPPING:
+ {
+ if (cbBuffer != sizeof(VBVAREPORTINPUTMAPPING))
+ {
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+ VBVAREPORTINPUTMAPPING *pReport = (VBVAREPORTINPUTMAPPING *)pvBuffer;
+ LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%u, y=%u, cx=%u, cy=%u\n", (unsigned)pReport->x, (unsigned)pReport->y,
+ (unsigned)pReport->cx, (unsigned)pReport->cy));
+ pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv, pReport->x, pReport->y, pReport->cx, pReport->cy);
+ } break;
+
+ case VBVA_CURSOR_POSITION:
+ {
+ if (cbBuffer != sizeof(VBVACURSORPOSITION))
+ {
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+ VBVACURSORPOSITION *pReport
+ = (VBVACURSORPOSITION *)pvBuffer;
+ LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=%RTbool",
+ RT_BOOL(pReport->fReportPosition)));
+ if (RT_BOOL(pReport->fReportPosition))
+ LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=true, x=%u, y=%u\n",
+ (unsigned)pReport->x, (unsigned)pReport->y));
+ else
+ LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=false\n"));
+ pReport->x = pCtx->xCursor;
+ pReport->y = pCtx->yCursor;
+ } break;
+
default:
Log(("Unsupported VBVA guest command %d!!!\n",
u16ChannelInfo));
@@ -2505,6 +2618,75 @@ int VBVAUpdateDisplay (PVGASTATE pVGAState)
return rc;
}
+static int vbvaSendModeHintWorker(PVGASTATE pThis, uint32_t cx, uint32_t cy,
+ uint32_t cBPP, uint32_t iDisplay, uint32_t dx,
+ uint32_t dy, uint32_t fEnabled,
+ uint32_t fNotifyGuest)
+{
+ VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pThis->pHGSMI);
+ /** @note See Display::setVideoModeHint: "It is up to the guest to decide
+ * whether the hint is valid. Therefore don't do any VRAM sanity checks
+ * here! */
+ if (iDisplay >= RT_MIN(pThis->cMonitors, RT_ELEMENTS(pCtx->aModeHints)))
+ return VERR_OUT_OF_RANGE;
+ pCtx->aModeHints[iDisplay].magic = VBVAMODEHINT_MAGIC;
+ pCtx->aModeHints[iDisplay].cx = cx;
+ pCtx->aModeHints[iDisplay].cy = cy;
+ pCtx->aModeHints[iDisplay].cBPP = cBPP;
+ pCtx->aModeHints[iDisplay].dx = dx;
+ pCtx->aModeHints[iDisplay].dy = dy;
+ pCtx->aModeHints[iDisplay].fEnabled = fEnabled;
+ if (fNotifyGuest && pThis->fGuestCaps & VBVACAPS_IRQ && pThis->fGuestCaps & VBVACAPS_VIDEO_MODE_HINTS)
+ VBVARaiseIrq(pThis, HGSMIHOSTFLAGS_HOTPLUG);
+ return VINF_SUCCESS;
+}
+
+/** Converts a display port interface pointer to a vga state pointer. */
+#define IDISPLAYPORT_2_VGASTATE(pInterface) ( (PVGASTATE)((uintptr_t)pInterface - RT_OFFSETOF(VGASTATE, IPort)) )
+
+DECLCALLBACK(int) vbvaPortSendModeHint(PPDMIDISPLAYPORT pInterface, uint32_t cx,
+ uint32_t cy, uint32_t cBPP,
+ uint32_t iDisplay, uint32_t dx,
+ uint32_t dy, uint32_t fEnabled,
+ uint32_t fNotifyGuest)
+{
+ PVGASTATE pThis;
+ int rc;
+
+ pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
+ rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+ AssertRC(rc);
+ rc = vbvaSendModeHintWorker(pThis, cx, cy, cBPP, iDisplay, dx, dy, fEnabled,
+ fNotifyGuest);
+ PDMCritSectLeave(&pThis->CritSect);
+ return rc;
+}
+
+DECLCALLBACK(void) vbvaPortReportHostCursorCapabilities(PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
+ uint32_t fCapabilitiesRemoved)
+{
+ PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+ AssertRC(rc);
+ pThis->fHostCursorCapabilities |= fCapabilitiesAdded;
+ pThis->fHostCursorCapabilities &= ~fCapabilitiesRemoved;
+ if (pThis->fGuestCaps & VBVACAPS_IRQ && pThis->fGuestCaps & VBVACAPS_DISABLE_CURSOR_INTEGRATION)
+ VBVARaiseIrqNoWait(pThis, HGSMIHOSTFLAGS_CURSOR_CAPABILITIES);
+ PDMCritSectLeave(&pThis->CritSect);
+}
+
+DECLCALLBACK(void) vbvaPortReportHostCursorPosition
+ (PPDMIDISPLAYPORT pInterface, uint32_t x, uint32_t y)
+{
+ PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
+ VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pThis->pHGSMI);
+ int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+ AssertRC(rc);
+ pCtx->xCursor = x;
+ pCtx->yCursor = y;
+ PDMCritSectLeave(&pThis->CritSect);
+}
+
static HGSMICHANNELHANDLER sOldChannelHandler;
int VBVAInit (PVGASTATE pVGAState)
@@ -2535,6 +2717,8 @@ int VBVAInit (PVGASTATE pVGAState)
VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext (pVGAState->pHGSMI);
pCtx->cViews = pVGAState->cMonitors;
pCtx->fPaused = true;
+ memset(pCtx->aModeHints, ~0, sizeof(*pCtx->aModeHints));
+ pVGAState->fHostCursorCapabilities = 0;
}
}
diff --git a/src/VBox/Devices/Graphics/VBoxSVGA3D.def b/src/VBox/Devices/Graphics/VBoxSVGA3D.def
new file mode 100644
index 0000000..310c7dd
--- /dev/null
+++ b/src/VBox/Devices/Graphics/VBoxSVGA3D.def
@@ -0,0 +1,38 @@
+; $Id: VBoxSVGA3D.def $
+;; @file
+; VBoxSVGA3D - Definition file for lazy import generation.
+;
+
+;
+; Copyright (C) 2014-2015 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+
+LIBRARY VBoxSVGA3D
+EXPORTS
+ ShaderInitLib
+ ShaderDestroyLib
+ ShaderContextCreate
+ ShaderContextDestroy
+ ShaderCreateVertexShader
+ ShaderCreatePixelShader
+ ShaderDestroyVertexShader
+ ShaderDestroyPixelShader
+ ShaderSetVertexShader
+ ShaderSetPixelShader
+ ShaderSetVertexShaderConstantB
+ ShaderSetVertexShaderConstantI
+ ShaderSetVertexShaderConstantF
+ ShaderSetPixelShaderConstantB
+ ShaderSetPixelShaderConstantI
+ ShaderSetPixelShaderConstantF
+ ShaderUpdateState
+ ShaderTransformProjection
+
diff --git a/src/VBox/Devices/Graphics/VBoxSVGA3D.rc b/src/VBox/Devices/Graphics/VBoxSVGA3D.rc
new file mode 100644
index 0000000..0f01a02
--- /dev/null
+++ b/src/VBox/Devices/Graphics/VBoxSVGA3D.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxSVGA3D.rc $ */
+/** @file
+ * VBoxSVGA3D - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox VMSVGA 3D\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxSVGA3D\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxSVGA3D.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Devices/Graphics/VBoxSVGA3DObjC.def b/src/VBox/Devices/Graphics/VBoxSVGA3DObjC.def
new file mode 100644
index 0000000..7fa01fa
--- /dev/null
+++ b/src/VBox/Devices/Graphics/VBoxSVGA3DObjC.def
@@ -0,0 +1,28 @@
+; $Id: VBoxSVGA3DObjC.def $
+;; @file
+; VBoxSVGA3DObjC - Definition file for lazy import generation (darwin specific).
+;
+
+;
+; Copyright (C) 2014-2015 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+
+LIBRARY VBoxSVGA3DObjC
+EXPORTS
+ vmsvga3dCocoaCreateContext
+ vmsvga3dCocoaDestroyContext
+ vmsvga3dCocoaCreateView
+ vmsvga3dCocoaDestroyView
+ vmsvga3dCocoaViewSetPosition
+ vmsvga3dCocoaViewSetSize
+ vmsvga3dCocoaViewMakeCurrentContext
+ vmsvga3dCocoaSwapBuffers
+
diff --git a/src/VBox/Devices/Graphics/shaderlib/directx.c b/src/VBox/Devices/Graphics/shaderlib/directx.c
index 458d2bd..585ed59 100644
--- a/src/VBox/Devices/Graphics/shaderlib/directx.c
+++ b/src/VBox/Devices/Graphics/shaderlib/directx.c
@@ -1830,7 +1830,11 @@ static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *
* memory behind our backs if really needed. Note that the amount of video
* memory can be overruled using a registry setting. */
+#ifndef VBOX
int i;
+#else
+ size_t i;
+#endif
for (i = 0; i < (sizeof(vendor_card_select_table) / sizeof(*vendor_card_select_table)); ++i)
{
@@ -1903,13 +1907,32 @@ static const struct blit_shader *select_blit_implementation(struct wined3d_adapt
}
#endif
+#ifdef VBOX_WITH_VMSVGA
+/** Checks if @a pszExtension is one of the extensions we're looking for and
+ * updates @a pGlInfo->supported accordingly. */
+static void check_gl_extension(struct wined3d_gl_info *pGlInfo, const char *pszExtension)
+{
+ size_t i;
+ TRACE_(d3d_caps)("- %s\n", debugstr_a(pszExtension));
+ for (i = 0; i < RT_ELEMENTS(EXTENSION_MAP); i++)
+ if (!strcmp(pszExtension, EXTENSION_MAP[i].extension_string))
+ {
+ TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
+ pGlInfo->supported[EXTENSION_MAP[i].extension] = TRUE;
+ return;
+ }
+}
+#endif
+
/* Context activation is done by the caller. */
-BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
+BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter, struct VBOXVMSVGASHADERIF *pVBoxShaderIf)
{
struct wined3d_driver_info *driver_info = &adapter->driver_info;
struct wined3d_gl_info *gl_info = &adapter->gl_info;
+#ifndef VBOX_WITH_VMSVGA
const char *GL_Extensions = NULL;
const char *WGL_Extensions = NULL;
+#endif
const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
struct fragment_caps fragment_caps;
enum wined3d_gl_vendor gl_vendor;
@@ -1927,7 +1950,7 @@ BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
ENTER_GL();
- gl_renderer_str = (const char *)glGetString(GL_RENDERER);
+ VBOX_CHECK_GL_CALL(gl_renderer_str = (const char *)glGetString(GL_RENDERER));
TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
if (!gl_renderer_str)
{
@@ -1936,7 +1959,7 @@ BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
return FALSE;
}
- gl_vendor_str = (const char *)glGetString(GL_VENDOR);
+ VBOX_CHECK_GL_CALL(gl_vendor_str = (const char *)glGetString(GL_VENDOR));
TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
if (!gl_vendor_str)
{
@@ -1946,7 +1969,7 @@ BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
}
/* Parse the GL_VERSION field into major and minor information */
- gl_version_str = (const char *)glGetString(GL_VERSION);
+ VBOX_CHECK_GL_CALL(gl_version_str = (const char *)glGetString(GL_VERSION));
TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
if (!gl_version_str)
{
@@ -1980,24 +2003,47 @@ BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
gl_info->limits.arb_ps_temps = 0;
/* Retrieve opengl defaults */
- glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max));
gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_LIGHTS, &gl_max));
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+ }
+#else
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_LIGHTS, &gl_max));
+#endif
gl_info->limits.lights = gl_max;
TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max));
gl_info->limits.texture_size = gl_max;
TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+ VBOX_CHECK_GL_CALL(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv));
+ if (glGetError() != GL_NO_ERROR)
+ gl_floatv[0] = gl_floatv[1] = 1;
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+ }
+#else
+ VBOX_CHECK_GL_CALL(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv));
+#endif
gl_info->limits.pointsize_min = gl_floatv[0];
gl_info->limits.pointsize_max = gl_floatv[1];
TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
/* Parse the gl supported features, in theory enabling parts of our code appropriately. */
+#ifndef VBOX_WITH_VMSVGA
GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
if (!GL_Extensions)
{
@@ -2009,11 +2055,25 @@ BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
LEAVE_GL();
TRACE_(d3d_caps)("GL_Extensions reported:\n");
+#endif
gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
gl_info->supported[VBOX_SHARED_CONTEXTS] = TRUE;
+#ifdef VBOX_WITH_VMSVGA
+ {
+ void *pvEnumCtx = NULL;
+ char szCurExt[256];
+ while (pVBoxShaderIf->pfnGetNextExtension(pVBoxShaderIf, &pvEnumCtx, szCurExt, sizeof(szCurExt), false /*fOtherProfile*/))
+ check_gl_extension(gl_info, szCurExt);
+
+ /* The cheap way out. */
+ pvEnumCtx = NULL;
+ while (pVBoxShaderIf->pfnGetNextExtension(pVBoxShaderIf, &pvEnumCtx, szCurExt, sizeof(szCurExt), true /*fOtherProfile*/))
+ check_gl_extension(gl_info, szCurExt);
+ }
+#else /* VBOX_WITH_VMSVGA */
while (*GL_Extensions)
{
const char *start;
@@ -2040,16 +2100,16 @@ BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter)
}
}
}
+#endif
#ifdef VBOX_WITH_VMSVGA
# ifdef RT_OS_WINDOWS
-# define OGLGETPROCADDRESS wglGetProcAddress
+# define OGLGETPROCADDRESS wglGetProcAddress
# elif RT_OS_DARWIN
-extern void (*MyNSGLGetProcAddress(const char *name))(void);
-# define OGLGETPROCADDRESS MyNSGLGetProcAddress
+# define OGLGETPROCADDRESS(x) MyNSGLGetProcAddress(x)
# else
extern void (*glXGetProcAddress(const GLubyte *procname))( void );
-# define OGLGETPROCADDRESS(x) glXGetProcAddress((const GLubyte *)x)
+# define OGLGETPROCADDRESS(x) glXGetProcAddress((const GLubyte *)x)
# endif
#endif
@@ -2149,40 +2209,46 @@ extern void (*glXGetProcAddress(const GLubyte *procname))( void );
if (gl_info->supported[NV_REGISTER_COMBINERS])
{
- glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max));
gl_info->limits.general_combiners = gl_max;
TRACE_(d3d_caps)("Max general combiners: %d.\n", gl_max);
}
if (gl_info->supported[ARB_DRAW_BUFFERS])
{
- glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max));
gl_info->limits.buffers = gl_max;
TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
}
if (gl_info->supported[ARB_MULTITEXTURE])
{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
+ if (glGetError() != GL_NO_ERROR)
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gl_max));
+#else
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max));
+#endif
gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->limits.textures);
if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
{
GLint tmp;
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp));
gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
}
else
{
- gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
+ gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, (UINT)gl_max);
}
TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
if (gl_info->supported[ARB_VERTEX_SHADER])
{
GLint tmp;
- glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp));
gl_info->limits.vertex_samplers = tmp;
- glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp));
gl_info->limits.combined_samplers = tmp;
/* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
@@ -2220,63 +2286,89 @@ extern void (*glXGetProcAddress(const GLubyte *procname))( void );
}
if (gl_info->supported[ARB_VERTEX_BLEND])
{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max));
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+ }
+#else
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max));
+#endif
gl_info->limits.blends = gl_max;
TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
}
if (gl_info->supported[EXT_TEXTURE3D])
{
- glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max));
gl_info->limits.texture3d_size = gl_max;
TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
}
if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
{
- glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max));
gl_info->limits.anisotropy = gl_max;
TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
}
if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+ if (glGetError() != GL_NO_ERROR)
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+#endif
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)));
gl_info->limits.arb_ps_float_constants = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
- GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max)));
gl_info->limits.arb_ps_native_constants = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
gl_info->limits.arb_ps_native_constants);
- GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max)));
gl_info->limits.arb_ps_temps = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
- GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max)));
gl_info->limits.arb_ps_instructions = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
- GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max)));
gl_info->limits.arb_ps_local_constants = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+#endif
}
if (gl_info->supported[ARB_VERTEX_PROGRAM])
{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
+ if (glGetError() != GL_NO_ERROR)
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+#endif
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)));
gl_info->limits.arb_vs_float_constants = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
- GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max)));
gl_info->limits.arb_vs_native_constants = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
gl_info->limits.arb_vs_native_constants);
- GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max)));
gl_info->limits.arb_vs_temps = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
- GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
+ VBOX_CHECK_GL_CALL(GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max)));
gl_info->limits.arb_vs_instructions = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+#endif
#ifndef VBOX_WITH_VMSVGA
if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
#endif
}
if (gl_info->supported[ARB_VERTEX_SHADER])
{
- glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max));
gl_info->limits.glsl_vs_float_constants = gl_max / 4;
#ifdef VBOX_WITH_WDDM
/* AFAICT the " / 4" here comes from that we're going to use the glsl_vs/ps_float_constants to create vec4 arrays,
@@ -2303,7 +2395,7 @@ extern void (*glXGetProcAddress(const GLubyte *procname))( void );
}
if (gl_info->supported[ARB_FRAGMENT_SHADER])
{
- glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max));
gl_info->limits.glsl_ps_float_constants = gl_max / 4;
#ifdef VBOX_WITH_WDDM
/* AFAICT the " / 4" here comes from that we're going to use the glsl_vs/ps_float_constants to create vec4 arrays,
@@ -2327,7 +2419,17 @@ extern void (*glXGetProcAddress(const GLubyte *procname))( void );
}
#endif
TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max));
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+ }
+#else
+ VBOX_CHECK_GL_CALL(glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max));
+#endif
gl_info->limits.glsl_varyings = gl_max;
TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
}
@@ -2344,7 +2446,17 @@ extern void (*glXGetProcAddress(const GLubyte *procname))( void );
}
if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
{
+#ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
+ if (glGetError() != GL_NO_ERROR)
+ {
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, true /*fOtherProfile*/);
+ VBOX_CHECK_GL_CALL(glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess));
+ pVBoxShaderIf->pfnSwitchInitProfile(pVBoxShaderIf, false /*fOtherProfile*/);
+ }
+#else
+ VBOX_CHECK_GL_CALL(glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess));
+#endif
}
else
{
diff --git a/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c b/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c
index b0e9ded..9438429 100644
--- a/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c
+++ b/src/VBox/Devices/Graphics/shaderlib/glsl_shader.c
@@ -5051,8 +5051,20 @@ static int glsl_program_key_compare(const void *key, const struct wine_rb_entry
static BOOL constant_heap_init(struct constant_heap *heap, unsigned int constant_count)
{
+#ifndef VBOX
SIZE_T size = (constant_count + 1) * sizeof(*heap->entries) + constant_count * sizeof(*heap->positions);
void *mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+#else
+ SIZE_T size;
+ void *mem;
+
+ /* Don't trash the heap if the input is bogus. */
+ if (constant_count == 0)
+ constant_count = 1;
+
+ size = (constant_count + 1) * sizeof(*heap->entries) + constant_count * sizeof(*heap->positions);
+ mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+#endif
if (!mem)
{
diff --git a/src/VBox/Devices/Graphics/shaderlib/shader.c b/src/VBox/Devices/Graphics/shaderlib/shader.c
index ff8e0d7..f197074 100644
--- a/src/VBox/Devices/Graphics/shaderlib/shader.c
+++ b/src/VBox/Devices/Graphics/shaderlib/shader.c
@@ -1248,22 +1248,22 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
if (comment_size > 4 && *(const DWORD *)comment == WINEMAKEFOURCC('T', 'E', 'X', 'T'))
{
const char *end = comment + comment_size;
- const char *ptr = comment + 4;
- const char *line = ptr;
+ const char *cur = comment + 4;
+ const char *line = cur;
TRACE("// TEXT\n");
- while (ptr != end)
+ while (cur != end)
{
- if (*ptr == '\n')
+ if (*cur == '\n')
{
- UINT len = ptr - line;
- if (len && *(ptr - 1) == '\r') --len;
+ UINT len = cur - line;
+ if (len && *(cur - 1) == '\r') --len;
TRACE("// %s\n", debugstr_an(line, len));
- line = ++ptr;
+ line = ++cur;
}
- else ++ptr;
+ else ++cur;
}
- if (line != ptr) TRACE("// %s\n", debugstr_an(line, ptr - line));
+ if (line != cur) TRACE("// %s\n", debugstr_an(line, cur - line));
}
else TRACE("// %s\n", debugstr_an(comment, comment_size));
continue;
diff --git a/src/VBox/Devices/Graphics/shaderlib/shaderapi.c b/src/VBox/Devices/Graphics/shaderlib/shaderapi.c
index 789982b..c5ac4d7 100644
--- a/src/VBox/Devices/Graphics/shaderlib/shaderapi.c
+++ b/src/VBox/Devices/Graphics/shaderlib/shaderapi.c
@@ -1,9 +1,10 @@
+/* $Id: shaderapi.c $ */
/** @file
* shaderlib -- interface to WINE's Direct3D shader functions
*/
/*
- * Copyright (C) 2014 Oracle Corporation
+ * Copyright (C) 2014-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,29 +19,30 @@
#include <iprt/mem.h>
#include <iprt/assert.h>
#include <iprt/log.h>
+#define WINED3D_EXTERN
#include "wined3d_private.h"
#include "shaderlib.h"
#ifdef RT_OS_WINDOWS
-#define OGLGETPROCADDRESS wglGetProcAddress
+# define OGLGETPROCADDRESS wglGetProcAddress
+
#elif RT_OS_DARWIN
-#include <mach-o/dyld.h>
-void *MyNSGLGetProcAddress(const char *name)
+# include <dlfcn.h>
+# define OGLGETPROCADDRESS(x) MyNSGLGetProcAddress((const char *)x)
+void *MyNSGLGetProcAddress(const char *pszSymbol)
{
- NSSymbol symbol = NULL;
- char *symbolName = malloc(strlen(name) + 2);
- strcpy(symbolName + 1, name);
- symbolName[0] = '_';
- if (NSIsSymbolNameDefined(symbolName))
- symbol = NSLookupAndBindSymbol(symbolName);
- free(symbolName);
- return symbol ? NSAddressOfSymbol(symbol) : NULL;
+ /* Another copy in DevVGA-SVGA3d-ogl.cpp. */
+ static void *s_pvImage = NULL;
+ if (s_pvImage == NULL)
+ s_pvImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
+ return s_pvImage ? dlsym(s_pvImage, pszSymbol) : NULL;
}
-#define OGLGETPROCADDRESS(x) MyNSGLGetProcAddress((const char *)x)
+
#else
extern void (*glXGetProcAddress(const GLubyte *procname))( void );
-#define OGLGETPROCADDRESS(x) glXGetProcAddress((const GLubyte *)x)
+# define OGLGETPROCADDRESS(x) glXGetProcAddress((const GLubyte *)x)
+
#endif
#undef GL_EXT_FUNCS_GEN
@@ -129,41 +131,63 @@ extern void (*glXGetProcAddress(const GLubyte *procname))( void );
USE_GL_FUNC(WINED3D_PFNGLGETATTRIBLOCATIONARBPROC, \
glGetAttribLocationARB, ARB_SHADER_OBJECTS, NULL) \
-extern BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter);
-
-static struct wined3d_context *pCurrentContext = NULL;
-static struct wined3d_adapter adapter = {0};
-static bool fInitializedLibrary = false;
+static struct wined3d_context *g_pCurrentContext = NULL;
+static struct wined3d_adapter g_adapter = {0};
+static bool g_fInitializedLibrary = false;
#define SHADER_SET_CURRENT_CONTEXT(ctx) \
- pCurrentContext = (struct wined3d_context *)ctx;
+ g_pCurrentContext = (struct wined3d_context *)ctx;
-SHADERDECL(int) ShaderInitLib()
+SHADERDECL(int) ShaderInitLib(PVBOXVMSVGASHADERIF pVBoxShaderIf)
{
- struct wined3d_gl_info *gl_info = &adapter.gl_info;
+ struct wined3d_gl_info *gl_info = &g_adapter.gl_info;
+ /* Dynamically load all GL core functions. */
#ifdef RT_OS_WINDOWS
-#define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(GetModuleHandle("opengl32.dll"), #pfn);
+# define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(GetModuleHandle("opengl32.dll"), #pfn);
#else
-#define USE_GL_FUNC(pfn) pfn = (void*)OGLGETPROCADDRESS(#pfn);
+# define USE_GL_FUNC(pfn) pfn = (void*)OGLGETPROCADDRESS(#pfn);
#endif
-
- /* Dynamically load all GL core functions */
GL_FUNCS_GEN;
#undef USE_GL_FUNC
+ /* Dynamically load all GL extension functions. */
#define USE_GL_FUNC(type, pfn, ext, replace) \
{ \
gl_info->pfn = (void*)OGLGETPROCADDRESS(#pfn); \
}
GL_EXT_FUNCS_GEN;
- IWineD3DImpl_FillGLCaps(&adapter);
- fInitializedLibrary = true;
+ /* Fill in GL capabilities. */
+ IWineD3DImpl_FillGLCaps(&g_adapter, pVBoxShaderIf);
+
+ LogRel(("shaderlib: GL Limits:\n"));
+ LogRel(("shaderlib: buffers=%-2u lights=%-2u textures=%-2u texture_stages=%u\n",
+ gl_info->limits.buffers, gl_info->limits.lights, gl_info->limits.textures, gl_info->limits.texture_stages));
+ LogRel(("shaderlib: fragment_samplers=%-2u vertex_samplers=%-2u combined_samplers=%-3u general_combiners=%u\n",
+ gl_info->limits.fragment_samplers, gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers, gl_info->limits.general_combiners));
+ LogRel(("shaderlib: sampler_stages=%-2u clipplanes=%-2u texture_size=%-5u texture3d_size=%u\n",
+ gl_info->limits.sampler_stages, gl_info->limits.clipplanes, gl_info->limits.texture_size, gl_info->limits.texture3d_size));
+ LogRel(("shaderlib: pointsize_max=%d.%d pointsize_min=%d.%d point_sprite_units=%-2u blends=%u\n",
+ (int)gl_info->limits.pointsize_max, (int)(gl_info->limits.pointsize_max * 10) % 10,
+ (int)gl_info->limits.pointsize_min, (int)(gl_info->limits.pointsize_min * 10) % 10,
+ gl_info->limits.point_sprite_units, gl_info->limits.blends));
+ LogRel(("shaderlib: anisotropy=%-2u shininess=%d.%02d\n",
+ gl_info->limits.anisotropy, (int)gl_info->limits.shininess, (int)(gl_info->limits.shininess * 100) % 100));
+ LogRel(("shaderlib: glsl_varyings=%-3u glsl_vs_float_constants=%-4u glsl_ps_float_constants=%u\n",
+ gl_info->limits.glsl_varyings, gl_info->limits.glsl_vs_float_constants, gl_info->limits.glsl_ps_float_constants));
+ LogRel(("shaderlib: arb_vs_instructions=%-4u arb_vs_native_constants=%-4u qarb_vs_float_constants=%u\n",
+ gl_info->limits.arb_vs_instructions, gl_info->limits.arb_vs_native_constants, gl_info->limits.arb_vs_float_constants));
+ LogRel(("shaderlib: arb_vs_temps=%-2u arb_ps_float_constants=%-4u arb_ps_local_constants=%u\n",
+ gl_info->limits.arb_vs_temps, gl_info->limits.arb_ps_float_constants, gl_info->limits.arb_ps_local_constants));
+ LogRel(("shaderlib: arb_ps_instructions=%-4u arb_ps_temps=%-2u arb_ps_native_constants=%u\n",
+ gl_info->limits.arb_ps_instructions, gl_info->limits.arb_ps_temps, gl_info->limits.arb_ps_native_constants));
+
+ g_fInitializedLibrary = true;
return VINF_SUCCESS;
}
-SHADERDECL(int) ShaderDestroyLib()
+SHADERDECL(int) ShaderDestroyLib(void)
{
return VINF_SUCCESS;
}
@@ -175,12 +199,12 @@ struct IWineD3DDeviceImpl *context_get_device(const struct wined3d_context *cont
struct wined3d_context *context_get_current(void)
{
- return pCurrentContext;
+ return g_pCurrentContext;
}
struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage)
{
- return pCurrentContext;
+ return g_pCurrentContext;
}
SHADERDECL(int) ShaderContextCreate(void **ppShaderContext)
@@ -193,9 +217,9 @@ SHADERDECL(int) ShaderContextCreate(void **ppShaderContext)
pContext->pDeviceContext = (IWineD3DDeviceImpl *)RTMemAllocZ(sizeof(IWineD3DDeviceImpl));
AssertReturn(pContext->pDeviceContext, VERR_NO_MEMORY);
- pContext->gl_info = &adapter.gl_info;
+ pContext->gl_info = &g_adapter.gl_info;
- pContext->pDeviceContext->adapter = &adapter;
+ pContext->pDeviceContext->adapter = &g_adapter;
pContext->pDeviceContext->shader_backend = &glsl_shader_backend;
pContext->pDeviceContext->ps_selected_mode = SHADER_GLSL;
pContext->pDeviceContext->vs_selected_mode = SHADER_GLSL;
@@ -203,7 +227,7 @@ SHADERDECL(int) ShaderContextCreate(void **ppShaderContext)
list_init(&pContext->pDeviceContext->shaders);
- if (fInitializedLibrary)
+ if (g_fInitializedLibrary)
{
struct shader_caps shader_caps;
uint32_t state;
@@ -213,7 +237,7 @@ SHADERDECL(int) ShaderContextCreate(void **ppShaderContext)
AssertReturn(hr == S_OK, VERR_INTERNAL_ERROR);
memset(&shader_caps, 0, sizeof(shader_caps));
- pContext->pDeviceContext->shader_backend->shader_get_caps(&adapter.gl_info, &shader_caps);
+ pContext->pDeviceContext->shader_backend->shader_get_caps(&g_adapter.gl_info, &shader_caps);
pContext->pDeviceContext->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
pContext->pDeviceContext->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
pContext->pDeviceContext->vs_clipping = shader_caps.VSClipping;
@@ -289,7 +313,7 @@ SHADERDECL(int) ShaderCreateVertexShader(void *pShaderContext, const uint32_t *p
HRESULT hr;
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
@@ -323,7 +347,7 @@ SHADERDECL(int) ShaderCreatePixelShader(void *pShaderContext, const uint32_t *pS
HRESULT hr;
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if (!object)
@@ -378,7 +402,7 @@ SHADERDECL(int) ShaderSetVertexShader(void *pShaderContext, void *pShaderObj)
IWineD3DVertexShader* oldShader;
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
pShader = (IWineD3DVertexShader* )pShaderObj;
oldShader = This->updateStateBlock->vertexShader;
@@ -395,8 +419,8 @@ SHADERDECL(int) ShaderSetVertexShader(void *pShaderContext, void *pShaderObj)
if(pShader) IWineD3DVertexShader_AddRef(pShader);
if(oldShader) IWineD3DVertexShader_Release(oldShader);
- pCurrentContext->fChangedVertexShader = true;
- pCurrentContext->fChangedVertexShaderConstant = true; /* force constant reload. */
+ g_pCurrentContext->fChangedVertexShader = true;
+ g_pCurrentContext->fChangedVertexShaderConstant = true; /* force constant reload. */
return VINF_SUCCESS;
}
@@ -408,7 +432,7 @@ SHADERDECL(int) ShaderSetPixelShader(void *pShaderContext, void *pShaderObj)
IWineD3DPixelShader* oldShader;
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
pShader = (IWineD3DPixelShader* )pShaderObj;
oldShader = This->updateStateBlock->pixelShader;
@@ -425,8 +449,8 @@ SHADERDECL(int) ShaderSetPixelShader(void *pShaderContext, void *pShaderObj)
if(pShader) IWineD3DPixelShader_AddRef(pShader);
if(oldShader) IWineD3DPixelShader_Release(oldShader);
- pCurrentContext->fChangedPixelShader = true;
- pCurrentContext->fChangedPixelShaderConstant = true; /* force constant reload. */
+ g_pCurrentContext->fChangedPixelShader = true;
+ g_pCurrentContext->fChangedPixelShaderConstant = true; /* force constant reload. */
return VINF_SUCCESS;
}
@@ -436,7 +460,7 @@ SHADERDECL(int) ShaderSetVertexShaderConstantB(void *pShaderContext, uint32_t st
unsigned int i, cnt = min(count, MAX_CONST_B - start);
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
Log(("(ShaderSetVertexShaderConstantB %p, srcData %p, start %d, count %d)\n",
srcData, start, count));
@@ -455,7 +479,7 @@ SHADERDECL(int) ShaderSetVertexShaderConstantB(void *pShaderContext, uint32_t st
This->updateStateBlock->changed.vertexShaderConstantsB |= (1 << i);
}
- pCurrentContext->fChangedVertexShaderConstant = true;
+ g_pCurrentContext->fChangedVertexShaderConstant = true;
return VINF_SUCCESS;
}
@@ -466,7 +490,7 @@ SHADERDECL(int) ShaderSetVertexShaderConstantI(void *pShaderContext, uint32_t st
unsigned int i, cnt = min(count, MAX_CONST_I - start);
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
Log(("(ShaderSetVertexShaderConstantI %p, srcData %p, start %d, count %d)\n",
srcData, start, count));
@@ -483,7 +507,7 @@ SHADERDECL(int) ShaderSetVertexShaderConstantI(void *pShaderContext, uint32_t st
This->updateStateBlock->changed.vertexShaderConstantsI |= (1 << i);
}
- pCurrentContext->fChangedVertexShaderConstant = true;
+ g_pCurrentContext->fChangedVertexShaderConstant = true;
return VINF_SUCCESS;
}
@@ -493,7 +517,7 @@ SHADERDECL(int) ShaderSetVertexShaderConstantF(void *pShaderContext, uint32_t st
IWineD3DDeviceImpl *This;
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
Log(("(ShaderSetVertexShaderConstantF %p, srcData %p, start %d, count %d)\n",
srcData, start, count));
@@ -510,7 +534,7 @@ SHADERDECL(int) ShaderSetVertexShaderConstantF(void *pShaderContext, uint32_t st
memset(This->updateStateBlock->changed.vertexShaderConstantsF + start, 1,
sizeof(*This->updateStateBlock->changed.vertexShaderConstantsF) * count);
- pCurrentContext->fChangedVertexShaderConstant = true;
+ g_pCurrentContext->fChangedVertexShaderConstant = true;
return VINF_SUCCESS;
}
@@ -521,7 +545,7 @@ SHADERDECL(int) ShaderSetPixelShaderConstantB(void *pShaderContext, uint32_t sta
unsigned int i, cnt = min(count, MAX_CONST_B - start);
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
Log(("(ShaderSetPixelShaderConstantB %p, srcData %p, start %d, count %d)\n",
srcData, start, count));
@@ -540,7 +564,7 @@ SHADERDECL(int) ShaderSetPixelShaderConstantB(void *pShaderContext, uint32_t sta
This->updateStateBlock->changed.pixelShaderConstantsB |= (1 << i);
}
- pCurrentContext->fChangedPixelShaderConstant = true;
+ g_pCurrentContext->fChangedPixelShaderConstant = true;
return VINF_SUCCESS;
}
@@ -551,7 +575,7 @@ SHADERDECL(int) ShaderSetPixelShaderConstantI(void *pShaderContext, uint32_t sta
unsigned int i, cnt = min(count, MAX_CONST_I - start);
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
Log(("(ShaderSetPixelShaderConstantI %p, srcData %p, start %d, count %d)\n",
srcData, start, count));
@@ -568,7 +592,7 @@ SHADERDECL(int) ShaderSetPixelShaderConstantI(void *pShaderContext, uint32_t sta
This->updateStateBlock->changed.pixelShaderConstantsI |= (1 << i);
}
- pCurrentContext->fChangedPixelShaderConstant = true;
+ g_pCurrentContext->fChangedPixelShaderConstant = true;
return VINF_SUCCESS;
}
@@ -578,7 +602,7 @@ SHADERDECL(int) ShaderSetPixelShaderConstantF(void *pShaderContext, uint32_t sta
IWineD3DDeviceImpl *This;
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- This = pCurrentContext->pDeviceContext;
+ This = g_pCurrentContext->pDeviceContext;
Log(("(ShaderSetPixelShaderConstantF %p, srcData %p, start %d, count %d)\n",
srcData, start, count));
@@ -596,7 +620,7 @@ SHADERDECL(int) ShaderSetPixelShaderConstantF(void *pShaderContext, uint32_t sta
memset(This->updateStateBlock->changed.pixelShaderConstantsF + start, 1,
sizeof(*This->updateStateBlock->changed.pixelShaderConstantsF) * count);
- pCurrentContext->fChangedPixelShaderConstant = true;
+ g_pCurrentContext->fChangedPixelShaderConstant = true;
return VINF_SUCCESS;
}
@@ -608,7 +632,7 @@ SHADERDECL(int) ShaderUpdateState(void *pShaderContext, uint32_t rtHeight)
GLint viewport[4];
SHADER_SET_CURRENT_CONTEXT(pShaderContext);
- pThis = pCurrentContext->pDeviceContext;
+ pThis = g_pCurrentContext->pDeviceContext;
glGetIntegerv(GL_VIEWPORT, viewport);
#ifdef DEBUG
@@ -629,16 +653,16 @@ SHADERDECL(int) ShaderUpdateState(void *pShaderContext, uint32_t rtHeight)
* - stateblock->vertexDecl->position_transformed
*/
- if ( pCurrentContext->fChangedPixelShader
- || pCurrentContext->fChangedVertexShader)
- pThis->shader_backend->shader_select(pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
- pCurrentContext->fChangedPixelShader = pCurrentContext->fChangedVertexShader = false;
+ if ( g_pCurrentContext->fChangedPixelShader
+ || g_pCurrentContext->fChangedVertexShader)
+ pThis->shader_backend->shader_select(g_pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
+ g_pCurrentContext->fChangedPixelShader = g_pCurrentContext->fChangedVertexShader = false;
- if ( pCurrentContext->fChangedPixelShaderConstant
- || pCurrentContext->fChangedVertexShaderConstant)
- pThis->shader_backend->shader_load_constants(pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
- pCurrentContext->fChangedPixelShaderConstant = false;
- pCurrentContext->fChangedVertexShaderConstant = false;
+ if ( g_pCurrentContext->fChangedPixelShaderConstant
+ || g_pCurrentContext->fChangedVertexShaderConstant)
+ pThis->shader_backend->shader_load_constants(g_pCurrentContext, !!pThis->updateStateBlock->pixelShader, !!pThis->updateStateBlock->vertexShader);
+ g_pCurrentContext->fChangedPixelShaderConstant = false;
+ g_pCurrentContext->fChangedVertexShaderConstant = false;
return VINF_SUCCESS;
}
diff --git a/src/VBox/Devices/Graphics/shaderlib/shaderlib.h b/src/VBox/Devices/Graphics/shaderlib/shaderlib.h
index a427994..24692c5 100644
--- a/src/VBox/Devices/Graphics/shaderlib/shaderlib.h
+++ b/src/VBox/Devices/Graphics/shaderlib/shaderlib.h
@@ -1,21 +1,70 @@
-#ifndef __SHADERLIB_H__
-#define __SHADERLIB_H__
+/* $Id: shaderlib.h $ */
+/** @file
+ * shaderlib -- interface to WINE's Direct3D shader functions
+ */
+
+/*
+ * Copyright (C) 2014-2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+#ifndef ___shaderlib_h___
+#define ___shaderlib_h___
#include <VBox/cdefs.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+RT_C_DECLS_BEGIN
#ifdef IN_SHADERLIB_STATIC
-# define SHADERDECL(type) DECLHIDDEN(type) RTCALL
+# define SHADERDECL(type) DECLHIDDEN(type) RTCALL
#else
-# define SHADERDECL(type) DECLEXPORT(type) RTCALL
+# define SHADERDECL(type) DECLEXPORT(type) RTCALL
#endif
+/** Pointer to shaderlib callback interface. */
+typedef struct VBOXVMSVGASHADERIF *PVBOXVMSVGASHADERIF;
+/**
+ * Interface the shader lib can use to talk back to the VBox VMSVGA OGL 3D code.
+ */
+typedef struct VBOXVMSVGASHADERIF
+{
+ /**
+ * Switches the initialization profile in builds where we have to juggle two
+ * OpenGL profiles to gather all the data (i.e. mac os x).
+ *
+ * @param pThis Pointer to this structure.
+ * @param fOtherProfile If set, switch to the non-default profile. If
+ * clear, switch back to the default profile.
+ */
+ DECLCALLBACKMEMBER(void, pfnSwitchInitProfile)(PVBOXVMSVGASHADERIF pThis, bool fOtherProfile);
-SHADERDECL(int) ShaderInitLib();
-SHADERDECL(int) ShaderDestroyLib();
+ /**
+ * Extension enumeration function.
+ *
+ * @param pThis Pointer to this structure.
+ * @param ppvEnumCtx Pointer to a void point that's initialized to NULL
+ * before the first call.
+ * @param pszBuf Where to store the extension name. Garbled on
+ * overflow (we assume no overflow).
+ * @param cbBuf The size of the buffer @a pszBuf points to.
+ * @param fOtherProfile Indicates which profile to get extensions from,
+ * we'll use the default profile if CLEAR and the
+ * non-default if SET.
+ */
+ DECLCALLBACKMEMBER(bool, pfnGetNextExtension)(PVBOXVMSVGASHADERIF pThis, void **ppvEnumCtx, char *pszBuf, size_t cbBuf,
+ bool fOtherProfile);
+} VBOXVMSVGASHADERIF;
+
+SHADERDECL(int) ShaderInitLib(PVBOXVMSVGASHADERIF pVBoxShaderIf);
+SHADERDECL(int) ShaderDestroyLib(void);
SHADERDECL(int) ShaderContextCreate(void **ppShaderContext);
SHADERDECL(int) ShaderContextDestroy(void *pShaderContext);
@@ -41,8 +90,7 @@ SHADERDECL(int) ShaderUpdateState(void *pShaderContext, uint32_t rtHeight);
SHADERDECL(int) ShaderTransformProjection(unsigned cxViewPort, unsigned cyViewPort, float matrix[16]);
-#ifdef __cplusplus
-}
-#endif
+RT_C_DECLS_END
+
+#endif /* !___shaderlib_h___ */
-#endif /* __SHADERLIB_H__ */
diff --git a/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h b/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h
index a1f8a5b..dea73c0 100644
--- a/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h
+++ b/src/VBox/Devices/Graphics/shaderlib/wined3d_gl.h
@@ -1007,361 +1007,365 @@ typedef void (WINE_GLAPI *PGLFNVERTEXATTRIB4USVPROC)(GLuint index, const GLushor
typedef void (WINE_GLAPI *PGLFNVERTEXATTRIBPOINTERPROC)(GLuint index,
GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
-void (WINE_GLAPI *glAccum)(GLenum op, GLfloat value) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glAlphaFunc)(GLenum func, GLclampf ref) DECLSPEC_HIDDEN;
-GLboolean (WINE_GLAPI *glAreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glArrayElement)(GLint i) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glBegin)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glBindTexture)(GLenum target, GLuint texture) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glBitmap)(GLsizei width, GLsizei height, GLfloat xorig,
+#ifndef WINED3D_EXTERN
+# define WINED3D_EXTERN extern
+#endif
+
+WINED3D_EXTERN void (WINE_GLAPI *glAccum)(GLenum op, GLfloat value) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glAlphaFunc)(GLenum func, GLclampf ref) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLboolean (WINE_GLAPI *glAreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glArrayElement)(GLint i) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glBegin)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glBindTexture)(GLenum target, GLuint texture) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glBitmap)(GLsizei width, GLsizei height, GLfloat xorig,
GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glBlendFunc)(GLenum sfactor, GLenum dfactor) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCallList)(GLuint list) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCallLists)(GLsizei n, GLenum type, const GLvoid *lists) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClear)(GLbitfield mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClearDepth)(GLclampd depth) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClearIndex)(GLfloat c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClearStencil)(GLint s) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glClipPlane)(GLenum plane, const GLdouble *equation) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3b)(GLbyte red, GLbyte green, GLbyte blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3bv)(const GLbyte *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3d)(GLdouble red, GLdouble green, GLdouble blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3f)(GLfloat red, GLfloat green, GLfloat blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3i)(GLint red, GLint green, GLint blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3s)(GLshort red, GLshort green, GLshort blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3ub)(GLubyte red, GLubyte green, GLubyte blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3ubv)(const GLubyte *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3ui)(GLuint red, GLuint green, GLuint blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3uiv)(const GLuint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3us)(GLushort red, GLushort green, GLushort blue) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor3usv)(const GLushort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4bv)(const GLbyte *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4i)(GLint red, GLint green, GLint blue, GLint alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4ubv)(const GLubyte *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4uiv)(const GLuint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColor4usv)(const GLushort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColorMaterial)(GLenum face, GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCopyTexImage1D)(GLenum target, GLint level,
- GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCopyTexImage2D)(GLenum target, GLint level,
- GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCopyTexSubImage1D)(GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCopyTexSubImage2D)(GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glCullFace)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDeleteLists)(GLuint list, GLsizei range) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDeleteTextures)(GLsizei n, const GLuint *textures) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDepthFunc)(GLenum func) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDepthMask)(GLboolean flag) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDepthRange)(GLclampd nearParam, GLclampd farParam) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDisable)(GLenum cap) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDisableWINE)(GLenum cap) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDisableClientState)(GLenum array) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDrawArrays)(GLenum mode, GLint first, GLsizei count) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDrawBuffer)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glDrawPixels)(GLsizei width, GLsizei height, GLenum format,
- GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEdgeFlag)(GLboolean flag) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEdgeFlagPointer)(GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEdgeFlagv)(const GLboolean *flag) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEnable)(GLenum cap) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEnableWINE)(GLenum cap) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEnableClientState)(GLenum array) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEnd)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEndList)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord1d)(GLdouble u) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord1dv)(const GLdouble *u) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord1f)(GLfloat u) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord1fv)(const GLfloat *u) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord2d)(GLdouble u, GLdouble v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord2dv)(const GLdouble *u) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord2f)(GLfloat u, GLfloat v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalCoord2fv)(const GLfloat *u) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalMesh1)(GLenum mode, GLint i1, GLint i2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalPoint1)(GLint i) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glEvalPoint2)(GLint i, GLint j) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFogf)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFogfv)(GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFogi)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFogiv)(GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFrontFace)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glFrustum)(GLdouble left, GLdouble right, GLdouble bottom,
- GLdouble top, GLdouble zNear, GLdouble zFar) DECLSPEC_HIDDEN;
-GLuint (WINE_GLAPI *glGenLists)(GLsizei range) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGenTextures)(GLsizei n, GLuint *textures) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetBooleanv)(GLenum pname, GLboolean *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetClipPlane)(GLenum plane, GLdouble *equation) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetDoublev)(GLenum pname, GLdouble *params) DECLSPEC_HIDDEN;
-GLenum (WINE_GLAPI *glGetError)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetFloatv)(GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetIntegerv)(GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetLightiv)(GLenum light, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetMapdv)(GLenum target, GLenum query, GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetMapfv)(GLenum target, GLenum query, GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetMapiv)(GLenum target, GLenum query, GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetMaterialiv)(GLenum face, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetPixelMapfv)(GLenum map, GLfloat *values) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetPixelMapuiv)(GLenum map, GLuint *values) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetPixelMapusv)(GLenum map, GLushort *values) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetPointerv)(GLenum pname, GLvoid **params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetPolygonStipple)(GLubyte *mask) DECLSPEC_HIDDEN;
-const GLubyte * (WINE_GLAPI *glGetString)(GLenum name) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexEnviv)(GLenum target, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexGendv)(GLenum coord, GLenum pname, GLdouble *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexGenfv)(GLenum coord, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexGeniv)(GLenum coord, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexImage)(GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glHint)(GLenum target, GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexMask)(GLuint mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexd)(GLdouble c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexdv)(const GLdouble *c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexf)(GLfloat c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexfv)(const GLfloat *c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexi)(GLint c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexiv)(const GLint *c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexs)(GLshort c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexsv)(const GLshort *c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexub)(GLubyte c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glIndexubv)(const GLubyte *c) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glInitNames)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glInterleavedArrays)(GLenum format, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-GLboolean (WINE_GLAPI *glIsEnabled)(GLenum cap) DECLSPEC_HIDDEN;
-GLboolean (WINE_GLAPI *glIsList)(GLuint list) DECLSPEC_HIDDEN;
-GLboolean (WINE_GLAPI *glIsTexture)(GLuint texture) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightModelf)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightModelfv)(GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightModeli)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightModeliv)(GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightf)(GLenum light, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightfv)(GLenum light, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLighti)(GLenum light, GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLightiv)(GLenum light, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLineStipple)(GLint factor, GLushort pattern) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLineWidth)(GLfloat width) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glListBase)(GLuint base) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLoadIdentity)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLoadMatrixd)(const GLdouble *m) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLoadMatrixf)(const GLfloat *m) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLoadName)(GLuint name) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glLogicOp)(GLenum opcode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMap1d)(GLenum target, GLdouble u1, GLdouble u2,
- GLint stride, GLint order, const GLdouble *points) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMap1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
- GLint order, const GLfloat *points) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMap2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
- GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMap2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
- GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMapGrid1d)(GLint un, GLdouble u1, GLdouble u2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMapGrid1f)(GLint un, GLfloat u1, GLfloat u2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMaterialf)(GLenum face, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMateriali)(GLenum face, GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMaterialiv)(GLenum face, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMatrixMode)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMultMatrixd)(const GLdouble *m) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glMultMatrixf)(const GLfloat *m) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNewList)(GLuint list, GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3b)(GLbyte nx, GLbyte ny, GLbyte nz) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3bv)(const GLbyte *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3d)(GLdouble nx, GLdouble ny, GLdouble nz) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3i)(GLint nx, GLint ny, GLint nz) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3s)(GLshort nx, GLshort ny, GLshort nz) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormal3sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glOrtho)(GLdouble left, GLdouble right, GLdouble bottom,
- GLdouble top, GLdouble zNear, GLdouble zFar) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPassThrough)(GLfloat token) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelMapusv)(GLenum map, GLint mapsize, const GLushort *values) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelStoref)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelStorei)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelTransferf)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelTransferi)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPixelZoom)(GLfloat xfactor, GLfloat yfactor) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPointSize)(GLfloat size) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPolygonMode)(GLenum face, GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPolygonOffset)(GLfloat factor, GLfloat units) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPolygonStipple)(const GLubyte *mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPopAttrib)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPopClientAttrib)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPopMatrix)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPopName)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPrioritizeTextures)(GLsizei n, const GLuint *textures, const GLclampf *priorities) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPushAttrib)(GLbitfield mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPushClientAttrib)(GLbitfield mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPushMatrix)(void) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPushName)(GLuint name) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2d)(GLdouble x, GLdouble y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2f)(GLfloat x, GLfloat y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2i)(GLint x, GLint y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2s)(GLshort x, GLshort y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos2sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3d)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3f)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3i)(GLint x, GLint y, GLint z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3s)(GLshort x, GLshort y, GLshort z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos3sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4i)(GLint x, GLint y, GLint z, GLint w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRasterPos4sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glReadBuffer)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRectdv)(const GLdouble *v1, const GLdouble *v2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRectfv)(const GLfloat *v1, const GLfloat *v2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRecti)(GLint x1, GLint y1, GLint x2, GLint y2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRectiv)(const GLint *v1, const GLint *v2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRectsv)(const GLshort *v1, const GLshort *v2) DECLSPEC_HIDDEN;
-GLint (WINE_GLAPI *glRenderMode)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glScaled)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glScalef)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glSelectBuffer)(GLsizei size, GLuint *buffer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glShadeModel)(GLenum mode) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glStencilFunc)(GLenum func, GLint ref, GLuint mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glStencilMask)(GLuint mask) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1d)(GLdouble s) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1f)(GLfloat s) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1i)(GLint s) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1s)(GLshort s) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord1sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2d)(GLdouble s, GLdouble t) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2f)(GLfloat s, GLfloat t) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2i)(GLint s, GLint t) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2s)(GLshort s, GLshort t) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord2sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3d)(GLdouble s, GLdouble t, GLdouble r) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3f)(GLfloat s, GLfloat t, GLfloat r) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3i)(GLint s, GLint t, GLint r) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3s)(GLshort s, GLshort t, GLshort r) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord3sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4i)(GLint s, GLint t, GLint r, GLint q) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoord4sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexEnvf)(GLenum target, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexEnvi)(GLenum target, GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexEnviv)(GLenum target, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexGend)(GLenum coord, GLenum pname, GLdouble param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexGendv)(GLenum coord, GLenum pname, const GLdouble *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexGenf)(GLenum coord, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexGenfv)(GLenum coord, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexGeni)(GLenum coord, GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexGeniv)(GLenum coord, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width,
- GLint border, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width,
- GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexParameterf)(GLenum target, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexParameteri)(GLenum target, GLenum pname, GLint param) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexSubImage1D)(GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTranslated)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glTranslatef)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2d)(GLdouble x, GLdouble y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2f)(GLfloat x, GLfloat y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2i)(GLint x, GLint y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2s)(GLshort x, GLshort y) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex2sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3d)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3f)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3i)(GLint x, GLint y, GLint z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3s)(GLshort x, GLshort y, GLshort z) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex3sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4i)(GLint x, GLint y, GLint z, GLint w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4iv)(const GLint *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4s)(GLshort x, GLshort y, GLshort z, GLshort w) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertex4sv)(const GLshort *v) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) DECLSPEC_HIDDEN;
-void (WINE_GLAPI *glPointParameterfv)(GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glBlendFunc)(GLenum sfactor, GLenum dfactor) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCallList)(GLuint list) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCallLists)(GLsizei n, GLenum type, const GLvoid *lists) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClear)(GLbitfield mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClearDepth)(GLclampd depth) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClearIndex)(GLfloat c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClearStencil)(GLint s) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glClipPlane)(GLenum plane, const GLdouble *equation) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3b)(GLbyte red, GLbyte green, GLbyte blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3bv)(const GLbyte *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3d)(GLdouble red, GLdouble green, GLdouble blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3f)(GLfloat red, GLfloat green, GLfloat blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3i)(GLint red, GLint green, GLint blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3s)(GLshort red, GLshort green, GLshort blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3ub)(GLubyte red, GLubyte green, GLubyte blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3ubv)(const GLubyte *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3ui)(GLuint red, GLuint green, GLuint blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3uiv)(const GLuint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3us)(GLushort red, GLushort green, GLushort blue) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor3usv)(const GLushort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4bv)(const GLbyte *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4i)(GLint red, GLint green, GLint blue, GLint alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4ubv)(const GLubyte *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4uiv)(const GLuint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColor4usv)(const GLushort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColorMaterial)(GLenum face, GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCopyTexImage1D)(GLenum target, GLint level,
+ GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCopyTexImage2D)(GLenum target, GLint level,
+ GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCopyTexSubImage1D)(GLenum target, GLint level,
+ GLint xoffset, GLint x, GLint y, GLsizei width) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCopyTexSubImage2D)(GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glCullFace)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDeleteLists)(GLuint list, GLsizei range) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDeleteTextures)(GLsizei n, const GLuint *textures) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDepthFunc)(GLenum func) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDepthMask)(GLboolean flag) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDepthRange)(GLclampd nearParam, GLclampd farParam) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDisable)(GLenum cap) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDisableWINE)(GLenum cap) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDisableClientState)(GLenum array) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDrawArrays)(GLenum mode, GLint first, GLsizei count) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDrawBuffer)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glDrawPixels)(GLsizei width, GLsizei height, GLenum format,
+ GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEdgeFlag)(GLboolean flag) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEdgeFlagPointer)(GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEdgeFlagv)(const GLboolean *flag) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEnable)(GLenum cap) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEnableWINE)(GLenum cap) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEnableClientState)(GLenum array) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEnd)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEndList)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord1d)(GLdouble u) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord1dv)(const GLdouble *u) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord1f)(GLfloat u) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord1fv)(const GLfloat *u) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord2d)(GLdouble u, GLdouble v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord2dv)(const GLdouble *u) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord2f)(GLfloat u, GLfloat v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalCoord2fv)(const GLfloat *u) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalMesh1)(GLenum mode, GLint i1, GLint i2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalPoint1)(GLint i) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glEvalPoint2)(GLint i, GLint j) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFogf)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFogfv)(GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFogi)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFogiv)(GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFrontFace)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glFrustum)(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble zNear, GLdouble zFar) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLuint (WINE_GLAPI *glGenLists)(GLsizei range) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGenTextures)(GLsizei n, GLuint *textures) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetBooleanv)(GLenum pname, GLboolean *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetClipPlane)(GLenum plane, GLdouble *equation) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetDoublev)(GLenum pname, GLdouble *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLenum (WINE_GLAPI *glGetError)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetFloatv)(GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetIntegerv)(GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetLightiv)(GLenum light, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetMapdv)(GLenum target, GLenum query, GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetMapfv)(GLenum target, GLenum query, GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetMapiv)(GLenum target, GLenum query, GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetMaterialiv)(GLenum face, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetPixelMapfv)(GLenum map, GLfloat *values) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetPixelMapuiv)(GLenum map, GLuint *values) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetPixelMapusv)(GLenum map, GLushort *values) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetPointerv)(GLenum pname, GLvoid **params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetPolygonStipple)(GLubyte *mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN const GLubyte * (WINE_GLAPI *glGetString)(GLenum name) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexEnviv)(GLenum target, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexGendv)(GLenum coord, GLenum pname, GLdouble *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexGenfv)(GLenum coord, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexGeniv)(GLenum coord, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexImage)(GLenum target, GLint level, GLenum format,
+ GLenum type, GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glHint)(GLenum target, GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexMask)(GLuint mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexd)(GLdouble c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexdv)(const GLdouble *c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexf)(GLfloat c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexfv)(const GLfloat *c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexi)(GLint c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexiv)(const GLint *c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexs)(GLshort c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexsv)(const GLshort *c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexub)(GLubyte c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glIndexubv)(const GLubyte *c) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glInitNames)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glInterleavedArrays)(GLenum format, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLboolean (WINE_GLAPI *glIsEnabled)(GLenum cap) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLboolean (WINE_GLAPI *glIsList)(GLuint list) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLboolean (WINE_GLAPI *glIsTexture)(GLuint texture) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightModelf)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightModelfv)(GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightModeli)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightModeliv)(GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightf)(GLenum light, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightfv)(GLenum light, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLighti)(GLenum light, GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLightiv)(GLenum light, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLineStipple)(GLint factor, GLushort pattern) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLineWidth)(GLfloat width) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glListBase)(GLuint base) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLoadIdentity)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLoadMatrixd)(const GLdouble *m) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLoadMatrixf)(const GLfloat *m) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLoadName)(GLuint name) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glLogicOp)(GLenum opcode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMap1d)(GLenum target, GLdouble u1, GLdouble u2,
+ GLint stride, GLint order, const GLdouble *points) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMap1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+ GLint order, const GLfloat *points) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMap2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
+ GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMap2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
+ GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMapGrid1d)(GLint un, GLdouble u1, GLdouble u2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMapGrid1f)(GLint un, GLfloat u1, GLfloat u2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMaterialf)(GLenum face, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMateriali)(GLenum face, GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMaterialiv)(GLenum face, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMatrixMode)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMultMatrixd)(const GLdouble *m) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glMultMatrixf)(const GLfloat *m) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNewList)(GLuint list, GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3b)(GLbyte nx, GLbyte ny, GLbyte nz) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3bv)(const GLbyte *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3d)(GLdouble nx, GLdouble ny, GLdouble nz) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3i)(GLint nx, GLint ny, GLint nz) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3s)(GLshort nx, GLshort ny, GLshort nz) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormal3sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glOrtho)(GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble zNear, GLdouble zFar) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPassThrough)(GLfloat token) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelMapusv)(GLenum map, GLint mapsize, const GLushort *values) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelStoref)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelStorei)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelTransferf)(GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelTransferi)(GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPixelZoom)(GLfloat xfactor, GLfloat yfactor) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPointSize)(GLfloat size) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPolygonMode)(GLenum face, GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPolygonOffset)(GLfloat factor, GLfloat units) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPolygonStipple)(const GLubyte *mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPopAttrib)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPopClientAttrib)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPopMatrix)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPopName)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPrioritizeTextures)(GLsizei n, const GLuint *textures, const GLclampf *priorities) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPushAttrib)(GLbitfield mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPushClientAttrib)(GLbitfield mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPushMatrix)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPushName)(GLuint name) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2d)(GLdouble x, GLdouble y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2f)(GLfloat x, GLfloat y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2i)(GLint x, GLint y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2s)(GLshort x, GLshort y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos2sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3d)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3f)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3i)(GLint x, GLint y, GLint z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3s)(GLshort x, GLshort y, GLshort z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos3sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4i)(GLint x, GLint y, GLint z, GLint w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRasterPos4sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glReadBuffer)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRectdv)(const GLdouble *v1, const GLdouble *v2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRectfv)(const GLfloat *v1, const GLfloat *v2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRecti)(GLint x1, GLint y1, GLint x2, GLint y2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRectiv)(const GLint *v1, const GLint *v2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRectsv)(const GLshort *v1, const GLshort *v2) DECLSPEC_HIDDEN;
+WINED3D_EXTERN GLint (WINE_GLAPI *glRenderMode)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glScaled)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glScalef)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glSelectBuffer)(GLsizei size, GLuint *buffer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glShadeModel)(GLenum mode) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glStencilFunc)(GLenum func, GLint ref, GLuint mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glStencilMask)(GLuint mask) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1d)(GLdouble s) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1f)(GLfloat s) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1i)(GLint s) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1s)(GLshort s) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord1sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2d)(GLdouble s, GLdouble t) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2f)(GLfloat s, GLfloat t) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2i)(GLint s, GLint t) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2s)(GLshort s, GLshort t) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord2sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3d)(GLdouble s, GLdouble t, GLdouble r) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3f)(GLfloat s, GLfloat t, GLfloat r) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3i)(GLint s, GLint t, GLint r) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3s)(GLshort s, GLshort t, GLshort r) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord3sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4i)(GLint s, GLint t, GLint r, GLint q) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoord4sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexEnvf)(GLenum target, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexEnvi)(GLenum target, GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexEnviv)(GLenum target, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexGend)(GLenum coord, GLenum pname, GLdouble param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexGendv)(GLenum coord, GLenum pname, const GLdouble *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexGenf)(GLenum coord, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexGenfv)(GLenum coord, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexGeni)(GLenum coord, GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexGeniv)(GLenum coord, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLint border, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexParameterf)(GLenum target, GLenum pname, GLfloat param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexParameteri)(GLenum target, GLenum pname, GLint param) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexSubImage1D)(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTranslated)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glTranslatef)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2d)(GLdouble x, GLdouble y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2f)(GLfloat x, GLfloat y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2i)(GLint x, GLint y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2s)(GLshort x, GLshort y) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex2sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3d)(GLdouble x, GLdouble y, GLdouble z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3f)(GLfloat x, GLfloat y, GLfloat z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3i)(GLint x, GLint y, GLint z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3s)(GLshort x, GLshort y, GLshort z) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex3sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4dv)(const GLdouble *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4fv)(const GLfloat *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4i)(GLint x, GLint y, GLint z, GLint w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4iv)(const GLint *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4s)(GLshort x, GLshort y, GLshort z, GLshort w) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertex4sv)(const GLshort *v) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINE_GLAPI *glPointParameterfv)(GLenum pname, const GLfloat *params) DECLSPEC_HIDDEN;
/* glFinish and glFlush are always loaded from opengl32.dll, thus they always have
* __stdcall calling convention.
@@ -1369,25 +1373,25 @@ void (WINE_GLAPI *glPointParameterfv)(GLenum pname, const GLfloat *params) DECLS
* They are wgl functions and must not be called inside the gl lock, give them a
* name that makes this clear
*/
-void (__stdcall *wglFinish)(void) DECLSPEC_HIDDEN;
-void (__stdcall *wglFlush)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (__stdcall *wglFinish)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (__stdcall *wglFlush)(void) DECLSPEC_HIDDEN;
/* WGL functions */
-BOOL (WINAPI *pwglDeleteContext)(HGLRC) DECLSPEC_HIDDEN;
-HGLRC (WINAPI *pwglGetCurrentContext)(void) DECLSPEC_HIDDEN;
-HDC (WINAPI *pwglGetCurrentDC)(void) DECLSPEC_HIDDEN;
-PROC (WINAPI *pwglGetProcAddress)(LPCSTR) DECLSPEC_HIDDEN;
-BOOL (WINAPI *pwglMakeCurrent)(HDC, HGLRC) DECLSPEC_HIDDEN;
-BOOL (WINAPI *pwglSwapLayerBuffers)(HDC, UINT) DECLSPEC_HIDDEN;
-BOOL (WINAPI *pwglShareLists)(HGLRC, HGLRC) DECLSPEC_HIDDEN;
-BOOL (WINAPI *pwglChoosePixelFormat)(HDC, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
-int (WINAPI *pwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR) DECLSPEC_HIDDEN;
-int (WINAPI *pwglGetPixelFormat)(HDC) DECLSPEC_HIDDEN;
-BOOL (WINAPI *pwglSetPixelFormat)(HDC, int, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
+WINED3D_EXTERN BOOL (WINAPI *pwglDeleteContext)(HGLRC) DECLSPEC_HIDDEN;
+WINED3D_EXTERN HGLRC (WINAPI *pwglGetCurrentContext)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN HDC (WINAPI *pwglGetCurrentDC)(void) DECLSPEC_HIDDEN;
+WINED3D_EXTERN PROC (WINAPI *pwglGetProcAddress)(LPCSTR) DECLSPEC_HIDDEN;
+WINED3D_EXTERN BOOL (WINAPI *pwglMakeCurrent)(HDC, HGLRC) DECLSPEC_HIDDEN;
+WINED3D_EXTERN BOOL (WINAPI *pwglSwapLayerBuffers)(HDC, UINT) DECLSPEC_HIDDEN;
+WINED3D_EXTERN BOOL (WINAPI *pwglShareLists)(HGLRC, HGLRC) DECLSPEC_HIDDEN;
+WINED3D_EXTERN BOOL (WINAPI *pwglChoosePixelFormat)(HDC, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
+WINED3D_EXTERN int (WINAPI *pwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR) DECLSPEC_HIDDEN;
+WINED3D_EXTERN int (WINAPI *pwglGetPixelFormat)(HDC) DECLSPEC_HIDDEN;
+WINED3D_EXTERN BOOL (WINAPI *pwglSetPixelFormat)(HDC, int, const PIXELFORMATDESCRIPTOR *) DECLSPEC_HIDDEN;
struct VBOXUHGSMI;
-HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
-void (WINAPI *pVBoxFlushToHost)(HGLRC) DECLSPEC_HIDDEN;
+WINED3D_EXTERN HGLRC (WINAPI *pVBoxCreateContext)(HDC, struct VBOXUHGSMI*) DECLSPEC_HIDDEN;
+WINED3D_EXTERN void (WINAPI *pVBoxFlushToHost)(HGLRC) DECLSPEC_HIDDEN;
#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
# define VBOX_WINE_WITH_DIRECT_VBOXOGL
diff --git a/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h b/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
index fa3ebf5..ca1bd61 100644
--- a/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
+++ b/src/VBox/Devices/Graphics/shaderlib/wined3d_private.h
@@ -62,7 +62,13 @@
#include "vboxext.h"
#ifdef VBOX_WITH_VMSVGA
-#include "winoverride.h"
+# ifndef LOG_GROUP
+# define LOG_GROUP LOG_GROUP_DEV_VMSVGA
+# endif
+# include <iprt/assert.h>
+# include <VBox/log.h>
+# include "winoverride.h"
+# include "shaderlib.h"
#endif
#ifdef VBOX_WITH_WDDM
@@ -73,6 +79,7 @@
# define VBoxTlsRefGetImpl(_tls) (TlsGetValue((DWORD)(_tls)))
# define VBoxTlsRefSetImpl(_tls, _val) (TlsSetValue((DWORD)(_tls), (_val)))
# define VBoxTlsRefAssertImpl Assert
+# undef cdecl /* see windef.h */
# include <VBox/VBoxVideo3D.h>
#endif
@@ -191,11 +198,11 @@ struct min_lookup
GLenum mip[WINED3DTEXF_LINEAR + 1];
};
-const struct min_lookup minMipLookup[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-const struct min_lookup minMipLookup_noMip[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-const GLenum magLookup[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
-const GLenum magLookup_noFilter[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const struct min_lookup minMipLookup[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const struct min_lookup minMipLookup_noMip[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const GLenum magLookup[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+extern const GLenum magLookup_noFilter[WINED3DTEXF_LINEAR + 1] DECLSPEC_HIDDEN;
static inline GLenum wined3d_gl_mag_filter(const GLenum mag_lookup[], WINED3DTEXTUREFILTERTYPE mag_filter)
{
@@ -1589,6 +1596,10 @@ extern long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram)
#endif
extern void add_gl_compat_wrappers(struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
+struct VBOXVMSVGASHADERIF;
+extern BOOL IWineD3DImpl_FillGLCaps(struct wined3d_adapter *adapter, struct VBOXVMSVGASHADERIF *pVBoxShaderIf);
+
+
/*****************************************************************************
* High order patch management
*/
@@ -2948,7 +2959,7 @@ struct IWineD3DSwapChainImpl
#endif
};
-const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN;
+extern const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl DECLSPEC_HIDDEN;
void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) DECLSPEC_HIDDEN;
HRESULT WINAPI IWineD3DBaseSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface,
@@ -3429,4 +3440,26 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface,
#define MAKEDWORD_VERSION(maj, min) (((maj & 0xffff) << 16) | (min & 0xffff))
+#ifdef RT_OS_DARWIN
+void *MyNSGLGetProcAddress(const char *name);
+#endif
+
+/** @def VBOX_CHECK_GL_CALL
+ * Performs OpenGL call @a a_Expr and check glGetError.
+ * Errors will be asserted in strict builds and hit the release log in
+ * non-strict builds.
+ * @param a_Expr The OpenGL call expression. Always executed!
+ */
+#ifdef VBOX_WITH_VMSVGA
+# define VBOX_CHECK_GL_CALL(a_Expr) \
+ do { \
+ GLint rcCheckCall; \
+ a_Expr; \
+ rcCheckCall = glGetError(); \
+ AssertLogRelMsg(rcCheckCall == GL_NO_ERROR, ("%s -> %#x\n", #a_Expr, rcCheckCall)); \
+ } while (0)
+#else
+# define VBOX_CHECK_GL_CALL(a_Expr) do { a_Expr; } while (0)
+#endif
+
#endif
diff --git a/src/VBox/Devices/Input/DevPS2.cpp b/src/VBox/Devices/Input/DevPS2.cpp
index 12d58bf..5abb04b 100644
--- a/src/VBox/Devices/Input/DevPS2.cpp
+++ b/src/VBox/Devices/Input/DevPS2.cpp
@@ -494,7 +494,7 @@ static int kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
kbd_update_irq(s);
break;
case KBD_CCMD_READ_INPORT:
- kbc_dbb_out(s, 0x00);
+ kbc_dbb_out(s, 0xBF);
break;
case KBD_CCMD_READ_OUTPORT:
/* XXX: check that */
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index 1a963d7..5c714e5 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -4,7 +4,7 @@
#
#
-# Copyright (C) 2006-2014 Oracle Corporation
+# Copyright (C) 2006-2015 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -80,6 +80,8 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Storage/VSCSI/VSCSIIoReq.cpp \
Storage/VSCSI/VSCSIVpdPagePool.cpp \
build/VBoxDDUDeps.cpp
+ VBoxDDU_SOURCES.win = \
+ build/VBoxDDU.rc
ifdef VBOX_WITH_USB
VBoxDDU_INCS.os2 += \
$(PATH_ROOT)/src/VBox/HostDrivers/VBoxUSB/os2
@@ -175,9 +177,6 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Serial/DrvNamedPipe.cpp \
Serial/DrvRawFile.cpp \
Storage/DrvBlock.cpp \
- Storage/DrvHostBase.cpp \
- Storage/DrvHostDVD.cpp \
- Storage/DrvHostFloppy.cpp \
Storage/DrvMediaISO.cpp \
Storage/DrvRawImage.cpp \
Storage/Debug.cpp \
@@ -185,6 +184,18 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Storage/ATAPIPassthrough.cpp \
Network/DrvNetSniffer.cpp \
Network/Pcap.cpp
+ VBoxDD_SOURCES.win = \
+ build/VBoxDD.rc
+ ifn1of ($(KBUILD_TARGET), os2)
+ VBoxDD_SOURCES += Storage/DrvHostBase.cpp
+ endif
+ ifn1of ($(KBUILD_TARGET), os2)
+ VBoxDD_SOURCES += Storage/DrvHostDVD.cpp
+ endif
+ ifn1of ($(KBUILD_TARGET), darwin freebsd os2 solaris)
+ VBoxDD_SOURCES += Storage/DrvHostFloppy.cpp
+ endif
+
VBoxDD_LIBS = # more later.
VBoxDD_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxDD.dylib \
-framework CoreAudio \
@@ -244,17 +255,33 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
VBoxDD_SOURCES += Graphics/DevVGA-SVGA3d-shared.cpp
ifeq ($(KBUILD_TARGET),win) # (Disable this to work with OpenGL on Windows.)
VBoxDD_SOURCES += Graphics/DevVGA-SVGA3d-win.cpp
- VBoxDD_LIBS.win += d3d9.lib
+ VBoxDD_LIBS.win += d3d9.lib $(PATH_TOOL_$(VBOX_VCC_TOOL)_LIB)/delayimp.lib
+ VBoxDD_LDFLAGS.win += /DELAYLOAD:d3d9.dll
else
- VBoxDD_SOURCES += Graphics/DevVGA-SVGA3d-ogl.cpp
- if1of ($(KBUILD_TARGET),win)
- VBoxDD_LIBS += $(PATH_STAGE_LIB)/VBoxSVGA3D$(VBOX_SUFF_LIB)
- else
- VBoxDD_LIBS += $(PATH_STAGE_BIN)/VBoxSVGA3D$(VBOX_SUFF_DLL)
- endif
+ VBoxDD_SOURCES += \
+ Graphics/DevVGA-SVGA3d-ogl.cpp \
+ $(VBoxDD_0_OUTDIR)/VBoxSVGA3DLazyLoad.asm
+ VBoxDD_SOURCES.darwin += \
+ $(VBoxDD_0_OUTDIR)/VBoxSVGA3DObjCLazyLoad.asm
+ VBoxDD_CLEAN += $(VBoxDD_0_OUTDIR)/VBoxSVGA3DLazyLoad.asm
+ $$(VBoxDD_0_OUTDIR)/VBoxSVGA3DLazyLoad.asm: $(PATH_SUB_CURRENT)/Graphics/VBoxSVGA3D.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+ $(call MSG_TOOL,VBoxDef2LazyLoad,VBoxDD,$(filter %.def, $^),$@)
+ $(QUIET)$(RM) -f -- "$@"
+ $(VBOX_DEF_2_LAZY_LOAD) --explicit-load-function --library VBoxSVGA3D --output "$@" $(filter %.def, $^)
+ $$(VBoxDD_0_OUTDIR)/VBoxSVGA3DObjCLazyLoad.asm: $(PATH_SUB_CURRENT)/Graphics/VBoxSVGA3DObjC.def $(VBOX_DEF_2_LAZY_LOAD) | $$(dir $$@)
+ $(call MSG_TOOL,VBoxDef2LazyLoad,VBoxDD,$(filter %.def, $^),$@)
+ $(QUIET)$(RM) -f -- "$@"
+ $(VBOX_DEF_2_LAZY_LOAD) --explicit-load-function --library VBoxSVGA3DObjC --output "$@" $(filter %.def, $^)
+
VBoxDD_LIBS.linux += GL X11
VBoxDD_LIBS.win += $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Opengl32.lib
VBoxDD_LDFLAGS.darwin += -framework OpenGL
+ VBoxDD_DEFS.darwin += VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ if 0 # Use the OpenGL 3.2 Core profile (see also VBoxSVGA3D_DEFS.darwin and VBoxSVGA3DObjC_DEFS.darwin).
+ VBoxDD_DEFS.darwin += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=3.2 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=2.1
+ else
+ VBoxDD_DEFS.darwin += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=2.1 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=3.2
+ endif
endif
Graphics/DevVGA-SVGA3d-ogl.cpp_CXXFLAGS.darwin = -F$(VBOX_PATH_MACOSX_SDK_10_7)/System/Library/Frameworks/
endif
@@ -541,6 +568,19 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Network/slirp/dnsproxy/hash.c \
Network/slirp/tftp.c \
Network/slirp/dnsproxy/dnsproxy.c
+
+ ifeq ($(KBUILD_TARGET), win)
+ VBOX_SLIRP_SOURCES += Network/slirp/ip_icmpwin.c
+ else ifneq ($(KBUILD_TARGET),darwin)
+ # helper for debugging unprivileged
+# Network/slirp/ip_icmp.c_DEFS += VBOX_RAWSOCK_DEBUG_HELPER
+# VBOX_SLIRP_SOURCES += ../NetworkServices/NAT/getrawsock.c
+ endif
+
+ ifneq ($(KBUILD_TARGET), win)
+ VBOX_SLIRP_SOURCES += Network/slirp/resolv_conf_parser.c
+ endif
+
ifdef VBOX_WITH_SLIRP_BSD_SBUF
VBOX_SLIRP_SOURCES += Network/slirp/bsd/kern/subr_sbuf.c
endif
@@ -622,37 +662,22 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
# --- OS specific driver hacks. ---
ifeq ($(KBUILD_TARGET),darwin)
- VBoxDD_SOURCES := \
- $(filter-out Storage/DrvHostRaw% Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
- Audio/coreaudio.c
- VBoxDD_SOURCES.darwin += \
- Serial/DrvHostSerial.cpp
+ VBoxDD_SOURCES.darwin += Serial/DrvHostSerial.cpp Audio/coreaudio.c
endif # darwin
ifeq ($(KBUILD_TARGET),freebsd)
- VBoxDD_SOURCES := \
- $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \
- Audio/ossaudio.c \
- Serial/DrvHostSerial.cpp
- VBoxDD_SOURCES.freebsd += \
- Network/DrvTAP.cpp
+ VBoxDD_SOURCES += Serial/DrvHostSerial.cpp Audio/ossaudio.c
+ VBoxDD_SOURCES.freebsd += Network/DrvTAP.cpp
endif # freebsd
- VBoxDD_SOURCES.linux += \
+ VBoxDD_SOURCES.linux += \
Network/DrvTAP.cpp \
Audio/ossaudio.c \
Parallel/DrvHostParallel.cpp \
Serial/DrvHostSerial.cpp
- ifeq ($(KBUILD_TARGET),os2)
- VBoxDD_SOURCES := $(filter-out Storage/DrvHost%, $(VBoxDD_SOURCES))
- endif
-
ifeq ($(KBUILD_TARGET),solaris)
- VBoxDD_SOURCES := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))
- VBoxDD_SOURCES.solaris += \
- Audio/solaudio.c \
- Serial/DrvHostSerial.cpp
+ VBoxDD_SOURCES.solaris += Serial/DrvHostSerial.cpp Audio/solaudio.c
ifdef VBOX_WITH_SOLARIS_OSS
VBoxDD_SOURCES += Audio/ossaudio.c
VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS
@@ -662,11 +687,11 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
endif
endif
- VBoxDD_DEFS.win += VBOX_WITH_WIN_PARPORT_SUP
- VBoxDD_SOURCES.win += \
+ VBoxDD_DEFS.win += VBOX_WITH_WIN_PARPORT_SUP
+ VBoxDD_SOURCES.win += \
Audio/dsoundaudio.c \
Serial/DrvHostSerial.cpp \
- Parallel/DrvHostParallel.cpp
+ Parallel/DrvHostParallel.cpp
ifdef VBOX_WITH_VIRTUALKD
VBoxDD_DEFS.win += VBOX_WITH_VIRTUALKD
@@ -675,9 +700,9 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
endif
if defined(VBOX_WITH_NETFLT)
- VBoxDD_DEFS += VBOX_WITH_NETFLT
+ VBoxDD_DEFS += VBOX_WITH_NETFLT
if defined(VBOX_NETFLT_ONDEMAND_BIND)
- VBoxDD_DEFS.win += VBOX_NETFLT_ONDEMAND_BIND
+ VBoxDD_DEFS.win += VBOX_NETFLT_ONDEMAND_BIND
endif
endif
@@ -925,6 +950,8 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
PC/DevAPIC.cpp \
PC/DevIoApic.cpp \
PC/DevLPC.cpp
+ VBoxDD2_SOURCES.win = \
+ build/VBoxDD2.rc
VBoxDD2_LIBS = \
$(PATH_STAGE_LIB)/PcBiosBin$(VBOX_SUFF_LIB) \
$(PATH_STAGE_LIB)/VgaBiosBin$(VBOX_SUFF_LIB) \
@@ -1209,6 +1236,8 @@ if defined(VBOX_WITH_EXTPACK_PUEL) && defined(VBOX_WITH_EXTPACK_PUEL_BUILD)
DLLS += VBoxEhciR3
VBoxEhciR3_TEMPLATE = VBoxR3ExtPackPuel
VBoxEhciR3_SOURCES = USB/DevEHCI.cpp
+ VBoxEhciR3_SOURCES.win = \
+ build/VBoxEhciR3.rc
SYSMODS += VBoxEhciR0
VBoxEhciR0_TEMPLATE = VBoxR0ExtPackPuel
@@ -1223,18 +1252,20 @@ if defined(VBOX_WITH_EXTPACK_PUEL) && defined(VBOX_WITH_EXTPACK_PUEL_BUILD)
if defined(VBOX_WITH_PCI_PASSTHROUGH)
DLLS += VBoxPciRawR3
- VBoxPciRawR3_TEMPLATE = VBoxR3ExtPackPuel
- VBoxPciRawR3_SOURCES = Bus/DevPciRaw.cpp
+ VBoxPciRawR3_TEMPLATE = VBoxR3ExtPackPuel
+ VBoxPciRawR3_SOURCES = Bus/DevPciRaw.cpp
+ VBoxPciRawR3_SOURCES.win = build/VBoxPciRawR3.rc
DLLS += VBoxPciRawDrv
- VBoxPciRawDrv_TEMPLATE = VBoxR3ExtPackPuel
- VBoxPciRawDrv_SOURCES = Bus/DrvPciRaw.cpp
+ VBoxPciRawDrv_TEMPLATE = VBoxR3ExtPackPuel
+ VBoxPciRawDrv_SOURCES = Bus/DrvPciRaw.cpp
+ VBoxPciRawDrv_SOURCES.win = build/VBoxPciRawDrv.rc
SYSMODS += VBoxPciRawR0
- VBoxPciRawR0_TEMPLATE = VBoxR0ExtPackPuel
- VBoxPciRawR0_SOURCES = Bus/DevPciRaw.cpp
+ VBoxPciRawR0_TEMPLATE = VBoxR0ExtPackPuel
+ VBoxPciRawR0_SOURCES = Bus/DevPciRaw.cpp
- Bus/DevPciRaw.cpp_INCS = Bus
+ Bus/DevPciRaw.cpp_INCS = Bus
endif
@@ -1251,16 +1282,14 @@ if defined(VBOX_WITH_VMSVGA3D) && !defined(VBOX_ONLY_EXTPACKS)
#
# Template used for VBoxSVGA3D. (Stips away compiler options.)
#
- TEMPLATE_VBoxSVGA3D = VBoxSVGA3D
- TEMPLATE_VBoxSVGA3D_EXTENDS = VBOXR3
- TEMPLATE_VBoxSVGA3D_CFLAGS = \
- $(filter-out -pedantic -fno-common -Wstrict-prototypes,$(TEMPLATE_VBOXR3_CFLAGS))
- TEMPLATE_VBoxSVGA3D_CXXFLAG = \
- $(filter-out -pedantic -fno-common,$(TEMPLATE_VBOXR3_CXXFLAGS))
- TEMPLATE_VBoxSVGA3D_CFLAGS.darwin = \
- $(filter-out -fno-common,$(TEMPLATE_VBOXR3_CFLAGS.darwin))
- TEMPLATE_VBoxSVGA3D_LDFLAGS.darwin = \
- -framework AppKit -framework OpenGL
+ TEMPLATE_VBoxSVGA3D := VBoxSVGA3D
+ TEMPLATE_VBoxSVGA3D_EXTENDS := $(if-expr "$(KBUILD_TARGET)" == "darwin",VBoxR3DllOsX107,VBOXR3)
+ TEMPLATE_VBoxSVGA3D_CFLAGS = $(filter-out -pedantic -Wstrict-prototypes,$(TEMPLATE_$(TEMPLATE_VBoxSVGA3D_EXTENDS)_CFLAGS))
+ TEMPLATE_VBoxSVGA3D_CXXFLAGS = $(filter-out -pedantic,$(TEMPLATE_$(TEMPLATE_VBoxSVGA3D_EXTENDS)_CXXFLAGS))
+ TEMPLATE_VBoxSVGA3D_OBJCFLAGS = $(filter-out -pedantic,$(TEMPLATE_$(TEMPLATE_VBoxSVGA3D_EXTENDS)_OBJCFLAGS))
+ TEMPLATE_VBoxSVGA3D_OBJCXXFLAGS = $(filter-out -pedantic,$(TEMPLATE_$(TEMPLATE_VBoxSVGA3D_EXTENDS)_OBJCXXFLAGS))
+ TEMPLATE_VBoxSVGA3D_LDFLAGS.darwin = $(TEMPLATE_VBoxR3DllOsX107_LDFLAGS.darwin) \
+ -framework AppKit -framework OpenGL -framework IOKit
#
# The shader library used by the SVGA3D implementation.
@@ -1286,6 +1315,7 @@ if defined(VBOX_WITH_VMSVGA3D) && !defined(VBOX_ONLY_EXTPACKS)
VBOX_USING_WINDDK_W7_OR_LATER \
VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT \
IN_vmsvgashader_STATIC \
+ IN_VMSVGA3D \
VBOX_WINE_WITH_IPRT
if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
VBoxSVGA3D_DEFS += WINE_NO_DEBUG_MSGS
@@ -1295,19 +1325,24 @@ if defined(VBOX_WITH_VMSVGA3D) && !defined(VBOX_ONLY_EXTPACKS)
VBoxSVGA3D_DEFS.win += \
USE_WIN32_OPENGL \
VBOX_WINE_WITHOUT_LIBWINE
+ VBoxSVGA3D_DEFS.darwin += VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE
+ if 0 # Use the OpenGL 3.2 Core profile (VBoxSVGA3D_DEFS.darwin).
+ VBoxSVGA3D_DEFS.darwin += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=3.2 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=2.1
+ else
+ VBoxSVGA3D_DEFS.darwin += VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE=2.1 VBOX_VMSVGA3D_OTHER_OGL_PROFILE=3.2
+ endif
+
# WINE relies on a gcc 4.4 feature but we have 4.2 on Darwin
VBoxSVGA3D_DEFS.darwin += \
__builtin_ms_va_list=va_list \
__stdcall= \
ms_abi=
- # WTF IS THIS? -fno-pic?? doubt it.
- VBoxSVGA3D_CFLAGS = \
- $(filter-out -pedantic -Wattributes,$(VBoxR3DllWarnNoPic_CFLAGS))
VBoxSVGA3D_INCS.win := \
Graphics/shaderlib/libWineStub/include
VBoxSVGA3D_INCS.linux := \
Graphics/shaderlib/wine/include
VBoxSVGA3D_INCS.darwin := \
+ Graphics/ \
Graphics/shaderlib/wine/include
VBoxSVGA3D_SOURCES := \
Graphics/shaderlib/glsl_shader.c \
@@ -1319,17 +1354,48 @@ if defined(VBOX_WITH_VMSVGA3D) && !defined(VBOX_ONLY_EXTPACKS)
Graphics/shaderlib/stateblock.c \
Graphics/shaderlib/directx.c \
Graphics/shaderlib/libWineStub/debug.c
- VBoxSVGA3D_SOURCES.darwin += \
- Graphics/DevVGA-SVGA3d-cocoa.m
- VBoxSVGA3D_LIBS = \
- $(LIB_RUNTIME)
- VBoxSVGA3D_LIBS.win += $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Opengl32.lib
+ VBoxSVGA3D_SOURCES.win := \
+ Graphics/VBoxSVGA3D.rc
+ VBoxSVGA3D_LIBS = $(LIB_RUNTIME)
+ VBoxSVGA3D_LIBS.win += $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/Opengl32.lib
if1of ($(KBUILD_TARGET), solaris linux freebsd)
- VBoxSVGA3D_LIBS += GL
+ VBoxSVGA3D_LIBS += GL
endif
VBoxSVGA3D_LDFLAGS.darwin += \
-install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxSVGA3D.dylib
+ #
+ # The Objective C code needs to be separate since the shaderlib redefines most
+ # GL functions as pointers, making it impossible to mix with code calling OpenGL
+ # functions directly. This module must be compiled for 10.7 or later, thus it
+ # needs to be separate from VBoxDD.dylib, or at least that's our belief...
+ #
+ DLLS.darwin += VBoxSVGA3DObjC
+ VBoxSVGA3DObjC_TEMPLATE = VBoxSVGA3D
+ VBoxSVGA3DObjC_DEFS = $(VBoxSVGA3D_DEFS)
+ VBoxSVGA3DObjC_DEFS.x86 = __i386__
+ VBoxSVGA3DObjC_DEFS.amd64 = __x86_64__
+ VBoxSVGA3DObjC_DEFS.darwin = $(VBoxSVGA3D_DEFS.darwin)
+ VBoxSVGA3DObjC_INCS = $(VBoxSVGA3D_INCS)
+ VBoxSVGA3DObjC_INCS.darwin = $(VBoxSVGA3D_INCS.darwin)
+ VBoxSVGA3DObjC_LIBS = $(LIB_RUNTIME)
+ VBoxSVGA3DObjC_LDFLAGS.darwin = \
+ -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxSVGA3DObjC.dylib \
+ -framework OpenGL
+ if 0
+ VBoxSVGA3DObjC_SOURCES.darwin += \
+ Graphics/DevVGA-SVGA3d-cocoa.m
+ else
+ VBoxSVGA3DObjC_SOURCES.darwin += \
+ ../HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m \
+ ../GuestHost/OpenGL/util/vreg.cpp \
+ ../GuestHost/OpenGL/util/blitter.cpp \
+ ../GuestHost/OpenGL/util/compositor.cpp \
+ ../HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp
+ endif
+
+
+
endif # defined(VBOX_WITH_VMSVGA3D) && !defined(VBOX_ONLY_EXTPACKS)
include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/Devices/Network/DrvNAT.cpp b/src/VBox/Devices/Network/DrvNAT.cpp
index 0980633..9aa54d2 100644
--- a/src/VBox/Devices/Network/DrvNAT.cpp
+++ b/src/VBox/Devices/Network/DrvNAT.cpp
@@ -81,7 +81,7 @@ extern "C" {
do { \
(rc) = CFGMR3Query ## type((node), name, &(var)); \
if (RT_FAILURE((rc)) && (rc) != VERR_CFGM_VALUE_NOT_FOUND) \
- return PDMDrvHlpVMSetError((pthis)->pDrvIns, (rc), RT_SRC_POS, N_("NAT#%d: configuration query for \""name"\" " #type_name " failed"), \
+ return PDMDrvHlpVMSetError((pthis)->pDrvIns, (rc), RT_SRC_POS, N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
(pthis)->pDrvIns->iInstance); \
} while (0)
@@ -89,7 +89,7 @@ do {
do { \
(rc) = CFGMR3Query ## type((node), name, &(var)); \
if (RT_FAILURE((rc))) \
- return PDMDrvHlpVMSetError((pthis)->pDrvIns, (rc), RT_SRC_POS, N_("NAT#%d: configuration query for \""name"\" " #type_name " failed"), \
+ return PDMDrvHlpVMSetError((pthis)->pDrvIns, (rc), RT_SRC_POS, N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
(pthis)->pDrvIns->iInstance); \
} while (0)
@@ -97,7 +97,7 @@ do {
do { \
(rc) = CFGMR3Query ## type((node), name, &(var), var_size); \
if (RT_FAILURE((rc)) && (rc) != VERR_CFGM_VALUE_NOT_FOUND) \
- return PDMDrvHlpVMSetError((pthis)->pDrvIns, (rc), RT_SRC_POS, N_("NAT#%d: configuration query for \""name"\" " #type_name " failed"), \
+ return PDMDrvHlpVMSetError((pthis)->pDrvIns, (rc), RT_SRC_POS, N_("NAT#%d: configuration query for \"" name "\" " #type_name " failed"), \
(pthis)->pDrvIns->iInstance); \
} while (0)
@@ -175,6 +175,9 @@ typedef struct DRVNAT
RTPIPE hPipeWrite;
/** The read end of the control pipe. */
RTPIPE hPipeRead;
+# if HC_ARCH_BITS == 32
+ uint32_t u32Padding;
+# endif
#else
/** for external notification */
HANDLE hWakeupEvent;
@@ -220,9 +223,7 @@ typedef DRVNAT *PDRVNAT;
* Internal Functions *
*******************************************************************************/
static void drvNATNotifyNATThread(PDRVNAT pThis, const char *pszWho);
-DECLINLINE(void) drvNATHostNetworkConfigurationChangeEventStrategySelector(
- PDRVNAT pThis,
- bool fHostNetworkConfigurationEventListener);
+DECLINLINE(void) drvNATUpdateDNS(PDRVNAT pThis, bool fFlapLink);
static DECLCALLBACK(int) drvNATReinitializeHostNameResolving(PDRVNAT pThis);
@@ -834,9 +835,9 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
slirp_select_fill(pThis->pNATState, &nFDs);
DWORD dwEvent = WSAWaitForMultipleEvents(nFDs, phEvents, FALSE,
slirp_get_timeout_ms(pThis->pNATState),
- FALSE);
+ /* :fAlertable */ TRUE);
if ( (dwEvent < WSA_WAIT_EVENT_0 || dwEvent > WSA_WAIT_EVENT_0 + nFDs - 1)
- && dwEvent != WSA_WAIT_TIMEOUT)
+ && dwEvent != WSA_WAIT_TIMEOUT && dwEvent != WSA_WAIT_IO_COMPLETION)
{
int error = WSAGetLastError();
LogRel(("NAT: WSAWaitForMultipleEvents returned %d (error %d)\n", dwEvent, error));
@@ -846,12 +847,12 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr
if (dwEvent == WSA_WAIT_TIMEOUT)
{
/* only check for slow/fast timers */
- slirp_select_poll(pThis->pNATState, /* fTimeout=*/true, /*fIcmp=*/false);
+ slirp_select_poll(pThis->pNATState, /* fTimeout=*/true);
continue;
}
/* poll the sockets in any case */
Log2(("%s: poll\n", __FUNCTION__));
- slirp_select_poll(pThis->pNATState, /* fTimeout=*/false, /* fIcmp=*/(dwEvent == WSA_WAIT_EVENT_0));
+ slirp_select_poll(pThis->pNATState, /* fTimeout=*/false);
/* process _all_ outstanding requests but don't wait */
RTReqQueueProcess(pThis->hSlirpReqQueue, 0);
# ifdef VBOX_NAT_DELAY_HACK
@@ -938,8 +939,8 @@ void slirp_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf, int cb)
PDRVNAT pThis = (PDRVNAT)pvUser;
Assert(pThis);
- LogFlow(("slirp_output BEGIN %x %d\n", pu8Buf, cb));
- Log2(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n%.*Rhxd\n", pu8Buf, cb, pThis, cb, pu8Buf));
+ LogFlow(("slirp_output BEGIN %p %d\n", pu8Buf, cb));
+ Log6(("slirp_output: pu8Buf=%p cb=%#x (pThis=%p)\n%.*Rhxd\n", pu8Buf, cb, pThis, cb, pu8Buf));
PRTREQ pReq = NULL;
@@ -957,6 +958,20 @@ void slirp_output(void *pvUser, struct mbuf *m, const uint8_t *pu8Buf, int cb)
}
+/**
+ * @interface_method_impl{PDMINETWORKNATCONFIG,pfnNotifyDnsChanged}
+ *
+ * We are notified that host's resolver configuration has changed. In
+ * the current setup we don't get any details and just reread that
+ * information ourselves.
+ */
+static DECLCALLBACK(void) drvNATNotifyDnsChanged(PPDMINETWORKNATCONFIG pInterface)
+{
+ PDRVNAT pThis = RT_FROM_MEMBER(pInterface, DRVNAT, INetworkNATCfg);
+ drvNATUpdateDNS(pThis, /* fFlapLink */ true);
+}
+
+
#ifdef RT_OS_DARWIN
/**
* Callback for the SystemConfiguration framework to notify us whenever the DNS
@@ -1006,7 +1021,7 @@ static DECLCALLBACK(void) drvNatDnsChanged(SCDynamicStoreRef hDynStor, CFArrayRe
else
LogRel(("NAT: DNS server list is empty (2)\n"));
#endif
- drvNATHostNetworkConfigurationChangeEventStrategySelector(pThis, /* RT_OS_DARWIN */ true);
+ drvNATUpdateDNS(pThis, /* fFlapLink */ true);
}
else
Log2(("NAT: No DNS changes detected\n"));
@@ -1082,11 +1097,15 @@ static DECLCALLBACK(void) drvNATResume(PPDMDRVINS pDrvIns)
switch (enmReason)
{
case VMRESUMEREASON_HOST_RESUME:
-#if RT_OS_DARWIN
- drvNATHostNetworkConfigurationChangeEventStrategySelector(pThis, false);
+ bool fFlapLink;
+#if HAVE_NOTIFICATION_FOR_DNS_UPDATE
+ /* let event handler do it if necessary */
+ fFlapLink = false;
#else
- drvNATHostNetworkConfigurationChangeEventStrategySelector(pThis, true);
+ /* XXX: when in doubt, use brute force */
+ fFlapLink = true;
#endif
+ drvNATUpdateDNS(pThis, fFlapLink);
return;
default: /* Ignore every other resume reason. */
/* do nothing */
@@ -1107,51 +1126,55 @@ static DECLCALLBACK(int) drvNATReinitializeHostNameResolving(PDRVNAT pThis)
* - drvNATResume (EMT?)
* - drvNatDnsChanged (darwin, GUI or main) "listener"
* When Main's interface IHost will support host network configuration change event on every host,
- * we won't call it from drvNATResume, but from listener of Main event in the similar way it done
+ * we won't call it from drvNATResume, but from listener of Main event in the similar way it done
* for port-forwarding, and it wan't be on GUI/main thread, but on EMT thread only.
*
- * Thread here is important, because we need to change DNS server list and domain name (+ perhaps,
+ * Thread here is important, because we need to change DNS server list and domain name (+ perhaps,
* search string) at runtime (VBOX_NAT_ENFORCE_INTERNAL_DNS_UPDATE), we can do it safely on NAT thread,
- * so with changing other variables (place where we handle update) the main mechanism of update
- * _won't_ be changed, the only thing will change is drop of fHostNetworkConfigurationEventListener parameter.
+ * so with changing other variables (place where we handle update) the main mechanism of update
+ * _won't_ be changed, the only thing will change is drop of fFlapLink parameter.
*/
-DECLINLINE(void) drvNATHostNetworkConfigurationChangeEventStrategySelector(PDRVNAT pThis,
- bool fHostNetworkConfigurationEventListener)
+DECLINLINE(void) drvNATUpdateDNS(PDRVNAT pThis, bool fFlapLink)
{
int strategy = slirp_host_network_configuration_change_strategy_selector(pThis->pNATState);
switch (strategy)
{
-
- case VBOX_NAT_HNCE_DNSPROXY:
+
+ case VBOX_NAT_DNS_DNSPROXY:
{
/**
+ * XXX: Here or in _strategy_selector we should deal with network change
+ * in "network change" scenario domain name change we have to update guest lease
+ * forcibly.
+ * Note at that built-in dhcp also updates DNS information on NAT thread.
+ */
+ /**
* It's unsafe to to do it directly on non-NAT thread
- * so we schedule the worker and kick the NAT thread.
+ * so we schedule the worker and kick the NAT thread.
*/
RTREQQUEUE hQueue = pThis->hSlirpReqQueue;
-
- int rc = RTReqQueueCallEx(hQueue, NULL /*ppReq*/, 0 /*cMillies*/,
+
+ int rc = RTReqQueueCallEx(hQueue, NULL /*ppReq*/, 0 /*cMillies*/,
RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT,
(PFNRT)drvNATReinitializeHostNameResolving, 1, pThis);
if (RT_SUCCESS(rc))
- drvNATNotifyNATThread(pThis, "drvNATNetworkUp_SendBuf");
-
+ drvNATNotifyNATThread(pThis, "drvNATUpdateDNS");
return;
-
}
- case VBOX_NAT_HNCE_EXSPOSED_NAME_RESOLUTION_INFO:
- case VBOX_NAT_HNCE_HOSTRESOLVER_TEMPORARY:
+
+ case VBOX_NAT_DNS_EXTERNAL:
/*
* Host resumed from a suspend and the network might have changed.
* Disconnect the guest from the network temporarily to let it pick up the changes.
*/
- if (fHostNetworkConfigurationEventListener)
+ if (fFlapLink)
pThis->pIAboveConfig->pfnSetLinkState(pThis->pIAboveConfig,
PDMNETWORKLINKSTATE_DOWN_RESUME);
return;
- case VBOX_NAT_HNCE_HOSTRESOLVER:
+
+ case VBOX_NAT_DNS_HOSTRESOLVER:
default:
return;
}
@@ -1395,6 +1418,18 @@ static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
/* NAT engine configuration */
pThis->INetworkNATCfg.pfnRedirectRuleCommand = drvNATNetworkNatConfig_RedirectRuleCommand;
+#if HAVE_NOTIFICATION_FOR_DNS_UPDATE && !defined(RT_OS_DARWIN)
+ /*
+ * On OS X we stick to the old OS X specific notifications for
+ * now. Elsewhere use IHostNameResolutionConfigurationChangeEvent
+ * by enbaling HAVE_NOTIFICATION_FOR_DNS_UPDATE in libslirp.h.
+ * This code is still in a bit of flux and is implemented and
+ * enabled in steps to simplify more conservative backporting.
+ */
+ pThis->INetworkNATCfg.pfnNotifyDnsChanged = drvNATNotifyDnsChanged;
+#else
+ pThis->INetworkNATCfg.pfnNotifyDnsChanged = NULL;
+#endif
/*
* Validate the config.
diff --git a/src/VBox/Devices/Network/SrvIntNetR0.cpp b/src/VBox/Devices/Network/SrvIntNetR0.cpp
index 42e4ef9..ceb6fa0 100644
--- a/src/VBox/Devices/Network/SrvIntNetR0.cpp
+++ b/src/VBox/Devices/Network/SrvIntNetR0.cpp
@@ -1581,10 +1581,6 @@ static INTNETSWDECISION intnetR0NetworkPreSwitchUnicast(PINTNETNETWORK pNetwork,
if (intnetR0IsMacAddrDummy(&pTab->paEntries[iIfMac].MacAddr))
break;
- /* Promiscuous mode? */
- if (pTab->paEntries[iIfMac].fPromiscuousSeeTrunk)
- break;
-
/* Paranoia - this shouldn't happen, right? */
if ( pSrcAddr
&& intnetR0AreMacAddrsEqual(&pTab->paEntries[iIfMac].MacAddr, pSrcAddr))
@@ -5086,7 +5082,8 @@ static DECLCALLBACK(INTNETSWDECISION) intnetR0TrunkIfPortPreRecv(PINTNETTRUNKSWP
PCRTNETETHERHDR pEthHdr = (PCRTNETETHERHDR)pvSrc;
if (intnetR0IsMacAddrMulticast(&pEthHdr->DstMac))
enmSwDecision = INTNETSWDECISION_BROADCAST;
- else if (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE)
+ else if ( fSrc == INTNETTRUNKDIR_WIRE
+ && (pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE))
enmSwDecision = INTNETSWDECISION_BROADCAST;
else
enmSwDecision = intnetR0NetworkPreSwitchUnicast(pNetwork,
diff --git a/src/VBox/Devices/Network/slirp/bootp.c b/src/VBox/Devices/Network/slirp/bootp.c
index 2234965..64c3c2c 100644
--- a/src/VBox/Devices/Network/slirp/bootp.c
+++ b/src/VBox/Devices/Network/slirp/bootp.c
@@ -41,6 +41,7 @@
* THE SOFTWARE.
*/
#include <slirp.h>
+#include <libslirp.h>
/** Entry in the table of known DHCP clients. */
typedef struct
@@ -304,14 +305,11 @@ static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, i
uint32_t addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_DNS);
FILL_BOOTP_EXT(q, RFC1533_DNS, 4, &addr);
}
- else
+ else if (!TAILQ_EMPTY(&pData->pDnsList))
{
- if (!TAILQ_EMPTY(&pData->pDnsList))
- {
- de = TAILQ_LAST(&pData->pDnsList, dns_list_head);
- q_dns_header = q;
- FILL_BOOTP_EXT(q, RFC1533_DNS, 4, &de->de_addr.s_addr);
- }
+ de = TAILQ_LAST(&pData->pDnsList, dns_list_head);
+ q_dns_header = q;
+ FILL_BOOTP_EXT(q, RFC1533_DNS, 4, &de->de_addr.s_addr);
TAILQ_FOREACH_REVERSE(de, &pData->pDnsList, dns_list_head, de_list)
{
@@ -320,6 +318,7 @@ static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, i
FILL_BOOTP_APP(q_dns_header, q, RFC1533_DNS, 4, &de->de_addr.s_addr);
}
}
+
if (pData->fPassDomain && !pData->fUseHostResolver)
{
LIST_FOREACH(dd, &pData->pDomainList, dd_list)
@@ -702,14 +701,25 @@ static void dhcp_decode(PNATState pData, struct bootp_t *bp, const uint8_t *buf,
Assert(pu8RawDhcpObject);
if (!pu8RawDhcpObject)
return;
- /*
+ /**
* We're going update dns list at least once per DHCP transaction (!not on every operation
* within transaction), assuming that transaction can't be longer than 1 min.
+ *
+ * @note: if we have notification update (HAVE_NOTIFICATION_FOR_DNS_UPDATE)
+ * provided by host, we don't need implicitly re-initialize dns list.
+ *
+ * @note: NATState::fUseHostResolver became (r89055) the flag signalling that Slirp
+ * wasn't able to fetch fresh host DNS info and fall down to use host-resolver, on one
+ * of the previous attempts to proxy dns requests to Host's name-resolving API
+ *
+ * @note: Checking NATState::fUseHostResolver == true, we want to try restore behaviour initialy
+ * wanted by user ASAP (P here when host serialize its configuration in files parsed by Slirp).
*/
- if ( !pData->fUseHostResolverPermanent
+ if ( !HAVE_NOTIFICATION_FOR_DNS_UPDATE
+ && !pData->fUseHostResolverPermanent
&& ( pData->dnsLastUpdate == 0
- || curtime - pData->dnsLastUpdate > 60 * 1000
- || pData->fUseHostResolver)) /* one minute*/
+ || curtime - pData->dnsLastUpdate > 60 * 1000 /* one minute */
+ || pData->fUseHostResolver))
{
uint8_t i = 2; /* i = 0 - tag, i == 1 - length */
parameter_list = dhcp_find_option(&bp->bp_vend[0], RFC2132_PARAM_LIST);
@@ -717,6 +727,7 @@ static void dhcp_decode(PNATState pData, struct bootp_t *bp, const uint8_t *buf,
{
if (parameter_list[i] == RFC1533_DNS)
{
+ /* XXX: How differs it from host Suspend/Resume? */
slirpReleaseDnsSettings(pData);
slirpInitializeDnsSettings(pData);
pData->dnsLastUpdate = curtime;
diff --git a/src/VBox/Devices/Network/slirp/bsd/kern/uipc_mbuf.c b/src/VBox/Devices/Network/slirp/bsd/kern/uipc_mbuf.c
index 5e5e90d..ee968bf 100644
--- a/src/VBox/Devices/Network/slirp/bsd/kern/uipc_mbuf.c
+++ b/src/VBox/Devices/Network/slirp/bsd/kern/uipc_mbuf.c
@@ -1100,7 +1100,7 @@ m_adj(PNATState pData, struct mbuf *mp, int req_len)
break;
m = m->m_next;
}
- if (m->m_len >= len) {
+ if (m->m_len > len || (m->m_len == len && m == mp)) {
m->m_len -= len;
if (mp->m_flags & M_PKTHDR)
mp->m_pkthdr.len -= len;
diff --git a/src/VBox/Devices/Network/slirp/debug.c b/src/VBox/Devices/Network/slirp/debug.c
index 22284b7..fd77c97 100644
--- a/src/VBox/Devices/Network/slirp/debug.c
+++ b/src/VBox/Devices/Network/slirp/debug.c
@@ -283,17 +283,16 @@ printSocket(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
void *pvUser)
{
struct socket *so = (struct socket*)pvValue;
- struct sockaddr addr;
- struct sockaddr_in *in_addr;
- socklen_t socklen = sizeof(struct sockaddr);
PNATState pData = (PNATState)pvUser;
- int status = 0;
+ size_t cb = 0;
+
NOREF(cchWidth);
NOREF(cchPrecision);
NOREF(fFlags);
Assert(pData);
AssertReturn(strcmp(pszType, "natsock") == 0, 0);
+
if (so == NULL)
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
"socket is null");
@@ -301,21 +300,13 @@ printSocket(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
"socket(%d)", so->s);
- status = getsockname(so->s, &addr, &socklen);
- if(status != 0 || addr.sa_family != AF_INET)
- {
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
- "socket(%d) is invalid(%s)", so->s, strerror(errno));
- }
-
- in_addr = (struct sockaddr_in *)&addr;
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "socket %d:(proto:%u) exp. in %d "
- "state=%R[natsockstate] "
- "fUnderPolling:%RTbool "
- "fShouldBeRemoved:%RTbool "
- "f_(addr:port)=%RTnaipv4:%d "
- "l_(addr:port)=%RTnaipv4:%d "
- "name=%RTnaipv4:%d",
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "socket %d:(proto:%u) exp. in %d "
+ " state=%R[natsockstate]"
+ " fUnderPolling:%RTbool"
+ " fShouldBeRemoved:%RTbool"
+ " f_(addr:port)=%RTnaipv4:%d"
+ " l_(addr:port)=%RTnaipv4:%d",
so->s, so->so_type,
so->so_expire ? so->so_expire - curtime : 0,
so->so_state,
@@ -324,9 +315,38 @@ printSocket(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
so->so_faddr.s_addr,
RT_N2H_U16(so->so_fport),
so->so_laddr.s_addr,
- RT_N2H_U16(so->so_lport),
- in_addr->sin_addr.s_addr,
- RT_N2H_U16(in_addr->sin_port));
+ RT_N2H_U16(so->so_lport));
+
+ if (so->s != -1)
+ {
+ struct sockaddr addr;
+ socklen_t socklen;
+ int status;
+
+ socklen = sizeof(addr);
+ status = getsockname(so->s, &addr, &socklen);
+
+ if (status != 0)
+ {
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ " (getsockname failed)");
+ }
+ else if (addr.sa_family != AF_INET)
+ {
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ " (unexpected address family %d)",
+ addr.sa_family);
+ }
+ else
+ {
+ struct sockaddr_in *in_addr = (struct sockaddr_in *)&addr;
+ cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ " name=%RTnaipv4:%d",
+ in_addr->sin_addr.s_addr,
+ RT_N2H_U16(in_addr->sin_port));
+ }
+ }
+ return cb;
}
static DECLCALLBACK(size_t)
diff --git a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c
index 02351aa..e3dc28e 100644
--- a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c
+++ b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.c
@@ -120,9 +120,16 @@ timeout(PNATState pData, struct socket *so, void *arg)
/* be paranoid */
AssertPtrReturnVoid(arg);
- if ( req->dns_server == NULL
+ if ( req->dnsgen != pData->dnsgen
+ || req->dns_server == NULL
|| (de = TAILQ_PREV(req->dns_server, dns_list_head, de_list)) == NULL)
{
+ if (req->dnsgen != pData->dnsgen)
+ {
+ /* XXX: Log2 */
+ LogRel(("NAT: dnsproxy: timeout: req %p dnsgen %u != %u on %R[natsock]\n",
+ req, req->dnsgen, pData->dnsgen, so));
+ }
hash_remove_request(pData, req);
RTMemFree(req);
++removed_queries;
@@ -337,7 +344,6 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
return;
}
-
req = so->so_timeout_arg;
if (!req)
@@ -356,17 +362,11 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
memcpy(&req->client, &fromaddr, sizeof(struct sockaddr_in));
memcpy(&req->clientid, &buf[0], 2);
req->dns_server = TAILQ_LAST(&pData->pDnsList, dns_list_head);
+ req->dnsgen = pData->dnsgen;
if (req->dns_server == NULL)
{
- static int fail_counter = 0;
RTMemFree(req);
- /** @todo: This is completely bogus, fail_counter will always be 0. */
- if (fail_counter == 0)
- LogRel(("NAT/dnsproxy: Empty DNS entry (suppressed 100 times)\n"));
- else
- fail_counter = (fail_counter == 100 ? 0 : fail_counter + 1);
return;
-
}
retransmit = 0;
so->so_timeout = timeout;
@@ -376,7 +376,20 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
}
else
{
- retransmit = 1;
+ if (req->dnsgen != pData->dnsgen)
+ {
+ /* XXX: Log2 */
+ LogRel(("NAT: dnsproxy: query: req %p dnsgen %u != %u on %R[natsock]\n",
+ req, req->dnsgen, pData->dnsgen, so));
+ /*
+ * XXX: TODO: this probably requires more cleanup.
+ * Cf. XXX comment for sendto() failure below, but that
+ * error leg is probably untested since ~never taken.
+ */
+ ++dropped_queries;
+ return;
+ }
+ retransmit = 1;
}
req->recursion = 0;
@@ -405,7 +418,8 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
addr.sin_port = htons(53);
/* send it to our authoritative server */
- Log2(("NAT: request will be sent to %RTnaipv4 on %R[natsock]\n", addr.sin_addr, so));
+ Log2(("NAT: request will be %ssent to %RTnaipv4 on %R[natsock]\n",
+ retransmit ? "re" : "", addr.sin_addr, so));
byte = sendto(so->s, buf, (unsigned int)byte, 0,
(struct sockaddr *)&addr,
@@ -419,7 +433,8 @@ dnsproxy_query(PNATState pData, struct socket *so, struct mbuf *m, int iphlen)
}
so->so_state = SS_ISFCONNECTED; /* now it's selected */
- Log2(("NAT: request was sent to %RTnaipv4 on %R[natsock]\n", addr.sin_addr, so));
+ Log2(("NAT: request was %ssent to %RTnaipv4 on %R[natsock]\n",
+ retransmit ? "re" : "", addr.sin_addr, so));
++authoritative_queries;
diff --git a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h
index 9d9df85..584f25d 100644
--- a/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h
+++ b/src/VBox/Devices/Network/slirp/dnsproxy/dnsproxy.h
@@ -81,8 +81,13 @@ struct request {
* to connect server, timeout function should change
* it's value on next server. And dnsproxy_query should
* initializate with first server in the list
+ *
+ * dnsgen is a generation number - a copy of pData->dnsgen at the
+ * time of request creation (poor man's weak reference).
+ * dns_server must not be used if pData->dnsgen changed.
*/
struct dns_entry *dns_server;
+ uint32_t dnsgen;
int nbyte; /* length of dns request */
char byte[1]; /* copy of original request */
#endif
diff --git a/src/VBox/Devices/Network/slirp/ip_icmp.c b/src/VBox/Devices/Network/slirp/ip_icmp.c
index be72a00..f73b226 100644
--- a/src/VBox/Devices/Network/slirp/ip_icmp.c
+++ b/src/VBox/Devices/Network/slirp/ip_icmp.c
@@ -55,12 +55,12 @@
#include "slirp.h"
#include "ip_icmp.h"
-#ifdef RT_OS_WINDOWS
-# include <Icmpapi.h>
-# include <Iphlpapi.h>
-# include <iprt/ldr.h>
+
+#ifdef VBOX_RAWSOCK_DEBUG_HELPER
+int getrawsock(int type);
#endif
+
/* The message sent when emulating PING */
/* Be nice and tell them it's just a psuedo-ping packet */
static const char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n";
@@ -96,13 +96,14 @@ icmp_init(PNATState pData, int iIcmpCacheLimit)
{
pData->icmp_socket.so_type = IPPROTO_ICMP;
pData->icmp_socket.so_state = SS_ISFCONNECTED;
+
+#ifndef RT_OS_WINDOWS
if (iIcmpCacheLimit < 0)
{
LogRel(("NAT: iIcmpCacheLimit is invalid %d, will be alter to default value 100\n", iIcmpCacheLimit));
iIcmpCacheLimit = 100;
}
pData->iIcmpCacheLimit = iIcmpCacheLimit;
-#ifndef RT_OS_WINDOWS
# ifndef RT_OS_DARWIN
pData->icmp_socket.s = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
# else /* !RT_OS_DARWIN */
@@ -111,58 +112,30 @@ icmp_init(PNATState pData, int iIcmpCacheLimit)
if (pData->icmp_socket.s == -1)
{
int rc = RTErrConvertFromErrno(errno);
+# if defined(RT_OS_DARWIN) || !defined(VBOX_RAWSOCK_DEBUG_HELPER)
LogRel(("NAT: ICMP/ping not available (could not open ICMP socket, error %Rrc)\n", rc));
return 1;
+# else
+ /* try to get it from privileged helper */
+ LogRel(("NAT: ICMP/ping raw socket error %Rrc, asking helper...\n", rc));
+ pData->icmp_socket.s = getrawsock(AF_INET);
+ if (pData->icmp_socket.s == -1)
+ {
+ LogRel(("NAT: ICMP/ping not available\n"));
+ return 1;
+ }
+# endif /* !RT_OS_DARWIN && VBOX_RAWSOCK_DEBUG_HELPER */
}
fd_nonblock(pData->icmp_socket.s);
NSOCK_INC();
-#else /* RT_OS_WINDOWS */
- /* Resolve symbols we need. */
- {
- RTLDRMOD hLdrMod;
- int rc = RTLdrLoadSystem("Iphlpapi.dll", true /*fNoUnload*/, &hLdrMod);
- if (RT_SUCCESS(rc))
- {
- pData->pfIcmpParseReplies = (long (WINAPI *)(void *, long))RTLdrGetFunction(hLdrMod, "IcmpParseReplies");
- pData->pfIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))RTLdrGetFunction(hLdrMod, "IcmpCloseHandle");
- rc = RTLdrGetSymbol(hLdrMod, "GetAdaptersAddresses", (void **)&pData->pfGetAdaptersAddresses);
- if (RT_FAILURE(rc))
- LogRel(("NAT: Can't find GetAdapterAddresses in Iphlpapi.dll\n"));
- RTLdrClose(hLdrMod);
- }
+ LIST_INIT(&pData->icmp_msg_head);
- if (pData->pfIcmpParseReplies == NULL)
- {
- int rc = RTLdrLoadSystem("Icmp.dll", true /*fNoUnload*/, &hLdrMod);
- if (RT_FAILURE(rc))
- {
- LogRel(("NAT: Icmp.dll could not be loaded: %Rrc\n", rc));
- return 1;
- }
- pData->pfIcmpParseReplies = (long (WINAPI *)(void *, long))RTLdrGetFunction(hLdrMod, "IcmpParseReplies");
- pData->pfIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))RTLdrGetFunction(hLdrMod, "IcmpCloseHandle");
- RTLdrClose(hLdrMod);
- }
- }
- if (pData->pfIcmpParseReplies == NULL)
- {
- LogRel(("NAT: Can't find IcmpParseReplies symbol\n"));
- return 1;
- }
- if (pData->pfIcmpCloseHandle == NULL)
- {
- LogRel(("NAT: Can't find IcmpCloseHandle symbol\n"));
+#else /* RT_OS_WINDOWS */
+ if (icmpwin_init(pData) != 0)
return 1;
- }
-
- pData->icmp_socket.sh = IcmpCreateFile();
- pData->phEvents[VBOX_ICMP_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
- pData->cbIcmpBuffer = sizeof(ICMP_ECHO_REPLY) * 10;
- pData->pvIcmpBuffer = RTMemAlloc(pData->cbIcmpBuffer);
#endif /* RT_OS_WINDOWS */
- LIST_INIT(&pData->icmp_msg_head);
return 0;
}
@@ -172,15 +145,15 @@ icmp_init(PNATState pData, int iIcmpCacheLimit)
void
icmp_finit(PNATState pData)
{
- icmp_cache_clean(pData, -1);
#ifdef RT_OS_WINDOWS
- pData->pfIcmpCloseHandle(pData->icmp_socket.sh);
- RTMemFree(pData->pvIcmpBuffer);
+ icmpwin_finit(pData);
#else
+ icmp_cache_clean(pData, -1);
closesocket(pData->icmp_socket.s);
#endif
}
+#if !defined(RT_OS_WINDOWS)
/*
* ip here is ip header + 64bytes readed from ICMP packet
*/
@@ -379,6 +352,7 @@ icmp_attach(PNATState pData, struct mbuf *m)
icmp_cache_clean(pData, pData->iIcmpCacheLimit/2);
return 0;
}
+#endif /* !RT_OS_WINDOWS */
/*
* Process a received ICMP message.
@@ -386,15 +360,11 @@ icmp_attach(PNATState pData, struct mbuf *m)
void
icmp_input(PNATState pData, struct mbuf *m, int hlen)
{
- register struct icmp *icp;
- void *icp_buf = NULL;
register struct ip *ip = mtod(m, struct ip *);
int icmplen = ip->ip_len;
- int status;
+ uint8_t icmp_type;
+ void *icp_buf = NULL;
uint32_t dst;
-#if !defined(RT_OS_WINDOWS)
- int ttl;
-#endif
/* int code; */
@@ -422,19 +392,8 @@ icmp_input(PNATState pData, struct mbuf *m, int hlen)
goto end_error_free_m;
}
- if (m->m_next)
- {
- icp_buf = RTMemAlloc(icmplen);
- if (!icp_buf)
- {
- Log(("NAT: not enought memory to allocate the buffer\n"));
- goto end_error_free_m;
- }
- m_copydata(m, 0, icmplen, icp_buf);
- icp = (struct icmp *)icp_buf;
- }
- else
- icp = mtod(m, struct icmp *);
+ /* are we guaranteed to have ICMP header in first mbuf? be safe. */
+ m_copydata(m, 0, sizeof(icmp_type), (caddr_t)&icmp_type);
m->m_len += hlen;
m->m_data -= hlen;
@@ -442,29 +401,36 @@ icmp_input(PNATState pData, struct mbuf *m, int hlen)
/* icmpstat.icps_inhist[icp->icmp_type]++; */
/* code = icp->icmp_code; */
- LogFlow(("icmp_type = %d\n", icp->icmp_type));
- switch (icp->icmp_type)
+ LogFlow(("icmp_type = %d\n", icmp_type));
+ switch (icmp_type)
{
case ICMP_ECHO:
ip->ip_len += hlen; /* since ip_input subtracts this */
dst = ip->ip_dst.s_addr;
if ( CTL_CHECK(dst, CTL_ALIAS)
- || CTL_CHECK(dst, CTL_DNS)
- || CTL_CHECK(dst, CTL_TFTP))
+ || CTL_CHECK(dst, CTL_DNS)
+ || CTL_CHECK(dst, CTL_TFTP))
{
- icp->icmp_type = ICMP_ECHOREPLY;
+ uint8_t echo_reply = ICMP_ECHOREPLY;
+ m_copyback(pData, m, hlen + RT_OFFSETOF(struct icmp, icmp_type),
+ sizeof(echo_reply), (caddr_t)&echo_reply);
ip->ip_dst.s_addr = ip->ip_src.s_addr;
ip->ip_src.s_addr = dst;
icmp_reflect(pData, m);
goto done;
}
- else
+
+#ifdef RT_OS_WINDOWS
+ {
+ icmpwin_ping(pData, m, hlen);
+ break; /* free mbuf */
+ }
+#else
{
+ struct icmp *icp;
struct sockaddr_in addr;
-#ifdef RT_OS_WINDOWS
- IP_OPTION_INFORMATION ipopt;
- int error;
-#endif
+
+ /* XXX: FIXME: this is bogus, see CTL_CHECKs above */
addr.sin_family = AF_INET;
if ((ip->ip_dst.s_addr & RT_H2N_U32(pData->netmask)) == pData->special_addr.s_addr)
{
@@ -480,11 +446,28 @@ icmp_input(PNATState pData, struct mbuf *m, int hlen)
}
else
addr.sin_addr.s_addr = ip->ip_dst.s_addr;
-#ifndef RT_OS_WINDOWS
+
+ if (m->m_next)
+ {
+ icp_buf = RTMemAlloc(icmplen);
+ if (!icp_buf)
+ {
+ Log(("NAT: not enought memory to allocate the buffer\n"));
+ goto end_error_free_m;
+ }
+ m_copydata(m, hlen, icmplen, icp_buf);
+ icp = (struct icmp *)icp_buf;
+ }
+ else
+ icp = (struct icmp *)(mtod(m, char *) + hlen);
+
if (pData->icmp_socket.s != -1)
{
- ssize_t rc;
static bool fIcmpSocketErrorReported;
+ int ttl;
+ int status;
+ ssize_t rc;
+
ttl = ip->ip_ttl;
Log(("NAT/ICMP: try to set TTL(%d)\n", ttl));
status = setsockopt(pData->icmp_socket.s, IPPROTO_IP, IP_TTL,
@@ -511,54 +494,8 @@ icmp_input(PNATState pData, struct mbuf *m, int hlen)
}
icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
}
-#else /* RT_OS_WINDOWS */
- pData->icmp_socket.so_laddr.s_addr = ip->ip_src.s_addr; /* XXX: hack*/
- pData->icmp_socket.so_icmp_id = icp->icmp_id;
- pData->icmp_socket.so_icmp_seq = icp->icmp_seq;
- memset(&ipopt, 0, sizeof(IP_OPTION_INFORMATION));
- ipopt.Ttl = ip->ip_ttl;
- status = IcmpSendEcho2(pData->icmp_socket.sh /*=handle*/,
- pData->phEvents[VBOX_ICMP_EVENT_INDEX] /*=Event*/,
- NULL /*=ApcRoutine*/,
- NULL /*=ApcContext*/,
- addr.sin_addr.s_addr /*=DestinationAddress*/,
- icp->icmp_data /*=RequestData*/,
- icmplen - ICMP_MINLEN /*=RequestSize*/,
- &ipopt /*=RequestOptions*/,
- pData->pvIcmpBuffer /*=ReplyBuffer*/,
- pData->cbIcmpBuffer /*=ReplySize*/,
- 1 /*=Timeout in ms*/);
- error = GetLastError();
- if ( status != 0
- || error == ERROR_IO_PENDING)
- {
- /* no error! */
- m->m_so = &pData->icmp_socket;
- icmp_attach(pData, m);
- /* don't let m_freem at the end free atached buffer */
- goto done;
- }
- Log(("NAT: Error (%d) occurred while sending ICMP (", error));
- switch (error)
- {
- case ERROR_INVALID_PARAMETER:
- Log(("icmp_socket:%lx is invalid)\n", pData->icmp_socket.s));
- break;
- case ERROR_NOT_SUPPORTED:
- Log(("operation is unsupported)\n"));
- break;
- case ERROR_NOT_ENOUGH_MEMORY:
- Log(("OOM!!!)\n"));
- break;
- case IP_BUF_TOO_SMALL:
- Log(("Buffer too small)\n"));
- break;
- default:
- Log(("Other error!!!)\n"));
- break;
- }
-#endif /* RT_OS_WINDOWS */
- } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
+ }
+#endif /* !RT_OS_WINDOWS */
break;
case ICMP_UNREACH:
case ICMP_TIMXCEED:
diff --git a/src/VBox/Devices/Network/slirp/ip_icmp.h b/src/VBox/Devices/Network/slirp/ip_icmp.h
index eb26aed..0bec0ec 100644
--- a/src/VBox/Devices/Network/slirp/ip_icmp.h
+++ b/src/VBox/Devices/Network/slirp/ip_icmp.h
@@ -202,4 +202,12 @@ int icmp_init (PNATState , int);
void icmp_finit (PNATState );
struct icmp_msg * icmp_find_original_mbuf (PNATState , struct ip *);
+#ifdef RT_OS_WINDOWS
+/* Windows ICMP API code in ip_icmpwin.c */
+int icmpwin_init (PNATState);
+void icmpwin_finit (PNATState);
+void icmpwin_ping(PNATState, struct mbuf *, int);
+void icmpwin_process(PNATState);
+#endif
+
#endif
diff --git a/src/VBox/Devices/Network/slirp/ip_icmpwin.c b/src/VBox/Devices/Network/slirp/ip_icmpwin.c
new file mode 100644
index 0000000..5657735
--- /dev/null
+++ b/src/VBox/Devices/Network/slirp/ip_icmpwin.c
@@ -0,0 +1,538 @@
+/* $Id: ip_icmpwin.c $ */
+/** @file
+ * NAT - Windows ICMP API based ping proxy.
+ */
+
+/*
+ * Copyright (C) 2006-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "slirp.h"
+#include "ip_icmp.h"
+
+#include <winternl.h> /* for PIO_APC_ROUTINE &c */
+#include <iphlpapi.h>
+#include <icmpapi.h>
+
+/*
+ * A header of ICMP ECHO. Intended for storage, unlike struct icmp
+ * which is intended to be overlayed onto a buffer.
+ */
+struct icmp_echo {
+ uint8_t icmp_type;
+ uint8_t icmp_code;
+ uint16_t icmp_cksum;
+ uint16_t icmp_echo_id;
+ uint16_t icmp_echo_seq;
+};
+
+AssertCompileSize(struct icmp_echo, 8);
+
+
+struct pong {
+ PNATState pData;
+
+ TAILQ_ENTRY(pong) queue_entry;
+
+ struct ip reqiph;
+ struct icmp_echo reqicmph;
+
+ size_t bufsize;
+ uint8_t buf[1];
+};
+
+
+static VOID WINAPI icmpwin_callback_apc(void *ctx, PIO_STATUS_BLOCK iob, ULONG reserved);
+static VOID WINAPI icmpwin_callback_old(void *ctx);
+
+static void icmpwin_callback(struct pong *pong);
+static void icmpwin_pong(struct pong *pong);
+
+static struct mbuf *icmpwin_get_error(struct pong *pong, int type, int code);
+static struct mbuf *icmpwin_get_mbuf(PNATState pData, size_t reqsize);
+
+
+/*
+ * On Windows XP and Windows Server 2003 IcmpSendEcho2() callback
+ * is FARPROC, but starting from Vista it's PIO_APC_ROUTINE with
+ * two extra arguments. Callbacks use WINAPI (stdcall) calling
+ * convention with callee responsible for popping the arguments,
+ * so to avoid stack corruption we check windows version at run
+ * time and provide correct callback.
+ *
+ * XXX: this is system-wide, but what about multiple NAT threads?
+ */
+static void *pfIcmpCallback;
+
+
+int
+icmpwin_init(PNATState pData)
+{
+ if (pfIcmpCallback == NULL)
+ {
+ OSVERSIONINFO osvi;
+ int status;
+
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ status = GetVersionEx(&osvi);
+ if (status == 0)
+ return 1;
+
+ if (osvi.dwMajorVersion >= 6)
+ pfIcmpCallback = icmpwin_callback_apc;
+ else
+ pfIcmpCallback = icmpwin_callback_old;
+ }
+
+ TAILQ_INIT(&pData->pongs_expected);
+ TAILQ_INIT(&pData->pongs_received);
+
+ pData->icmp_socket.sh = IcmpCreateFile();
+ pData->phEvents[VBOX_ICMP_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ return 0;
+}
+
+
+void
+icmpwin_finit(PNATState pData)
+{
+ IcmpCloseHandle(pData->icmp_socket.sh);
+
+ while (!TAILQ_EMPTY(&pData->pongs_received)) {
+ struct pong *pong = TAILQ_FIRST(&pData->pongs_received);
+ TAILQ_REMOVE(&pData->pongs_received, pong, queue_entry);
+ RTMemFree(pong);
+ }
+
+ /* this should be empty */
+ while (!TAILQ_EMPTY(&pData->pongs_expected)) {
+ struct pong *pong = TAILQ_FIRST(&pData->pongs_expected);
+ TAILQ_REMOVE(&pData->pongs_expected, pong, queue_entry);
+ pong->pData = NULL;
+ }
+}
+
+
+/*
+ * Outgoing ping from guest.
+ */
+void
+icmpwin_ping(PNATState pData, struct mbuf *m, int hlen)
+{
+ struct ip *ip = mtod(m, struct ip *);
+ size_t reqsize, pongsize;
+ uint8_t ttl;
+ size_t bufsize;
+ struct pong *pong;
+ IPAddr dst;
+ IP_OPTION_INFORMATION opts;
+ void *reqdata;
+ int status;
+
+ ttl = ip->ip_ttl;
+ AssertReturnVoid(ttl > 0);
+
+ reqsize = ip->ip_len - hlen - sizeof(struct icmp_echo);
+
+ bufsize = sizeof(ICMP_ECHO_REPLY);
+ if (reqsize < sizeof(IO_STATUS_BLOCK) + sizeof(struct icmp_echo))
+ bufsize += sizeof(IO_STATUS_BLOCK) + sizeof(struct icmp_echo);
+ else
+ bufsize += reqsize;
+ bufsize += 16; /* whatever that is; empirically at least XP needs it */
+
+ pongsize = RT_OFFSETOF(struct pong, buf) + bufsize;
+ if (pData->cbIcmpPending + pongsize > 1024 * 1024)
+ return;
+
+ pong = RTMemAlloc(pongsize);
+ if (RT_UNLIKELY(pong == NULL))
+ return;
+
+ pong->pData = pData;
+ pong->bufsize = bufsize;
+ m_copydata(m, 0, hlen, (caddr_t)&pong->reqiph);
+ m_copydata(m, hlen, sizeof(struct icmp_echo), (caddr_t)&pong->reqicmph);
+ AssertReturnVoid(pong->reqicmph.icmp_type == ICMP_ECHO);
+
+ if (m->m_next == NULL)
+ {
+ /* already in single contiguous buffer */
+ reqdata = mtod(m, char *) + sizeof(struct ip) + sizeof(struct icmp_echo);
+ }
+ else
+ {
+ /* use reply buffer as temporary storage */
+ reqdata = pong->buf;
+ m_copydata(m, sizeof(struct ip) + sizeof(struct icmp_echo),
+ reqsize, reqdata);
+ }
+
+ dst = ip->ip_dst.s_addr;
+
+ opts.Ttl = ttl;
+ opts.Tos = ip->ip_tos; /* affected by DisableUserTOSSetting key */
+ opts.Flags = (ip->ip_off & IP_DF) != 0 ? IP_FLAG_DF : 0;
+ opts.OptionsSize = 0;
+ opts.OptionsData = 0;
+
+
+ status = IcmpSendEcho2(pData->icmp_socket.sh, NULL,
+ pfIcmpCallback, pong,
+ dst, reqdata, (WORD)reqsize, &opts,
+ pong->buf, (DWORD)pong->bufsize,
+ 5 * 1000 /* ms */);
+
+ if (RT_UNLIKELY(status != 0))
+ {
+ Log2(("NAT: IcmpSendEcho2: unexpected status %d\n", status));
+ }
+ else if ((status = GetLastError()) != ERROR_IO_PENDING)
+ {
+ int code;
+
+ Log2(("NAT: IcmpSendEcho2: error %d\n", status));
+ switch (status) {
+ case ERROR_NETWORK_UNREACHABLE:
+ code = ICMP_UNREACH_NET;
+ break;
+ case ERROR_HOST_UNREACHABLE:
+ code = ICMP_UNREACH_HOST;
+ break;
+ default:
+ code = -1;
+ break;
+ }
+
+ if (code != -1) /* send icmp error */
+ {
+ struct mbuf *em = icmpwin_get_error(pong, ICMP_UNREACH, code);
+ if (em != NULL)
+ {
+ struct ip *eip = mtod(em, struct ip *);
+ eip->ip_src = alias_addr;
+ ip_output(pData, NULL, em);
+ }
+ }
+ }
+ else /* success */
+ {
+ Log2(("NAT: pong %p for ping %RTnaipv4 id 0x%04x seq %d len %zu (%zu)\n",
+ pong, dst,
+ RT_N2H_U16(pong->reqicmph.icmp_echo_id),
+ RT_N2H_U16(pong->reqicmph.icmp_echo_seq),
+ pongsize, reqsize));
+
+ pData->cbIcmpPending += pongsize;
+ TAILQ_INSERT_TAIL(&pData->pongs_expected, pong, queue_entry);
+ pong = NULL; /* callback owns it now */
+ }
+
+ if (pong != NULL)
+ RTMemFree(pong);
+}
+
+
+static VOID WINAPI
+icmpwin_callback_apc(void *ctx, PIO_STATUS_BLOCK iob, ULONG reserved)
+{
+ struct pong *pong = (struct pong *)ctx;
+ if (pong != NULL)
+ icmpwin_callback(pong);
+}
+
+
+static VOID WINAPI
+icmpwin_callback_old(void *ctx)
+{
+ struct pong *pong = (struct pong *)ctx;
+ if (pong != NULL)
+ icmpwin_callback(pong);
+}
+
+
+/*
+ * Actual callback code for IcmpSendEcho2(). OS version specific
+ * trampoline will free "pong" argument for us.
+ *
+ * Since async callback can be called anytime the thread is alertable,
+ * it's not safe to do any processing here. Instead queue it and
+ * notify the main loop.
+ */
+static void
+icmpwin_callback(struct pong *pong)
+{
+ PNATState pData = pong->pData;
+
+ if (pData == NULL)
+ {
+ RTMemFree(pong);
+ return;
+ }
+
+#ifdef DEBUG
+ {
+ struct pong *expected, *already;
+
+ TAILQ_FOREACH(expected, &pData->pongs_expected, queue_entry)
+ {
+ if (expected == pong)
+ break;
+ }
+ Assert(expected);
+
+ TAILQ_FOREACH(already, &pData->pongs_received, queue_entry)
+ {
+ if (already == pong)
+ break;
+ }
+ Assert(!already);
+ }
+#endif
+
+ TAILQ_REMOVE(&pData->pongs_expected, pong, queue_entry);
+ TAILQ_INSERT_TAIL(&pData->pongs_received, pong, queue_entry);
+
+ WSASetEvent(pData->phEvents[VBOX_ICMP_EVENT_INDEX]);
+}
+
+
+void
+icmpwin_process(PNATState pData)
+{
+ struct pong_tailq pongs;
+
+ if (TAILQ_EMPTY(&pData->pongs_received))
+ return;
+
+ TAILQ_INIT(&pongs);
+ TAILQ_CONCAT(&pongs, &pData->pongs_received, queue_entry);
+
+ while (!TAILQ_EMPTY(&pongs)) {
+ struct pong *pong = TAILQ_FIRST(&pongs);
+ size_t sz;
+
+ sz = RT_OFFSETOF(struct pong, buf) + pong->bufsize;
+ Assert(pData->cbIcmpPending >= sz);
+ pData->cbIcmpPending -= sz;
+
+ icmpwin_pong(pong);
+
+ TAILQ_REMOVE(&pongs, pong, queue_entry);
+ RTMemFree(pong);
+ }
+}
+
+
+void
+icmpwin_pong(struct pong *pong)
+{
+ PNATState pData;
+ DWORD nreplies;
+ ICMP_ECHO_REPLY *reply;
+ struct mbuf *m;
+ struct ip *ip;
+ struct icmp_echo *icmp;
+ size_t reqsize;
+
+ pData = pong->pData; /* to make slirp_state.h macro hackery work */
+
+ nreplies = IcmpParseReplies(pong->buf, (DWORD)pong->bufsize);
+ if (nreplies == 0)
+ {
+ DWORD error = GetLastError();
+ if (error == IP_REQ_TIMED_OUT)
+ Log2(("NAT: ping %p timed out\n", (void *)pong));
+ else
+ Log2(("NAT: ping %p: IcmpParseReplies: error %d\n",
+ (void *)pong, error));
+ return;
+ }
+
+ reply = (ICMP_ECHO_REPLY *)pong->buf;
+
+ if (reply->Status == IP_SUCCESS)
+ {
+ if (reply->Options.OptionsSize != 0) /* don't do options */
+ return;
+
+ /* need to remap &reply->Address ? */
+ if (/* not a mapped loopback */ 1)
+ {
+ if (reply->Options.Ttl <= 1)
+ return;
+ --reply->Options.Ttl;
+ }
+
+ reqsize = reply->DataSize;
+ if ( (reply->Options.Flags & IP_FLAG_DF) != 0
+ && sizeof(struct ip) + sizeof(struct icmp_echo) + reqsize > if_mtu)
+ return;
+
+ m = icmpwin_get_mbuf(pData, reqsize);
+ if (m == NULL)
+ return;
+
+ ip = mtod(m, struct ip *);
+ icmp = (struct icmp_echo *)(mtod(m, char *) + sizeof(*ip));
+
+ /* fill in ip (ip_output0() does the boilerplate for us) */
+ ip->ip_tos = reply->Options.Tos;
+ ip->ip_len = sizeof(*ip) + sizeof(*icmp) + reqsize;
+ ip->ip_off = 0;
+ ip->ip_ttl = reply->Options.Ttl;
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_src.s_addr = reply->Address;
+ ip->ip_dst = pong->reqiph.ip_src;
+
+ icmp->icmp_type = ICMP_ECHOREPLY;
+ icmp->icmp_code = 0;
+ icmp->icmp_cksum = 0;
+ icmp->icmp_echo_id = pong->reqicmph.icmp_echo_id;
+ icmp->icmp_echo_seq = pong->reqicmph.icmp_echo_seq;
+
+ m_append(pData, m, reqsize, reply->Data);
+
+ icmp->icmp_cksum = in_cksum_skip(m, ip->ip_len, sizeof(*ip));
+ }
+ else {
+ uint8_t type, code;
+
+ switch (reply->Status) {
+ case IP_DEST_NET_UNREACHABLE:
+ type = ICMP_UNREACH; code = ICMP_UNREACH_NET;
+ break;
+ case IP_DEST_HOST_UNREACHABLE:
+ type = ICMP_UNREACH; code = ICMP_UNREACH_HOST;
+ break;
+ case IP_DEST_PROT_UNREACHABLE:
+ type = ICMP_UNREACH; code = ICMP_UNREACH_PROTOCOL;
+ break;
+ case IP_PACKET_TOO_BIG:
+ type = ICMP_UNREACH; code = ICMP_UNREACH_NEEDFRAG;
+ break;
+ case IP_SOURCE_QUENCH:
+ type = ICMP_SOURCEQUENCH; code = 0;
+ break;
+ case IP_TTL_EXPIRED_TRANSIT:
+ type = ICMP_TIMXCEED; code = ICMP_TIMXCEED_INTRANS;
+ break;
+ case IP_TTL_EXPIRED_REASSEM:
+ type = ICMP_TIMXCEED; code = ICMP_TIMXCEED_REASS;
+ break;
+ default:
+ Log2(("NAT: ping reply status %d, dropped\n", reply->Status));
+ return;
+ }
+
+ Log2(("NAT: ping status %d -> type %d/code %d\n",
+ reply->Status, type, code));
+
+ /*
+ * XXX: we don't know the TTL of the request at the time this
+ * ICMP error was generated (we can guess it was 1 for ttl
+ * exceeded, but don't bother faking it).
+ */
+ m = icmpwin_get_error(pong, type, code);
+ if (m == NULL)
+ return;
+
+ ip = mtod(m, struct ip *);
+
+ ip->ip_tos = reply->Options.Tos;
+ ip->ip_ttl = reply->Options.Ttl; /* XXX: decrement */
+ ip->ip_src.s_addr = reply->Address;
+ }
+
+ Assert(ip->ip_len == m_length(m, NULL));
+ ip_output(pData, NULL, m);
+}
+
+
+/*
+ * Prepare mbuf with ICMP error type/code.
+ * IP source must be filled by the caller.
+ */
+static struct mbuf *
+icmpwin_get_error(struct pong *pong, int type, int code)
+{
+ PNATState pData = pong->pData;
+ struct mbuf *m;
+ struct ip *ip;
+ struct icmp_echo *icmp;
+ size_t reqsize;
+
+ Log2(("NAT: ping error type %d/code %d\n", type, code));
+
+ reqsize = sizeof(pong->reqiph) + sizeof(pong->reqicmph);
+
+ m = icmpwin_get_mbuf(pData, reqsize);
+ if (m == NULL)
+ return NULL;
+
+ ip = mtod(m, struct ip *);
+ icmp = (struct icmp_echo *)(mtod(m, char *) + sizeof(*ip));
+
+ ip->ip_tos = 0;
+ ip->ip_len = sizeof(*ip) + sizeof(*icmp) + reqsize;
+ ip->ip_off = 0;
+ ip->ip_ttl = IPDEFTTL;
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_src.s_addr = 0; /* NB */
+ ip->ip_dst = pong->reqiph.ip_src;
+
+ icmp->icmp_type = type;
+ icmp->icmp_code = code;
+ icmp->icmp_cksum = 0;
+ icmp->icmp_echo_id = 0;
+ icmp->icmp_echo_seq = 0;
+
+ m_append(pData, m, sizeof(pong->reqiph), (caddr_t)&pong->reqiph);
+ m_append(pData, m, sizeof(pong->reqicmph), (caddr_t)&pong->reqicmph);
+
+ icmp->icmp_cksum = in_cksum_skip(m, ip->ip_len, sizeof(*ip));
+
+ return m;
+}
+
+
+/*
+ * Replacing original simple slirp mbufs with real mbufs from freebsd
+ * was a bit messy since assumption are different. This leads to
+ * rather ugly code at times. Hide the gore here.
+ */
+static struct mbuf *
+icmpwin_get_mbuf(PNATState pData, size_t reqsize)
+{
+ struct mbuf *m;
+
+ reqsize += if_maxlinkhdr;
+ reqsize += sizeof(struct ip) + sizeof(struct icmp_echo);
+
+ if (reqsize <= MHLEN)
+ /* good pings come in small packets */
+ m = m_gethdr(pData, M_NOWAIT, MT_HEADER);
+ else
+ m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, slirp_size(pData));
+
+ if (m == NULL)
+ return NULL;
+
+ m->m_flags |= M_SKIP_FIREWALL;
+ m->m_data += if_maxlinkhdr; /* reserve leading space for ethernet header */
+
+ m->m_pkthdr.header = mtod(m, void *);
+ m->m_len = sizeof(struct ip) + sizeof(struct icmp_echo);
+
+ return m;
+}
diff --git a/src/VBox/Devices/Network/slirp/ip_input.c b/src/VBox/Devices/Network/slirp/ip_input.c
index 0e96641..00579d4 100644
--- a/src/VBox/Devices/Network/slirp/ip_input.c
+++ b/src/VBox/Devices/Network/slirp/ip_input.c
@@ -84,17 +84,6 @@ ip_init(PNATState pData)
tcp_init(pData);
}
-static struct libalias *select_alias(PNATState pData, struct mbuf* m)
-{
- struct libalias *la = pData->proxy_alias;
-
- struct m_tag *t;
- if ((t = m_tag_find(m, PACKET_TAG_ALIAS, NULL)) != 0)
- return (struct libalias *)&t[1];
-
- return la;
-}
-
/*
* Ip input routine. Checksum and byte swap header. If fragmented
* try to reassemble. Process options. Pass to next level.
@@ -118,7 +107,7 @@ ip_input(PNATState pData, struct mbuf *m)
if (!(m->m_flags & M_SKIP_FIREWALL))
{
STAM_PROFILE_START(&pData->StatALIAS_input, b);
- rc = LibAliasIn(select_alias(pData, m), mtod(m, char *), m_length(m, NULL));
+ rc = LibAliasIn(pData->proxy_alias, mtod(m, char *), m_length(m, NULL));
STAM_PROFILE_STOP(&pData->StatALIAS_input, b);
Log2(("NAT: LibAlias return %d\n", rc));
}
@@ -198,6 +187,7 @@ ip_input(PNATState pData, struct mbuf *m)
/* check ip_ttl for a correct ICMP reply */
if (ip->ip_ttl==0 || ip->ip_ttl == 1)
{
+ /* XXX: if we're in destination so perhaps we need to send ICMP_TIMXCEED_REASS */
icmp_error(pData, m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, "ttl");
goto no_free_m;
}
diff --git a/src/VBox/Devices/Network/slirp/ip_output.c b/src/VBox/Devices/Network/slirp/ip_output.c
index 5625718..65ae5bf 100644
--- a/src/VBox/Devices/Network/slirp/ip_output.c
+++ b/src/VBox/Devices/Network/slirp/ip_output.c
@@ -175,13 +175,7 @@ ip_output0(PNATState pData, struct socket *so, struct mbuf *m0, int urg)
if (!(m->m_flags & M_SKIP_FIREWALL)){
struct m_tag *t;
STAM_PROFILE_START(&pData->StatALIAS_output, b);
- if ((t = m_tag_find(m, PACKET_TAG_ALIAS, NULL)) != 0)
- rc = LibAliasOut((struct libalias *)&t[1], mtod(m, char *),
- m_length(m, NULL));
- else
- rc = LibAliasOut(pData->proxy_alias, mtod(m, char *),
- m_length(m, NULL));
-
+ rc = LibAliasOut(pData->proxy_alias, mtod(m, char *), m_length(m, NULL));
if (rc == PKT_ALIAS_IGNORED)
{
Log(("NAT: packet was droppped\n"));
@@ -309,11 +303,8 @@ send_or_free:
*/
struct m_tag *t;
int rcLa;
- if ((t = m_tag_find(m, PACKET_TAG_ALIAS, NULL)) != 0)
- rcLa = LibAliasOut((struct libalias *)&t[1], mtod(m, char *), m->m_len);
- else
- rcLa = LibAliasOut(pData->proxy_alias, mtod(m, char *), m->m_len);
+ rcLa = LibAliasOut(pData->proxy_alias, mtod(m, char *), m->m_len);
if (rcLa == PKT_ALIAS_IGNORED)
{
Log(("NAT: packet was droppped\n"));
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias.c b/src/VBox/Devices/Network/slirp/libalias/alias.c
index 0dadc76..243a284 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias.c
@@ -143,7 +143,7 @@ __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias.c,v 1.58.2.1.4.1 2009/04/15 0
#include "alias_local.h"
#include "alias_mod.h"
#endif
-#else /* !VBOX */
+#else /* VBOX */
# include <slirp.h>
# include "alias.h"
# include "alias_local.h"
@@ -1652,7 +1652,7 @@ LibAliasLoadModule(char *path)
}
LibAliasAttachHandlers(m);
-#else /* !VBOX */
+#else /* VBOX */
NOREF(path);
#endif /* VBOX */
return (0);
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_db.c b/src/VBox/Devices/Network/slirp/libalias/alias_db.c
index d75c862..7a37dc8 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_db.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_db.c
@@ -28,6 +28,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_db.c,v 1.71.2.2.4.1 2009/04/15 03:14:26 kensmith Exp $");
#endif
+
/*
Alias_db.c encapsulates all data structures used for storing
packet aliasing data. Other parts of the aliasing software
@@ -172,7 +173,7 @@ __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_db.c,v 1.71.2.2.4.1 2009/04/1
#include "alias_local.h"
#include "alias_mod.h"
#endif
-#else /* !VBOX */
+#else /* VBOX */
# include <iprt/assert.h>
# include "alias.h"
# include "alias_local.h"
@@ -337,16 +338,7 @@ struct alias_link { /* Main data structure */
#endif
#ifndef NO_USE_SOCKETS
-# ifndef VBOX
- /*
- * in VBox we do not use host's sockets here, which are managed
- * inside slirp. yes we have to create new sockets here but latter
- * managment and deletion are in repsponsible of Slirp.
- */
int sockfd; /* socket descriptor */
-# else
- struct socket *pSo;
-# endif
#endif
LIST_ENTRY (alias_link) list_out; /* Linked list of
* pointers for */
@@ -571,11 +563,7 @@ Port search:
/* Local prototypes */
static int GetNewPort(struct libalias *, struct alias_link *, int);
#ifndef NO_USE_SOCKETS
-# ifdef VBOX
-static u_short GetSocket(struct libalias *, u_short, struct alias_link*, int);
-# else
static u_short GetSocket(struct libalias *, u_short, int *, int);
-# endif
#endif
static void CleanupAliasData(struct libalias *);
@@ -690,11 +678,7 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
&& (lnk->flags & LINK_PARTIALLY_SPECIFIED)
&& ((lnk->link_type == LINK_TCP) ||
(lnk->link_type == LINK_UDP))) {
-#ifndef VBOX
if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) {
-#else
- if (GetSocket(la, port_net, lnk, lnk->link_type)) {
-#endif
lnk->alias_port = port_net;
return (0);
}
@@ -721,31 +705,13 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
#ifndef NO_USE_SOCKETS
static u_short
-# ifndef VBOX
GetSocket(struct libalias *la, u_short port_net, int *sockfd, int link_type)
-# else
-GetSocket(struct libalias *la, u_short port_net, struct alias_link *pLnk, int link_type)
-# endif
{
int err;
int sock;
struct sockaddr_in sock_addr;
-#ifdef VBOX
- int opt = 1;
- int status = 0;
- struct socket *so = NULL;
- struct sockaddr sa_addr;
- socklen_t socklen = sizeof(struct sockaddr);
-#endif
LIBALIAS_LOCK_ASSERT(la);
-#ifdef VBOX
- so = socreate();
- if (so == NULL)
- {
- return 0;
- }
-#endif
if (link_type == LINK_TCP)
sock = socket(AF_INET, SOCK_STREAM, 0);
else if (link_type == LINK_UDP)
@@ -755,33 +721,21 @@ GetSocket(struct libalias *la, u_short port_net, struct alias_link *pLnk, int li
fprintf(stderr, "PacketAlias/GetSocket(): ");
fprintf(stderr, "incorrect link type\n");
#endif
-#ifdef VBOX
- RTMemFree(so);
-#endif
return (0);
}
if (sock < 0) {
#ifdef LIBALIAS_DEBUG
fprintf(stderr, "PacketAlias/GetSocket(): ");
-# ifndef VBOX
fprintf(stderr, "socket() error %d\n", *sockfd);
-# else
- fprintf(stderr, "socket() error %d\n", errno);
-# endif
#endif
return (0);
}
-#ifdef VBOX
- so->s = sock;
- fd_nonblock(so->s);
-#endif
+
memset(&sock_addr, 0, sizeof(struct sockaddr_in));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-#if 0
- sock_addr.sin_port = htons(port_net);
-#endif
+ sock_addr.sin_port = port_net;
#ifdef RT_OS_DARWIN
sock_addr.sin_len = sizeof(struct sockaddr_in);
#endif
@@ -792,76 +746,10 @@ GetSocket(struct libalias *la, u_short port_net, struct alias_link *pLnk, int li
sizeof(sock_addr));
if (err == 0) {
la->sockCount++;
-#ifdef VBOX
- so->so_expire = la->curtime + SO_EXPIRE;
- setsockopt(so->s, SOL_SOCKET, SO_BROADCAST,
- (const char *)&opt, sizeof(opt));
- status = getsockname(so->s, &sa_addr, &socklen);
- if (status != 0 || sa_addr.sa_family != AF_INET)
- {
- closesocket(so->s);
- RTMemFree(so);
- return 0;
- }
- so->so_laddr.s_addr = la->aliasAddress.s_addr;
- so->so_lport = htons(port_net);
- so->so_faddr.s_addr = la->true_addr.s_addr;
- so->so_fport = la->true_port;
- so->so_hlport = ((struct sockaddr_in *)&sa_addr)->sin_port;
- so->so_hladdr.s_addr =
- ((struct sockaddr_in *)&sa_addr)->sin_addr.s_addr;
- NSOCK_INC_EX(la);
- if (link_type == LINK_TCP)
- {
- int ret = 0;
- struct sockaddr_in sin;
- RT_ZERO(sin);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = so->so_faddr.s_addr;
- sin.sin_port = so->so_fport;
- ret = connect(so->s, (struct sockaddr *)&sin, sizeof(sin));
- if ( ret < 0
- && !soIgnorableErrorCode(errno))
- {
- closesocket(so->s);
- RTMemFree(so);
- return 0;
- }
- so->so_state = SS_ISFCONNECTING; /* slirp happy??? */
- tcp_attach(la->pData, so);
- /* tcp_{snd,rcv}space -> pData->tcp_{snd,rcv}space */
- sbreserve(la->pData, &so->so_snd, la->tcp_sndspace);
- sbreserve(la->pData, &so->so_rcv, la->tcp_rcvspace);
- }
- else if (link_type == LINK_UDP)
- {
- so->so_type = IPPROTO_UDP;
- insque(la->pData, so, &la->udb);
- }
- else
- {
- /* socket wasn't added to queue */
- closesocket(so->s);
- RTMemFree(so);
- Assert(!"Shouldn't be here");
- return 0;
- }
- LogFunc(("bind called for socket: %R[natsock]\n", so));
- pLnk->pSo = so;
- so->so_pvLnk = pLnk;
-#else
*sockfd = sock;
-#endif
return (1);
} else {
-#ifdef VBOX
- if (sock >= 0)
- closesocket(sock);
- /* socket wasn't enqueued so we shouldn't use sofree */
- RTMemFree(so);
-#else
- close(sock);
-#endif
+ closesocket(sock);
return (0);
}
}
@@ -990,12 +878,7 @@ IncrementalCleanup(struct libalias *la)
LIBALIAS_LOCK_ASSERT(la);
LIST_FOREACH_SAFE(lnk, &la->linkTableOut[la->cleanupIndex++],
list_out, lnk_tmp) {
-#ifndef VBOX
if (la->timeStamp - lnk->timestamp > lnk->expire_time)
-#else
- /* libalias counts time in seconds while slirp in millis */
- if (la->timeStamp - lnk->timestamp > (1000 * lnk->expire_time))
-#endif
DeleteLink(lnk);
}
@@ -1003,35 +886,11 @@ IncrementalCleanup(struct libalias *la)
la->cleanupIndex = 0;
}
-#if defined(VBOX) && !defined(NO_USE_SOCKETS)
-
-/**
- * when slirp delete the link we need inform libalias about it.
- */
-void slirpDeleteLinkSocket(void *pvLnk)
-{
- struct alias_link *lnk = (struct alias_link *)pvLnk;
- if ( lnk
- && lnk->pSo)
- {
- struct libalias *la = lnk->la;
- la->sockCount--;
- lnk->pSo->fShouldBeRemoved = 1;
- lnk->pSo->so_pvLnk = NULL; /* forget me, please ! */
- lnk->pSo = NULL;
- }
-}
-#endif /* VBOX && !NO_USE_SOCKETS */
-
static void
DeleteLink(struct alias_link *lnk)
{
struct libalias *la = lnk->la;
-#ifndef NO_USE_SOCKETS
- LogFlowFunc(("ENTER: lnk->pSo:%R[natsock]\n", lnk->pSo));
-#else
LogFlowFuncEnter();
-#endif
LIBALIAS_LOCK_ASSERT(la);
/* Don't do anything if the link is marked permanent */
@@ -1060,28 +919,10 @@ DeleteLink(struct alias_link *lnk)
LIST_REMOVE(lnk, list_in);
#ifndef NO_USE_SOCKETS
/* Close socket, if one has been allocated */
-# ifndef VBOX
if (lnk->sockfd != -1) {
la->sockCount--;
- close(lnk->sockfd);
- }
-# else /* VBOX */
- if (lnk->pSo)
- {
- /* libalias's sockCount decremented in slirpDeleteLinkSocket,
- * which called from sofree
- */
- /* la->sockCount--; */
- /* should we be more smart, or it's enough to be
- * narrow-minded and just do sofree here
- */
-#if 0
- sofree(la->pData, lnk->pSo);
-#else
- slirpDeleteLinkSocket(lnk);
-#endif
+ closesocket(lnk->sockfd);
}
-# endif
#endif
/* Link-type dependent cleanup */
switch (lnk->link_type) {
@@ -1152,11 +993,7 @@ AddLink(struct libalias *la, struct in_addr src_addr,
lnk->server = NULL;
lnk->link_type = link_type;
#ifndef NO_USE_SOCKETS
-# ifndef VBOX
lnk->sockfd = -1;
-# else
- lnk->pSo = NULL;
-# endif
#endif
lnk->flags = 0;
lnk->pflags = 0;
@@ -2382,6 +2219,7 @@ HouseKeeping(struct libalias *la)
struct timeval tv;
struct timezone tz;
#endif
+#endif /* !VBOX */
LIBALIAS_LOCK_ASSERT(la);
/*
@@ -2389,23 +2227,19 @@ HouseKeeping(struct libalias *la)
* by other functions. This is done so as not to unnecessarily
* waste timeline by making system calls.
*/
+#ifndef VBOX
#ifdef _KERNEL
la->timeStamp = time_uptime;
#else
gettimeofday(&tv, &tz);
la->timeStamp = tv.tv_sec;
#endif
-#else /* !VBOX */
- LIBALIAS_LOCK_ASSERT(la);
- la->timeStamp = la->curtime;
+#else /* VBOX */
+ la->timeStamp = la->curtime / 1000; /* NB: la->pData->curtime (msec) */
#endif
/* Compute number of spokes (output table link chains) to cover */
-#ifndef VBOX
n = LINK_TABLE_OUT_SIZE * (la->timeStamp - la->lastCleanupTime);
-#else
- n = LINK_TABLE_OUT_SIZE * ((la->timeStamp - la->lastCleanupTime)/1000);
-#endif
n /= ALIAS_CLEANUP_INTERVAL_SECS;
/* Handle different cases */
@@ -2720,7 +2554,7 @@ LibAliasInit(PNATState pData, struct libalias *la)
if (LIST_EMPTY(&instancehead))
atexit(finishoff);
#endif
-#endif /*!VBOX*/
+#endif /* !VBOX */
LIST_INSERT_HEAD(&instancehead, la, instancelist);
#ifndef VBOX
@@ -2732,10 +2566,10 @@ LibAliasInit(PNATState pData, struct libalias *la)
la->timeStamp = tv.tv_sec;
la->lastCleanupTime = tv.tv_sec;
#endif
-#else /* !VBOX */
+#else /* VBOX */
la->pData = pData;
- la->timeStamp = curtime;
- la->lastCleanupTime = curtime;
+ la->timeStamp = la->curtime / 1000; /* NB: la->pData->curtime (msec) */
+ la->lastCleanupTime = la->timeStamp;
#endif /* VBOX */
for (i = 0; i < LINK_TABLE_OUT_SIZE; i++)
@@ -2973,11 +2807,7 @@ UninitPunchFW(struct libalias *la)
LIBALIAS_LOCK_ASSERT(la);
ClearAllFWHoles(la);
if (la->fireWallFD >= 0)
-#ifdef VBOX /* this code is currently dead but anyway ... */
closesocket(la->fireWallFD);
-#else
- close(la->fireWallFD);
-#endif
la->fireWallFD = -1;
if (la->fireWallField)
free(la->fireWallField);
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_ftp.c b/src/VBox/Devices/Network/slirp/libalias/alias_ftp.c
index 31ffefe..64596be 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_ftp.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_ftp.c
@@ -147,7 +147,7 @@ struct proto_handler handlers[] = {
},
{ EOH }
};
-#else /* !VBOX */
+#else /* VBOX */
#define handlers pData->ftp_module
#endif /* VBOX */
@@ -216,7 +216,7 @@ static
moduledata_t alias_mod = {
"alias_ftp", mod_handler, NULL
};
-#endif /*!VBOX*/
+#endif /* !VBOX */
#ifdef _KERNEL
DECLARE_MODULE(alias_ftp, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
@@ -541,8 +541,11 @@ ParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
}
if (state == 13) {
+ if (addr != INADDR_LOOPBACK)
+ la->true_addr.s_addr = htonl(addr);
+ else
+ la->true_addr.s_addr = la->pData->alias_addr.s_addr;
la->true_port = port;
- la->true_addr.s_addr = htonl(addr);
return (1);
} else
return (0);
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_local.h b/src/VBox/Devices/Network/slirp/libalias/alias_local.h
index e6174f5..9ee4d03 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_local.h
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_local.h
@@ -59,7 +59,7 @@
/* XXX: LibAliasSetTarget() uses this constant. */
#define INADDR_NONE 0xffffffff
#endif
-#else /* !VBOX */
+#else /* VBOX */
# include <slirp.h>
#endif /* VBOX */
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_mod.c b/src/VBox/Devices/Network/slirp/libalias/alias_mod.c
index 4da9939..76ca009 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_mod.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_mod.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_mod.c,v 1.3.8.1 2009/04/15 03
/* Protocol and userland module handlers chains. */
LIST_HEAD(handler_chain, proto_handler) handler_chain = LIST_HEAD_INITIALIZER(foo);
-#else /* !VBOX */
+#else /* VBOX */
# include <slirp.h>
# include "alias_local.h"
# include "alias_mod.h"
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_mod.h b/src/VBox/Devices/Network/slirp/libalias/alias_mod.h
index 19258a8..74a5213 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_mod.h
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_mod.h
@@ -43,7 +43,7 @@ MALLOC_DECLARE(M_ALIAS);
#define calloc(x, n) malloc(x*n)
#define free(x) free(x, M_ALIAS)
#endif
-#else /* !VBOX */
+#else /* VBOX */
# ifdef RT_OS_WINDOWS
# undef IN
# undef OUT
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_nbt.c b/src/VBox/Devices/Network/slirp/libalias/alias_nbt.c
index fcc9bdf..221b4cd 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_nbt.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_nbt.c
@@ -65,13 +65,13 @@ __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_nbt.c,v 1.20.8.1 2009/04/15 0
#include "alias_local.h"
#include "alias_mod.h"
#endif
-#else /*VBOX*/
+#else /* VBOX */
# include <iprt/ctype.h>
# include <slirp.h>
# include "alias_local.h"
# include "alias_mod.h"
# define isprint RT_C_IS_PRINT
-#endif /*VBOX*/
+#endif /* VBOX */
#define NETBIOS_NS_PORT_NUMBER 137
#define NETBIOS_DGM_PORT_NUMBER 138
@@ -169,14 +169,14 @@ struct proto_handler handlers[] = {
},
{ EOH }
};
-#else /* !VBOX */
+#else /* VBOX */
#define handlers pData->nbt_module
-#endif /*VBOX*/
+#endif /* VBOX */
#ifndef VBOX
static int
mod_handler(module_t mod, int type, void *data)
-#else /*!VBOX*/
+#else /* VBOX */
static int nbt_alias_handler(PNATState pData, int type);
int
@@ -192,7 +192,7 @@ nbt_alias_unload(PNATState pData)
}
static int
nbt_alias_handler(PNATState pData, int type)
-#endif /*VBOX*/
+#endif /* VBOX */
{
int error;
#ifdef VBOX
@@ -219,7 +219,7 @@ nbt_alias_handler(PNATState pData, int type)
handlers[2].protohandler = &protohandler2out;
handlers[3].pri = EOH;
-#endif /*VBOX*/
+#endif /* VBOX */
switch (type) {
case MOD_LOAD:
@@ -253,7 +253,7 @@ static
moduledata_t alias_mod = {
"alias_nbt", mod_handler, NULL
};
-#endif /*!VBOX*/
+#endif /* !VBOX */
#ifdef _KERNEL
DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_util.c b/src/VBox/Devices/Network/slirp/libalias/alias_util.c
index 8e52dd3..9a0310d 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_util.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_util.c
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_util.c,v 1.20.8.1 2009/04/15
#include "alias.h"
#include "alias_local.h"
#endif
-#else /* !VBOX */
+#else /* VBOX */
# include <slirp.h>
# include "alias.h"
# include "alias_local.h"
diff --git a/src/VBox/Devices/Network/slirp/libslirp.h b/src/VBox/Devices/Network/slirp/libslirp.h
index 9cbea94..03cb5ae 100644
--- a/src/VBox/Devices/Network/slirp/libslirp.h
+++ b/src/VBox/Devices/Network/slirp/libslirp.h
@@ -55,7 +55,7 @@ void slirp_link_down(PNATState);
#if defined(RT_OS_WINDOWS)
void slirp_select_fill(PNATState pData, int *pndfs);
-void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp);
+void slirp_select_poll(PNATState pData, int fTimeout);
#else /* RT_OS_WINDOWS */
void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls);
void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs);
@@ -96,24 +96,31 @@ void slirp_info(PNATState pData, const void *pvArg, const char *pszArgs);
void slirp_set_somaxconn(PNATState pData, int iSoMaxConn);
/**
+ * This macrodefinition is shortcut for check of hosts where Slirp,
+ * receives notifications from host. For now it's Darwin only. But
+ * Main API has primitives for listening DNS change event since 4.3.
+ */
+#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS)
+# define HAVE_NOTIFICATION_FOR_DNS_UPDATE 1
+#else
+# define HAVE_NOTIFICATION_FOR_DNS_UPDATE 0
+#endif
+
+
+/**
* This method help DrvNAT to select strategy: about VMRESUMEREASON_HOST_RESUME:
* - proceed with link termination (we let guest track host DNS settings)
- * VBOX_NAT_HNCE_EXPOSED_NAME_RESOLVING_INFO
+ * VBOX_NAT_DNS_EXTERNAL
* - enforce internal DNS update (we are using dnsproxy and track but don't export DNS host settings)
- * VBOX_NAT_HNCE_DNSPROXY
- * - flap link and trigger guest to request new DHCP configuration (means that NAT was temporary in
- * host resolver mode due to temporary DNS data outage)
- * VBOX_NAT_HNCE_HOSTRESOLVER_TEMPORARY
+ * VBOX_NAT_DNS_DNSPROXY
* - ignore (NAT configured to use hostresolver - we aren't track any host DNS changes)
- * VBOX_NAT_HNCE_HOSTRESOLVER
- * @note: It's safe to call this method from any thread, because settings we're checking
+ * VBOX_NAT_DNS_HOSTRESOLVER
+ * @note: It's safe to call this method from any thread, because settings we're checking
* are immutable at runtime.
*/
-#define VBOX_NAT_HNCE_EXSPOSED_NAME_RESOLUTION_INFO 0
-#define VBOX_NAT_HNCE_DNSPROXY 1
-#define VBOX_NAT_HNCE_HOSTRESOLVER_TEMPORARY 2
-#define VBOX_NAT_HNCE_HOSTRESOLVER 3
-
+#define VBOX_NAT_DNS_EXTERNAL 0
+#define VBOX_NAT_DNS_DNSPROXY 1
+#define VBOX_NAT_DNS_HOSTRESOLVER 2
int slirp_host_network_configuration_change_strategy_selector(const PNATState);
#if defined(RT_OS_WINDOWS)
diff --git a/src/VBox/Devices/Network/slirp/misc.c b/src/VBox/Devices/Network/slirp/misc.c
index f785a6e..5071427 100644
--- a/src/VBox/Devices/Network/slirp/misc.c
+++ b/src/VBox/Devices/Network/slirp/misc.c
@@ -495,9 +495,8 @@ struct mbuf *slirp_ext_m_get(PNATState pData, size_t cbMin, void **ppvBuf, size_
struct mbuf *m;
size_t size = MCLBYTES;
LogFlowFunc(("ENTER: cbMin:%d, ppvBuf:%p, pcbBuf:%p\n", cbMin, ppvBuf, pcbBuf));
- if (cbMin < MSIZE)
- size = MCLBYTES;
- else if (cbMin < MCLBYTES)
+
+ if (cbMin < MCLBYTES)
size = MCLBYTES;
else if (cbMin < MJUM9BYTES)
size = MJUM9BYTES;
diff --git a/src/VBox/Devices/Network/slirp/resolv_conf_parser.c b/src/VBox/Devices/Network/slirp/resolv_conf_parser.c
index dd5fb82..647d705 100644
--- a/src/VBox/Devices/Network/slirp/resolv_conf_parser.c
+++ b/src/VBox/Devices/Network/slirp/resolv_conf_parser.c
@@ -28,6 +28,8 @@
#include "resolv_conf_parser.h"
+/* XXX: it's required to add the aliases for keywords and
+ * types to handle conditions more clearly */
enum RCP_TOKEN
{
tok_eof = -1, /* EOF */
@@ -37,6 +39,7 @@ enum RCP_TOKEN
tok_ipv4_port = -5, /* ipv4 port */
tok_ipv6 = -6, /* ipv6 */
tok_ipv6_port = -7, /* ipv6 port */
+ /* keywords */
tok_nameserver = -8, /* nameserver */
tok_port = -9, /* port, Mac OSX specific */
tok_domain = -10, /* domain */
@@ -252,7 +255,6 @@ static enum RCP_TOKEN rcp_parse_nameserver(struct rcp_parser *parser)
address = &st->rcps_nameserver[st->rcps_num_nameserver];
str_address = &st->rcps_nameserver_str_buffer[st->rcps_num_nameserver * RCPS_IPVX_SIZE];
-
#ifdef RT_OS_DARWIN
if ( tok == tok_ipv4_port
|| ( tok == tok_ipv6_port
@@ -382,6 +384,7 @@ static enum RCP_TOKEN rcp_parse_domain(struct rcp_parser *parser)
* "The search list is currently limited to six domains with a total of 256 characters."
* @note: resolv.conf (5) Linux:
* "The search list is currently limited to six domains with a total of 256 characters."
+ * @note: 'search' parameter could contains numbers only hex or decimal, 1c1e or 111
*/
static enum RCP_TOKEN rcp_parse_search(struct rcp_parser *parser)
{
@@ -393,32 +396,53 @@ static enum RCP_TOKEN rcp_parse_search(struct rcp_parser *parser)
Assert(parser->rcpp_state);
st = parser->rcpp_state;
- /**
- * We asume that duplication of search list in resolv.conf isn't correct.
- */
if ( tok == tok_eof
- || tok == tok_error
- || tok != tok_string
- || st->rcps_searchlist[0] != NULL)
+ || tok == tok_error)
return tok_error;
- i = 0;
- trailing = RCPS_BUFFER_SIZE;
- do {
+ /* just ignore "too many search list" */
+ if (st->rcps_num_searchlist >= RCPS_MAX_SEARCHLIST)
+ return rcp_get_token(parser);
+
+ /* we don't want accept keywords */
+ if (tok <= tok_nameserver)
+ return tok;
+
+ /* if there're several entries of "search" we compose them together */
+ i = st->rcps_num_searchlist;
+ if ( i == 0)
+ trailing = RCPS_BUFFER_SIZE;
+ else
+ {
+ ptr = st->rcps_searchlist[i - 1];
+ trailing = RCPS_BUFFER_SIZE - (ptr -
+ st->rcps_searchlist_buffer + strlen(ptr) + 1);
+ }
+
+ while (1)
+ {
len = strlen(parser->rcpp_str_buffer);
if (len + 1 > trailing)
break; /* not enough room for new entry */
+ if (i >= RCPS_MAX_SEARCHLIST)
+ break; /* not enought free entries for 'search' items */
+
ptr = st->rcps_searchlist_buffer + RCPS_BUFFER_SIZE - trailing;
strcpy(ptr, parser->rcpp_str_buffer);
trailing -= len + 1; /* 1 reserved for '\0' */
- st->rcps_searchlist[i] = ptr;
+ st->rcps_searchlist[i++] = ptr;
+ tok = rcp_get_token(parser);
- } while( (tok = rcp_get_token(parser)) == tok_string
- && ++i != RCPS_MAX_SEARCHLIST);
+ /* token filter */
+ if ( tok == tok_eof
+ || tok == tok_error
+ || tok <= tok_nameserver)
+ break;
+ }
st->rcps_num_searchlist = i;
diff --git a/src/VBox/Devices/Network/slirp/resolv_conf_parser.h b/src/VBox/Devices/Network/slirp/resolv_conf_parser.h
index ca322b9..cfb1086 100644
--- a/src/VBox/Devices/Network/slirp/resolv_conf_parser.h
+++ b/src/VBox/Devices/Network/slirp/resolv_conf_parser.h
@@ -27,9 +27,21 @@ RT_C_DECLS_BEGIN
#define RCPS_MAX_SEARCHLIST 10
#define RCPS_BUFFER_SIZE 256
#define RCPS_IPVX_SIZE 47
+
+/**
+ * RESOLV_CONF_FILE can be defined in external tests for verification of Slirp behaviour.
+ */
+#ifndef RESOLV_CONF_FILE
+# ifndef RT_OS_OS2
+# define RESOLV_CONF_FILE "/etc/resolv.conf"
+# else
+# define RESOLV_CONF_FILE "\\MPTN\\ETC\\RESOLV2"
+# endif
+#endif
+
/**
- * In Slirp we don't need IPv6 for general case (only for dnsproxy mode
- * it's potentially acceptable)
+ * In Slirp we don't need IPv6 for general case (only for dnsproxy mode
+ * it's potentially acceptable)
*/
#define RCPSF_IGNORE_IPV6 RT_BIT(0)
/**
diff --git a/src/VBox/Devices/Network/slirp/sbuf.c b/src/VBox/Devices/Network/slirp/sbuf.c
index 45babce..8f94d37 100644
--- a/src/VBox/Devices/Network/slirp/sbuf.c
+++ b/src/VBox/Devices/Network/slirp/sbuf.c
@@ -111,7 +111,6 @@ sbappend(PNATState pData, struct socket *so, struct mbuf *m)
{
int ret = 0;
int mlen = 0;
- caddr_t buf = NULL;
STAM_PROFILE_START(&pData->StatIOSBAppend_pf, a);
LogFlow(("sbappend: so = %lx, m = %lx, m->m_len = %d\n", (long)so, (long)m, m ? m->m_len : 0));
@@ -140,26 +139,30 @@ sbappend(PNATState pData, struct socket *so, struct mbuf *m)
/*
* We only write if there's nothing in the buffer,
- * ottherwise it'll arrive out of order, and hence corrupt
+ * otherwise it'll arrive out of order, and hence corrupt
*/
- if (m->m_next)
+ if (so->so_rcv.sb_cc == 0)
{
- buf = RTMemAlloc(mlen);
- if (buf == NULL)
+ caddr_t buf = NULL;
+
+ if (m->m_next)
{
- ret = 0;
- goto no_sent;
+ buf = RTMemAlloc(mlen);
+ if (buf == NULL)
+ {
+ ret = 0;
+ goto no_sent;
+ }
+ m_copydata(m, 0, mlen, buf);
}
- m_copydata(m, 0, mlen, buf);
- }
- else
- buf = mtod(m, char *);
+ else
+ buf = mtod(m, char *);
- if(!so->so_rcv.sb_cc)
ret = send(so->s, buf, mlen, 0);
- if (m->m_next)
- RTMemFree(buf);
+ if (m->m_next)
+ RTMemFree(buf);
+ }
no_sent:
if (ret <= 0)
diff --git a/src/VBox/Devices/Network/slirp/slirp.c b/src/VBox/Devices/Network/slirp/slirp.c
index 068e201..986d3b3 100644
--- a/src/VBox/Devices/Network/slirp/slirp.c
+++ b/src/VBox/Devices/Network/slirp/slirp.c
@@ -63,7 +63,15 @@
#include <alias.h>
#ifndef RT_OS_WINDOWS
+/**
+ * XXX: It shouldn't be non-Windows specific.
+ * resolv_conf_parser.h client's structure isn't OS specific, it's just need to be generalized a
+ * a bit to replace slirp_state.h DNS server (domain) lists with rcp_state like structure.
+ */
+# include "resolv_conf_parser.h"
+#endif
+#ifndef RT_OS_WINDOWS
# define DO_ENGAGE_EVENT1(so, fdset, label) \
do { \
if ( so->so_poll_index != -1 \
@@ -192,7 +200,7 @@
# define closefds_win_bit FD_CLOSE_BIT
# define DO_CHECK_FD_SET(so, events, fdset) \
- (((events).lNetworkEvents & fdset ## _win) && ((events).iErrorCode[fdset ## _win_bit] == 0))
+ ((events).lNetworkEvents & fdset ## _win)
# define DO_WIN_CHECK_FD_SET(so, events, fdset) DO_CHECK_FD_SET((so), (events), fdset)
# define DO_UNIX_CHECK_FD_SET(so, events, fdset) 1 /*specific for Unix API */
@@ -323,7 +331,19 @@ int slirp_init(PNATState *ppData, uint32_t u32NetAddr, uint32_t u32Netmask,
#ifdef RT_OS_WINDOWS
{
WSADATA Data;
+ RTLDRMOD hLdrMod;
+
WSAStartup(MAKEWORD(2, 0), &Data);
+
+ rc = RTLdrLoadSystem("Iphlpapi.dll", /* :fNoUnload */ true, &hLdrMod);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTLdrGetSymbol(hLdrMod, "GetAdaptersAddresses", (void **)&pData->pfGetAdaptersAddresses);
+ if (RT_FAILURE(rc))
+ LogRel(("NAT: Can't find GetAdapterAddresses in Iphlpapi.dll\n"));
+
+ RTLdrClose(hLdrMod);
+ }
}
pData->phEvents[VBOX_SOCKET_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
#endif
@@ -870,7 +890,7 @@ static bool slirpConnectOrWrite(PNATState pData, struct socket *so, bool fConnec
}
#if defined(RT_OS_WINDOWS)
-void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp)
+void slirp_select_poll(PNATState pData, int fTimeout)
#else /* RT_OS_WINDOWS */
void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
#endif /* !RT_OS_WINDOWS */
@@ -920,11 +940,7 @@ void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
if (!link_up)
goto done;
#if defined(RT_OS_WINDOWS)
- /*XXX: before renaming please make see define
- * fIcmp in slirp_state.h
- */
- if (fIcmp)
- sorecvfrom(pData, &pData->icmp_socket);
+ icmpwin_process(pData);
#else
if ( (pData->icmp_socket.s != -1)
&& CHECK_FD_SET(&pData->icmp_socket, ignored, readfds))
@@ -957,6 +973,61 @@ void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
LOG_NAT_SOCK(so, TCP, &NetworkEvents, readfds, writefds, xfds);
+ if (so->so_state & SS_ISFCONNECTING)
+ {
+ int sockerr = 0;
+#if !defined(RT_OS_WINDOWS)
+ {
+ int revents = 0;
+
+ /*
+ * Failed connect(2) is reported by poll(2) on
+ * different OSes with different combinations of
+ * POLLERR, POLLHUP, and POLLOUT.
+ */
+ if ( CHECK_FD_SET(so, NetworkEvents, closefds) /* POLLHUP */
+ || CHECK_FD_SET(so, NetworkEvents, rderr)) /* POLLERR */
+ {
+ revents = POLLHUP; /* squash to single "failed" flag */
+ }
+#if defined(RT_OS_SOLARIS) || defined(RT_OS_NETBSD)
+ /* Solaris and NetBSD report plain POLLOUT even on error */
+ else if (CHECK_FD_SET(so, NetworkEvents, writefds)) /* POLLOUT */
+ {
+ revents = POLLOUT;
+ }
+#endif
+
+ if (revents != 0)
+ {
+ socklen_t optlen = (socklen_t)sizeof(sockerr);
+ ret = getsockopt(so->s, SOL_SOCKET, SO_ERROR, &sockerr, &optlen);
+
+ if ( RT_UNLIKELY(ret < 0)
+ || ( (revents & POLLHUP)
+ && RT_UNLIKELY(sockerr == 0)))
+ sockerr = ETIMEDOUT;
+ }
+ }
+#else /* RT_OS_WINDOWS */
+ {
+ if (NetworkEvents.lNetworkEvents & FD_CONNECT)
+ sockerr = NetworkEvents.iErrorCode[FD_CONNECT_BIT];
+ }
+#endif
+ if (sockerr != 0)
+ {
+ tcp_fconnect_failed(pData, so, sockerr);
+ ret = slirpVerifyAndFreeSocket(pData, so);
+ Assert(ret == 1); /* freed */
+ CONTINUE(tcp);
+ }
+
+ /*
+ * XXX: For now just fall through to the old code to
+ * handle successful connect(2).
+ */
+ }
/*
* Check for URG data
@@ -1372,6 +1443,8 @@ void if_encap(PNATState pData, uint16_t eth_proto, struct mbuf *m, int flags)
pData, eth_proto, m, flags));
M_ASSERTPKTHDR(m);
+
+ Assert(M_LEADINGSPACE(m) >= ETH_HLEN);
m->m_data -= ETH_HLEN;
m->m_len += ETH_HLEN;
eh = mtod(m, struct ethhdr *);
@@ -1460,13 +1533,9 @@ static void activate_port_forwarding(PNATState pData, const uint8_t *h_source)
LIST_FOREACH_SAFE(rule, &pData->port_forward_rule_head, list, tmp)
{
struct socket *so;
- struct alias_link *alias_link;
- struct libalias *lib;
- int flags;
struct sockaddr sa;
struct sockaddr_in *psin;
socklen_t socketlen;
- struct in_addr alias;
int rc;
uint32_t guest_addr; /* need to understand if we already give address to guest */
@@ -1496,8 +1565,10 @@ static void activate_port_forwarding(PNATState pData, const uint8_t *h_source)
rule->guest_addr.s_addr = guest_addr;
#endif
- LogRel(("NAT: set redirect %s host port %d => guest port %d @ %RTnaipv4\n",
- rule->proto == IPPROTO_UDP ? "UDP" : "TCP", rule->host_port, rule->guest_port, guest_addr));
+ LogRel(("NAT: set redirect %s host %RTnaipv4:%d => guest %RTnaipv4:%d\n",
+ rule->proto == IPPROTO_UDP ? "UDP" : "TCP",
+ rule->bind_ip.s_addr, rule->host_port,
+ guest_addr, rule->guest_port));
if (rule->proto == IPPROTO_UDP)
so = udp_listen(pData, rule->bind_ip.s_addr, RT_H2N_U16(rule->host_port), guest_addr,
@@ -1519,31 +1590,16 @@ static void activate_port_forwarding(PNATState pData, const uint8_t *h_source)
if (rc < 0 || sa.sa_family != AF_INET)
goto remove_port_forwarding;
- psin = (struct sockaddr_in *)&sa;
-
- lib = LibAliasInit(pData, NULL);
- flags = LibAliasSetMode(lib, 0, 0);
- flags |= pData->i32AliasMode;
- flags |= PKT_ALIAS_REVERSE; /* set reverse */
- flags = LibAliasSetMode(lib, flags, ~0);
-
- alias.s_addr = RT_H2N_U32(RT_N2H_U32(guest_addr) | CTL_ALIAS);
- alias_link = LibAliasRedirectPort(lib, psin->sin_addr, RT_H2N_U16(rule->host_port),
- alias, RT_H2N_U16(rule->guest_port),
- pData->special_addr, -1, /* not very clear for now */
- rule->proto);
- if (!alias_link)
- goto remove_port_forwarding;
-
- so->so_la = lib;
rule->activated = 1;
rule->so = so;
pData->cRedirectionsActive++;
continue;
remove_port_forwarding:
- LogRel(("NAT: failed to redirect %s %d => %d\n",
- (rule->proto == IPPROTO_UDP?"UDP":"TCP"), rule->host_port, rule->guest_port));
+ LogRel(("NAT: failed to redirect %s %RTnaipv4:%d => %RTnaipv4:%d\n",
+ (rule->proto == IPPROTO_UDP ? "UDP" : "TCP"),
+ rule->bind_ip.s_addr, rule->host_port,
+ guest_addr, rule->guest_port));
LIST_REMOVE(rule, list);
pData->cRedirectionsStored--;
RTMemFree(rule);
@@ -1611,10 +1667,11 @@ int slirp_remove_redirect(PNATState pData, int is_udp, struct in_addr host_addr,
&& rule->guest_addr.s_addr == guest_addr.s_addr
&& rule->activated)
{
- LogRel(("NAT: remove redirect %s host port %d => guest port %d @ %RTnaipv4\n",
- rule->proto == IPPROTO_UDP ? "UDP" : "TCP", rule->host_port, rule->guest_port, guest_addr.s_addr));
+ LogRel(("NAT: remove redirect %s host %RTnaipv4:%d => guest %RTnaipv4:%d\n",
+ rule->proto == IPPROTO_UDP ? "UDP" : "TCP",
+ rule->bind_ip.s_addr, rule->host_port,
+ guest_addr.s_addr, rule->guest_port));
- LibAliasUninit(rule->so->so_la);
if (is_udp)
udp_detach(pData, rule->so);
else
@@ -1940,9 +1997,9 @@ static inline int slirp_arp_cache_update(PNATState pData, uint32_t dst, const ui
&& memcmp(mac, zerro_ethaddr, ETH_ALEN)));
LIST_FOREACH(ac, &pData->arp_cache, list)
{
- if (!memcmp(ac->ether, mac, ETH_ALEN))
+ if (ac->ip == dst)
{
- ac->ip = dst;
+ memcpy(ac->ether, mac, ETH_ALEN);
return 0;
}
}
@@ -2046,11 +2103,41 @@ void slirp_info(PNATState pData, const void *pvArg, const char *pszArgs)
}
}
-
+/**
+ * @note: NATState::fUseHostResolver could be changed in bootp.c::dhcp_decode
+ * @note: this function is executed on GUI/VirtualBox or main/VBoxHeadless thread.
+ * @note: this function can potentially race with bootp.c::dhcp_decode (except Darwin)
+ */
int slirp_host_network_configuration_change_strategy_selector(const PNATState pData)
{
- if (pData->fUseHostResolverPermanent) return VBOX_NAT_HNCE_HOSTRESOLVER;
- if (pData->fUseHostResolver) return VBOX_NAT_HNCE_HOSTRESOLVER_TEMPORARY;
- if (pData->fUseDnsProxy) return VBOX_NAT_HNCE_DNSPROXY;
- return VBOX_NAT_HNCE_EXSPOSED_NAME_RESOLUTION_INFO;
+ if (pData->fUseHostResolverPermanent)
+ return VBOX_NAT_DNS_HOSTRESOLVER;
+
+ if (pData->fUseDnsProxy) {
+#if HAVE_NOTIFICATION_FOR_DNS_UPDATE /* XXX */ && !defined(RT_OS_WINDOWS)
+ /* We dont conflict with bootp.c::dhcp_decode */
+ struct rcp_state rcp_state;
+ int rc;
+
+ rcp_state.rcps_flags |= RCPSF_IGNORE_IPV6;
+ rc = rcp_parse(&rcp_state, RESOLV_CONF_FILE);
+ LogRelFunc(("NAT: rcp_parse:%Rrc old domain:%s new domain:%s\n",
+ rc, LIST_FIRST(&pData->pDomainList)->dd_pszDomain,
+ rcp_state.rcps_domain));
+ if ( RT_FAILURE(rc)
+ || LIST_EMPTY(&pData->pDomainList))
+ return VBOX_NAT_DNS_DNSPROXY;
+
+ if ( rcp_state.rcps_domain
+ && strcmp(rcp_state.rcps_domain, LIST_FIRST(&pData->pDomainList)->dd_pszDomain) == 0)
+ return VBOX_NAT_DNS_DNSPROXY;
+ else
+ return VBOX_NAT_DNS_EXTERNAL;
+#else
+ /* copy domain name */
+ /* domain only compare with coy version */
+ return VBOX_NAT_DNS_DNSPROXY;
+#endif
+ }
+ return VBOX_NAT_DNS_EXTERNAL;
}
diff --git a/src/VBox/Devices/Network/slirp/slirp.h b/src/VBox/Devices/Network/slirp/slirp.h
index dde76a4..c2ddcfa 100644
--- a/src/VBox/Devices/Network/slirp/slirp.h
+++ b/src/VBox/Devices/Network/slirp/slirp.h
@@ -87,6 +87,9 @@ typedef int socklen_t;
# undef EHOSTUNREACH
# undef ENETUNREACH
# undef ECONNREFUSED
+# undef ECONNRESET
+# undef EHOSTDOWN
+# undef ENETDOWN
# endif
# define EWOULDBLOCK WSAEWOULDBLOCK
# define EINPROGRESS WSAEINPROGRESS
@@ -94,6 +97,9 @@ typedef int socklen_t;
# define EHOSTUNREACH WSAEHOSTUNREACH
# define ENETUNREACH WSAENETUNREACH
# define ECONNREFUSED WSAECONNREFUSED
+# define ECONNRESET WSAECONNRESET
+# define EHOSTDOWN WSAEHOSTDOWN
+# define ENETDOWN WSAENETDOWN
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
@@ -320,6 +326,7 @@ int ip_output0 (PNATState, struct socket *, struct mbuf *, int urg);
/* tcp_input.c */
int tcp_reass (PNATState, struct tcpcb *, struct tcphdr *, int *, struct mbuf *);
void tcp_input (PNATState, register struct mbuf *, int, struct socket *);
+void tcp_fconnect_failed(PNATState, struct socket *, int);
void tcp_dooptions (PNATState, struct tcpcb *, u_char *, int, struct tcpiphdr *);
void tcp_xmit_timer (PNATState, register struct tcpcb *, int);
int tcp_mss (PNATState, register struct tcpcb *, u_int);
diff --git a/src/VBox/Devices/Network/slirp/slirp_dns.c b/src/VBox/Devices/Network/slirp/slirp_dns.c
index 9ff44c1..d82bda9 100644
--- a/src/VBox/Devices/Network/slirp/slirp_dns.c
+++ b/src/VBox/Devices/Network/slirp/slirp_dns.c
@@ -43,7 +43,7 @@ static int get_dns_addr_domain(PNATState pData,
struct dns_domain_entry *pDomain = NULL;
ULONG ret = ERROR_SUCCESS;
- /* @todo add SKIPing flags to get only required information */
+ /** @todo add SKIPing flags to get only required information */
/* determine size of buffer */
size = 0;
@@ -151,178 +151,79 @@ static int get_dns_addr_domain(PNATState pData,
#else /* !RT_OS_WINDOWS */
-static int RTFileGets(RTFILE File, void *pvBuf, size_t cbBufSize, size_t *pcbRead)
-{
- size_t cbRead;
- char bTest;
- int rc = VERR_NO_MEMORY;
- char *pu8Buf = (char *)pvBuf;
- *pcbRead = 0;
-
- while ( RT_SUCCESS(rc = RTFileRead(File, &bTest, 1, &cbRead))
- && (pu8Buf - (char *)pvBuf) < cbBufSize)
- {
- if (cbRead == 0)
- return VERR_EOF;
+#include "resolv_conf_parser.h"
- if (bTest == '\r' || bTest == '\n')
- {
- *pu8Buf = 0;
- return VINF_SUCCESS;
- }
- *pu8Buf = bTest;
- pu8Buf++;
- (*pcbRead)++;
- }
- return rc;
-}
-
-static int slirpOpenResolvConfFile(PRTFILE pResolvConfFile)
-{
- int rc;
- char buff[512];
- char *etc = NULL;
- char *home = NULL;
- AssertPtrReturn(pResolvConfFile, VERR_INVALID_PARAMETER);
- LogFlowFuncEnter();
-# ifdef RT_OS_OS2
- /* Try various locations. */
- NOREF(home);
- etc = getenv("ETC");
- if (etc)
- {
- RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", etc);
- rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
- }
- if (RT_FAILURE(rc))
- {
- RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", _PATH_ETC);
- rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
- }
- if (RT_FAILURE(rc))
- {
- RTStrmPrintf(buff, sizeof(buff), "%s/resolv.conf", _PATH_ETC);
- rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
- }
-# else /* !RT_OS_OS2 */
-# ifndef DEBUG_vvl
- rc = RTFileOpen(pResolvConfFile, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
-# else
- NOREF(etc);
- home = getenv("HOME");
- RTStrPrintf(buff, sizeof(buff), "%s/resolv.conf", home);
- rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
- if (RT_SUCCESS(rc))
- Log(("NAT: DNS we're using %s\n", buff));
- else
- {
- rc = RTFileOpen(pResolvConfFile, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
- Log(("NAT: DNS we're using %s\n", buff));
- }
-# endif
-# endif /* !RT_OS_OS2 */
- LogFlowFuncLeaveRC(rc);
- return rc;
-}
static int get_dns_addr_domain(PNATState pData, const char **ppszDomain)
{
- char buff[256];
- char buff2[256];
- RTFILE ResolvConfFile;
- int cNameserversFound = 0;
- bool fWarnTooManyDnsServers = false;
- struct in_addr tmp_addr;
+ struct rcp_state st;
int rc;
- size_t bytes;
+ unsigned i;
- rc = slirpOpenResolvConfFile(&ResolvConfFile);
- if (RT_FAILURE(rc))
- {
- LogRel(("NAT: there're some problems with accessing resolv.conf (or known analog), thus NAT switches to use host resolver mechanism\n"));
- pData->fUseHostResolver = 1;
- return VINF_SUCCESS;
- }
+ /* XXX: perhaps IPv6 shouldn't be ignored if we're using DNS proxy */
+ st.rcps_flags = RCPSF_IGNORE_IPV6;
+ rc = rcp_parse(&st, RESOLV_CONF_FILE);
+
+ if (rc < 0)
+ return -1;
+
+ /* for historical reasons: Slirp returns -1 if no nameservers were found */
+ if (st.rcps_num_nameserver == 0)
+ return -1;
- if (ppszDomain)
- *ppszDomain = NULL;
- Log(("NAT: DNS Servers:\n"));
- while ( RT_SUCCESS(rc = RTFileGets(ResolvConfFile, buff, sizeof(buff), &bytes))
- && rc != VERR_EOF)
+ /* XXX: We're composing the list, but we already knows
+ * its size so we can allocate array instead (Linux guests
+ * dont like >3 servers in the list anyway)
+ * or use pre-allocated array in NATState.
+ */
+ for (i = 0; i != st.rcps_num_nameserver; ++i)
{
- struct dns_entry *pDns = NULL;
- if ( cNameserversFound == 4
- && !fWarnTooManyDnsServers
- && sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1)
+ struct dns_entry *pDns;
+ RTNETADDRU *address = &st.rcps_nameserver[i].uAddr;
+ if ( (address->IPv4.u & RT_H2N_U32_C(IN_CLASSA_NET))
+ == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
{
- fWarnTooManyDnsServers = true;
- LogRel(("NAT: too many nameservers registered.\n"));
+ /**
+ * XXX: Note shouldn't patch the address in case of using DNS proxy,
+ * because DNS proxy we do revert it back actually.
+ */
+ if (address->IPv4.u == RT_N2H_U32_C(INADDR_LOOPBACK))
+ address->IPv4.u = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
+ else if (pData->fUseDnsProxy == 0) {
+ /* We detects that using some address in 127/8 network */
+ LogRel(("NAT: DNS server %RTnaipv4 registration detected, switching to the DNS proxy\n", address->IPv4));
+ pData->fUseDnsProxy = 1;
+ }
}
- if ( sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1
- && cNameserversFound < 4) /* Unix doesn't accept more than 4 name servers*/
+
+ pDns = RTMemAllocZ(sizeof(struct dns_entry));
+ if (pDns == NULL)
{
- if (!inet_aton(buff2, &tmp_addr))
- continue;
+ slirpReleaseDnsSettings(pData);
+ return VERR_NO_MEMORY;
+ }
- /* localhost mask */
- pDns = RTMemAllocZ(sizeof (struct dns_entry));
- if (!pDns)
- {
- Log(("can't alloc memory for DNS entry\n"));
- return -1;
- }
+ pDns->de_addr.s_addr = address->IPv4.u;
+ TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
+ }
- /* check */
- pDns->de_addr.s_addr = tmp_addr.s_addr;
- if ((pDns->de_addr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
- {
- if ((pDns->de_addr.s_addr) == RT_N2H_U32_C(INADDR_LOOPBACK))
- pDns->de_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
- else if (pData->fUseDnsProxy != 1)
- {
- /* Modern Ubuntu register 127.0.1.1 as DNS server */
- LogRel(("NAT: DNS server %RTnaipv4 registration detected, switching to the DNS proxy.\n",
- pDns->de_addr.s_addr));
- pData->fUseDnsProxy = 1;
- pData->fUseHostResolver = 0;
- }
- }
- TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
- cNameserversFound++;
- }
- if ((!strncmp(buff, "domain", 6) || !strncmp(buff, "search", 6)))
+ if (st.rcps_domain != 0)
+ {
+ struct dns_domain_entry *pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
+ if (pDomain == NULL)
{
- char *tok;
- char *saveptr;
- struct dns_domain_entry *pDomain = NULL;
- int fFoundDomain = 0;
- tok = strtok_r(&buff[6], " \t\n", &saveptr);
- LIST_FOREACH(pDomain, &pData->pDomainList, dd_list)
- {
- if ( tok != NULL
- && strcmp(tok, pDomain->dd_pszDomain) == 0)
- {
- fFoundDomain = 1;
- break;
- }
- }
- if (tok != NULL && !fFoundDomain)
- {
- pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
- if (!pDomain)
- {
- Log(("NAT: not enought memory to add domain list\n"));
- return VERR_NO_MEMORY;
- }
- pDomain->dd_pszDomain = RTStrDup(tok);
- Log(("NAT: adding domain name %s to search list\n", pDomain->dd_pszDomain));
- LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
- }
+ slirpReleaseDnsSettings(pData);
+ return -1;
}
+
+ pDomain->dd_pszDomain = RTStrDup(st.rcps_domain);
+ LogRel(("NAT: adding domain name %s\n", pDomain->dd_pszDomain));
+ LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
}
- RTFileClose(ResolvConfFile);
- if (!cNameserversFound)
- return -1;
+
+ if (ppszDomain && st.rcps_domain != 0)
+ *ppszDomain = RTStrDup(st.rcps_domain);
+
return 0;
}
@@ -337,7 +238,8 @@ int slirpInitializeDnsSettings(PNATState pData)
{
TAILQ_INIT(&pData->pDnsList);
LIST_INIT(&pData->pDomainList);
- /**
+
+ /*
* Some distributions haven't got /etc/resolv.conf
* so we should other way to configure DNS settings.
*/
@@ -396,6 +298,10 @@ int slirpReleaseDnsSettings(PNATState pData)
RTStrFree(pDomain->dd_pszDomain);
RTMemFree(pDomain);
}
+
+ /* tell any pending dnsproxy requests their copy is expired */
+ ++pData->dnsgen;
+
LogFlowFuncLeaveRC(rc);
return rc;
}
diff --git a/src/VBox/Devices/Network/slirp/slirp_state.h b/src/VBox/Devices/Network/slirp/slirp_state.h
index ffab722..fcfa4ae 100644
--- a/src/VBox/Devices/Network/slirp/slirp_state.h
+++ b/src/VBox/Devices/Network/slirp/slirp_state.h
@@ -95,6 +95,10 @@ struct port_forward_rule
LIST_HEAD(port_forward_rule_list, port_forward_rule);
+#ifdef RT_OS_WINDOWS
+struct pong;
+TAILQ_HEAD(pong_tailq, pong);
+#endif
/* forward declaration */
struct proto_handler;
@@ -146,6 +150,7 @@ typedef struct NATState
#endif
struct dns_list_head pDnsList;
struct dns_domain_list_head pDomainList;
+ uint32_t dnsgen; /* XXX: merge with dnsLastUpdate? */
struct in_addr tftp_server;
struct in_addr loopback_addr;
uint32_t dnsLastUpdate;
@@ -177,8 +182,7 @@ typedef struct NATState
struct udpstat_t udpstat;
struct socket udb;
struct socket *udp_last_so;
- struct socket icmp_socket;
- struct icmp_storage icmp_msg_head;
+
# ifndef RT_OS_WINDOWS
/* counter of sockets needed for allocation enough room to
* process sockets with poll/epoll
@@ -197,17 +201,18 @@ typedef struct NATState
# define NSOCK_INC_EX(ex) do {} while (0)
# define NSOCK_DEC_EX(ex) do {} while (0)
# endif
+
+ struct socket icmp_socket;
+# if !defined(RT_OS_WINDOWS)
+ struct icmp_storage icmp_msg_head;
int cIcmpCacheSize;
int iIcmpCacheLimit;
-# ifdef RT_OS_WINDOWS
- void *pvIcmpBuffer;
- uint32_t cbIcmpBuffer;
- /* According MSDN specification IcmpParseReplies
- * function should be detected at runtime.
- */
- long (WINAPI * pfIcmpParseReplies)(void *, long);
- BOOL (WINAPI * pfIcmpCloseHandle)(HANDLE);
+# else
+ struct pong_tailq pongs_expected;
+ struct pong_tailq pongs_received;
+ size_t cbIcmpPending;
# endif
+
#if defined(RT_OS_WINDOWS)
# define VBOX_SOCKET_EVENT (pData->phEvents[VBOX_SOCKET_EVENT_INDEX])
HANDLE phEvents[VBOX_EVENT_COUNT];
@@ -245,9 +250,17 @@ typedef struct NATState
struct mbstat mbstat;
#endif
uma_zone_t zone_ext_refcnt;
+ /**
+ * in (r89055) using of this behaviour has been changed and mean that Slirp
+ * can't parse hosts strucutures/files to provide to guest host name-resolving
+ * configuration, instead Slirp provides .{interface-number + 1}.3 as a nameserver
+ * and proxies DNS queiries to Host's Name Resolver API.
+ */
bool fUseHostResolver;
- /** Flag whether using the host resolver mode is permanent
- * because the user configured it that way. */
+ /**
+ * Flag whether using the host resolver mode is permanent
+ * because the user configured it that way.
+ */
bool fUseHostResolverPermanent;
/* from dnsproxy/dnsproxy.h*/
unsigned int authoritative_port;
@@ -283,7 +296,6 @@ typedef struct NATState
LIST_HEAD(RT_NOTHING, libalias) instancehead;
int i32AliasMode;
struct libalias *proxy_alias;
- struct libalias *dns_alias;
LIST_HEAD(handler_chain, proto_handler) handler_chain;
struct port_forward_rule_list port_forward_rule_head;
int cRedirectionsActive;
@@ -421,7 +433,7 @@ typedef struct NATState
(so) = (sonext)) \
{ \
(sonext) = (so)->so_next; \
- Log2(("%s:%d Processing so:%R[natsock]\n", __FUNCTION__, __LINE__, (so)));
+ Log5(("%s:%d Processing so:%R[natsock]\n", __FUNCTION__, __LINE__, (so)));
# define CONTINUE(label) continue
# define CONTINUE_NO_UNLOCK(label) continue
# define LOOP_LABEL(label, so, sonext) /* empty*/
diff --git a/src/VBox/Devices/Network/slirp/socket.c b/src/VBox/Devices/Network/slirp/socket.c
index 5a5bae6..24a02ea 100644
--- a/src/VBox/Devices/Network/slirp/socket.c
+++ b/src/VBox/Devices/Network/slirp/socket.c
@@ -127,10 +127,9 @@ DECLINLINE(bool) slirpSend2Home(PNATState pData, struct socket *pSo, const void
return fSendDone;
}
#endif /* !VBOX_WITH_NAT_SEND2HOME */
+
+#if !defined(RT_OS_WINDOWS)
static void send_icmp_to_guest(PNATState, char *, size_t, const struct sockaddr_in *);
-#ifdef RT_OS_WINDOWS
-static void sorecvfrom_icmp_win(PNATState, struct socket *);
-#else /* RT_OS_WINDOWS */
static void sorecvfrom_icmp_unix(PNATState, struct socket *);
#endif /* !RT_OS_WINDOWS */
@@ -208,12 +207,6 @@ sofree(PNATState pData, struct socket *so)
else if (so == udp_last_so)
udp_last_so = &udb;
-#if 0 /* XXX: !defined(NO_USE_SOCKETS) */
- /* libalias notification */
- if (so->so_pvLnk)
- slirpDeleteLinkSocket(so->so_pvLnk);
-#endif
-
/* check if mbuf haven't been already freed */
if (so->so_m != NULL)
{
@@ -221,6 +214,12 @@ sofree(PNATState pData, struct socket *so)
so->so_m = NULL;
}
+ if (so->so_ohdr != NULL)
+ {
+ RTMemFree(so->so_ohdr);
+ so->so_ohdr = NULL;
+ }
+
if (so->so_next && so->so_prev)
{
remque(pData, so); /* crashes if so is not in a queue */
@@ -811,17 +810,18 @@ sorecvfrom(PNATState pData, struct socket *so)
{
LogFlowFunc(("sorecvfrom: so = %lx\n", (long)so));
+#ifdef RT_OS_WINDOWS
+ /* ping is handled with ICMP API in ip_icmpwin.c */
+ Assert(so->so_type == IPPROTO_UDP);
+#else
if (so->so_type == IPPROTO_ICMP)
{
/* This is a "ping" reply */
-#ifdef RT_OS_WINDOWS
- sorecvfrom_icmp_win(pData, so);
-#else /* RT_OS_WINDOWS */
sorecvfrom_icmp_unix(pData, so);
-#endif /* !RT_OS_WINDOWS */
udp_detach(pData, so);
}
else
+#endif /* !RT_OS_WINDOWS */
{
static uint8_t au8Buf[64 * 1024];
@@ -878,7 +878,10 @@ sorecvfrom(PNATState pData, struct socket *so)
status = WSARecvFrom(so->s, iov, 2, &nbytes, &flags,
(struct sockaddr *)&addr, &addrlen,
NULL, NULL);
- nread = (status != SOCKET_ERROR) ? nbytes : -1;
+ if (status != SOCKET_ERROR)
+ nread = nbytes;
+ else
+ nread = -1;
}
#endif
if (nread >= 0)
@@ -925,7 +928,6 @@ sorecvfrom(PNATState pData, struct socket *so)
else
{
m_freem(pData, m);
- so->so_m = NULL;
if (!soIgnorableErrorCode(errno))
{
@@ -939,6 +941,7 @@ sorecvfrom(PNATState pData, struct socket *so)
Log2((" rx error, tx icmp ICMP_UNREACH:%i\n", code));
icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
+ so->so_m = NULL;
}
}
@@ -1271,6 +1274,7 @@ sofwdrain(struct socket *so)
sofcantsendmore(so);
}
+#if !defined(RT_OS_WINDOWS)
static void
send_icmp_to_guest(PNATState pData, char *buff, size_t len, const struct sockaddr_in *addr)
{
@@ -1441,155 +1445,6 @@ send_icmp_to_guest(PNATState pData, char *buff, size_t len, const struct sockadd
RTMemFree(icm);
}
-#ifdef RT_OS_WINDOWS
-static void
-sorecvfrom_icmp_win(PNATState pData, struct socket *so)
-{
- int len;
- int i;
- struct ip *ip;
- struct mbuf *m;
- struct icmp *icp;
- struct icmp_msg *icm;
- struct ip *ip_broken; /* ICMP returns header + 64 bit of packet */
- uint32_t src;
- ICMP_ECHO_REPLY *icr;
- int hlen = 0;
- int nbytes = 0;
- u_char code = ~0;
- int out_len;
- int size;
-
- len = pData->pfIcmpParseReplies(pData->pvIcmpBuffer, pData->cbIcmpBuffer);
- if (len < 0)
- {
- LogRel(("NAT: Error (%d) occurred on ICMP receiving\n", GetLastError()));
- return;
- }
- if (len == 0)
- return; /* no error */
-
- icr = (ICMP_ECHO_REPLY *)pData->pvIcmpBuffer;
- for (i = 0; i < len; ++i)
- {
- LogFunc(("icr[%d] Data:%p, DataSize:%d\n",
- i, icr[i].Data, icr[i].DataSize));
- switch(icr[i].Status)
- {
- case IP_DEST_HOST_UNREACHABLE:
- code = (code != ~0 ? code : ICMP_UNREACH_HOST);
- case IP_DEST_NET_UNREACHABLE:
- code = (code != ~0 ? code : ICMP_UNREACH_NET);
- case IP_DEST_PROT_UNREACHABLE:
- code = (code != ~0 ? code : ICMP_UNREACH_PROTOCOL);
- /* UNREACH error inject here */
- case IP_DEST_PORT_UNREACHABLE:
- code = (code != ~0 ? code : ICMP_UNREACH_PORT);
- icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, "Error occurred!!!");
- so->so_m = NULL;
- break;
- case IP_SUCCESS: /* echo replied */
- out_len = ETH_HLEN + sizeof(struct ip) + 8;
- size;
- size = MCLBYTES;
- if (out_len < MSIZE)
- size = MCLBYTES;
- else if (out_len < MCLBYTES)
- size = MCLBYTES;
- else if (out_len < MJUM9BYTES)
- size = MJUM9BYTES;
- else if (out_len < MJUM16BYTES)
- size = MJUM16BYTES;
- else
- AssertMsgFailed(("Unsupported size"));
-
- m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, size);
- LogFunc(("m_getjcl returns m: %p\n", m));
- if (m == NULL)
- return;
- m->m_len = 0;
- m->m_data += if_maxlinkhdr;
- m->m_pkthdr.header = mtod(m, void *);
-
- ip = mtod(m, struct ip *);
- ip->ip_src.s_addr = icr[i].Address;
- ip->ip_p = IPPROTO_ICMP;
- ip->ip_dst.s_addr = so->so_laddr.s_addr; /*XXX: still the hack*/
- ip->ip_hl = sizeof(struct ip) >> 2; /* requiered for icmp_reflect, no IP options */
- ip->ip_ttl = icr[i].Options.Ttl;
-
- icp = (struct icmp *)&ip[1]; /* no options */
- icp->icmp_type = ICMP_ECHOREPLY;
- icp->icmp_code = 0;
- icp->icmp_id = so->so_icmp_id;
- icp->icmp_seq = so->so_icmp_seq;
-
- icm = icmp_find_original_mbuf(pData, ip);
- if (icm)
- {
- /* on this branch we don't need stored variant */
- m_freem(pData, icm->im_m);
- LIST_REMOVE(icm, im_list);
- pData->cIcmpCacheSize--;
- RTMemFree(icm);
- }
-
-
- hlen = (ip->ip_hl << 2);
- Assert((hlen >= sizeof(struct ip)));
-
- m->m_data += hlen + ICMP_MINLEN;
- if (!RT_VALID_PTR(icr[i].Data))
- {
- m_freem(pData, m);
- break;
- }
- m_copyback(pData, m, 0, icr[i].DataSize, icr[i].Data);
- m->m_data -= hlen + ICMP_MINLEN;
- m->m_len += hlen + ICMP_MINLEN;
-
-
- ip->ip_len = m_length(m, NULL);
- Assert((ip->ip_len == hlen + ICMP_MINLEN + icr[i].DataSize));
-
- icmp_reflect(pData, m);
- break;
- case IP_TTL_EXPIRED_TRANSIT: /* TTL expired */
-
- ip_broken = icr[i].Data;
- icm = icmp_find_original_mbuf(pData, ip_broken);
- if (icm == NULL) {
- Log(("ICMP: can't find original package (first double word %x)\n", *(uint32_t *)ip_broken));
- return;
- }
- m = icm->im_m;
- ip = mtod(m, struct ip *);
- Assert(((ip_broken->ip_hl >> 2) >= sizeof(struct ip)));
- ip->ip_ttl = icr[i].Options.Ttl;
- src = ip->ip_src.s_addr;
- ip->ip_dst.s_addr = src;
- ip->ip_dst.s_addr = icr[i].Address;
-
- hlen = (ip->ip_hl << 2);
- icp = (struct icmp *)((char *)ip + hlen);
- ip_broken->ip_src.s_addr = src; /*it packet sent from host not from guest*/
-
- m->m_len = (ip_broken->ip_hl << 2) + 64;
- m->m_pkthdr.header = mtod(m, void *);
- m_copyback(pData, m, ip->ip_hl >> 2, icr[i].DataSize, icr[i].Data);
- icmp_reflect(pData, m);
- /* Here is different situation from Unix world, where we can receive icmp in response on TCP/UDP */
- LIST_REMOVE(icm, im_list);
- pData->cIcmpCacheSize--;
- RTMemFree(icm);
- break;
- default:
- Log(("ICMP(default): message with Status: %x was received from %x\n", icr[i].Status, icr[i].Address));
- break;
- }
- }
-}
-#else /* !RT_OS_WINDOWS */
static void sorecvfrom_icmp_unix(PNATState pData, struct socket *so)
{
struct sockaddr_in addr;
diff --git a/src/VBox/Devices/Network/slirp/socket.h b/src/VBox/Devices/Network/slirp/socket.h
index 65e0505..6f14e3f 100644
--- a/src/VBox/Devices/Network/slirp/socket.h
+++ b/src/VBox/Devices/Network/slirp/socket.h
@@ -58,6 +58,7 @@ struct socket
* PING reply's */
struct tcpiphdr *so_ti; /* Pointer to the original ti within
* so_mconn, for non-blocking connections */
+ uint8_t *so_ohdr; /* unmolested IP header of the datagram in so_m */
int so_urgc;
struct in_addr so_faddr; /* foreign host table entry */
struct in_addr so_laddr; /* local host table entry */
@@ -100,10 +101,7 @@ struct socket
/* storage of source ether address */
unsigned char so_ethaddr[6];
#endif
- /* required for port-forwarding */
- struct libalias *so_la;
- /* libalias might attach the socket and we want to notify libalias we're freeing it */
- void *so_pvLnk;
+
#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
struct socket *so_cloneOf; /* pointer to master instance */
int so_cCloneCounter; /* number of clones */
@@ -132,10 +130,6 @@ struct socket
int fShouldBeRemoved;
};
-/* this function inform libalias about socket close */
-void slirpDeleteLinkSocket(void *pvLnk);
-
-
# define SOCKET_LOCK(so) do {} while (0)
# define SOCKET_UNLOCK(so) do {} while (0)
# define SOCKET_LOCK_CREATE(so) do {} while (0)
diff --git a/src/VBox/Devices/Network/slirp/tcp_input.c b/src/VBox/Devices/Network/slirp/tcp_input.c
index dd67b06..167a123 100644
--- a/src/VBox/Devices/Network/slirp/tcp_input.c
+++ b/src/VBox/Devices/Network/slirp/tcp_input.c
@@ -289,7 +289,7 @@ present:
void
tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *inso)
{
- struct ip save_ip, *ip;
+ struct ip *ip, *save_ip;
register struct tcpiphdr *ti;
caddr_t optp = NULL;
int optlen = 0;
@@ -302,6 +302,9 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
int iss = 0;
u_long tiwin;
/* int ts_present = 0; */
+ size_t ohdrlen;
+ uint8_t ohdr[60 + 8]; /* max IP header plus 8 bytes of payload for icmp */
+
STAM_PROFILE_START(&pData->StatTCP_input, counter_input);
LogFlow(("tcp_input: m = %8lx, iphlen = %2d, inso = %R[natsock]\n",
@@ -323,8 +326,14 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
/* Re-set a few variables */
tp = sototcpcb(so);
m = so->so_m;
-
so->so_m = 0;
+
+ if (RT_LIKELY(so->so_ohdr != NULL))
+ {
+ RTMemFree(so->so_ohdr);
+ so->so_ohdr = NULL;
+ }
+
ti = so->so_ti;
/** @todo (vvl) clarify why it might happens */
@@ -346,6 +355,32 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
}
tcpstat.tcps_rcvtotal++;
+
+ ip = mtod(m, struct ip *);
+
+ /* ip_input() subtracts iphlen from ip::ip_len */
+ AssertStmt((ip->ip_len + iphlen == m_length(m, NULL)), goto drop);
+ if (RT_UNLIKELY(ip->ip_len < sizeof(struct tcphdr)))
+ {
+ /* tcps_rcvshort++; */
+ goto drop;
+ }
+
+ /*
+ * Save a copy of the IP header in case we want to restore it for
+ * sending an ICMP error message in response.
+ *
+ * XXX: This function should really be fixed to not strip IP
+ * options, to not overwrite IP header and to use "tlen" local
+ * variable (instead of ti->ti_len), then "m" could be passed to
+ * icmp_error() directly.
+ */
+ ohdrlen = iphlen + 8;
+ m_copydata(m, 0, ohdrlen, (caddr_t)ohdr);
+ save_ip = (struct ip *)ohdr;
+ save_ip->ip_len += iphlen; /* undo change by ip_input() */
+
+
/*
* Get IP and TCP header together in first mbuf.
* Note: IP leaves IP header in first mbuf.
@@ -356,21 +391,6 @@ tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *i
ip_stripoptions(m, (struct mbuf *)0);
iphlen = sizeof(struct ip);
}
- /* XXX Check if too short */
-
-
- /*
- * Save a copy of the IP header in case we want restore it
- * for sending an ICMP error message in response.
- */
- ip = mtod(m, struct ip *);
- /*
- * (vvl) ip_input substracts IP header length from ip->ip_len value.
- * here we do the test the same as input method of UDP protocol.
- */
- Assert((ip->ip_len + iphlen == m_length(m, NULL)));
- save_ip = *ip;
- save_ip.ip_len+= iphlen;
/*
* Checksum extended TCP header and data.
@@ -801,7 +821,7 @@ findso:
HTONS(ti->ti_urp);
m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
- *ip = save_ip;
+ *ip = *save_ip;
icmp_error(pData, m, ICMP_UNREACH, code, 0, strerror(errno));
tp->t_socket->so_m = NULL;
}
@@ -817,6 +837,7 @@ findso:
*/
so->so_m = m;
so->so_ti = ti;
+ so->so_ohdr = RTMemDup(ohdr, ohdrlen);
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
TCP_STATE_SWITCH_TO(tp, TCPS_SYN_RECEIVED);
}
@@ -1742,6 +1763,67 @@ drop:
return;
}
+
+void
+tcp_fconnect_failed(PNATState pData, struct socket *so, int sockerr)
+{
+ struct tcpcb *tp;
+ int code;
+
+ Log2(("NAT: connect error %d %R[natsock]\n", sockerr, so));
+
+ Assert(so->so_state & SS_ISFCONNECTING);
+ so->so_state = SS_NOFDREF;
+
+ if (sockerr == ECONNREFUSED || sockerr == ECONNRESET)
+ {
+ /* hand off to tcp_input():cont_conn to send RST */
+ TCP_INPUT(pData, NULL, 0, so);
+ return;
+ }
+
+ tp = sototcpcb(so);
+ if (RT_UNLIKELY(tp == NULL)) /* should never happen */
+ {
+ LogRel(("NAT: tp == NULL %R[natsock]\n", so));
+ sofree(pData, so);
+ return;
+ }
+
+ if (sockerr == ENETUNREACH || sockerr == ENETDOWN)
+ code = ICMP_UNREACH_NET;
+ else if (sockerr == EHOSTUNREACH || sockerr == EHOSTDOWN)
+ code = ICMP_UNREACH_HOST;
+ else
+ code = -1;
+
+ if (code >= 0)
+ {
+ struct ip *oip;
+ size_t ohdrlen;
+ struct mbuf *m;
+
+ if (RT_UNLIKELY(so->so_ohdr == NULL))
+ goto out;
+
+ oip = (struct ip *)so->so_ohdr;
+ ohdrlen = oip->ip_hl * 4 + 8;
+
+ m = m_gethdr(pData, M_NOWAIT, MT_HEADER);
+ if (RT_UNLIKELY(m == NULL))
+ goto out;
+
+ m_copyback(pData, m, 0, ohdrlen, (caddr_t)so->so_ohdr);
+ m->m_pkthdr.header = mtod(m, void *);
+
+ icmp_error(pData, m, ICMP_UNREACH, code, 0, NULL);
+ }
+
+ out:
+ tcp_close(pData, tp);
+}
+
+
void
tcp_dooptions(PNATState pData, struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
{
diff --git a/src/VBox/Devices/Network/slirp/tcp_subr.c b/src/VBox/Devices/Network/slirp/tcp_subr.c
index be5ef84..c18dde6 100644
--- a/src/VBox/Devices/Network/slirp/tcp_subr.c
+++ b/src/VBox/Devices/Network/slirp/tcp_subr.c
@@ -125,13 +125,10 @@ void
tcp_respond(PNATState pData, struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags)
{
register int tlen;
- int win = 0;
LogFlowFunc(("ENTER: tp = %R[tcpcb793], ti = %lx, m = %lx, ack = %u, seq = %u, flags = %x\n",
tp, (long)ti, (long)m, ack, seq, flags));
- if (tp)
- win = sbspace(&tp->t_socket->so_rcv);
if (m == 0)
{
if ((m = m_gethdr(pData, M_DONTWAIT, MT_HEADER)) == NULL)
@@ -173,9 +170,12 @@ tcp_respond(PNATState pData, struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf
ti->ti_off = sizeof (struct tcphdr) >> 2;
ti->ti_flags = flags;
if (tp)
+ {
+ int win = sbspace(&tp->t_socket->so_rcv);
ti->ti_win = RT_H2N_U16((u_int16_t) (win >> tp->rcv_scale));
+ }
else
- ti->ti_win = RT_H2N_U16((u_int16_t)win);
+ ti->ti_win = 0;
ti->ti_urp = 0;
ti->ti_sum = 0;
ti->ti_sum = cksum(m, tlen);
@@ -505,7 +505,6 @@ tcp_connect(PNATState pData, struct socket *inso)
}
so->so_laddr = inso->so_laddr;
so->so_lport = inso->so_lport;
- so->so_la = inso->so_la;
}
(void) tcp_mss(pData, sototcpcb(so), 0);
diff --git a/src/VBox/Devices/Network/slirp/udp.c b/src/VBox/Devices/Network/slirp/udp.c
index 98ca8c3..01cdf66 100644
--- a/src/VBox/Devices/Network/slirp/udp.c
+++ b/src/VBox/Devices/Network/slirp/udp.c
@@ -344,19 +344,7 @@ udp_input(PNATState pData, register struct mbuf *m, int iphlen)
*ip = save_ip;
Log2(("NAT: UDP tx errno = %d (%s) on sent to %RTnaipv4\n",
errno, strerror(errno), ip->ip_dst));
-#if 0
- /* ICMP_SOURCEQUENCH haven't got any effect, the idea here
- * inform guest about the exosting NAT resources with assumption that
- * that guest reduce traffic. But it doesn't work
- */
- if( errno == EAGAIN
- || errno == EWOULDBLOCK
- || errno == EINPROGRESS
- || errno == ENOTCONN)
- icmp_error(pData, m, ICMP_SOURCEQUENCH, 0, 1, strerror(errno));
- else
-#endif
- icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
+ icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
so->so_m = NULL;
LogFlowFuncLeave();
return;
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
index b8c6a9f..d9fffa3 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.asm
@@ -965,7 +965,7 @@ section CONST progbits vstart=0xb0 align=1 ; size=0xcf8 class=DATA group=DGROUP
section CONST2 progbits vstart=0xda8 align=1 ; size=0x3fa class=DATA group=DGROUP
_bios_cvs_version_string: ; 0xf0da8 LB 0x12
- db 'VirtualBox 4.3.20', 000h
+ db 'VirtualBox 4.3.22', 000h
_bios_prefix_string: ; 0xf0dba LB 0x8
db 'BIOS: ', 000h, 000h
_isotag: ; 0xf0dc2 LB 0x6
@@ -16070,4 +16070,4 @@ dummy_iret: ; 0xfff53 LB 0x9d
db 'XM'
cpu_reset: ; 0xffff0 LB 0x10
jmp far 0f000h:0e05bh ; ea 5b e0 00 f0
- db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 003h
+ db 030h, 036h, 02fh, 032h, 033h, 02fh, 039h, 039h, 000h, 0fch, 001h
diff --git a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
index 6a481cc..b69e107 100644
--- a/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
+++ b/src/VBox/Devices/PC/BIOS/VBoxBiosAlternative.md5sum
@@ -1 +1 @@
-ee569a1dd9437f09dd31efdf6fe2de72 *VBoxPcBios.rom
+326fd38fc077b04f5130d31a86caf685 *VBoxPcBios.rom
diff --git a/src/VBox/Devices/PC/DevACPI.cpp b/src/VBox/Devices/PC/DevACPI.cpp
index 740b5a2..b807d94 100644
--- a/src/VBox/Devices/PC/DevACPI.cpp
+++ b/src/VBox/Devices/PC/DevACPI.cpp
@@ -853,6 +853,24 @@ static DECLCALLBACK(int) acpiR3Port_SleepButtonPress(PPDMIACPIPORT pInterface)
}
/**
+ * Send an ACPI monitor hot-plug event.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the
+ * called function pointer.
+ */
+static DECLCALLBACK(int) acpiR3Port_MonitorHotPlugEvent(PPDMIACPIPORT pInterface)
+{
+ ACPIState *pThis = RT_FROM_MEMBER(pInterface, ACPIState, IACPIPort);
+ DEVACPI_LOCK_R3(pThis);
+
+ apicR3UpdateGpe0(pThis, pThis->gpe0_sts | 0x4, pThis->gpe0_en);
+
+ DEVACPI_UNLOCK(pThis);
+ return VINF_SUCCESS;
+}
+
+/**
* Used by acpiR3PmTimer to re-arm the PM timer.
*
* The caller is expected to either hold the clock lock or to have made sure
@@ -2988,6 +3006,7 @@ static DECLCALLBACK(int) acpiR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFG
pThis->IACPIPort.pfnGetPowerButtonHandled = acpiR3Port_GetPowerButtonHandled;
pThis->IACPIPort.pfnGetGuestEnteredACPIMode = acpiR3Port_GetGuestEnteredACPIMode;
pThis->IACPIPort.pfnGetCpuStatus = acpiR3Port_GetCpuStatus;
+ pThis->IACPIPort.pfnMonitorHotPlugEvent = acpiR3Port_MonitorHotPlugEvent;
/*
* Set the default critical section to NOP (related to the PM timer).
diff --git a/src/VBox/Devices/PC/vbox.dsl b/src/VBox/Devices/PC/vbox.dsl
index 1a7b330..f914b6a 100644
--- a/src/VBox/Devices/PC/vbox.dsl
+++ b/src/VBox/Devices/PC/vbox.dsl
@@ -909,6 +909,41 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "VBOX ", "VBOXBIOS", 2)
}
}
+ // Graphics device
+ Device (GFX0)
+ {
+ Name (_ADR, 0x00020000)
+
+ Scope (\_GPE)
+ {
+ // GPE bit 2 handler
+ // GPE.2 must be set and SCI raised when
+ // display information changes.
+ Method (_L02, 0, NotSerialized)
+ {
+ Notify (\_SB.PCI0.GFX0, 0x81)
+ }
+ }
+
+ Method (_DOS, 1) { }
+
+ Method (_DOD, 0, NotSerialized)
+ {
+ Return (Package()
+ {
+ 0x80000100
+ })
+ }
+
+ Device (VGA)
+ {
+ Method (_ADR, 0, Serialized)
+ {
+ Return (0x0100)
+ }
+ }
+ }
+
// HDA Audio card
Device (HDEF)
{
diff --git a/src/VBox/Devices/Storage/DevAHCI.cpp b/src/VBox/Devices/Storage/DevAHCI.cpp
index 875ae4d..3c91e33 100644
--- a/src/VBox/Devices/Storage/DevAHCI.cpp
+++ b/src/VBox/Devices/Storage/DevAHCI.cpp
@@ -4168,7 +4168,7 @@ static int atapiReadDVDStructureSS(PAHCIREQ pAhciReq, PAHCIPort pAhciPort, size_
int media = pAhciReq->aATAPICmd[1];
int format = pAhciReq->aATAPICmd[7];
- uint16_t max_len = ataBE2H_U16(&pAhciReq->aATAPICmd[8]);
+ uint16_t max_len = RT_MIN(ataBE2H_U16(&pAhciReq->aATAPICmd[8]), sizeof(aBuf));
memset(buf, 0, max_len);
@@ -6635,6 +6635,14 @@ static DECLCALLBACK(int) ahciAsyncIOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
ASMAtomicWriteBool(&pAhciPort->fWrkThreadSleeping, false);
ASMAtomicIncU32(&pAhci->cThreadsActive);
+ /* Check whether the thread should be suspended. */
+ if (pAhci->fSignalIdle)
+ {
+ if (!ASMAtomicDecU32(&pAhci->cThreadsActive))
+ PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3);
+ continue;
+ }
+
/*
* Check whether the global host controller bit is set and go to sleep immediately again
* if it is set.
@@ -6644,6 +6652,8 @@ static DECLCALLBACK(int) ahciAsyncIOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
&& !ASMAtomicDecU32(&pAhci->cThreadsActive))
{
ahciHBAReset(pAhci);
+ if (pAhci->fSignalIdle)
+ PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3);
continue;
}
@@ -6860,6 +6870,9 @@ static DECLCALLBACK(int) ahciAsyncIOLoop(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
if ( (u32RegHbaCtrl & AHCI_HBA_CTRL_HR)
&& !cThreadsActive)
ahciHBAReset(pAhci);
+
+ if (!cThreadsActive && pAhci->fSignalIdle)
+ PDMDevHlpAsyncNotificationCompleted(pAhciPort->pDevInsR3);
} /* While running */
ahciLog(("%s: Port %d async IO thread exiting\n", __FUNCTION__, pAhciPort->iLUN));
@@ -8100,14 +8113,8 @@ static DECLCALLBACK(int) ahciR3Destruct(PPDMDEVINS pDevIns)
}
#ifdef VBOX_STRICT
- /* Check that all cached tasks were freed at this point. */
- for (unsigned iPort = 0; iPort < pThis->cPortsImpl; iPort++)
- {
- PAHCIPort pAhciPort = &pThis->ahciPort[iPort];
-
- for (uint32_t i = 0; i < AHCI_NR_COMMAND_SLOTS; i++)
- Assert(!pAhciPort->aCachedTasks[i]);
- }
+ for (uint32_t i = 0; i < AHCI_NR_COMMAND_SLOTS; i++)
+ Assert(!pAhciPort->aCachedTasks[i]);
#endif
}
diff --git a/src/VBox/Devices/Storage/DevATA.cpp b/src/VBox/Devices/Storage/DevATA.cpp
index 009f80f..ec50f91 100644
--- a/src/VBox/Devices/Storage/DevATA.cpp
+++ b/src/VBox/Devices/Storage/DevATA.cpp
@@ -182,10 +182,14 @@ typedef struct ATADevState
uint32_t cbElementaryTransfer;
/** Maximum ATAPI elementary transfer size, PIO only. */
uint32_t cbPIOTransferLimit;
+ /** ATAPI passthrough transfer size, shared PIO/DMA */
+ uint32_t cbAtapiPassthroughTransfer;
/** Current read/write buffer position, shared PIO/DMA. */
uint32_t iIOBufferCur;
/** First element beyond end of valid buffer content, shared PIO/DMA. */
uint32_t iIOBufferEnd;
+ /** Align the following fields correctly. */
+ uint32_t Alignment0;
/** ATA/ATAPI current PIO read/write transfer position. Not shared with DMA for safety reasons. */
uint32_t iIOBufferPIODataStart;
@@ -1736,6 +1740,7 @@ static void atapiCmdError(ATADevState *s, const uint8_t *pabATAPISense, size_t c
memcpy(s->abATAPISense, pabATAPISense, RT_MIN(cbATAPISense, sizeof(s->abATAPISense)));
s->cbTotalTransfer = 0;
s->cbElementaryTransfer = 0;
+ s->cbAtapiPassthroughTransfer = 0;
s->iIOBufferCur = 0;
s->iIOBufferEnd = 0;
s->uTxDir = PDMBLOCKTXDIR_NONE;
@@ -1762,6 +1767,7 @@ static void atapiCmdBT(ATADevState *s)
{
s->fATAPITransfer = true;
s->cbElementaryTransfer = s->cbTotalTransfer;
+ s->cbAtapiPassthroughTransfer = s->cbTotalTransfer;
s->cbPIOTransferLimit = s->uATARegLCyl | (s->uATARegHCyl << 8);
if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
atapiCmdOK(s);
@@ -1952,7 +1958,7 @@ static bool atapiPassthroughSS(ATADevState *s)
uint32_t cbTransfer;
PSTAMPROFILEADV pProf = NULL;
- cbTransfer = RT_MIN(s->cbTotalTransfer, s->cbIOBuffer);
+ cbTransfer = RT_MIN(s->cbAtapiPassthroughTransfer, s->cbIOBuffer);
if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
Log3(("ATAPI PT data write (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
@@ -2178,7 +2184,7 @@ static bool atapiPassthroughSS(ATADevState *s)
if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
{
- Assert(cbTransfer <= s->cbTotalTransfer);
+ Assert(cbTransfer <= s->cbAtapiPassthroughTransfer);
/*
* Reply with the same amount of data as the real drive
* but only if the command wasn't split.
@@ -2208,7 +2214,7 @@ static bool atapiPassthroughSS(ATADevState *s)
* transfer size. But the I/O buffer size limits what can actually be
* done in one transfer, so set the actual value of the buffer end. */
s->cbElementaryTransfer = cbTransfer;
- if (cbTransfer >= s->cbTotalTransfer)
+ if (cbTransfer >= s->cbAtapiPassthroughTransfer)
{
s->iSourceSink = ATAFN_SS_NULL;
atapiCmdOK(s);
@@ -3750,6 +3756,7 @@ static bool ataPacketSS(ATADevState *s)
s->uTxDir = PDMBLOCKTXDIR_NONE;
s->cbTotalTransfer = 0;
s->cbElementaryTransfer = 0;
+ s->cbAtapiPassthroughTransfer = 0;
atapiParseCmd(s);
return false;
}
@@ -3842,6 +3849,7 @@ static DECLCALLBACK(void) ataUnmountNotify(PPDMIMOUNTNOTIFY pInterface)
static void ataPacketBT(ATADevState *s)
{
s->cbElementaryTransfer = s->cbTotalTransfer;
+ s->cbAtapiPassthroughTransfer = s->cbTotalTransfer;
s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_CD;
Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector));
ataSetStatusValue(s, ATA_STAT_READY);
@@ -3861,6 +3869,7 @@ static void ataResetDevice(ATADevState *s)
ataSetSignature(s);
s->cbTotalTransfer = 0;
s->cbElementaryTransfer = 0;
+ s->cbAtapiPassthroughTransfer = 0;
s->iIOBufferPIODataStart = 0;
s->iIOBufferPIODataEnd = 0;
s->iBeginTransfer = ATAFN_BT_NULL;
diff --git a/src/VBox/Devices/Storage/DrvVD.cpp b/src/VBox/Devices/Storage/DrvVD.cpp
index 803ff1d..d018669 100644
--- a/src/VBox/Devices/Storage/DrvVD.cpp
+++ b/src/VBox/Devices/Storage/DrvVD.cpp
@@ -198,6 +198,8 @@ typedef struct VBOXDISK
VDINTERFACECRYPTO VDIfCrypto;
/** The secret key interface used to retrieve keys. */
PPDMISECKEY pIfSecKey;
+ /** The secret key helper interface used to notify about missing keys. */
+ PPDMISECKEYHLP pIfSecKeyHlp;
/** @} */
} VBOXDISK, *PVBOXDISK;
@@ -725,7 +727,8 @@ static DECLCALLBACK(int) drvvdINIPSocketDestroy(VDSOCKET Sock)
}
/** @copydoc VDINTERFACETCPNET::pfnClientConnect */
-static DECLCALLBACK(int) drvvdINIPClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort)
+static DECLCALLBACK(int) drvvdINIPClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort,
+ RTMSINTERVAL cMillies)
{
int rc = VINF_SUCCESS;
PINIPSOCKET pSocketInt = (PINIPSOCKET)Sock;
@@ -735,6 +738,8 @@ static DECLCALLBACK(int) drvvdINIPClientConnect(VDSOCKET Sock, const char *pszAd
ip6_addr_t ip6;
#endif
+ NOREF(cMillies); /** LwIP doesn't support connect timeout. */
+
/* Check whether lwIP is set up in this VM instance. */
if (!DevINIPConfigured())
{
@@ -1164,12 +1169,13 @@ static DECLCALLBACK(int) drvvdTcpSocketDestroy(VDSOCKET Sock)
}
/** @copydoc VDINTERFACETCPNET::pfnClientConnect */
-static DECLCALLBACK(int) drvvdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort)
+static DECLCALLBACK(int) drvvdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort,
+ RTMSINTERVAL cMillies)
{
int rc = VINF_SUCCESS;
PVDSOCKETINT pSockInt = (PVDSOCKETINT)Sock;
- rc = RTTcpClientConnect(pszAddress, uPort, &pSockInt->hSocket);
+ rc = RTTcpClientConnectEx(pszAddress, uPort, &pSockInt->hSocket, cMillies, NULL);
if (RT_SUCCESS(rc))
{
/* Add to the pollset if required. */
@@ -1536,6 +1542,28 @@ static DECLCALLBACK(int) drvvdTcpPoke(VDSOCKET Sock)
return VINF_SUCCESS;
}
+/**
+ * Checks the prerequisites for encrypted I/O.
+ *
+ * @returns VBox status code.
+ * @param pThis The VD driver instance data.
+ */
+static int drvvdKeyCheckPrereqs(PVBOXDISK pThis)
+{
+ if ( pThis->pCfgCrypto
+ && !pThis->pIfSecKey)
+ {
+ AssertPtr(pThis->pIfSecKeyHlp);
+ pThis->pIfSecKeyHlp->pfnKeyMissingNotify(pThis->pIfSecKeyHlp);
+
+ int rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
+ N_("VD: The DEK for this disk is missing"));
+ AssertRC(rc);
+ return VERR_VD_DEK_MISSING;
+ }
+
+ return VINF_SUCCESS;
+}
/*******************************************************************************
* Media interface methods *
@@ -1550,14 +1578,9 @@ static DECLCALLBACK(int) drvvdRead(PPDMIMEDIA pInterface,
LogFlowFunc(("off=%#llx pvBuf=%p cbRead=%d\n", off, pvBuf, cbRead));
PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
- if ( pThis->pCfgCrypto
- && !pThis->pIfSecKey)
- {
- rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
- N_("VD: The DEK for this disk is missing"));
- AssertRC(rc);
- return VERR_VD_DEK_MISSING;
- }
+ rc = drvvdKeyCheckPrereqs(pThis);
+ if (RT_FAILURE(rc))
+ return rc;
if (!pThis->fBootAccelActive)
rc = VDRead(pThis->pDisk, off, pvBuf, cbRead);
@@ -1664,14 +1687,9 @@ static DECLCALLBACK(int) drvvdWrite(PPDMIMEDIA pInterface,
Log2(("%s: off=%#llx pvBuf=%p cbWrite=%d\n%.*Rhxd\n", __FUNCTION__,
off, pvBuf, cbWrite, cbWrite, pvBuf));
- if ( pThis->pCfgCrypto
- && !pThis->pIfSecKey)
- {
- int rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
- N_("VD: The DEK for this disk is missing"));
- AssertRC(rc);
- return VERR_VD_DEK_MISSING;
- }
+ int rc = drvvdKeyCheckPrereqs(pThis);
+ if (RT_FAILURE(rc))
+ return rc;
/* Invalidate any buffer if boot acceleration is enabled. */
if (pThis->fBootAccelActive)
@@ -1680,7 +1698,7 @@ static DECLCALLBACK(int) drvvdWrite(PPDMIMEDIA pInterface,
pThis->offDisk = 0;
}
- int rc = VDWrite(pThis->pDisk, off, pvBuf, cbWrite);
+ rc = VDWrite(pThis->pDisk, off, pvBuf, cbWrite);
LogFlowFunc(("returns %Rrc\n", rc));
return rc;
}
@@ -1731,7 +1749,7 @@ static DECLCALLBACK(int) drvvdMerge(PPDMIMEDIA pInterface,
}
/** @copydoc PDMIMEDIA::pfnSetKey */
-static DECLCALLBACK(int) drvvdSetSecKeyIf(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey)
+static DECLCALLBACK(int) drvvdSetSecKeyIf(PPDMIMEDIA pInterface, PPDMISECKEY pIfSecKey, PPDMISECKEYHLP pIfSecKeyHlp)
{
LogFlowFunc(("\n"));
PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
@@ -1741,6 +1759,8 @@ static DECLCALLBACK(int) drvvdSetSecKeyIf(PPDMIMEDIA pInterface, PPDMISECKEY pIf
{
PVDINTERFACE pVDIfFilter = NULL;
+ pThis->pIfSecKeyHlp = pIfSecKeyHlp;
+
if ( pThis->pIfSecKey
&& !pIfSecKey)
{
@@ -1985,14 +2005,9 @@ static DECLCALLBACK(int) drvvdStartRead(PPDMIMEDIAASYNC pInterface, uint64_t uOf
int rc = VINF_SUCCESS;
PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
- if ( pThis->pCfgCrypto
- && !pThis->pIfSecKey)
- {
- rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
- N_("VD: The DEK for this disk is missing"));
- AssertRC(rc);
- return VERR_VD_DEK_MISSING;
- }
+ rc = drvvdKeyCheckPrereqs(pThis);
+ if (RT_FAILURE(rc))
+ return rc;
pThis->fBootAccelActive = false;
@@ -2023,14 +2038,9 @@ static DECLCALLBACK(int) drvvdStartWrite(PPDMIMEDIAASYNC pInterface, uint64_t uO
int rc = VINF_SUCCESS;
PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
- if ( pThis->pCfgCrypto
- && !pThis->pIfSecKey)
- {
- rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
- N_("VD: The DEK for this disk is missing"));
- AssertRC(rc);
- return VERR_VD_DEK_MISSING;
- }
+ rc = drvvdKeyCheckPrereqs(pThis);
+ if (RT_FAILURE(rc))
+ return rc;
pThis->fBootAccelActive = false;
diff --git a/src/VBox/Devices/USB/DevOHCI.cpp b/src/VBox/Devices/USB/DevOHCI.cpp
index c21fddb..f02d144 100644
--- a/src/VBox/Devices/USB/DevOHCI.cpp
+++ b/src/VBox/Devices/USB/DevOHCI.cpp
@@ -2142,6 +2142,64 @@ static bool ohciHasUrbBeenCanceled(POHCI pThis, PVUSBURB pUrb, PCOHCIED pEd)
/**
+ * Calculate frame timer variables given a frame rate (1,000 Hz is the full speed).
+ */
+static void ohciCalcTimerIntervals(POHCI pThis, uint32_t u32FrameRate)
+{
+ Assert(u32FrameRate <= OHCI_DEFAULT_TIMER_FREQ);
+
+ pThis->cTicksPerFrame = pThis->u64TimerHz / u32FrameRate;
+ if (!pThis->cTicksPerFrame)
+ pThis->cTicksPerFrame = 1;
+ pThis->cTicksPerUsbTick = pThis->u64TimerHz >= VUSB_BUS_HZ ? pThis->u64TimerHz / VUSB_BUS_HZ : 1;
+ pThis->nsWait = RT_NS_1SEC / u32FrameRate;
+ pThis->uFrameRate = u32FrameRate;
+}
+
+
+/**
+ * Calculates the new frame rate based on the idle detection and number of idle
+ * cycles.
+ *
+ * @returns nothing.
+ * @param pThis The OHCI device data.
+ */
+static void ohciFramerateCalcNew(POHCI pThis)
+{
+ uint32_t uNewFrameRate = pThis->uFrameRate;
+
+ /*
+ * Adjust the frame timer interval based on idle detection.
+ */
+ if (pThis->fIdle)
+ {
+ pThis->cIdleCycles++;
+ /* Set the new frame rate based on how long we've been idle. Tunable. */
+ switch (pThis->cIdleCycles)
+ {
+ case 4: uNewFrameRate = 500; break; /* 2ms interval */
+ case 16:uNewFrameRate = 125; break; /* 8ms interval */
+ case 24:uNewFrameRate = 50; break; /* 20ms interval */
+ default: break;
+ }
+ /* Avoid overflow. */
+ if (pThis->cIdleCycles > 60000)
+ pThis->cIdleCycles = 20000;
+ }
+ else
+ {
+ if (pThis->cIdleCycles)
+ {
+ pThis->cIdleCycles = 0;
+ uNewFrameRate = OHCI_DEFAULT_TIMER_FREQ;
+ }
+ }
+ if (uNewFrameRate != pThis->uFrameRate)
+ ohciCalcTimerIntervals(pThis, uNewFrameRate);
+}
+
+
+/**
* Returns the OHCI_CC_* corresponding to the VUSB status code.
*
* @returns OHCI_CC_* value.
@@ -2526,6 +2584,10 @@ static DECLCALLBACK(void) ohciRhXferCompletion(PVUSBIROOTHUBPORT pInterface, PVU
/* finally write back the endpoint descriptor. */
ohciWriteEd(pThis, pUrb->Hci.EdAddr, &Ed);
+
+ /* Calculate new frame rate and wakeup the . */
+ ohciFramerateCalcNew(pThis);
+ RTSemEventSignal(pThis->hSemEventFrame);
RTCritSectLeave(&pThis->CritSect);
}
@@ -3569,21 +3631,6 @@ static void ohciUpdateHCCA(POHCI pThis)
/**
- * Calculate frame timer variables given a frame rate (1,000 Hz is the full speed).
- */
-static void ohciCalcTimerIntervals(POHCI pThis, uint32_t u32FrameRate)
-{
- Assert(u32FrameRate <= OHCI_DEFAULT_TIMER_FREQ);
-
- pThis->cTicksPerFrame = pThis->u64TimerHz / u32FrameRate;
- if (!pThis->cTicksPerFrame)
- pThis->cTicksPerFrame = 1;
- pThis->cTicksPerUsbTick = pThis->u64TimerHz >= VUSB_BUS_HZ ? pThis->u64TimerHz / VUSB_BUS_HZ : 1;
- pThis->nsWait = RT_NS_1SEC / u32FrameRate;
- pThis->uFrameRate = u32FrameRate;
-}
-
-/**
* Go over the in-flight URB list and cancel any URBs that are no longer in use.
* This occurs when the host removes EDs or TDs from the lists and we don't notice
* the sKip bit. Such URBs must be promptly canceled, otherwise there is a risk
@@ -3682,7 +3729,6 @@ static void ohciCancelOrphanedURBs(POHCI pThis)
*/
static void ohciStartOfFrame(POHCI pThis)
{
- uint32_t uNewFrameRate = pThis->uFrameRate;
#ifdef LOG_ENABLED
const uint32_t status_old = pThis->status;
#endif
@@ -3784,31 +3830,7 @@ static void ohciStartOfFrame(POHCI pThis)
/*
* Adjust the frame timer interval based on idle detection.
*/
- if (pThis->fIdle)
- {
- pThis->cIdleCycles++;
- /* Set the new frame rate based on how long we've been idle. Tunable. */
- switch (pThis->cIdleCycles)
- {
- case 4: uNewFrameRate = 500; break; /* 2ms interval */
- case 16:uNewFrameRate = 125; break; /* 8ms interval */
- case 24:uNewFrameRate = 50; break; /* 20ms interval */
- default: break;
- }
- /* Avoid overflow. */
- if (pThis->cIdleCycles > 60000)
- pThis->cIdleCycles = 20000;
- }
- else
- {
- if (pThis->cIdleCycles)
- {
- pThis->cIdleCycles = 0;
- uNewFrameRate = OHCI_DEFAULT_TIMER_FREQ;
- }
- }
- if (uNewFrameRate != pThis->uFrameRate)
- ohciCalcTimerIntervals(pThis, uNewFrameRate);
+ ohciFramerateCalcNew(pThis);
}
/**
diff --git a/src/VBox/Devices/USB/VUSBDevice.cpp b/src/VBox/Devices/USB/VUSBDevice.cpp
index f01eb2e..7ba3632 100644
--- a/src/VBox/Devices/USB/VUSBDevice.cpp
+++ b/src/VBox/Devices/USB/VUSBDevice.cpp
@@ -1051,7 +1051,8 @@ static DECLCALLBACK(int) vusbDevCancelAllUrbsWorker(PVUSBDEV pDev, bool fDetachi
Assert(pUrb->VUsb.pDev == pDev);
LogFlow(("%s: vusbDevCancelAllUrbs: CANCELING URB\n", pUrb->pszDesc));
- vusbUrbCancelWorker(pUrb, CANCELMODE_FAIL);
+ int rc = vusbUrbCancelWorker(pUrb, CANCELMODE_FAIL);
+ AssertRC(rc);
pUrb = pNext;
}
diff --git a/src/VBox/Devices/USB/VUSBInternal.h b/src/VBox/Devices/USB/VUSBInternal.h
index e2603bf..9c75315 100644
--- a/src/VBox/Devices/USB/VUSBInternal.h
+++ b/src/VBox/Devices/USB/VUSBInternal.h
@@ -456,7 +456,7 @@ int vusbDevUrbIoThreadDestroy(PVUSBDEV pDev);
DECLHIDDEN(int) vusbDevIoThreadExecV(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
DECLHIDDEN(int) vusbDevIoThreadExec(PVUSBDEV pDev, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
DECLHIDDEN(int) vusbDevIoThreadExecSync(PVUSBDEV pDev, PFNRT pfnFunction, unsigned cArgs, ...);
-DECLHIDDEN(void) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode);
+DECLHIDDEN(int) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode);
void vusbUrbCompletionReadAhead(PVUSBURB pUrb);
VUSBREADAHEAD vusbReadAheadStart(PVUSBDEV pDev, PVUSBPIPE pPipe);
diff --git a/src/VBox/Devices/USB/VUSBUrb.cpp b/src/VBox/Devices/USB/VUSBUrb.cpp
index 389a6ab..b11debf 100644
--- a/src/VBox/Devices/USB/VUSBUrb.cpp
+++ b/src/VBox/Devices/USB/VUSBUrb.cpp
@@ -1595,8 +1595,12 @@ static int vusbUrbSubmitCtrl(PVUSBURB pUrb)
}
PVUSBSETUP pSetup = pExtra->pMsg;
- AssertMsgReturn(!pPipe->async, ("%u\n", pPipe->async), VERR_GENERAL_FAILURE);
-
+ if (pPipe->async)
+ {
+ AssertMsgFailed(("%u\n", pPipe->async));
+ RTCritSectLeave(&pPipe->CritSectCtrl);
+ return VERR_GENERAL_FAILURE;
+ }
/*
* A setup packet always resets the transaction and the
@@ -2062,11 +2066,11 @@ static void vusbUrbCompletion(PVUSBURB pUrb)
/**
* The worker for vusbUrbCancel() which is executed on the I/O thread.
*
- * @returns nothing.
+ * @returns IPRT status code.
* @param pUrb The URB to cancel.
* @param enmMode The way the URB should be canceled.
*/
-DECLHIDDEN(void) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode)
+DECLHIDDEN(int) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode)
{
vusbUrbAssert(pUrb);
#ifdef VBOX_WITH_STATISTICS
@@ -2119,6 +2123,7 @@ DECLHIDDEN(void) vusbUrbCancelWorker(PVUSBURB pUrb, CANCELMODE enmMode)
}
}
+ return VINF_SUCCESS;
}
/**
diff --git a/src/VBox/Devices/VMMDev/VMMDev.cpp b/src/VBox/Devices/VMMDev/VMMDev.cpp
index 534f103..95a25c5 100644
--- a/src/VBox/Devices/VMMDev/VMMDev.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDev.cpp
@@ -726,23 +726,23 @@ static int vmmdevReqHandler_ReportGuestCapabilities(PVMMDEV pThis, VMMDevRequest
VMMDevReqGuestCapabilities *pReq = (VMMDevReqGuestCapabilities *)pReqHdr;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
- /* Enable this automatically for guests using the old
- request to report their capabilities. */
- /** @todo change this when we next bump the interface version */
- pReq->caps |= VMMDEV_GUEST_SUPPORTS_GRAPHICS;
- if (pThis->guestCaps != pReq->caps)
+ /* Enable VMMDEV_GUEST_SUPPORTS_GRAPHICS automatically for guests using the old
+ * request to report their capabilities.
+ */
+ const uint32_t fu32Caps = pReq->caps | VMMDEV_GUEST_SUPPORTS_GRAPHICS;
+
+ if (pThis->guestCaps != fu32Caps)
{
/* make a copy of supplied information */
- pThis->guestCaps = pReq->caps;
+ pThis->guestCaps = fu32Caps;
- LogRel(("Guest Additions capability report: (0x%x) seamless: %s, hostWindowMapping: %s, graphics: %s\n",
- pReq->caps,
- pReq->caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? "yes" : "no",
- pReq->caps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no",
- pReq->caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? "yes" : "no"));
+ LogRel(("Guest Additions capability report (legacy): (0x%x) seamless: %s, hostWindowMapping: %s, graphics: yes\n",
+ fu32Caps,
+ fu32Caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? "yes" : "no",
+ fu32Caps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no"));
if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
- pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pReq->caps);
+ pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, fu32Caps);
}
return VINF_SUCCESS;
}
@@ -760,18 +760,20 @@ static int vmmdevReqHandler_SetGuestCapabilities(PVMMDEV pThis, VMMDevRequestHea
VMMDevReqGuestCapabilities2 *pReq = (VMMDevReqGuestCapabilities2 *)pReqHdr;
AssertMsgReturn(pReq->header.size == sizeof(*pReq), ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
- uint32_t const fOldCaps = pThis->guestCaps; NOREF(fOldCaps);
- pThis->guestCaps |= pReq->u32OrMask;
- pThis->guestCaps &= ~pReq->u32NotMask;
+ uint32_t fu32Caps = pThis->guestCaps;
+ fu32Caps |= pReq->u32OrMask;
+ fu32Caps &= ~pReq->u32NotMask;
LogRel(("Guest Additions capability report: (%#x -> %#x) seamless: %s, hostWindowMapping: %s, graphics: %s\n",
- fOldCaps, pThis->guestCaps,
- pThis->guestCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? "yes" : "no",
- pThis->guestCaps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no",
- pThis->guestCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? "yes" : "no"));
+ pThis->guestCaps, fu32Caps,
+ fu32Caps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? "yes" : "no",
+ fu32Caps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no",
+ fu32Caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? "yes" : "no"));
+
+ pThis->guestCaps = fu32Caps;
if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
- pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
+ pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, fu32Caps);
return VINF_SUCCESS;
}
@@ -3567,6 +3569,8 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
pThis->fu32AdditionsOk = false;
memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo));
RT_ZERO(pThis->guestInfo2);
+ const bool fCapsChanged = pThis->guestCaps != 0; /* Report transition to 0. */
+ pThis->guestCaps = 0;
/* Clear facilities. No need to tell Main as it will get a
pfnUpdateGuestInfo callback. */
@@ -3613,19 +3617,12 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
pThis->u32NewGuestFilterMask = 0;
pThis->fNewGuestFilterMask = 0;
- /* This is the default, as Windows and OS/2 guests take this for granted. (Actually, neither does...) */
- /** @todo change this when we next bump the interface version */
- const bool fCapsChanged = pThis->guestCaps != VMMDEV_GUEST_SUPPORTS_GRAPHICS;
- if (fCapsChanged)
- Log(("vmmdevReset: fCapsChanged=%#x -> %#x\n", pThis->guestCaps, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
- pThis->guestCaps = VMMDEV_GUEST_SUPPORTS_GRAPHICS; /** @todo r=bird: why? I cannot see this being done at construction?*/
-
/*
* Call the update functions as required.
*/
if (fVersionChanged && pThis->pDrv && pThis->pDrv->pfnUpdateGuestInfo)
pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
- if (fCapsChanged && pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
+ if (fCapsChanged && pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
/* Generate a unique session id for this VM; it will be changed for each start, reset or restore.
diff --git a/src/VBox/Devices/VMMDev/VMMDevTesting.cpp b/src/VBox/Devices/VMMDev/VMMDevTesting.cpp
index 220f479..75abcbb 100644
--- a/src/VBox/Devices/VMMDev/VMMDevTesting.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDevTesting.cpp
@@ -67,6 +67,23 @@ PDMBOTHCBDECL(int) vmmdevTestingMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGC
}
return VINF_SUCCESS;
+ case VMMDEV_TESTING_MMIO_NOP_R3:
+ switch (cb)
+ {
+ case 8:
+ case 4:
+ case 2:
+ case 1:
+#ifndef IN_RING3
+ return VINF_IOM_R3_MMIO_READ_WRITE;
+#else
+ return VINF_SUCCESS;
+#endif
+ default:
+ AssertFailed();
+ return VERR_INTERNAL_ERROR_5;
+ }
+
default:
break;
}
@@ -81,6 +98,18 @@ PDMBOTHCBDECL(int) vmmdevTestingMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCP
{
switch (GCPhysAddr)
{
+ case VMMDEV_TESTING_MMIO_NOP_R3:
+#ifndef IN_RING3
+ switch (cb)
+ {
+ case 8:
+ case 4:
+ case 2:
+ case 1:
+ return VINF_IOM_R3_MMIO_READ;
+ }
+#endif
+ /* fall thru. */
case VMMDEV_TESTING_MMIO_NOP:
switch (cb)
{
@@ -102,7 +131,6 @@ PDMBOTHCBDECL(int) vmmdevTestingMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCP
}
return VINF_SUCCESS;
-
default:
break;
}
@@ -189,6 +217,22 @@ PDMBOTHCBDECL(int) vmmdevTestingIoWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPO
}
return VINF_SUCCESS;
+ case VMMDEV_TESTING_IOPORT_NOP_R3:
+ switch (cb)
+ {
+ case 4:
+ case 2:
+ case 1:
+#ifndef IN_RING3
+ return VINF_IOM_R3_IOPORT_WRITE;
+#else
+ return VINF_SUCCESS;
+#endif
+ default:
+ AssertFailed();
+ return VERR_INTERNAL_ERROR_2;
+ }
+
/* The timestamp I/O ports are read-only. */
case VMMDEV_TESTING_IOPORT_TS_LOW:
case VMMDEV_TESTING_IOPORT_TS_HIGH:
@@ -423,6 +467,23 @@ PDMBOTHCBDECL(int) vmmdevTestingIoRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPOR
*pu32 = VMMDEV_TESTING_NOP_RET;
return VINF_SUCCESS;
+ case VMMDEV_TESTING_IOPORT_NOP_R3:
+ switch (cb)
+ {
+ case 4:
+ case 2:
+ case 1:
+#ifndef IN_RING3
+ return VINF_IOM_R3_IOPORT_READ;
+#else
+ *pu32 = VMMDEV_TESTING_NOP_RET;
+ return VINF_SUCCESS;
+#endif
+ default:
+ AssertFailed();
+ return VERR_INTERNAL_ERROR_2;
+ }
+
/*
* The timestamp I/O ports are obviously used for getting a good fix
* on the current time (as seen by the host?).
diff --git a/src/VBox/Devices/build/VBoxDD.rc b/src/VBox/Devices/build/VBoxDD.rc
new file mode 100644
index 0000000..71c6beb
--- /dev/null
+++ b/src/VBox/Devices/build/VBoxDD.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxDD.rc $ */
+/** @file
+ * VBoxDD - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox VMM Devices and Drivers\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxDD\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxDD.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Devices/build/VBoxDD2.rc b/src/VBox/Devices/build/VBoxDD2.rc
new file mode 100644
index 0000000..57e9f72
--- /dev/null
+++ b/src/VBox/Devices/build/VBoxDD2.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxDD2.rc $ */
+/** @file
+ * VBoxDD2 - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox VMM Devices and Drivers 2\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxDD2\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxDD2.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Devices/build/VBoxDDU.rc b/src/VBox/Devices/build/VBoxDDU.rc
new file mode 100644
index 0000000..b8ae01a
--- /dev/null
+++ b/src/VBox/Devices/build/VBoxDDU.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxDDU.rc $ */
+/** @file
+ * VBoxDDU - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox VMM Devices and Drivers Utilities\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxDDU\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxDDU.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk b/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
index d5fcf2a..481f22d 100644
--- a/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxBalloonCtrl/Makefile.kmk
@@ -28,5 +28,7 @@ PROGRAMS += VBoxBalloonCtrl
VBoxWatchdogUtils.cpp \
VBoxModAPIMonitor.cpp \
VBoxModBallooning.cpp
+ VBoxBalloonCtrl_SOURCES.win = \
+ VBoxBalloonCtrl.rc
include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.rc b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.rc
new file mode 100644
index 0000000..5a8e233
--- /dev/null
+++ b/src/VBox/Frontends/VBoxBalloonCtrl/VBoxBalloonCtrl.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxBalloonCtrl.rc $ */
+/** @file
+ * VBoxBalloonCtrl - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Balloon Control Tool\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxBalloonCtrl\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxBalloonCtrl.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Frontends/VBoxHeadless/Makefile.kmk b/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
index 8d4be8f..7b8e188 100644
--- a/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxHeadless/Makefile.kmk
@@ -55,12 +55,16 @@ ifdef VBOX_WITH_HARDENING
endif
+ifeq ($(KBUILD_TARGET),win)
# Icon include file.
-VBoxHeadless_SOURCES.win += $(VBoxHeadless_0_OUTDIR)/VBoxHeadless-icon.rc
-VBoxHeadless_CLEAN.win += $(VBoxHeadless_0_OUTDIR)/VBoxHeadless-icon.rc
+VBoxHeadless_SOURCES += VBoxHeadless.rc
+VBoxHeadless.rc_INCS = $(VBoxHeadless_0_OUTDIR)
+VBoxHeadless.rc_DEPS = $(VBoxHeadless_0_OUTDIR)/VBoxHeadless-icon.rc
+VBoxHeadless.rc_CLEAN = $(VBoxHeadless_0_OUTDIR)/VBoxHeadless-icon.rc
$$(VBoxHeadless_0_OUTDIR)/VBoxHeadless-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $$(VBoxHeadless_DEFPATH)/Makefile.kmk | $$(dir $$@)
$(RM) -f $@
$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
+endif # win
include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc b/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.rc
similarity index 62%
copy from src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
copy to src/VBox/Frontends/VBoxHeadless/VBoxHeadless.rc
index 30719f4..e8169ae 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
+++ b/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.rc
@@ -1,10 +1,10 @@
-/* $Id: VirtualBox.rc $ */
+/* $Id: VBoxHeadless.rc $ */
/** @file
- * Windows resource file for VirtualBox.exe.
+ * VBox headless frontent - Windows resource file.
*/
/*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,7 +18,7 @@
#include <windows.h>
#include <VBox/version.h>
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -39,22 +39,22 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", VBOX_PRODUCT " Manager\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Headless Frontend\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
#ifdef VBOXR3_HARDENED_DLL
- VALUE "InternalName", "VirtualBox\0"
+ VALUE "InternalName", "VBoxHeadless\0"
#else
- VALUE "InternalName", "VirtualBox.exe\0"
+ VALUE "InternalName", "VBoxHeadless\0"
#endif
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
#ifdef VBOXR3_HARDENED_DLL
- VALUE "OriginalFilename","VirtualBox.dll\0"
+ VALUE "OriginalFilename", "VBoxHeadless.dll\0"
#else
- VALUE "OriginalFilename","VirtualBox.exe\0"
+ VALUE "OriginalFilename", "VBoxHeadless.exe\0"
#endif
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
BLOCK "VarFileInfo"
@@ -64,5 +64,5 @@ BEGIN
END
/* Creates the application icon. */
-#include "VirtualBox-icon.rc"
+#include "VBoxHeadless-icon.rc"
diff --git a/src/VBox/Frontends/VBoxManage/Makefile.kmk b/src/VBox/Frontends/VBoxManage/Makefile.kmk
index ae33599..ec7f4bc 100644
--- a/src/VBox/Frontends/VBoxManage/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxManage/Makefile.kmk
@@ -60,6 +60,8 @@ VBoxManage_SOURCES = \
VBoxManageUSB.cpp \
$(if $(VBOX_WITH_NAT_SERVICE),VBoxManageNATNetwork.cpp,) \
$(if $(VBOX_WITH_NAT_SERVICE),../../NetworkServices/NetLib/VBoxNetPortForwardString.cpp,)
+VBoxManage_SOURCES.win = \
+ VBoxManage.rc
VBoxManage_LIBS += $(LIB_DDU)
VBoxManage_DEFS += \
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManage.rc b/src/VBox/Frontends/VBoxManage/VBoxManage.rc
new file mode 100644
index 0000000..bd11cd1
--- /dev/null
+++ b/src/VBox/Frontends/VBoxManage/VBoxManage.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxManage.rc $ */
+/** @file
+ * VBoxManage - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Command Line Tool\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxManage\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxManage.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
index a1158dd..1801bc1 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
@@ -606,15 +606,14 @@ int handleStartVM(HandlerArg *a)
CHECK_ERROR(progress, COMGETTER(ResultCode)(&iRc));
if (SUCCEEDED(rc))
{
- if (FAILED(iRc))
+ if (SUCCEEDED(rc))
+ RTPrintf("VM \"%s\" has been successfully started.\n", pszVM);
+ else
{
ProgressErrorInfo info(progress);
com::GluePrintErrorInfo(info);
}
- else
- {
- RTPrintf("VM \"%s\" has been successfully started.\n", pszVM);
- }
+ rc = iRc;
}
}
}
diff --git a/src/VBox/Frontends/VBoxSDL/Makefile.kmk b/src/VBox/Frontends/VBoxSDL/Makefile.kmk
index 941b5d6..a3be1c0 100644
--- a/src/VBox/Frontends/VBoxSDL/Makefile.kmk
+++ b/src/VBox/Frontends/VBoxSDL/Makefile.kmk
@@ -104,10 +104,16 @@ $$(VBoxSDL_0_OUTDIR)/Ico64x01.h: $(PATH_ROOT)/src/VBox/Frontends/VBoxSDL/ico64x0
$(call MSG_TOOL,bin2c,VBoxSDL,$<,$@)
$(QUIET)$(VBOX_BIN2C) Ico64x01 $< $@
+ifeq ($(KBUILD_TARGET),win)
+VBoxSDL_SOURCES += VBoxSDL.rc
+VBoxSDL.rc_INCS = $(VBoxSDL_0_OUTDIR)
+VBoxSDL.rc_DEPS = $(VBoxSDL_0_OUTDIR)/VBoxSDL-icon.rc
+VBoxSDL.rc_CLEAN = $(VBoxSDL_0_OUTDIR)/VBoxSDL-icon.rc
# Icon include file.
$$(VBoxSDL_0_OUTDIR)/VBoxSDL-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $$(VBoxSDL_DEFPATH)/Makefile.kmk | $$(dir $$@)
$(RM) -f $@
$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
+endif
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc b/src/VBox/Frontends/VBoxSDL/VBoxSDL.rc
similarity index 63%
copy from src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
copy to src/VBox/Frontends/VBoxSDL/VBoxSDL.rc
index 30719f4..3f20457 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDL.rc
@@ -1,10 +1,10 @@
-/* $Id: VirtualBox.rc $ */
+/* $Id: VBoxSDL.rc $ */
/** @file
- * Windows resource file for VirtualBox.exe.
+ * VBox purge SDL frontent - Windows resource file.
*/
/*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,7 +18,7 @@
#include <windows.h>
#include <VBox/version.h>
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -39,22 +39,22 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", VBOX_PRODUCT " Manager\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Pure SDL Frontend\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
#ifdef VBOXR3_HARDENED_DLL
- VALUE "InternalName", "VirtualBox\0"
+ VALUE "InternalName", "VBoxSDL\0"
#else
- VALUE "InternalName", "VirtualBox.exe\0"
+ VALUE "InternalName", "VBoxSDL\0"
#endif
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
#ifdef VBOXR3_HARDENED_DLL
- VALUE "OriginalFilename","VirtualBox.dll\0"
+ VALUE "OriginalFilename", "VBoxSDL.dll\0"
#else
- VALUE "OriginalFilename","VirtualBox.exe\0"
+ VALUE "OriginalFilename", "VBoxSDL.exe\0"
#endif
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
BLOCK "VarFileInfo"
@@ -64,5 +64,5 @@ BEGIN
END
/* Creates the application icon. */
-#include "VirtualBox-icon.rc"
+#include "VBoxSDL-icon.rc"
diff --git a/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc b/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc
index 96eeb63..3282db8 100644
--- a/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc
+++ b/src/VBox/Frontends/VirtualBox/VirtualBox2.qrc
@@ -58,6 +58,10 @@
<file alias="os_win7_64.png">images/os_win7_64.png</file>
<file alias="os_win8.png">images/os_win8.png</file>
<file alias="os_win8_64.png">images/os_win8_64.png</file>
+ <file alias="os_win81.png">images/os_win81.png</file>
+ <file alias="os_win81_64.png">images/os_win81_64.png</file>
+ <file alias="os_win10.png">images/os_win10.png</file>
+ <file alias="os_win10_64.png">images/os_win10_64.png</file>
<file alias="os_win95.png">images/os_win95.png</file>
<file alias="os_win98.png">images/os_win98.png</file>
<file alias="os_winme.png">images/os_winme.png</file>
diff --git a/src/VBox/Frontends/VirtualBox/images/os_win10.png b/src/VBox/Frontends/VirtualBox/images/os_win10.png
new file mode 100644
index 0000000..9ac5c5b
Binary files /dev/null and b/src/VBox/Frontends/VirtualBox/images/os_win10.png differ
diff --git a/src/VBox/Frontends/VirtualBox/images/os_win10_64.png b/src/VBox/Frontends/VirtualBox/images/os_win10_64.png
new file mode 100644
index 0000000..e3a3b92
Binary files /dev/null and b/src/VBox/Frontends/VirtualBox/images/os_win10_64.png differ
diff --git a/src/VBox/Frontends/VirtualBox/images/os_win81.png b/src/VBox/Frontends/VirtualBox/images/os_win81.png
new file mode 100644
index 0000000..8d6b293
Binary files /dev/null and b/src/VBox/Frontends/VirtualBox/images/os_win81.png differ
diff --git a/src/VBox/Frontends/VirtualBox/images/os_win81_64.png b/src/VBox/Frontends/VirtualBox/images/os_win81_64.png
new file mode 100644
index 0000000..27b305e
Binary files /dev/null and b/src/VBox/Frontends/VirtualBox/images/os_win81_64.png differ
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl b/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl
index 9ce8210..1385263 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl
+++ b/src/VBox/Frontends/VirtualBox/src/globals/COMWrappers.xsl
@@ -1231,6 +1231,7 @@
<xsl:text>#ifdef RT_OS_WINDOWS
</xsl:text>
<xsl:text> Assert(mRC != RPC_E_WRONG_THREAD);
</xsl:text>
+ <xsl:text> Assert(mRC != CO_E_NOTINITIALIZED);
</xsl:text>
<xsl:text>#endif
</xsl:text>
<!-- apply 'post-call' hooks -->
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp b/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
index 0da45ea..0ec3c0a 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
@@ -2488,7 +2488,7 @@ void UIMessageCenter::sltShowHelpHelpDialog()
/* For OSE version we have to check if it present first: */
QString strUserManualFileName1 = vboxGlobal().helpFile();
QString strShortFileName = QFileInfo(strUserManualFileName1).fileName();
- QString strUserManualFileName2 = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(strShortFileName);
+ QString strUserManualFileName2 = QDir(vboxGlobal().homeFolder()).absoluteFilePath(strShortFileName);
/* Show if user manual already present: */
if (QFile::exists(strUserManualFileName1))
sltShowUserManual(strUserManualFileName1);
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
index 51f4a7b..f406cde 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
@@ -1668,7 +1668,7 @@ QString VBoxGlobal::openMediumWithFileOpenDialog(UIMediumType mediumType, QWidge
break;
}
QString strHomeFolder = fUseLastFolder && !strLastFolder.isEmpty() ? strLastFolder :
- strDefaultFolder.isEmpty() ? vboxGlobal().virtualBox().GetHomeFolder() : strDefaultFolder;
+ strDefaultFolder.isEmpty() ? vboxGlobal().homeFolder() : strDefaultFolder;
/* Prepare filters and backends: */
for (int i = 0; i < filters.count(); ++i)
@@ -3309,6 +3309,7 @@ bool VBoxGlobal::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
|| strGuestOSTypeId.startsWith("Windows7")
|| strGuestOSTypeId.startsWith("Windows8")
|| strGuestOSTypeId.startsWith("Windows81")
+ || strGuestOSTypeId.startsWith("Windows10")
|| strGuestOSTypeId.startsWith("Windows2008")
|| strGuestOSTypeId.startsWith("Windows2012");
}
@@ -4075,6 +4076,7 @@ void VBoxGlobal::prepare()
return;
}
mHost = virtualBox().GetHost();
+ mHomeFolder = virtualBox().GetHomeFolder();
/* create default non-null global settings */
gset = VBoxGlobalSettings (false);
@@ -4150,9 +4152,11 @@ void VBoxGlobal::prepare()
{"Windows7_64", ":/os_win7_64.png"},
{"Windows8", ":/os_win8.png"},
{"Windows8_64", ":/os_win8_64.png"},
- {"Windows81", ":/os_win8.png"},
- {"Windows81_64", ":/os_win8_64.png"},
+ {"Windows81", ":/os_win81.png"},
+ {"Windows81_64", ":/os_win81_64.png"},
{"Windows2012_64", ":/os_win2k12_64.png"},
+ {"Windows10", ":/os_win10.png"},
+ {"Windows10_64", ":/os_win10_64.png"},
{"WindowsNT", ":/os_win_other.png"},
{"WindowsNT_64", ":/os_win_other.png"}, /// @todo os_win_other_64.png
{"OS2Warp3", ":/os_os2warp3.png"},
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
index cffd98e..b2c86ca 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
@@ -91,6 +91,7 @@ public:
CVirtualBox virtualBox() const { return mVBox; }
CHost host() const { return mHost; }
+ QString homeFolder() const { return mHomeFolder; }
VBoxGlobalSettings &settings() { return gset; }
bool setSettings (VBoxGlobalSettings &gs);
@@ -455,6 +456,7 @@ private:
CVirtualBox mVBox;
CHost mHost;
+ QString mHomeFolder;
VBoxGlobalSettings gset;
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderAdditions.cpp b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderAdditions.cpp
index 4532835..c7cdba9 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderAdditions.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderAdditions.cpp
@@ -58,7 +58,7 @@ UIDownloaderAdditions::UIDownloaderAdditions()
/* Prepare source/target: */
const QString &strName = QString("VBoxGuestAdditions_%1.iso").arg(vboxGlobal().vboxVersionStringNormalized());
const QString &strSource = QString("http://download.virtualbox.org/virtualbox/%1/").arg(vboxGlobal().vboxVersionStringNormalized()) + strName;
- const QString &strTarget = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(strName);
+ const QString &strTarget = QDir(vboxGlobal().homeFolder()).absoluteFilePath(strName);
/* Set source/target: */
setSource(strSource);
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp
index 8cb4ff2..a9a230e 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp
@@ -63,7 +63,7 @@ UIDownloaderExtensionPack::UIDownloaderExtensionPack()
QString strSourcePath(strTemplateSourcePath.arg(vboxGlobal().vboxVersionStringNormalized()));
QString strSourceName(strTemplateSourceName.arg(vboxGlobal().vboxVersionStringNormalized()));
QString strSource(strSourcePath + strSourceName);
- QString strTargetPath(vboxGlobal().virtualBox().GetHomeFolder());
+ QString strTargetPath(vboxGlobal().homeFolder());
QString strTargetName(strSourceName);
QString strTarget(QDir(strTargetPath).absoluteFilePath(strTargetName));
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderUserManual.cpp b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderUserManual.cpp
index bb525f4..1394f98 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderUserManual.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderUserManual.cpp
@@ -64,7 +64,7 @@ UIDownloaderUserManual::UIDownloaderUserManual()
addSource(QString("http://download.virtualbox.org/virtualbox/") + strUserManualShortFileName);
/* Set target: */
- QString strUserManualDestination = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(strUserManualShortFileName);
+ QString strUserManualDestination = QDir(vboxGlobal().homeFolder()).absoluteFilePath(strUserManualShortFileName);
setTarget(strUserManualDestination);
}
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp b/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp
index 02734cb..9c33dc1 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp
@@ -200,7 +200,7 @@ void UINetworkReplyPrivateThread::run()
/* static */
QString UINetworkReplyPrivateThread::fullCertificateFileName()
{
- const QDir homeDir(QDir::toNativeSeparators(vboxGlobal().virtualBox().GetHomeFolder()));
+ const QDir homeDir(QDir::toNativeSeparators(vboxGlobal().homeFolder()));
return QDir::toNativeSeparators(homeDir.absoluteFilePath(m_strCertificateFileName));
}
@@ -237,7 +237,7 @@ int UINetworkReplyPrivateThread::applyCertificates(RTHTTP pHttp, const QString &
return VERR_INVALID_POINTER;
/* Apply HTTPs certificates: */
- return RTHttpSetCAFile(pHttp, strFullCertificateFileName.toAscii().constData());
+ return RTHttpSetCAFile(pHttp, strFullCertificateFileName.toUtf8().constData());
}
/* static */
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp b/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
index 52a124e..437e981 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
@@ -253,7 +253,10 @@ static const uint16_t g_aDarwinToSet1[] =
0x4d|K_EX, /* QZ_RIGHT 0x7C */
0x50|K_EX, /* QZ_DOWN 0x7D */
0x48|K_EX, /* QZ_UP 0x7E */
- 0x5e|K_EX, /* QZ_POWER 0x7F */ /* have different break key! */
+ 0,/*0x5e|K_EX*/ /* QZ_POWER 0x7F */ /* have different break key! */
+ /* do NEVER deliver the Power
+ * scancode as e.g. Windows will
+ * handle it, @bugref{7692}. */
};
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc b/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
index 30719f4..72d71da 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
+++ b/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBox.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -18,7 +18,7 @@
#include <windows.h>
#include <VBox/version.h>
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -39,22 +39,22 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", VBOX_PRODUCT " Manager\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Manager\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
#ifdef VBOXR3_HARDENED_DLL
- VALUE "InternalName", "VirtualBox\0"
+ VALUE "InternalName", "VirtualBox\0"
#else
- VALUE "InternalName", "VirtualBox.exe\0"
+ VALUE "InternalName", "VirtualBox\0"
#endif
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
#ifdef VBOXR3_HARDENED_DLL
- VALUE "OriginalFilename","VirtualBox.dll\0"
+ VALUE "OriginalFilename", "VirtualBox.dll\0"
#else
- VALUE "OriginalFilename","VirtualBox.exe\0"
+ VALUE "OriginalFilename", "VirtualBox.exe\0"
#endif
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBoxHardened.rc b/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBoxHardened.rc
index 47a6f6a..0e52a05 100644
--- a/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBoxHardened.rc
+++ b/src/VBox/Frontends/VirtualBox/src/platform/win/VirtualBoxHardened.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2014 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -19,7 +19,7 @@
#include <VBox/version.h>
#if 0 /* Causes more DLLs to be loaded, don't enable it! */
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -36,14 +36,14 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", VBOX_PRODUCT " Manager\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VirtualBox.exe\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename","VirtualBox.exe\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Manager\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VirtualBox\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename","VirtualBox.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
index bfa37c9..ee69e82 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
@@ -141,7 +141,9 @@ void UIFrameBufferQImage::resizeEvent(UIResizeEvent *pEvent)
}
/* Remind if requested: */
- if (bRemind && m_pMachineView->uisession()->isGuestAdditionsActive())
+ /* This check (supports graphics) is not quite right due to past mistakes
+ * in the Guest Additions protocol, but in practice it should be fine. */
+ if (bRemind && m_pMachineView->uisession()->isGuestSupportsGraphics())
popupCenter().remindAboutWrongColorDepth(m_pMachineView->machineWindow(),
pEvent->bitsPerPixel(), 32);
else
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
index a90e526..bfb437a 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
@@ -234,7 +234,9 @@ void UIFrameBufferQuartz2D::resizeEvent(UIResizeEvent *aEvent)
setImageRef(m_image);
#endif
- if (remind && m_pMachineView->uisession()->isGuestAdditionsActive())
+ /* This check (supports graphics) is not quite right due to past mistakes
+ * in the Guest Additions protocol, but in practice it should be fine. */
+ if (remind && m_pMachineView->uisession()->isGuestSupportsGraphics())
popupCenter().remindAboutWrongColorDepth(m_pMachineView->machineWindow(),
aEvent->bitsPerPixel(), 32);
else
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
index 49a752b..e3baca5 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp
@@ -1479,12 +1479,14 @@ bool UIKeyboardHandler::keyEvent(int iKey, uint8_t uScan, int fFlags, ulong uScr
* 2. if currently released key releases host-combo too.
* Using that rule, we are NOT sending to the guest:
* 1. the last key-press of host-combo,
- * 2. all keys pressed while the host-combo being held. */
+ * 2. all keys pressed while the host-combo being held (but we still send releases). */
LONG aCodesBuffer[16];
LONG *pCodes = aCodesBuffer;
uint uCodesCount = 0;
+ uint8_t uWhatPressed = fFlags & KeyExtended ? IsExtKeyPressed : IsKeyPressed;
if ((!m_bIsHostComboPressed && !isHostComboStateChanged) ||
- ( m_bIsHostComboPressed && isHostComboStateChanged))
+ ( m_bIsHostComboPressed && isHostComboStateChanged) ||
+ (!(fFlags & KeyPressed) && (m_pressedKeys[uScan] & uWhatPressed)))
{
/* Special flags handling (KeyPrint): */
if (fFlags & KeyPrint)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
index b9120c3..8614ce7 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
@@ -818,7 +818,7 @@ void UIMachineLogic::prepareSessionConnections()
connect(uisession(), SIGNAL(sigMachineStateChange()), this, SLOT(sltMachineStateChanged()));
/* Guest additions state-change updater: */
- connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged()));
+ connect(uisession(), SIGNAL(sigAdditionsStateActualChange()), this, SLOT(sltAdditionsStateChanged()));
/* Mouse capability state-change updater: */
connect(uisession(), SIGNAL(sigMouseCapabilityChange()), this, SLOT(sltMouseCapabilityChanged()));
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
index eccf9c4..bc488c1 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
@@ -565,6 +565,9 @@ void UIMachineView::prepareFilters()
/* Enable MouseMove events: */
viewport()->setMouseTracking(true);
+ /* We have to watch for own events too: */
+ installEventFilter(this);
+
/* QScrollView does the below on its own, but let's
* do it anyway for the case it will not do it in the future: */
viewport()->installEventFilter(this);
@@ -1018,6 +1021,28 @@ bool UIMachineView::eventFilter(QObject *pWatched, QEvent *pEvent)
break;
}
}
+
+ if (pWatched == this)
+ {
+ switch (pEvent->type())
+ {
+ case QEvent::Move:
+ {
+ /* In some cases viewport resize-events can provoke the
+ * machine-view position changes inside the machine-window.
+ * We have to notify interested listeners like 3D service. */
+ session().GetConsole().GetDisplay().ViewportChanged(screenId(),
+ contentsX(),
+ contentsY(),
+ visibleWidth(),
+ visibleHeight());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
if (pWatched == machineWindow())
{
switch (pEvent->type())
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp
index afeb422..06df0b8 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMultiScreenLayout.cpp
@@ -267,7 +267,7 @@ void UIMultiScreenLayout::sltScreenLayoutChanged(QAction *pAction)
/* Check the memory requirements first: */
bool fSuccess = true;
CMachine machine = m_pMachineLogic->session().GetMachine();
- if (m_pMachineLogic->uisession()->isGuestAdditionsActive())
+ if (m_pMachineLogic->uisession()->isGuestSupportsGraphics())
{
quint64 availBits = machine.GetVRAMSize() * _1M * 8;
quint64 usedBits = memoryRequirements(tmpMap);
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
index 9a836b4..8c8e679 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
@@ -963,9 +963,12 @@ void UISession::sltAdditionsChange()
m_fIsGuestSupportsGraphics = fIsGuestSupportsGraphics;
m_fIsGuestSupportsSeamless = fIsGuestSupportsSeamless;
- /* Notify listeners about guest additions state changed: */
- emit sigAdditionsStateChange();
+ /* Notify listeners about guest additions state really changed: */
+ emit sigAdditionsStateActualChange();
}
+
+ /* Notify listeners about guest additions state event came: */
+ emit sigAdditionsStateChange();
}
void UISession::prepareConsoleEventHandlers()
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
index 2f7b5d5..496f9b8 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
@@ -192,7 +192,9 @@ public:
/* Guest additions state getters: */
bool isGuestAdditionsActive() const { return (m_ulGuestAdditionsRunLevel > AdditionsRunLevelType_None); }
- bool isGuestSupportsGraphics() const { return isGuestAdditionsActive() && m_fIsGuestSupportsGraphics; }
+ bool isGuestSupportsGraphics() const { return m_fIsGuestSupportsGraphics; }
+ /* The double check below is correct, even though it is an implementation
+ * detail of the Additions which the GUI should not ideally have to know. */
bool isGuestSupportsSeamless() const { return isGuestSupportsGraphics() && m_fIsGuestSupportsSeamless; }
/* Keyboard getters: */
@@ -254,6 +256,7 @@ signals:
void sigKeyboardLedsChange();
void sigMachineStateChange();
void sigAdditionsStateChange();
+ void sigAdditionsStateActualChange();
void sigNetworkAdapterChange(const CNetworkAdapter &networkAdapter);
void sigMediumChange(const CMediumAttachment &mediumAttachment);
void sigVRDEChange();
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
index 355f7bf..0f77aee 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineLogicFullscreen.cpp
@@ -58,7 +58,7 @@ bool UIMachineLogicFullscreen::checkAvailability()
const CMachine &machine = uisession()->session().GetMachine();
/* Check if there is enough physical memory to enter fullscreen: */
- if (uisession()->isGuestAdditionsActive())
+ if (uisession()->isGuestSupportsGraphics())
{
quint64 availBits = machine.GetVRAMSize() /* VRAM */ * _1M /* MiB to bytes */ * 8 /* to bits */;
quint64 usedBits = m_pScreenLayout->memoryRequirements();
@@ -329,6 +329,9 @@ void UIMachineLogicFullscreen::sltChangeVisualStateToScale()
void UIMachineLogicFullscreen::sltCheckForRequestedVisualStateType()
{
+ LogRel(("UIMachineLogicFullscreen::sltCheckForRequestedVisualStateType: Requested-state=%d, Machine-state=%d\n",
+ uisession()->requestedVisualState(), uisession()->machineState()));
+
/* Do not try to change visual-state type if machine was not started yet: */
if (!uisession()->isRunning() && !uisession()->isPaused())
return;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
index 5bad43c..037fe10 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineViewFullscreen.cpp
@@ -121,7 +121,7 @@ void UIMachineViewFullscreen::prepareConsoleConnections()
UIMachineView::prepareConsoleConnections();
/* Guest additions state-change updater: */
- connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged()));
+ connect(uisession(), SIGNAL(sigAdditionsStateActualChange()), this, SLOT(sltAdditionsStateChanged()));
}
void UIMachineViewFullscreen::setGuestAutoresizeEnabled(bool fEnabled)
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
index 3828c6c..dc50f49 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
@@ -42,6 +42,9 @@ bool UIMachineLogicNormal::checkAvailability()
void UIMachineLogicNormal::sltCheckForRequestedVisualStateType()
{
+ LogRel(("UIMachineLogicNormal::sltCheckForRequestedVisualStateType: Requested-state=%d, Machine-state=%d\n",
+ uisession()->requestedVisualState(), uisession()->machineState()));
+
/* Do not try to change visual-state type if machine was not started yet: */
if (!uisession()->isRunning() && !uisession()->isPaused())
return;
@@ -60,6 +63,9 @@ void UIMachineLogicNormal::sltCheckForRequestedVisualStateType()
uisession()->setRequestedVisualState(UIVisualStateType_Invalid);
uisession()->changeVisualState(UIVisualStateType_Seamless);
}
+ else
+ LogRel(("UIMachineLogicNormal::sltCheckForRequestedVisualStateType: "
+ "Rejecting 'seamless' as is it not yet supported...\n"));
break;
}
default:
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
index 016e5e8..e64e864 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
@@ -137,7 +137,7 @@ void UIMachineViewNormal::prepareConsoleConnections()
UIMachineView::prepareConsoleConnections();
/* Guest additions state-change updater: */
- connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged()));
+ connect(uisession(), SIGNAL(sigAdditionsStateActualChange()), this, SLOT(sltAdditionsStateChanged()));
}
void UIMachineViewNormal::saveMachineViewSettings()
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
index 1432951..44b02b0 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineLogicSeamless.cpp
@@ -50,7 +50,7 @@ bool UIMachineLogicSeamless::checkAvailability()
const CMachine &machine = uisession()->session().GetMachine();
/* Check if there is enough physical memory to enter seamless: */
- if (uisession()->isGuestAdditionsActive())
+ if (uisession()->isGuestSupportsSeamless())
{
quint64 availBits = machine.GetVRAMSize() /* VRAM */ * _1M /* MiB to bytes */ * 8 /* to bits */;
quint64 usedBits = m_pScreenLayout->memoryRequirements();
@@ -112,6 +112,9 @@ void UIMachineLogicSeamless::notifyAbout3DOverlayVisibilityChange(bool)
void UIMachineLogicSeamless::sltCheckForRequestedVisualStateType()
{
+ LogRel(("UIMachineLogicSeamless::sltCheckForRequestedVisualStateType: Requested-state=%d, Machine-state=%d\n",
+ uisession()->requestedVisualState(), uisession()->machineState()));
+
/* Do not try to change visual-state type if machine was not started yet: */
if (!uisession()->isRunning() && !uisession()->isPaused())
return;
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
index 20a1edc..56b516c 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
@@ -136,7 +136,7 @@ void UIMachineViewSeamless::prepareConsoleConnections()
UIMachineView::prepareConsoleConnections();
/* Guest additions state-change updater: */
- connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged()));
+ connect(uisession(), SIGNAL(sigAdditionsStateActualChange()), this, SLOT(sltAdditionsStateChanged()));
}
void UIMachineViewSeamless::prepareSeamless()
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp
index c395e61..4c5f9eb 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsGeneral.cpp
@@ -38,8 +38,8 @@ UIGlobalSettingsGeneral::UIGlobalSettingsGeneral()
m_pCheckBoxHostScreenSaver->hide();
/* Setup widgets: */
- m_pSelectorMachineFolder->setHomeDir(vboxGlobal().virtualBox().GetHomeFolder());
- m_pSelectorVRDPLibName->setHomeDir(vboxGlobal().virtualBox().GetHomeFolder());
+ m_pSelectorMachineFolder->setHomeDir(vboxGlobal().homeFolder());
+ m_pSelectorVRDPLibName->setHomeDir(vboxGlobal().homeFolder());
m_pSelectorVRDPLibName->setMode(VBoxFilePathSelectorWidget::Mode_File_Open);
/* Apply language settings: */
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp
index acb0458..90cce68 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp
@@ -68,6 +68,8 @@ static const osTypePattern gs_OSTypePattern[] =
{ QRegExp( "(Wi.*8.*1.*32)|(W8.*32)", Qt::CaseInsensitive), "Windows81" },
{ QRegExp( "(Wi.*8.*64)|(W8.*64)", Qt::CaseInsensitive), "Windows8_64" },
{ QRegExp( "(Wi.*8.*32)|(W8.*32)", Qt::CaseInsensitive), "Windows8" },
+ { QRegExp( "(Wi.*10.*64)|(W10.*64)", Qt::CaseInsensitive), "Windows10_64" },
+ { QRegExp( "(Wi.*10.*32)|(W10.*32)", Qt::CaseInsensitive), "Windows10" },
{ QRegExp( "Wi.*3.*1", Qt::CaseInsensitive), "Windows31" },
{ QRegExp( "Wi.*64", Qt::CaseInsensitive), "WindowsXP_64" },
{ QRegExp( "Wi.*32", Qt::CaseInsensitive), "WindowsXP" },
diff --git a/src/VBox/GuestHost/OpenGL/Makefile.kmk b/src/VBox/GuestHost/OpenGL/Makefile.kmk
index 7233624..1583084 100644
--- a/src/VBox/GuestHost/OpenGL/Makefile.kmk
+++ b/src/VBox/GuestHost/OpenGL/Makefile.kmk
@@ -89,9 +89,10 @@ VBoxOGLcrutil_SOURCES = \
util/bmpscale.cpp \
util/vboxhgcm.c \
$(VBOX_PATH_CROGL_GENFILES)/debug_opcodes.c
+VBoxOGLcrutil_SOURCES.win = \
+ util/VBoxOGLcrutil.rc
VBoxOGLcrutil_SOURCES.win.x86 = \
- util/util.def \
- util/util.rc
+ util/util.def
VBoxOGLcrutil_LIBS.win = \
$(PATH_SDK_$(VBOX_WINDDK)_LIB)/ddraw.lib \
$(PATH_SDK_$(VBOX_WINDDK)_LIB)/dxguid.lib \
@@ -109,7 +110,7 @@ VBoxOGLcrutil_DEFS.win += VBOX_WITH_CRHGSMI
VBoxOGLcrutil_LIBS.win += $(VBOX_PATH_ADDITIONS_LIB)/VBoxCrHgsmi$(VBOX_SUFF_LIB)
endif
ifdef VBOX_WITH_WDDM
-VBoxOGLcrutil_DEFS.win += VBOX_WITH_WDDM
+VBoxOGLcrutil_DEFS.win += VBOX_WITH_WDDM
VBoxOGLcrutil_DEFS.win += CR_DEBUG_BACKDOOR_ENABLE
VBoxOGLcrutil_INCS.win += $(PATH_ROOT)/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm
VBoxOGLcrutil_LIBS.win += $(VBOX_PATH_ADDITIONS_LIB)/VBoxDispMpLogger$(VBOX_SUFF_LIB)
@@ -625,9 +626,10 @@ endif
VBoxOGLerrorspu_SOURCES = \
$(VBOX_PATH_CROGL_GENFILES)/errorspu.c \
error/errorspu_init.c
+VBoxOGLerrorspu_SOURCES.win = \
+ error/VBoxOGLerrorspu.rc
VBoxOGLerrorspu_SOURCES.win.x86 = \
- error/error.def \
- error/errorspu.rc
+ error/error.def
VBoxOGLerrorspu_CLEAN = \
$(VBOX_PATH_CROGL_GENFILES)/errorspu.c
VBoxOGLerrorspu_LIBS = \
diff --git a/src/VBox/GuestHost/OpenGL/error/VBoxOGLerrorspu.rc b/src/VBox/GuestHost/OpenGL/error/VBoxOGLerrorspu.rc
new file mode 100644
index 0000000..8e88cf8
--- /dev/null
+++ b/src/VBox/GuestHost/OpenGL/error/VBoxOGLerrorspu.rc
@@ -0,0 +1,81 @@
+/* $Id: VBoxOGLerrorspu.rc $ */
+/** @file
+ * VBoxOGLerrorspu.rc - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+#ifdef IN_GUEST
+ #define DESCRIPTION_STR "VirtualBox crOpenGL ICD\0"
+ #ifdef VBOX_WDDM_WOW64
+ #define FILENAME_STR "VBoxOGLerrorspu-x86"
+ #else
+ #define FILENAME_STR "VBoxOGLerrorspu"
+ #endif
+ #define PRODUCT_STR VBOX_PRODUCT " Guest Additions\0"
+#else
+ #define DESCRIPTION_STR "VirtualBox crOpenGL ICD\0"
+ #define FILENAME_STR "VBoxOGLerrorspu"
+ #define PRODUCT_STR VBOX_PRODUCT "\0"
+#endif
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", DESCRIPTION_STR
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", FILENAME_STR "\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", FILENAME_STR ".dll\0"
+ VALUE "ProductName", PRODUCT_STR
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+// XXX is this really required?
+#if defined(VBOX_WDDM_WOW64) && defined(IN_GUEST)
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
+#endif
diff --git a/src/VBox/GuestHost/OpenGL/error/error.py b/src/VBox/GuestHost/OpenGL/error/error.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/error/errorspu.rc b/src/VBox/GuestHost/OpenGL/error/errorspu.rc
index af3aac9..ced9633 100644
--- a/src/VBox/GuestHost/OpenGL/error/errorspu.rc
+++ b/src/VBox/GuestHost/OpenGL/error/errorspu.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,29 +21,29 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK 0x3fL
- FILEFLAGS 0x0L
- FILEOS 0x40004L
- FILETYPE 0x3L
- FILESUBTYPE 0x4L
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0x0L
+ FILEOS 0x40004L
+ FILETYPE 0x3L
+ FILESUBTYPE 0x4L
BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxOGLerrorspu\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxOGLerrorspu\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
#ifdef VBOX_WDDM_WOW64
- VALUE "OriginalFilename", "VBoxOGLerrorspu-x86.dll\0"
+ VALUE "OriginalFilename", "VBoxOGLerrorspu-x86.dll\0"
#else
- VALUE "OriginalFilename", "VBoxOGLerrorspu.dll\0"
+ VALUE "OriginalFilename", "VBoxOGLerrorspu.dll\0"
#endif
- VALUE "ProductName", VBOX_PRODUCT " Guest Additions\0"
+ VALUE "ProductName", VBOX_PRODUCT " Guest Additions\0"
VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
diff --git a/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py b/src/VBox/GuestHost/OpenGL/glapi_parser/apiutil.py
old mode 100755
new mode 100644
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_blitter.h b/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
index b683072..e7dd02e 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
@@ -1,10 +1,10 @@
-/* $Id$ */
-
+/* $Id: cr_blitter.h $ */
/** @file
- * Blitter API
+ * Blitter API.
*/
+
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -14,14 +14,23 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#ifndef ___cr_blitter_h__
-#define ___cr_blitter_h__
+
+#ifndef ___cr_blitter_h
+#define ___cr_blitter_h
#include <iprt/cdefs.h>
#include <iprt/asm.h>
-#include "cr_spu.h"
+#include <iprt/string.h>
#include "cr_vreg.h"
+#ifdef IN_VMSVGA3D
+# include <iprt/assert.h>
+typedef struct TODO_VMSVGA3D_DISPATCH_TABLE SPUDispatchTable;
+# include <OpenGL/OpenGL.h>
+#else
+# include "cr_spu.h"
+#endif
+/** @todo r=bird: VBOXBLITTERDECL makes no sense. */
#ifndef IN_RING0
# define VBOXBLITTERDECL(_type) DECLEXPORT(_type)
#else
@@ -37,16 +46,23 @@ typedef struct CR_BLITTER_IMG
GLuint width, height;
GLuint bpp;
GLuint pitch;
-} CR_BLITTER_IMG, *PCR_BLITTER_IMG;
-
-VBOXBLITTERDECL(void) CrMClrFillImgRect(CR_BLITTER_IMG *pDst, const RTRECT *pCopyRect, uint32_t u32Color);
-VBOXBLITTERDECL(void) CrMClrFillImg(CR_BLITTER_IMG *pImg, uint32_t cRects, const RTRECT *pRects, uint32_t u32Color);
-VBOXBLITTERDECL(void) CrMBltImgRect(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, CR_BLITTER_IMG *pDst);
-VBOXBLITTERDECL(void) CrMBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pPos, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pDst);
-VBOXBLITTERDECL(void) CrMBltImgRectScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pPos, bool fSrcInvert, const RTRECT *pCopyRect, float strX, float strY, CR_BLITTER_IMG *pDst);
-VBOXBLITTERDECL(void) CrMBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTRECTSIZE *pSrcRectSize, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pDst);
+} CR_BLITTER_IMG;
+typedef CR_BLITTER_IMG *PCR_BLITTER_IMG;
+typedef CR_BLITTER_IMG const *PCCR_BLITTER_IMG;
+
+VBOXBLITTERDECL(void) CrMClrFillImgRect(PCR_BLITTER_IMG pDst, PCRTRECT pCopyRect, uint32_t u32Color);
+VBOXBLITTERDECL(void) CrMClrFillImg(PCR_BLITTER_IMG pImg, uint32_t cRects, PCRTRECT pRects, uint32_t u32Color);
+VBOXBLITTERDECL(void) CrMBltImgRect(PCCR_BLITTER_IMG pSrc, PCRTPOINT pSrcDataPoint, bool fSrcInvert, PCRTRECT pCopyRect,
+ PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrMBltImg(PCCR_BLITTER_IMG pSrc, PCRTPOINT pPos, uint32_t cRects, PCRTRECT pRects, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrMBltImgRectScaled(PCCR_BLITTER_IMG pSrc, PCRTPOINT pPos, bool fSrcInvert, PCRTRECT pCopyRect,
+ float strX, float strY, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrMBltImgScaled(PCCR_BLITTER_IMG pSrc, PCRTRECTSIZE pSrcRectSize, PCRTRECT pDstRect, uint32_t cRects,
+ PCRTRECT pRects, PCR_BLITTER_IMG pDst);
-/* GLSL Cache */
+/*
+ * GLSL Cache
+ */
typedef struct CR_GLSL_CACHE
{
int iGlVersion;
@@ -54,35 +70,41 @@ typedef struct CR_GLSL_CACHE
GLuint uNoAlpha2DRectProg;
SPUDispatchTable *pDispatch;
} CR_GLSL_CACHE;
+typedef CR_GLSL_CACHE *PCR_GLSL_CACHE;
+typedef CR_GLSL_CACHE const *PCCR_GLSL_CACHE;
-DECLINLINE(void) CrGlslInit(CR_GLSL_CACHE *pCache, SPUDispatchTable *pDispatch)
+DECLINLINE(void) CrGlslInit(PCR_GLSL_CACHE pCache, SPUDispatchTable *pDispatch)
{
- memset(pCache, 0, sizeof (*pCache));
+ RT_ZERO(*pCache);
pCache->pDispatch = pDispatch;
}
-DECLINLINE(bool) CrGlslIsInited(const CR_GLSL_CACHE *pCache)
+DECLINLINE(bool) CrGlslIsInited(PCCR_GLSL_CACHE pCache)
{
return !!pCache->pDispatch;
}
/* clients should set proper context before calling these funcs */
-VBOXBLITTERDECL(bool) CrGlslIsSupported(CR_GLSL_CACHE *pCache);
-VBOXBLITTERDECL(int) CrGlslProgGenAllNoAlpha(CR_GLSL_CACHE *pCache);
-VBOXBLITTERDECL(int) CrGlslProgGenNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTexTarget);
-VBOXBLITTERDECL(int) CrGlslProgUseGenNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTexTarget);
-VBOXBLITTERDECL(int) CrGlslProgUseNoAlpha(const CR_GLSL_CACHE *pCache, GLenum enmTexTarget);
-VBOXBLITTERDECL(void) CrGlslProgClear(const CR_GLSL_CACHE *pCache);
-VBOXBLITTERDECL(bool) CrGlslNeedsCleanup(const CR_GLSL_CACHE *pCache);
-VBOXBLITTERDECL(void) CrGlslCleanup(CR_GLSL_CACHE *pCache);
-VBOXBLITTERDECL(void) CrGlslTerm(CR_GLSL_CACHE *pCache);
-
-/* BLITTER */
+VBOXBLITTERDECL(bool) CrGlslIsSupported(PCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(int) CrGlslProgGenAllNoAlpha(PCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(int) CrGlslProgGenNoAlpha(PCR_GLSL_CACHE pCache, GLenum enmTexTarget);
+VBOXBLITTERDECL(int) CrGlslProgUseGenNoAlpha(PCR_GLSL_CACHE pCache, GLenum enmTexTarget);
+VBOXBLITTERDECL(int) CrGlslProgUseNoAlpha(PCCR_GLSL_CACHE pCache, GLenum enmTexTarget);
+VBOXBLITTERDECL(void) CrGlslProgClear(PCCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(bool) CrGlslNeedsCleanup(PCCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(void) CrGlslCleanup(PCR_GLSL_CACHE pCache);
+VBOXBLITTERDECL(void) CrGlslTerm(PCR_GLSL_CACHE pCache);
+
+/*
+ * BLITTER
+ */
typedef struct CR_BLITTER_BUFFER
{
GLuint cbBuffer;
- GLvoid * pvBuffer;
-} CR_BLITTER_BUFFER, *PCR_BLITTER_BUFFER;
+ GLvoid *pvBuffer;
+} CR_BLITTER_BUFFER;
+typedef CR_BLITTER_BUFFER *PCR_BLITTER_BUFFER;
+typedef CR_BLITTER_BUFFER const *PCCR_BLITTER_BUFFER;
typedef union CR_BLITTER_FLAGS
{
@@ -99,11 +121,12 @@ typedef union CR_BLITTER_FLAGS
uint32_t Reserved : 24;
};
uint32_t Value;
-} CR_BLITTER_FLAGS, *PCR_BLITTER_FLAGS;
+} CR_BLITTER_FLAGS;
struct CR_BLITTER;
-typedef DECLCALLBACK(int) FNCRBLT_BLITTER(struct CR_BLITTER *pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags);
+typedef DECLCALLBACK(int) FNCRBLT_BLITTER(struct CR_BLITTER *pBlitter, PCVBOXVR_TEXTURE pSrc, PCRTRECT paSrcRect,
+ PCRTRECTSIZE pDstSize, PCRTRECT paDstRect, uint32_t cRects, uint32_t fFlags);
typedef FNCRBLT_BLITTER *PFNCRBLT_BLITTER;
typedef struct CR_BLITTER_SPUITEM
@@ -115,13 +138,17 @@ typedef struct CR_BLITTER_SPUITEM
typedef struct CR_BLITTER_CONTEXT
{
CR_BLITTER_SPUITEM Base;
-} CR_BLITTER_CONTEXT, *PCR_BLITTER_CONTEXT;
+} CR_BLITTER_CONTEXT;
+typedef CR_BLITTER_CONTEXT *PCR_BLITTER_CONTEXT;
+typedef CR_BLITTER_CONTEXT const *PCCR_BLITTER_CONTEXT;
typedef struct CR_BLITTER_WINDOW
{
CR_BLITTER_SPUITEM Base;
GLuint width, height;
-} CR_BLITTER_WINDOW, *PCR_BLITTER_WINDOW;
+} CR_BLITTER_WINDOW;
+typedef CR_BLITTER_WINDOW *PCR_BLITTER_WINDOW;
+typedef CR_BLITTER_WINDOW const *PCCR_BLITTER_WINDOW;
typedef struct CR_BLITTER
{
@@ -136,20 +163,23 @@ typedef struct CR_BLITTER
CR_BLITTER_CONTEXT CtxInfo;
int32_t i32MakeCurrentUserData;
SPUDispatchTable *pDispatch;
- const CR_GLSL_CACHE *pGlslCache;
+ PCCR_GLSL_CACHE pGlslCache;
CR_GLSL_CACHE LocalGlslCache;
-} CR_BLITTER, *PCR_BLITTER;
+} CR_BLITTER;
+typedef CR_BLITTER *PCR_BLITTER;
+typedef CR_BLITTER const *PCCR_BLITTER;
DECLINLINE(GLboolean) CrBltIsInitialized(PCR_BLITTER pBlitter)
{
return !!pBlitter->pDispatch;
}
-VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, const CR_GLSL_CACHE *pShaders, SPUDispatchTable *pDispatch);
+VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, PCCR_BLITTER_CONTEXT pCtxBase, bool fCreateNewCtx,
+ bool fForceDrawBlt, PCCR_GLSL_CACHE pShaders, SPUDispatchTable *pDispatch);
VBOXBLITTERDECL(void) CrBltTerm(PCR_BLITTER pBlitter);
-VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter);
+VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter);
DECLINLINE(GLboolean) CrBltSupportsTexTex(PCR_BLITTER pBlitter)
{
@@ -177,8 +207,9 @@ DECLINLINE(void) CrBltSetMakeCurrentUserData(PCR_BLITTER pBlitter, int32_t i32Ma
pBlitter->i32MakeCurrentUserData = i32MakeCurrentUserData;
}
-VBOXBLITTERDECL(int) CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural);
-DECLINLINE(const CR_BLITTER_WINDOW *) CrBltMuralGetCurrentInfo(PCR_BLITTER pBlitter)
+VBOXBLITTERDECL(int) CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, PCCR_BLITTER_WINDOW pMural);
+
+DECLINLINE(PCCR_BLITTER_WINDOW) CrBltMuralGetCurrentInfo(PCR_BLITTER pBlitter)
{
return &pBlitter->CurrentMural;
}
@@ -187,12 +218,14 @@ VBOXBLITTERDECL(void) CrBltCheckUpdateViewport(PCR_BLITTER pBlitter);
VBOXBLITTERDECL(void) CrBltLeave(PCR_BLITTER pBlitter);
VBOXBLITTERDECL(int) CrBltEnter(PCR_BLITTER pBlitter);
-VBOXBLITTERDECL(void) CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags);
-VBOXBLITTERDECL(void) CrBltBlitTexTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *pSrcRect, const VBOXVR_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags);
-VBOXBLITTERDECL(int) CrBltImgGetTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, GLenum enmFormat, CR_BLITTER_IMG *pDst);
-
-VBOXBLITTERDECL(int) CrBltImgGetMural(PCR_BLITTER pBlitter, bool fBb, CR_BLITTER_IMG *pDst);
-VBOXBLITTERDECL(void) CrBltImgFree(PCR_BLITTER pBlitter, CR_BLITTER_IMG *pDst);
+VBOXBLITTERDECL(void) CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, PCVBOXVR_TEXTURE pSrc, PCRTRECT paSrcRects,
+ PCRTRECT paDstRects, uint32_t cRects, uint32_t fFlags);
+VBOXBLITTERDECL(void) CrBltBlitTexTex(PCR_BLITTER pBlitter, PCVBOXVR_TEXTURE pSrc, PCRTRECT pSrcRect, PCVBOXVR_TEXTURE pDst,
+ PCRTRECT pDstRect, uint32_t cRects, uint32_t fFlags);
+VBOXBLITTERDECL(int) CrBltImgGetTex(PCR_BLITTER pBlitter, PCVBOXVR_TEXTURE pSrc, GLenum enmFormat, PCR_BLITTER_IMG pDst);
+
+VBOXBLITTERDECL(int) CrBltImgGetMural(PCR_BLITTER pBlitter, bool fBb, PCR_BLITTER_IMG pDst);
+VBOXBLITTERDECL(void) CrBltImgFree(PCR_BLITTER pBlitter, PCR_BLITTER_IMG pDst);
VBOXBLITTERDECL(void) CrBltPresent(PCR_BLITTER pBlitter);
/* */
struct CR_TEXDATA;
@@ -211,7 +244,7 @@ typedef union CR_TEXDATA_FLAGS
uint32_t Reserved : 28;
};
uint32_t Value;
-} CR_TEXDATA_FLAGS, *PCR_TEXDATA_FLAGS;
+} CR_TEXDATA_FLAGS;
typedef struct CR_TEXDATA
@@ -227,9 +260,11 @@ typedef struct CR_TEXDATA
/*dtor*/
PFNCRTEXDATA_RELEASED pfnTextureReleased;
struct CR_TEXDATA *pScaledCache;
-} CR_TEXDATA, *PCR_TEXDATA;
+} CR_TEXDATA;
+typedef CR_TEXDATA *PCR_TEXDATA;
+typedef CR_TEXDATA const *PCCR_TEXDATA;
-DECLINLINE(void) CrTdInit(PCR_TEXDATA pTex, const VBOXVR_TEXTURE *pVrTex, PCR_BLITTER pBlitter, PFNCRTEXDATA_RELEASED pfnTextureReleased)
+DECLINLINE(void) CrTdInit(PCR_TEXDATA pTex, PCVBOXVR_TEXTURE pVrTex, PCR_BLITTER pBlitter, PFNCRTEXDATA_RELEASED pfnTextureReleased)
{
memset(pTex, 0, sizeof (*pTex));
pTex->Tex = *pVrTex;
@@ -238,12 +273,12 @@ DECLINLINE(void) CrTdInit(PCR_TEXDATA pTex, const VBOXVR_TEXTURE *pVrTex, PCR_BL
pTex->pfnTextureReleased = pfnTextureReleased;
}
-DECLINLINE(const VBOXVR_TEXTURE*) CrTdTexGet(const CR_TEXDATA *pTex)
+DECLINLINE(PCVBOXVR_TEXTURE) CrTdTexGet(PCCR_TEXDATA pTex)
{
return &pTex->Tex;
}
-DECLINLINE(PCR_BLITTER) CrTdBlitterGet(CR_TEXDATA *pTex)
+DECLINLINE(PCR_BLITTER) CrTdBlitterGet(PCR_TEXDATA pTex)
{
return pTex->pBlitter;
}
@@ -251,57 +286,68 @@ DECLINLINE(PCR_BLITTER) CrTdBlitterGet(CR_TEXDATA *pTex)
DECLINLINE(int) CrTdBltEnter(PCR_TEXDATA pTex)
{
int rc;
- if (pTex->Flags.Entered)
- return VERR_INVALID_STATE;
- rc = CrBltEnter(pTex->pBlitter);
+ if (pTex->Flags.Entered)
+ return VERR_INVALID_STATE;
+ rc = CrBltEnter(pTex->pBlitter);
+#ifdef IN_VMSVGA3D
+ AssertRCReturn(rc, rc);
+#else
if (!RT_SUCCESS(rc))
{
WARN(("CrBltEnter failed rc %d", rc));
return rc;
}
- pTex->Flags.Entered = 1;
- return VINF_SUCCESS;
+#endif
+ pTex->Flags.Entered = 1;
+ return VINF_SUCCESS;
}
DECLINLINE(bool) CrTdBltIsEntered(PCR_TEXDATA pTex)
{
- return pTex->Flags.Entered;
+ return pTex->Flags.Entered;
}
DECLINLINE(void) CrTdBltLeave(PCR_TEXDATA pTex)
{
- if (!pTex->Flags.Entered)
- {
- WARN(("invalid Blt Leave"));
- return;
- }
+#ifdef IN_VMSVGA3D
+ AssertReturnVoid(pTex->Flags.Entered);
+#else
+ if (!pTex->Flags.Entered)
+ {
+ WARN(("invalid Blt Leave"));
+ return;
+ }
+#endif
- CrBltLeave(pTex->pBlitter);
+ CrBltLeave(pTex->pBlitter);
- pTex->Flags.Entered = 0;
+ pTex->Flags.Entered = 0;
}
/* the CrTdBltXxx calls are done with the entered blitter */
-/* acquire the texture data, returns the cached data in case it is cached.
- * the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup.
- * */
-VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, const CR_BLITTER_IMG**ppImg);
+/** Acquire the texture data, returns the cached data in case it is cached.
+ * The data remains cached in the CR_TEXDATA object until it is discarded with
+ * CrTdBltDataFree or CrTdBltDataCleanup. */
+VBOXBLITTERDECL(int) CrTdBltDataAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, PCCR_BLITTER_IMG *ppImg);
-VBOXBLITTERDECL(int) CrTdBltDataAcquireScaled(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted, uint32_t width, uint32_t height, const CR_BLITTER_IMG**ppImg);
+VBOXBLITTERDECL(int) CrTdBltDataAcquireScaled(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted,
+ uint32_t width, uint32_t height, PCCR_BLITTER_IMG *ppImg);
-VBOXBLITTERDECL(int) CrTdBltDataReleaseScaled(PCR_TEXDATA pTex, const CR_BLITTER_IMG *pImg);
+VBOXBLITTERDECL(int) CrTdBltDataReleaseScaled(PCR_TEXDATA pTex, PCCR_BLITTER_IMG pImg);
VBOXBLITTERDECL(void) CrTdBltScaleCacheMoveTo(PCR_TEXDATA pTex, PCR_TEXDATA pDstTex);
-/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup */
+/** Release the texture data, the data remains cached in the CR_TEXDATA object
+ * until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup. */
VBOXBLITTERDECL(int) CrTdBltDataRelease(PCR_TEXDATA pTex);
-/* discard the texture data cached with previous CrTdBltDataAcquire.
- * Must be called wit data released (CrTdBltDataRelease) */
+/** Discard the texture data cached with previous CrTdBltDataAcquire.
+ * Must be called wit data released (CrTdBltDataRelease). */
VBOXBLITTERDECL(int) CrTdBltDataFree(PCR_TEXDATA pTex);
VBOXBLITTERDECL(int) CrTdBltDataFreeNe(PCR_TEXDATA pTex);
VBOXBLITTERDECL(void) CrTdBltDataInvalidateNe(PCR_TEXDATA pTex);
-/* does same as CrTdBltDataFree, and in addition cleans up.
- * this is kind of a texture destructor, which clients should call on texture object destruction, e.g. from the PFNCRTEXDATA_RELEASED callback */
+/** Does same as CrTdBltDataFree, and in addition cleans up.
+ * This is kind of a texture destructor, which clients should call on texture object destruction,
+ * e.g. from the PFNCRTEXDATA_RELEASED callback. */
VBOXBLITTERDECL(int) CrTdBltDataCleanup(PCR_TEXDATA pTex);
VBOXBLITTERDECL(int) CrTdBltDataCleanupNe(PCR_TEXDATA pTex);
@@ -320,11 +366,12 @@ DECLINLINE(uint32_t) CrTdRelease(PCR_TEXDATA pTex)
pTex->pfnTextureReleased(pTex);
else
CrTdBltDataCleanupNe(pTex);
- }
+ }
return cRefs;
}
RT_C_DECLS_END
-#endif /* #ifndef ___cr_blitter_h__ */
+#endif
+
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_compositor.h b/src/VBox/GuestHost/OpenGL/include/cr_compositor.h
index 4ad5693..74496d6 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_compositor.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_compositor.h
@@ -1,11 +1,10 @@
/* $Id: cr_compositor.h $ */
-
/** @file
- * uint32_t compositor API
+ * Compositor API.
*/
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -15,10 +14,13 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#ifndef ___cr_compositor_h_
-#define ___cr_compositor_h_
-#include <cr_vreg.h>
-#include <cr_blitter.h>
+
+#ifndef ___cr_compositor_h
+#define ___cr_compositor_h
+
+#include "cr_vreg.h"
+#include "cr_blitter.h"
+
/* Compositor with Stretching & Cached Rectangles info */
@@ -27,7 +29,9 @@ RT_C_DECLS_BEGIN
struct VBOXVR_SCR_COMPOSITOR_ENTRY;
struct VBOXVR_SCR_COMPOSITOR;
-typedef DECLCALLBACK(void) FNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry);
+typedef DECLCALLBACK(void) FNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED(const struct VBOXVR_SCR_COMPOSITOR *pCompositor,
+ struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry,
+ struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry);
typedef FNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED *PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED;
@@ -43,7 +47,9 @@ typedef struct VBOXVR_SCR_COMPOSITOR_ENTRY
PRTRECT paDstUnstretchedRects;
PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased;
PCR_TEXDATA pTex;
-} VBOXVR_SCR_COMPOSITOR_ENTRY, *PVBOXVR_SCR_COMPOSITOR_ENTRY;
+} VBOXVR_SCR_COMPOSITOR_ENTRY;
+typedef VBOXVR_SCR_COMPOSITOR_ENTRY *PVBOXVR_SCR_COMPOSITOR_ENTRY;
+typedef VBOXVR_SCR_COMPOSITOR_ENTRY const *PCVBOXVR_SCR_COMPOSITOR_ENTRY;
typedef struct VBOXVR_SCR_COMPOSITOR
{
@@ -59,13 +65,17 @@ typedef struct VBOXVR_SCR_COMPOSITOR
PRTRECT paSrcRects;
PRTRECT paDstRects;
PRTRECT paDstUnstretchedRects;
-} VBOXVR_SCR_COMPOSITOR, *PVBOXVR_SCR_COMPOSITOR;
+} VBOXVR_SCR_COMPOSITOR;
+typedef VBOXVR_SCR_COMPOSITOR *PVBOXVR_SCR_COMPOSITOR;
+typedef VBOXVR_SCR_COMPOSITOR const *PCVBOXVR_SCR_COMPOSITOR;
-typedef DECLCALLBACK(bool) FNVBOXVRSCRCOMPOSITOR_VISITOR(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, void *pvVisitor);
+typedef DECLCALLBACK(bool) FNVBOXVRSCRCOMPOSITOR_VISITOR(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ void *pvVisitor);
typedef FNVBOXVRSCRCOMPOSITOR_VISITOR *PFNVBOXVRSCRCOMPOSITOR_VISITOR;
-DECLINLINE(void) CrVrScrCompositorEntryInit(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect, CR_TEXDATA *pTex, PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased)
+DECLINLINE(void) CrVrScrCompositorEntryInit(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PCRTRECT pRect, CR_TEXDATA *pTex,
+ PFNVBOXVRSCRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased)
{
memset(pEntry, 0, sizeof (*pEntry));
VBoxVrCompositorEntryInit(&pEntry->Ce);
@@ -87,7 +97,7 @@ DECLINLINE(void) CrVrScrCompositorEntryCleanup(PVBOXVR_SCR_COMPOSITOR_ENTRY pEnt
}
}
-DECLINLINE(bool) CrVrScrCompositorEntryIsUsed(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+DECLINLINE(bool) CrVrScrCompositorEntryIsUsed(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
}
@@ -108,55 +118,72 @@ DECLINLINE(void) CrVrScrCompositorEntryTexSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntr
pEntry->pTex = pTex;
}
-DECLINLINE(CR_TEXDATA *) CrVrScrCompositorEntryTexGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+DECLINLINE(CR_TEXDATA *) CrVrScrCompositorEntryTexGet(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return pEntry->pTex;
}
-DECLINLINE(bool) CrVrScrCompositorEntryIsChanged(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+DECLINLINE(bool) CrVrScrCompositorEntryIsChanged(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return !!pEntry->fChanged;
}
-DECLINLINE(bool) CrVrScrCompositorIsEmpty(const VBOXVR_SCR_COMPOSITOR *pCompositor)
+DECLINLINE(bool) CrVrScrCompositorIsEmpty(PCVBOXVR_SCR_COMPOSITOR pCompositor)
{
return VBoxVrCompositorIsEmpty(&pCompositor->Compositor);
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect);
-VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, CR_TEXDATA *pTex);
-VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor);
+VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTRECT pRect);
+VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ CR_TEXDATA *pTex);
+VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor,
+ void *pvVisitor);
VBOXVREGDECL(void) CrVrScrCompositorEntrySetAllChanged(PVBOXVR_SCR_COMPOSITOR pCompositor, bool fChanged);
-DECLINLINE(bool) CrVrScrCompositorEntryIsInList(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+DECLINLINE(bool) CrVrScrCompositorEntryIsInList(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangeFlags);
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, bool *pfChanged);
-VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged);
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
-VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged);
-VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos);
-DECLINLINE(const RTRECT*) CrVrScrCompositorEntryRectGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos, uint32_t cRegions, PCRTRECT paRegions, bool fPosRelated,
+ VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangeFlags);
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos, uint32_t cRegions, PCRTRECT paRegions, bool fPosRelated,
+ bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCVBOXVR_LIST pList2, bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions, bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions,
+ PCRTRECT paRegions, bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, PCVBOXVR_LIST pList2,
+ bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos);
+DECLINLINE(PCRTRECT) CrVrScrCompositorEntryRectGet(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return &pEntry->Rect;
}
/* regions are valid until the next CrVrScrCompositor call */
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PCVBOXVR_SCR_COMPOSITOR pCompositor,
+ PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions,
+ PCRTRECT *ppaSrcRegions, PCRTRECT *ppaDstRegions,
+ PCRTRECT *ppaDstUnstretchedRects);
VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
-VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry);
+VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry);
VBOXVREGDECL(void) CrVrScrCompositorEntryFlagsSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t fFlags);
-VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry);
-DECLINLINE(uint32_t) CrVrScrCompositorEntryFlagsGet(const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PCVBOXVR_SCR_COMPOSITOR pCompositor,
+ PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
+DECLINLINE(uint32_t) CrVrScrCompositorEntryFlagsGet(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return pEntry->fFlags;
}
-VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor, const RTRECT *pRect);
-VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, const RTRECT *pRect, bool *pfChanged);
-DECLINLINE(const RTRECT*) CrVrScrCompositorRectGet(const VBOXVR_SCR_COMPOSITOR *pCompositor)
+VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor, PCRTRECT pRect);
+VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PCRTRECT pRect, bool *pfChanged);
+DECLINLINE(PCRTRECT) CrVrScrCompositorRectGet(PCVBOXVR_SCR_COMPOSITOR pCompositor)
{
return &pCompositor->Rect;
}
@@ -164,15 +191,19 @@ DECLINLINE(const RTRECT*) CrVrScrCompositorRectGet(const VBOXVR_SCR_COMPOSITOR *
VBOXVREGDECL(void) CrVrScrCompositorClear(PVBOXVR_SCR_COMPOSITOR pCompositor);
VBOXVREGDECL(void) CrVrScrCompositorRegionsClear(PVBOXVR_SCR_COMPOSITOR pCompositor, bool *pfChanged);
-typedef DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) FNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR(const VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext);
+typedef DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) FNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR(PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ void *pvContext);
typedef FNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR *PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR;
-VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor);
-VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, bool *pfChanged);
-VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorClone(PCVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor,
+ PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void *pvEntryFor);
+VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, PCVBOXVR_LIST pVr, bool *pfChanged);
+VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(PCVBOXVR_SCR_COMPOSITOR pCompositor, PCVBOXVR_LIST pVr,
+ PVBOXVR_SCR_COMPOSITOR pDstCompositor,
+ PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void *pvEntryFor, bool *pfChanged);
#ifndef IN_RING0
VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompositor, float StretchX, float StretchY);
-DECLINLINE(void) CrVrScrCompositorGetStretching(const VBOXVR_SCR_COMPOSITOR *pCompositor, float *pStretchX, float *pStretchY)
+DECLINLINE(void) CrVrScrCompositorGetStretching(PCVBOXVR_SCR_COMPOSITOR pCompositor, float *pStretchX, float *pStretchY)
{
if (pStretchX)
*pStretchX = pCompositor->StretchX;
@@ -182,28 +213,32 @@ DECLINLINE(void) CrVrScrCompositorGetStretching(const VBOXVR_SCR_COMPOSITOR *pCo
}
#endif
/* regions are valid until the next CrVrScrCompositor call */
-VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects);
+VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PCVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions,
+ PCRTRECT *ppaSrcRegions, PCRTRECT *ppaDstRegions, PCRTRECT *ppaDstUnstretchedRects);
-#define VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(_p) ((PVBOXVR_SCR_COMPOSITOR_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)))
-#define VBOXVR_SCR_COMPOSITOR_CONST_ENTRY_FROM_ENTRY(_p) ((const VBOXVR_SCR_COMPOSITOR_ENTRY*)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)))
-#define VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(_p) ((PVBOXVR_SCR_COMPOSITOR)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_SCR_COMPOSITOR, Compositor)))
+#define VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(_p) RT_FROM_MEMBER(_p, VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)
+#define VBOXVR_SCR_COMPOSITOR_CONST_ENTRY_FROM_ENTRY(_p) RT_FROM_MEMBER(_p, const VBOXVR_SCR_COMPOSITOR_ENTRY, Ce)
+#define VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(_p) RT_FROM_MEMBER(_p, VBOXVR_SCR_COMPOSITOR, Compositor)
typedef struct VBOXVR_SCR_COMPOSITOR_ITERATOR
{
VBOXVR_COMPOSITOR_ITERATOR Base;
-} VBOXVR_SCR_COMPOSITOR_ITERATOR ,*PVBOXVR_SCR_COMPOSITOR_ITERATOR;
+} VBOXVR_SCR_COMPOSITOR_ITERATOR;
+typedef VBOXVR_SCR_COMPOSITOR_ITERATOR *PVBOXVR_SCR_COMPOSITOR_ITERATOR;
typedef struct VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR
{
VBOXVR_COMPOSITOR_CONST_ITERATOR Base;
-} VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR ,*PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR;
+} VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR;
+typedef VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR *PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR;
DECLINLINE(void) CrVrScrCompositorIterInit(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ITERATOR pIter)
{
VBoxVrCompositorIterInit(&pCompositor->Compositor, &pIter->Base);
}
-DECLINLINE(void) CrVrScrCompositorConstIterInit(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR pIter)
+DECLINLINE(void) CrVrScrCompositorConstIterInit(PCVBOXVR_SCR_COMPOSITOR pCompositor,
+ PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR pIter)
{
VBoxVrCompositorConstIterInit(&pCompositor->Compositor, &pIter->Base);
}
@@ -212,22 +247,19 @@ DECLINLINE(PVBOXVR_SCR_COMPOSITOR_ENTRY) CrVrScrCompositorIterNext(PVBOXVR_SCR_C
{
PVBOXVR_COMPOSITOR_ENTRY pCe = VBoxVrCompositorIterNext(&pIter->Base);
if (pCe)
- {
return VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pCe);
- }
return NULL;
}
-DECLINLINE(const VBOXVR_SCR_COMPOSITOR_ENTRY*) CrVrScrCompositorConstIterNext(PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR pIter)
+DECLINLINE(PCVBOXVR_SCR_COMPOSITOR_ENTRY) CrVrScrCompositorConstIterNext(PVBOXVR_SCR_COMPOSITOR_CONST_ITERATOR pIter)
{
- const VBOXVR_COMPOSITOR_ENTRY *pCe = VBoxVrCompositorConstIterNext(&pIter->Base);
+ PCVBOXVR_COMPOSITOR_ENTRY pCe = VBoxVrCompositorConstIterNext(&pIter->Base);
if (pCe)
- {
return VBOXVR_SCR_COMPOSITOR_CONST_ENTRY_FROM_ENTRY(pCe);
- }
return NULL;
}
RT_C_DECLS_END
-#endif /* ___cr_compositor_h_ */
+#endif
+
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_protocol.h b/src/VBox/GuestHost/OpenGL/include/cr_protocol.h
index c58c590..2192f9b 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_protocol.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_protocol.h
@@ -52,8 +52,10 @@ typedef struct CR_CAPS_INFO
#define CR_VBOX_CAP_GETATTRIBSLOCATIONS 0x00000008
/* flush command blocks for execution */
#define CR_VBOX_CAP_CMDBLOCKS_FLUSH 0x00000010
+/* Notify guest if host reports minimal OpenGL capabilities. */
+#define CR_VBOX_CAP_HOST_CAPS_NOT_SUFFICIENT 0x00000020
-#define CR_VBOX_CAPS_ALL 0x0000001f
+#define CR_VBOX_CAPS_ALL 0x0000003f
#define CR_PRESENT_SCREEN_MASK 0xffff
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_vreg.h b/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
index 9d60caa..aaf74ae 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
@@ -1,11 +1,10 @@
/* $Id: cr_vreg.h $ */
-
/** @file
* Visible Regions processing API
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -15,6 +14,7 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+
#ifndef ___cr_vreg_h_
#define ___cr_vreg_h_
@@ -29,6 +29,7 @@
#ifndef IN_RING0
# define VBOXVREGDECL(_type) DECLEXPORT(_type)
#else
+/** @todo r=bird: Using RTDECL is just SOO wrong! */
# define VBOXVREGDECL(_type) RTDECL(_type)
#endif
@@ -38,27 +39,29 @@ RT_C_DECLS_BEGIN
typedef struct VBOXVR_LIST
{
- RTLISTNODE ListHead;
+ RTLISTANCHOR ListHead;
uint32_t cEntries;
-} VBOXVR_LIST, *PVBOXVR_LIST;
+} VBOXVR_LIST;
+typedef VBOXVR_LIST *PVBOXVR_LIST;
+typedef VBOXVR_LIST const *PCVBOXVR_LIST;
-DECLINLINE(int) VBoxRectCmp(const RTRECT * pRect1, const RTRECT * pRect2)
+DECLINLINE(int) VBoxRectCmp(PCRTRECT pRect1, PCRTRECT pRect2)
{
- return memcmp(pRect1, pRect2, sizeof (*pRect1));
+ return memcmp(pRect1, pRect2, sizeof(*pRect1));
}
#ifndef IN_RING0
-#define CR_FLOAT_RCAST(_t, _v) ((_t)((float)(_v) + 0.5))
+# define CR_FLOAT_RCAST(_t, _v) ((_t)((float)(_v) + 0.5))
DECLINLINE(void) VBoxRectScale(PRTRECT pRect, float xScale, float yScale)
{
- pRect->xLeft = CR_FLOAT_RCAST(int32_t, pRect->xLeft * xScale);
- pRect->yTop = CR_FLOAT_RCAST(int32_t, pRect->yTop * yScale);
- pRect->xRight = CR_FLOAT_RCAST(int32_t, pRect->xRight * xScale);
+ pRect->xLeft = CR_FLOAT_RCAST(int32_t, pRect->xLeft * xScale);
+ pRect->yTop = CR_FLOAT_RCAST(int32_t, pRect->yTop * yScale);
+ pRect->xRight = CR_FLOAT_RCAST(int32_t, pRect->xRight * xScale);
pRect->yBottom = CR_FLOAT_RCAST(int32_t, pRect->yBottom * yScale);
}
-DECLINLINE(void) VBoxRectScaled(const RTRECT *pRect, float xScale, float yScale, PRTRECT pResult)
+DECLINLINE(void) VBoxRectScaled(PCRTRECT pRect, float xScale, float yScale, PRTRECT pResult)
{
*pResult = *pRect;
VBoxRectScale(pResult, xScale, yScale);
@@ -66,40 +69,41 @@ DECLINLINE(void) VBoxRectScaled(const RTRECT *pRect, float xScale, float yScale,
DECLINLINE(void) VBoxRectUnscale(PRTRECT pRect, float xScale, float yScale)
{
- pRect->xLeft = CR_FLOAT_RCAST(int32_t, pRect->xLeft / xScale);
- pRect->yTop = CR_FLOAT_RCAST(int32_t, pRect->yTop / yScale);
- pRect->xRight = CR_FLOAT_RCAST(int32_t, pRect->xRight / xScale);
+ pRect->xLeft = CR_FLOAT_RCAST(int32_t, pRect->xLeft / xScale);
+ pRect->yTop = CR_FLOAT_RCAST(int32_t, pRect->yTop / yScale);
+ pRect->xRight = CR_FLOAT_RCAST(int32_t, pRect->xRight / xScale);
pRect->yBottom = CR_FLOAT_RCAST(int32_t, pRect->yBottom / yScale);
}
-DECLINLINE(void) VBoxRectUnscaled(const RTRECT *pRect, float xScale, float yScale, PRTRECT pResult)
+DECLINLINE(void) VBoxRectUnscaled(PCRTRECT pRect, float xScale, float yScale, PRTRECT pResult)
{
*pResult = *pRect;
VBoxRectUnscale(pResult, xScale, yScale);
}
-#endif
-DECLINLINE(void) VBoxRectIntersect(PRTRECT pRect1, const RTRECT * pRect2)
+#endif /* IN_RING0 */
+
+DECLINLINE(void) VBoxRectIntersect(PRTRECT pRect1, PCRTRECT pRect2)
{
Assert(pRect1);
Assert(pRect2);
- pRect1->xLeft = RT_MAX(pRect1->xLeft, pRect2->xLeft);
- pRect1->yTop = RT_MAX(pRect1->yTop, pRect2->yTop);
- pRect1->xRight = RT_MIN(pRect1->xRight, pRect2->xRight);
+ pRect1->xLeft = RT_MAX(pRect1->xLeft, pRect2->xLeft);
+ pRect1->yTop = RT_MAX(pRect1->yTop, pRect2->yTop);
+ pRect1->xRight = RT_MIN(pRect1->xRight, pRect2->xRight);
pRect1->yBottom = RT_MIN(pRect1->yBottom, pRect2->yBottom);
/* ensure the rect is valid */
- pRect1->xRight = RT_MAX(pRect1->xRight, pRect1->xLeft);
+ pRect1->xRight = RT_MAX(pRect1->xRight, pRect1->xLeft);
pRect1->yBottom = RT_MAX(pRect1->yBottom, pRect1->yTop);
}
-DECLINLINE(void) VBoxRectIntersected(const RTRECT *pRect1, const RTRECT * pRect2, RTRECT *pResult)
+DECLINLINE(void) VBoxRectIntersected(PCRTRECT pRect1, PCRTRECT pRect2, PRTRECT pResult)
{
*pResult = *pRect1;
VBoxRectIntersect(pResult, pRect2);
}
-DECLINLINE(void) VBoxRectTranslate(RTRECT * pRect, int32_t x, int32_t y)
+DECLINLINE(void) VBoxRectTranslate(PRTRECT pRect, int32_t x, int32_t y)
{
pRect->xLeft += x;
pRect->yTop += y;
@@ -107,45 +111,45 @@ DECLINLINE(void) VBoxRectTranslate(RTRECT * pRect, int32_t x, int32_t y)
pRect->yBottom += y;
}
-DECLINLINE(void) VBoxRectTranslated(const RTRECT * pRect, int32_t x, int32_t y, RTRECT *pResult)
+DECLINLINE(void) VBoxRectTranslated(PCRTRECT pRect, int32_t x, int32_t y, PRTRECT pResult)
{
*pResult = *pRect;
VBoxRectTranslate(pResult, x, y);
}
-DECLINLINE(void) VBoxRectInvertY(RTRECT * pRect)
+DECLINLINE(void) VBoxRectInvertY(PRTRECT pRect)
{
int32_t y = pRect->yTop;
pRect->yTop = pRect->yBottom;
pRect->yBottom = y;
}
-DECLINLINE(void) VBoxRectInvertedY(const RTRECT * pRect, RTRECT * pResult)
+DECLINLINE(void) VBoxRectInvertedY(PCRTRECT pRect, PRTRECT pResult)
{
*pResult = *pRect;
VBoxRectInvertY(pResult);
}
-DECLINLINE(void) VBoxRectMove(RTRECT * pRect, int32_t x, int32_t y)
+DECLINLINE(void) VBoxRectMove(PRTRECT pRect, int32_t x, int32_t y)
{
- int32_t w = pRect->xRight - pRect->xLeft;
- int32_t h = pRect->yBottom - pRect->yTop;
+ int32_t cx = pRect->xRight - pRect->xLeft;
+ int32_t cy = pRect->yBottom - pRect->yTop;
pRect->xLeft = x;
pRect->yTop = y;
- pRect->xRight = w + x;
- pRect->yBottom = h + y;
+ pRect->xRight = cx + x;
+ pRect->yBottom = cy + y;
}
-DECLINLINE(void) VBoxRectMoved(const RTRECT * pRect, int32_t x, int32_t y, RTRECT *pResult)
+DECLINLINE(void) VBoxRectMoved(PCRTRECT pRect, int32_t x, int32_t y, PRTRECT pResult)
{
*pResult = *pRect;
VBoxRectMove(pResult, x, y);
}
-DECLINLINE(bool) VBoxRectCovers(const RTRECT *pRect, const RTRECT *pCovered)
+DECLINLINE(bool) VBoxRectCovers(PCRTRECT pRect, PCRTRECT pCovered)
{
- Assert(pRect);
- Assert(pCovered);
+ AssertPtr(pRect);
+ AssertPtr(pCovered);
if (pRect->xLeft > pCovered->xLeft)
return false;
if (pRect->yTop > pCovered->yTop)
@@ -157,25 +161,25 @@ DECLINLINE(bool) VBoxRectCovers(const RTRECT *pRect, const RTRECT *pCovered)
return true;
}
-DECLINLINE(bool) VBoxRectIsZero(const RTRECT *pRect)
+DECLINLINE(bool) VBoxRectIsZero(PCRTRECT pRect)
{
return pRect->xLeft == pRect->xRight || pRect->yTop == pRect->yBottom;
}
-DECLINLINE(bool) VBoxRectIsIntersect(const RTRECT * pRect1, const RTRECT * pRect2)
+DECLINLINE(bool) VBoxRectIsIntersect(PCRTRECT pRect1, PCRTRECT pRect2)
{
- return !((pRect1->xLeft < pRect2->xLeft && pRect1->xRight <= pRect2->xLeft)
- || (pRect2->xLeft < pRect1->xLeft && pRect2->xRight <= pRect1->xLeft)
- || (pRect1->yTop < pRect2->yTop && pRect1->yBottom <= pRect2->yTop)
- || (pRect2->yTop < pRect1->yTop && pRect2->yBottom <= pRect1->yTop));
+ return !( (pRect1->xLeft < pRect2->xLeft && pRect1->xRight <= pRect2->xLeft)
+ || (pRect2->xLeft < pRect1->xLeft && pRect2->xRight <= pRect1->xLeft)
+ || (pRect1->yTop < pRect2->yTop && pRect1->yBottom <= pRect2->yTop)
+ || (pRect2->yTop < pRect1->yTop && pRect2->yBottom <= pRect1->yTop) );
}
-DECLINLINE(uint32_t) VBoxVrListRectsCount(const VBOXVR_LIST *pList)
+DECLINLINE(uint32_t) VBoxVrListRectsCount(PCVBOXVR_LIST pList)
{
return pList->cEntries;
}
-DECLINLINE(bool) VBoxVrListIsEmpty(const VBOXVR_LIST *pList)
+DECLINLINE(bool) VBoxVrListIsEmpty(PCVBOXVR_LIST pList)
{
return !VBoxVrListRectsCount(pList);
}
@@ -193,19 +197,20 @@ VBOXVREGDECL(void) VBoxVrListMoveTo(PVBOXVR_LIST pList, PVBOXVR_LIST pDstList);
VBOXVREGDECL(void) VBoxVrListTranslate(PVBOXVR_LIST pList, int32_t x, int32_t y);
-VBOXVREGDECL(int) VBoxVrListCmp(const VBOXVR_LIST *pList1, const VBOXVR_LIST *pList2);
+VBOXVREGDECL(int) VBoxVrListCmp(PCVBOXVR_LIST pList1, PCVBOXVR_LIST pList2);
-VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrListRectsGet(PVBOXVR_LIST pList, uint32_t cRects, RTRECT * aRects);
+VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT paRects, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT paRects, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT paRects, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrListRectsGet(PVBOXVR_LIST pList, uint32_t cRects, PRTRECT paRects);
-VBOXVREGDECL(int) VBoxVrListClone(const VBOXVR_LIST *pList, VBOXVR_LIST *pDstList);
+VBOXVREGDECL(int) VBoxVrListClone(PCVBOXVR_LIST pList, VBOXVR_LIST *pDstList);
/* NOTE: with the current implementation the VBoxVrListIntersect is faster than VBoxVrListRectsIntersect,
- * i.e. VBoxVrListRectsIntersect is actually a convenience function that create a temporary list and calls VBoxVrListIntersect internally */
-VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged);
+ * i.e. VBoxVrListRectsIntersect is actually a convenience function that create a temporary list and calls
+ * VBoxVrListIntersect internally. */
+VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT paRects, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, PCVBOXVR_LIST pList2, bool *pfChanged);
VBOXVREGDECL(int) VBoxVrInit(void);
VBOXVREGDECL(void) VBoxVrTerm(void);
@@ -214,7 +219,9 @@ typedef struct VBOXVR_LIST_ITERATOR
{
PVBOXVR_LIST pList;
PRTLISTNODE pNextEntry;
-} VBOXVR_LIST_ITERATOR, *PVBOXVR_LIST_ITERATOR;
+} VBOXVR_LIST_ITERATOR;
+typedef VBOXVR_LIST_ITERATOR *PVBOXVR_LIST_ITERATOR;
+typedef VBOXVR_LIST_ITERATOR const *PCVBOXVR_LIST_ITERATOR;
DECLINLINE(void) VBoxVrListIterInit(PVBOXVR_LIST pList, PVBOXVR_LIST_ITERATOR pIter)
{
@@ -226,16 +233,18 @@ typedef struct VBOXVR_REG
{
RTLISTNODE ListEntry;
RTRECT Rect;
-} VBOXVR_REG, *PVBOXVR_REG;
+} VBOXVR_REG;
+typedef VBOXVR_REG *PVBOXVR_REG;
+typedef VBOXVR_REG const *PCVBOXVR_REG;
-#define PVBOXVR_REG_FROM_ENTRY(_pEntry) ((PVBOXVR_REG)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXVR_REG, ListEntry)))
+#define PVBOXVR_REG_FROM_ENTRY(_pEntry) RT_FROM_MEMBER(_pEntry, VBOXVR_REG, ListEntry)
DECLINLINE(PCRTRECT) VBoxVrListIterNext(PVBOXVR_LIST_ITERATOR pIter)
{
PRTLISTNODE pNextEntry = pIter->pNextEntry;
if (pNextEntry != &pIter->pList->ListHead)
{
- PCRTRECT pRect = &(PVBOXVR_REG_FROM_ENTRY(pNextEntry)->Rect);
+ PCRTRECT pRect = &PVBOXVR_REG_FROM_ENTRY(pNextEntry)->Rect;
pIter->pNextEntry = pNextEntry->pNext;
return pRect;
}
@@ -247,27 +256,35 @@ typedef struct VBOXVR_COMPOSITOR_ENTRY
RTLISTNODE Node;
VBOXVR_LIST Vr;
uint32_t cRefs;
-} VBOXVR_COMPOSITOR_ENTRY, *PVBOXVR_COMPOSITOR_ENTRY;
+} VBOXVR_COMPOSITOR_ENTRY;
+typedef VBOXVR_COMPOSITOR_ENTRY *PVBOXVR_COMPOSITOR_ENTRY;
+typedef VBOXVR_COMPOSITOR_ENTRY const *PCVBOXVR_COMPOSITOR_ENTRY;
struct VBOXVR_COMPOSITOR;
-typedef DECLCALLBACK(void) FNVBOXVRCOMPOSITOR_ENTRY_RELEASED(const struct VBOXVR_COMPOSITOR *pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry);
+typedef DECLCALLBACK(void) FNVBOXVRCOMPOSITOR_ENTRY_RELEASED(const struct VBOXVR_COMPOSITOR *pCompositor,
+ PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry);
typedef FNVBOXVRCOMPOSITOR_ENTRY_RELEASED *PFNVBOXVRCOMPOSITOR_ENTRY_RELEASED;
typedef struct VBOXVR_COMPOSITOR
{
- RTLISTNODE List;
+ RTLISTANCHOR List;
PFNVBOXVRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased;
-} VBOXVR_COMPOSITOR, *PVBOXVR_COMPOSITOR;
+} VBOXVR_COMPOSITOR;
+typedef VBOXVR_COMPOSITOR *PVBOXVR_COMPOSITOR;
+typedef VBOXVR_COMPOSITOR const *PCVBOXVR_COMPOSITOR;
-typedef DECLCALLBACK(bool) FNVBOXVRCOMPOSITOR_VISITOR(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor);
+typedef DECLCALLBACK(bool) FNVBOXVRCOMPOSITOR_VISITOR(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ void *pvVisitor);
typedef FNVBOXVRCOMPOSITOR_VISITOR *PFNVBOXVRCOMPOSITOR_VISITOR;
VBOXVREGDECL(void) VBoxVrCompositorInit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_ENTRY_RELEASED pfnEntryReleased);
VBOXVREGDECL(void) VBoxVrCompositorClear(PVBOXVR_COMPOSITOR pCompositor);
VBOXVREGDECL(void) VBoxVrCompositorRegionsClear(PVBOXVR_COMPOSITOR pCompositor, bool *pfChanged);
VBOXVREGDECL(void) VBoxVrCompositorEntryInit(PVBOXVR_COMPOSITOR_ENTRY pEntry);
-DECLINLINE(bool) VBoxVrCompositorEntryIsInList(const VBOXVR_COMPOSITOR_ENTRY *pEntry)
+
+DECLINLINE(bool) VBoxVrCompositorEntryIsInList(PCVBOXVR_COMPOSITOR_ENTRY pEntry)
{
return !VBoxVrListIsEmpty(&pEntry->Vr);
}
@@ -283,8 +300,8 @@ DECLINLINE(bool) VBoxVrCompositorEntryIsInList(const VBOXVR_COMPOSITOR_ENTRY *pE
#define CRBLT_FTYPE_OR (CRBLT_F_LINEAR | CRBLT_F_NOALPHA)
#define CRBLT_FOP_COMBINE(_f1, _f2) ((((_f1) ^ (_f2)) & CRBLT_FTYPE_XOR) | (((_f1) | (_f2)) & CRBLT_FTYPE_OR))
-#define CRBLT_FLAGS_FROM_FILTER(_f) ( ((_f) & GL_LINEAR) ? CRBLT_F_LINEAR : 0)
-#define CRBLT_FILTER_FROM_FLAGS(_f) (((_f) & CRBLT_F_LINEAR) ? GL_LINEAR : GL_NEAREST)
+#define CRBLT_FLAGS_FROM_FILTER(_f) ( ((_f) & GL_LINEAR) ? CRBLT_F_LINEAR : 0)
+#define CRBLT_FILTER_FROM_FLAGS(_f) (((_f) & CRBLT_F_LINEAR) ? GL_LINEAR : GL_NEAREST)
/* compositor regions changed */
#define VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED 0x00000001
@@ -300,18 +317,27 @@ DECLINLINE(bool) VBoxVrCompositorEntryIsInList(const VBOXVR_COMPOSITOR_ENTRY *pE
VBOXVREGDECL(bool) VBoxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry);
-VBOXVREGDECL(bool) VBoxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pNewEntry);
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, PVBOXVR_COMPOSITOR_ENTRY *ppReplacedEntry, uint32_t *pfChangeFlags);
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged);
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, int32_t x, int32_t y, bool *pfChanged);
+VBOXVREGDECL(bool) VBoxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pNewEntry);
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions,
+ PVBOXVR_COMPOSITOR_ENTRY *ppReplacedEntry, uint32_t *pfChangeFlags);
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PCVBOXVR_LIST pList2, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, PCRTRECT paRegions,
+ bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, PCVBOXVR_LIST pList2, bool *pfChanged);
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ int32_t x, int32_t y, bool *pfChanged);
VBOXVREGDECL(void) VBoxVrCompositorVisit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOXVRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor);
-DECLINLINE(bool) VBoxVrCompositorIsEmpty(const VBOXVR_COMPOSITOR *pCompositor)
+DECLINLINE(bool) VBoxVrCompositorIsEmpty(PCVBOXVR_COMPOSITOR pCompositor)
{
return RTListIsEmpty(&pCompositor->List);
}
@@ -320,13 +346,15 @@ typedef struct VBOXVR_COMPOSITOR_ITERATOR
{
PVBOXVR_COMPOSITOR pCompositor;
PRTLISTNODE pNextEntry;
-} VBOXVR_COMPOSITOR_ITERATOR ,*PVBOXVR_COMPOSITOR_ITERATOR;
+} VBOXVR_COMPOSITOR_ITERATOR;
+typedef VBOXVR_COMPOSITOR_ITERATOR *PVBOXVR_COMPOSITOR_ITERATOR;
typedef struct VBOXVR_COMPOSITOR_CONST_ITERATOR
{
- const VBOXVR_COMPOSITOR *pCompositor;
- const RTLISTNODE *pNextEntry;
-} VBOXVR_COMPOSITOR_CONST_ITERATOR ,*PVBOXVR_COMPOSITOR_CONST_ITERATOR;
+ PCVBOXVR_COMPOSITOR pCompositor;
+ PCRTLISTNODE pNextEntry;
+} VBOXVR_COMPOSITOR_CONST_ITERATOR;
+typedef VBOXVR_COMPOSITOR_CONST_ITERATOR *PVBOXVR_COMPOSITOR_CONST_ITERATOR;
DECLINLINE(void) VBoxVrCompositorIterInit(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ITERATOR pIter)
{
@@ -334,14 +362,14 @@ DECLINLINE(void) VBoxVrCompositorIterInit(PVBOXVR_COMPOSITOR pCompositor, PVBOXV
pIter->pNextEntry = pCompositor->List.pNext;
}
-DECLINLINE(void) VBoxVrCompositorConstIterInit(const VBOXVR_COMPOSITOR *pCompositor, PVBOXVR_COMPOSITOR_CONST_ITERATOR pIter)
+DECLINLINE(void) VBoxVrCompositorConstIterInit(PCVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_CONST_ITERATOR pIter)
{
pIter->pCompositor = pCompositor;
pIter->pNextEntry = pCompositor->List.pNext;
}
-#define VBOXVR_COMPOSITOR_ENTRY_FROM_NODE(_p) ((PVBOXVR_COMPOSITOR_ENTRY)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_COMPOSITOR_ENTRY, Node)))
-#define VBOXVR_COMPOSITOR_CONST_ENTRY_FROM_NODE(_p) ((const VBOXVR_COMPOSITOR_ENTRY*)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVR_COMPOSITOR_ENTRY, Node)))
+#define VBOXVR_COMPOSITOR_ENTRY_FROM_NODE(_p) RT_FROM_MEMBER(_p, VBOXVR_COMPOSITOR_ENTRY, Node)
+#define VBOXVR_COMPOSITOR_CONST_ENTRY_FROM_NODE(_p) RT_FROM_MEMBER(_p, const VBOXVR_COMPOSITOR_ENTRY, Node)
DECLINLINE(PVBOXVR_COMPOSITOR_ENTRY) VBoxVrCompositorIterNext(PVBOXVR_COMPOSITOR_ITERATOR pIter)
{
@@ -355,12 +383,12 @@ DECLINLINE(PVBOXVR_COMPOSITOR_ENTRY) VBoxVrCompositorIterNext(PVBOXVR_COMPOSITOR
return NULL;
}
-DECLINLINE(const VBOXVR_COMPOSITOR_ENTRY*) VBoxVrCompositorConstIterNext(PVBOXVR_COMPOSITOR_CONST_ITERATOR pIter)
+DECLINLINE(PCVBOXVR_COMPOSITOR_ENTRY) VBoxVrCompositorConstIterNext(PVBOXVR_COMPOSITOR_CONST_ITERATOR pIter)
{
- const RTLISTNODE *pNextEntry = pIter->pNextEntry;
+ PCRTLISTNODE pNextEntry = pIter->pNextEntry;
if (pNextEntry != &pIter->pCompositor->List)
{
- const VBOXVR_COMPOSITOR_ENTRY *pEntry = VBOXVR_COMPOSITOR_CONST_ENTRY_FROM_NODE(pNextEntry);
+ PCVBOXVR_COMPOSITOR_ENTRY pEntry = VBOXVR_COMPOSITOR_CONST_ENTRY_FROM_NODE(pNextEntry);
pIter->pNextEntry = pNextEntry->pNext;
return pEntry;
}
@@ -369,12 +397,15 @@ DECLINLINE(const VBOXVR_COMPOSITOR_ENTRY*) VBoxVrCompositorConstIterNext(PVBOXVR
typedef struct VBOXVR_TEXTURE
{
- int32_t width;
- int32_t height;
+ int32_t width;
+ int32_t height;
uint32_t target;
uint32_t hwid;
-} VBOXVR_TEXTURE, *PVBOXVR_TEXTURE;
+} VBOXVR_TEXTURE;
+typedef VBOXVR_TEXTURE *PVBOXVR_TEXTURE;
+typedef VBOXVR_TEXTURE const *PCVBOXVR_TEXTURE;
RT_C_DECLS_END
-#endif /* #ifndef ___cr_vreg_h_ */
+#endif
+
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_current.py b/src/VBox/GuestHost/OpenGL/packer/pack_current.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_currentheader.py b/src/VBox/GuestHost/OpenGL/packer/pack_currentheader.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/pack_header.py b/src/VBox/GuestHost/OpenGL/packer/pack_header.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/packer.py b/src/VBox/GuestHost/OpenGL/packer/packer.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/packer/packer_bbox.py b/src/VBox/GuestHost/OpenGL/packer/packer_bbox.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/dispatch.py b/src/VBox/GuestHost/OpenGL/spu_loader/dispatch.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/dispatchheader.py b/src/VBox/GuestHost/OpenGL/spu_loader/dispatchheader.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py b/src/VBox/GuestHost/OpenGL/spu_loader/glloader.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py b/src/VBox/GuestHost/OpenGL/spu_loader/spuchange.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/spucopy.py b/src/VBox/GuestHost/OpenGL/spu_loader/spucopy.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/convert.py b/src/VBox/GuestHost/OpenGL/state_tracker/convert.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/dump_gen.py b/src/VBox/GuestHost/OpenGL/state_tracker/dump_gen.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_current.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_current.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_defs.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_defs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_funcs.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_funcs.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_get.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_get.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_isenabled.py b/src/VBox/GuestHost/OpenGL/state_tracker/state_isenabled.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/util/VBoxOGLcrutil.rc b/src/VBox/GuestHost/OpenGL/util/VBoxOGLcrutil.rc
new file mode 100644
index 0000000..f475a29
--- /dev/null
+++ b/src/VBox/GuestHost/OpenGL/util/VBoxOGLcrutil.rc
@@ -0,0 +1,81 @@
+/* $Id: VBoxOGLcrutil.rc $ */
+/** @file
+ * VBoxOGLcrutil - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+#ifdef IN_GUEST
+ #define DESCRIPTION_STR "VirtualBox crOpenGL ICD\0"
+ #ifdef VBOX_WDDM_WOW64
+ #define FILENAME_STR "VBoxOGLcrutil-x86"
+ #else
+ #define FILENAME_STR "VBoxOGLcrutil.dll"
+ #endif
+ #define PRODUCT_STR VBOX_PRODUCT " Guest Additions\0"
+#else
+ #define DESCRIPTION_STR "VirtualBox crOpenGL ICD\0"
+ #define FILENAME_STR "VBoxOGLcrhostutil"
+ #define PRODUCT_STR VBOX_PRODUCT "\0"
+#endif
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", DESCRIPTION_STR
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", FILENAME_STR "\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", FILENAME_STR ".dll\0"
+ VALUE "ProductName", PRODUCT_STR
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+// XXX is this really required?
+#if defined(VBOX_WDDM_WOW64) && defined(IN_GUEST)
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
+#endif
diff --git a/src/VBox/GuestHost/OpenGL/util/blitter.cpp b/src/VBox/GuestHost/OpenGL/util/blitter.cpp
index cc41168..52a0cff 100644
--- a/src/VBox/GuestHost/OpenGL/util/blitter.cpp
+++ b/src/VBox/GuestHost/OpenGL/util/blitter.cpp
@@ -1,10 +1,10 @@
-/* $Id$ */
-
+/* $Id: blitter.cpp $ */
/** @file
* Blitter API implementation
*/
+
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -14,20 +14,37 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include "cr_blitter.h"
-#include "cr_spu.h"
-#include "chromium.h"
-#include "cr_error.h"
-#include "cr_net.h"
-#include "cr_rand.h"
-#include "cr_mem.h"
-#include "cr_string.h"
-#include "cr_bmpscale.h"
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#ifdef IN_VMSVGA3D
+# include <OpenGL/OpenGL.h>
+# include <OpenGL/gl3.h>
+# include "../include/cr_blitter.h"
+# include <iprt/assert.h>
+# define WARN AssertMsgFailed
+# define CRASSERT Assert
+DECLINLINE(void) crWarning(const char *format, ... ) {}
+#else
+# include "cr_blitter.h"
+# include "cr_spu.h"
+# include "chromium.h"
+# include "cr_error.h"
+# include "cr_net.h"
+# include "cr_rand.h"
+# include "cr_mem.h"
+# include "cr_string.h"
+# include "cr_bmpscale.h"
+#endif
#include <iprt/cdefs.h>
#include <iprt/types.h>
#include <iprt/mem.h>
+
+
static void crMClrFillMem(uint32_t *pu32Dst, int32_t cbDstPitch, uint32_t width, uint32_t height, uint32_t u32Color)
{
for (uint32_t i = 0; i < height; ++i)
@@ -144,6 +161,8 @@ void CrMBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pPos, uint32_t cRects,
}
}
+#ifndef IN_VMSVGA3D
+
void CrMBltImgRectScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pPos, bool fSrcInvert, const RTRECT *pCopyRect, float strX, float strY, CR_BLITTER_IMG *pDst)
{
RTPOINT UnscaledPos;
@@ -258,25 +277,51 @@ void CrMBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTRECTSIZE *pSrcRectSize,
}
}
-/* @param pCtxBase - contains the blitter context info. Its value is treated differently depending on the fCreateNewCtx value
- * @param fCreateNewCtx - if true - the pCtxBase must NOT be NULL. its visualBits is used as a visual bits info for the new context,
- * its id field is used to specified the shared context id to be used for blitter context.
- * The id can be null to specify no shared context is needed
- * if false - if pCtxBase is NOT null AND its id field is NOT null -
- * specified the blitter context to be used
- * blitter treats it as if it has default ogl state.
- * otherwise -
- * the blitter works in a "no-context" mode, i.e. a caller is responsible
- * to making a proper context current before calling the blitter.
- * Note that BltEnter/Leave MUST still be called, but the proper context
- * must be set before doing BltEnter, and ResoreContext info is ignored in that case.
- * Also note that blitter caches the current window info, and assumes the current context's values are preserved
- * wrt that window before the calls, so if one uses different contexts for one blitter,
- * the blitter current window values must be explicitly reset by doing CrBltMuralSetCurrentInfo(pBlitter, NULL)
- * @param fForceDrawBlt - if true - forces the blitter to always use glDrawXxx-based blits even if GL_EXT_framebuffer_blit.
- * This is needed because BlitFramebufferEXT is known to be often buggy, and glDrawXxx-based blits appear to be more reliable
+#endif /* !IN_VMSVGA3D */
+
+
+/**
+ *
+ * @param pBlitter The blitter to initialize.
+ * @param pCtxBase Contains the blitter context info. Its value is
+ * treated differently depending on the fCreateNewCtx
+ * value.
+ * @param fCreateNewCtx If true, then @a pCtxBase must NOT be NULL. Its
+ * visualBits is used as a visual bits info for the new
+ * context, its id field is used to specified the
+ * shared context id to be used for blitter context.
+ * The id can be null to specify no shared context is
+ * needed
+ *
+ * If false and @a pCtxBase is NOT null AND its id
+ * field is NOT null, then specified the blitter
+ * context to be used blitter treats it as if it has
+ * default ogl state.
+ *
+ * Otherwise, the blitter works in a "no-context" mode,
+ * i.e. the� caller is responsible for making a proper
+ * context current before calling the blitter. Note
+ * that BltEnter/Leave MUST still be called, but the
+ * proper context must be set before doing BltEnter,
+ * and ResoreContext info is ignored in that case. Also
+ * note that the blitter caches the current window
+ * info, and assumes the current context's values are
+ * preserved wrt that window before the calls, so if
+ * one uses different contexts for one blitter, the
+ * blitter current window values must be explicitly
+ * reset by doing CrBltMuralSetCurrentInfo(pBlitter,
+ * NULL).
+ * @param fForceDrawBlt If true this forces the blitter to always use
+ * glDrawXxx-based blits even if
+ * GL_EXT_framebuffer_blit. This is needed because
+ * BlitFramebufferEXT is often known to be buggy, and
+ * glDrawXxx-based blits appear to be more reliable.
+ * @param pShaders
+ * @param pDispatch
*/
-VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, const CR_GLSL_CACHE *pShaders, SPUDispatchTable *pDispatch)
+VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase,
+ bool fCreateNewCtx, bool fForceDrawBlt, const CR_GLSL_CACHE *pShaders,
+ SPUDispatchTable *pDispatch)
{
if (pCtxBase && pCtxBase->Base.id < 0)
{
@@ -290,7 +335,7 @@ VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *p
return VERR_INVALID_PARAMETER;
}
- memset(pBlitter, 0, sizeof (*pBlitter));
+ RT_ZERO(*pBlitter);
pBlitter->pDispatch = pDispatch;
if (pCtxBase)
@@ -300,10 +345,15 @@ VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *p
if (fCreateNewCtx)
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+ pBlitter->CtxInfo.Base.id = 0;
+#else
pBlitter->CtxInfo.Base.id = pDispatch->CreateContext("", pCtxBase->Base.visualBits, pCtxBase->Base.id);
+#endif
if (!pBlitter->CtxInfo.Base.id)
{
- memset(pBlitter, 0, sizeof (*pBlitter));
+ RT_ZERO(*pBlitter);
crWarning("CreateContext failed!");
return VERR_GENERAL_FAILURE;
}
@@ -351,8 +401,12 @@ VBOXBLITTERDECL(int) CrBltCleanup(PCR_BLITTER pBlitter)
void CrBltTerm(PCR_BLITTER pBlitter)
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
if (pBlitter->Flags.CtxCreated)
pBlitter->pDispatch->DestroyContext(pBlitter->CtxInfo.Base.id);
+#endif
memset(pBlitter, 0, sizeof (*pBlitter));
}
@@ -380,7 +434,8 @@ int CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMur
if (!CrBltIsEntered(pBlitter))
return VINF_SUCCESS;
- else if (!pBlitter->CtxInfo.Base.id)
+
+ if (!pBlitter->CtxInfo.Base.id)
{
WARN(("setting current mural for entered no-context blitter"));
return VERR_INVALID_STATE;
@@ -388,13 +443,20 @@ int CrBltMuralSetCurrentInfo(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMur
WARN(("changing mural for entered blitter, is is somewhat expected?"));
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->Flush();
pBlitter->pDispatch->MakeCurrent(pMural->Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
+#endif
return VINF_SUCCESS;
}
+
+#ifndef IN_VMSVGA3D
+
static DECLCALLBACK(int) crBltBlitTexBufImplFbo(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
{
GLenum filter = CRBLT_FILTER_FROM_FLAGS(fFlags);
@@ -597,7 +659,7 @@ static GLfloat* crBltVtRectsITNormalized(const RTRECT *paRects, uint32_t cRects,
return pBuff;
}
-static void* crBltBufGet(PCR_BLITTER_BUFFER pBuffer, GLuint cbBuffer)
+static void *crBltBufGet(PCR_BLITTER_BUFFER pBuffer, GLuint cbBuffer)
{
if (pBuffer->cbBuffer < cbBuffer)
{
@@ -623,28 +685,42 @@ static void* crBltBufGet(PCR_BLITTER_BUFFER pBuffer, GLuint cbBuffer)
return pBuffer->pvBuffer;
}
+#endif /* !IN_VMSVGA3D */
+
+
static void crBltCheckSetupViewport(PCR_BLITTER pBlitter, const RTRECTSIZE *pDstSize, bool fFBODraw)
{
bool fUpdateViewport = pBlitter->Flags.CurrentMuralChanged;
- if (pBlitter->CurrentSetSize.cx != pDstSize->cx
- || pBlitter->CurrentSetSize.cy != pDstSize->cy)
+ if ( pBlitter->CurrentSetSize.cx != pDstSize->cx
+ || pBlitter->CurrentSetSize.cy != pDstSize->cy)
{
pBlitter->CurrentSetSize = *pDstSize;
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->MatrixMode(GL_PROJECTION);
pBlitter->pDispatch->LoadIdentity();
pBlitter->pDispatch->Ortho(0, pDstSize->cx, 0, pDstSize->cy, -1, 1);
+#endif
fUpdateViewport = true;
}
if (fUpdateViewport)
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->Viewport(0, 0, pBlitter->CurrentSetSize.cx, pBlitter->CurrentSetSize.cy);
+#endif
pBlitter->Flags.CurrentMuralChanged = 0;
}
pBlitter->Flags.LastWasFBODraw = fFBODraw;
}
+
+#ifndef IN_VMSVGA3D
+
static DECLCALLBACK(int) crBltBlitTexBufImplDraw2D(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRect, const RTRECTSIZE *pDstSize, const RTRECT *paDstRect, uint32_t cRects, uint32_t fFlags)
{
GLuint normalX, normalY;
@@ -776,6 +852,9 @@ static int crBltInitOnMakeCurent(PCR_BLITTER pBlitter)
return VINF_SUCCESS;
}
+#endif /* !IN_VMSVGA3D */
+
+
void CrBltLeave(PCR_BLITTER pBlitter)
{
if (!pBlitter->cEnters)
@@ -787,6 +866,9 @@ void CrBltLeave(PCR_BLITTER pBlitter)
if (--pBlitter->cEnters)
return;
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
if (pBlitter->Flags.SupportsFBO)
{
pBlitter->pDispatch->BindFramebufferEXT(GL_FRAMEBUFFER, 0);
@@ -798,6 +880,7 @@ void CrBltLeave(PCR_BLITTER pBlitter)
if (pBlitter->CtxInfo.Base.id)
pBlitter->pDispatch->MakeCurrent(0, 0, 0);
+#endif
}
int CrBltEnter(PCR_BLITTER pBlitter)
@@ -813,13 +896,22 @@ int CrBltEnter(PCR_BLITTER pBlitter)
if (pBlitter->CurrentMural.Base.id) /* <- pBlitter->CurrentMural.Base.id can be null if the blitter is in a "no-context" mode (see comments to BltInit for detail)*/
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
+#endif
}
if (pBlitter->Flags.Initialized)
return VINF_SUCCESS;
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+ int rc = VINF_SUCCESS;
+#else
int rc = crBltInitOnMakeCurent(pBlitter);
+#endif
if (RT_SUCCESS(rc))
{
pBlitter->Flags.Initialized = 1;
@@ -831,8 +923,12 @@ int CrBltEnter(PCR_BLITTER pBlitter)
return rc;
}
+
static void crBltBlitTexBuf(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *paSrcRects, GLenum enmDstBuff, const RTRECTSIZE *pDstSize, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags)
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->DrawBuffer(enmDstBuff);
crBltCheckSetupViewport(pBlitter, pDstSize, enmDstBuff == GL_DRAW_FRAMEBUFFER);
@@ -841,10 +937,9 @@ static void crBltBlitTexBuf(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, co
pBlitter->pfnBlt(pBlitter, pSrc, paSrcRects, pDstSize, paDstRects, cRects, fFlags);
else
{
- int rc = pBlitter->Flags.ShadersGloal ?
- CrGlslProgUseNoAlpha(pBlitter->pGlslCache, pSrc->target)
- :
- CrGlslProgUseGenNoAlpha(&pBlitter->LocalGlslCache, pSrc->target);
+ int rc = pBlitter->Flags.ShadersGloal
+ ? CrGlslProgUseNoAlpha(pBlitter->pGlslCache, pSrc->target)
+ : CrGlslProgUseGenNoAlpha(&pBlitter->LocalGlslCache, pSrc->target);
if (!RT_SUCCESS(rc))
{
@@ -861,6 +956,7 @@ static void crBltBlitTexBuf(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, co
CrGlslProgClear(pBlitter->pGlslCache);
}
+#endif
}
void CrBltCheckUpdateViewport(PCR_BLITTER pBlitter)
@@ -879,11 +975,18 @@ void CrBltBlitTexMural(PCR_BLITTER pBlitter, bool fBb, const VBOXVR_TEXTURE *pSr
RTRECTSIZE DstSize = {pBlitter->CurrentMural.width, pBlitter->CurrentMural.height};
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+#endif
crBltBlitTexBuf(pBlitter, pSrc, paSrcRects, fBb ? GL_BACK : GL_FRONT, &DstSize, paDstRects, cRects, fFlags);
}
+
+#ifndef IN_VMSVGA3D
+
void CrBltBlitTexTex(PCR_BLITTER pBlitter, const VBOXVR_TEXTURE *pSrc, const RTRECT *pSrcRect, const VBOXVR_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags)
{
if (!CrBltIsEntered(pBlitter))
@@ -1321,6 +1424,8 @@ VBOXBLITTERDECL(int) CrGlslProgUseGenNoAlpha(CR_GLSL_CACHE *pCache, GLenum enmTe
return VINF_SUCCESS;
}
+#endif /* !IN_VMSVGA3D */
+
VBOXBLITTERDECL(bool) CrGlslNeedsCleanup(const CR_GLSL_CACHE *pCache)
{
return pCache->uNoAlpha2DProg || pCache->uNoAlpha2DRectProg;
@@ -1330,13 +1435,21 @@ VBOXBLITTERDECL(void) CrGlslCleanup(CR_GLSL_CACHE *pCache)
{
if (pCache->uNoAlpha2DProg)
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pCache->pDispatch->DeleteProgram(pCache->uNoAlpha2DProg);
+#endif
pCache->uNoAlpha2DProg = 0;
}
if (pCache->uNoAlpha2DRectProg)
{
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pCache->pDispatch->DeleteProgram(pCache->uNoAlpha2DRectProg);
+#endif
pCache->uNoAlpha2DRectProg = 0;
}
}
@@ -1351,6 +1464,7 @@ VBOXBLITTERDECL(void) CrGlslTerm(CR_GLSL_CACHE *pCache)
memset(pCache, 0, sizeof (*pCache));
}
+#ifndef IN_VMSVGA3D
/*TdBlt*/
static void crTdBltCheckPBO(PCR_TEXDATA pTex)
@@ -1417,6 +1531,9 @@ int crTdBltCheckInvertTex(PCR_TEXDATA pTex)
return VINF_SUCCESS;
}
+#endif /* !IN_VMSVGA3D */
+
+
void crTdBltImgRelease(PCR_TEXDATA pTex)
{
pTex->Flags.DataValid = 0;
@@ -1440,9 +1557,13 @@ void crTdBltImgFree(PCR_TEXDATA pTex)
PCR_BLITTER pBlitter = pTex->pBlitter;
Assert(CrBltIsEntered(pBlitter));
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pTex->idPBO);
pBlitter->pDispatch->UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
pBlitter->pDispatch->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
+#endif
}
else
{
@@ -1453,6 +1574,9 @@ void crTdBltImgFree(PCR_TEXDATA pTex)
pTex->Img.pvData = NULL;
}
+
+#ifndef IN_VMSVGA3D
+
int crTdBltImgAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted)
{
void *pvData = pTex->Img.pvData;
@@ -1520,6 +1644,9 @@ int crTdBltImgAcquire(PCR_TEXDATA pTex, GLenum enmFormat, bool fInverted)
return VINF_SUCCESS;
}
+#endif /* !IN_VMSVGA3D */
+
+
/* release the texture data, the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataInvalidateNe or CrTdBltDataCleanup */
VBOXBLITTERDECL(int) CrTdBltDataRelease(PCR_TEXDATA pTex)
{
@@ -1619,14 +1746,22 @@ static void crTdBltDataCleanup(PCR_TEXDATA pTex)
if (pTex->idPBO)
{
Assert(CrBltIsEntered(pBlitter));
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->DeleteBuffersARB(1, &pTex->idPBO);
+#endif
pTex->idPBO = 0;
}
if (pTex->idInvertTex)
{
Assert(CrBltIsEntered(pBlitter));
+#ifdef IN_VMSVGA3D
+ /** @todo IN_VMSVGA3D */
+#else
pBlitter->pDispatch->DeleteTextures(1, &pTex->idInvertTex);
+#endif
pTex->idInvertTex = 0;
}
@@ -1670,6 +1805,9 @@ VBOXBLITTERDECL(int) CrTdBltDataCleanupNe(PCR_TEXDATA pTex)
return VINF_SUCCESS;
}
+
+#ifndef IN_VMSVGA3D
+
/* acquire the texture data, returns the cached data in case it is cached.
* the data remains cached in the CR_TEXDATA object until it is discarded with CrTdBltDataFree or CrTdBltDataCleanup.
* */
@@ -1980,3 +2118,6 @@ VBOXBLITTERDECL(void) CrTdBltScaleCacheMoveTo(PCR_TEXDATA pTex, PCR_TEXDATA pDst
pDstTex->pScaledCache = pTex->pScaledCache;
pTex->pScaledCache = NULL;
}
+
+#endif /* !IN_VMSVGA3D */
+
diff --git a/src/VBox/GuestHost/OpenGL/util/compositor.cpp b/src/VBox/GuestHost/OpenGL/util/compositor.cpp
index f7c50bc..84e2f9a 100644
--- a/src/VBox/GuestHost/OpenGL/util/compositor.cpp
+++ b/src/VBox/GuestHost/OpenGL/util/compositor.cpp
@@ -1,11 +1,10 @@
/* $Id: compositor.cpp $ */
-
/** @file
- * Compositor impl
+ * Compositor implementation.
*/
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -15,9 +14,21 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <cr_compositor.h>
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include "../include/cr_compositor.h"
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
#define VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED UINT32_MAX
+#ifdef IN_VMSVGA3D
+# define WARN AssertMsgFailed
+#endif
+
static int crVrScrCompositorRectsAssignBuffer(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRects)
@@ -49,13 +60,13 @@ static int crVrScrCompositorRectsAssignBuffer(PVBOXVR_SCR_COMPOSITOR pCompositor
Assert(!pCompositor->paDstUnstretchedRects);
}
- pCompositor->paSrcRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paSrcRects) * cRects);
+ pCompositor->paSrcRects = (PRTRECT)RTMemAlloc(sizeof(*pCompositor->paSrcRects) * cRects);
if (pCompositor->paSrcRects)
{
- pCompositor->paDstRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstRects) * cRects);
+ pCompositor->paDstRects = (PRTRECT)RTMemAlloc(sizeof(*pCompositor->paDstRects) * cRects);
if (pCompositor->paDstRects)
{
- pCompositor->paDstUnstretchedRects = (PRTRECT)RTMemAlloc(sizeof (*pCompositor->paDstUnstretchedRects) * cRects);
+ pCompositor->paDstUnstretchedRects = (PRTRECT)RTMemAlloc(sizeof(*pCompositor->paDstUnstretchedRects) * cRects);
if (pCompositor->paDstUnstretchedRects)
{
pCompositor->cRects = cRects;
@@ -89,7 +100,8 @@ static void crVrScrCompositorRectsInvalidate(PVBOXVR_SCR_COMPOSITOR pCompositor)
pCompositor->cRects = VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED;
}
-static DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, void *pvVisitor)
+static DECLCALLBACK(bool) crVrScrCompositorRectsCounterCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ void *pvVisitor)
{
uint32_t* pCounter = (uint32_t*)pvVisitor;
Assert(VBoxVrListRectsCount(&pEntry->Vr));
@@ -105,7 +117,8 @@ typedef struct VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER
uint32_t cRects;
} VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER, *PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER;
-static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
+static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry,
+ void *pvVisitor)
{
PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER pData = (PVBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER)pvVisitor;
PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
@@ -121,7 +134,7 @@ static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pC
if (!pEntry->Rect.xLeft && !pEntry->Rect.yTop)
{
- memcpy(pEntry->paSrcRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paSrcRects));
+ memcpy(pEntry->paSrcRects, pEntry->paDstUnstretchedRects, cRects * sizeof(*pEntry->paSrcRects));
}
else
{
@@ -154,7 +167,7 @@ static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pC
else
#endif
{
- memcpy(pEntry->paDstRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paDstUnstretchedRects));
+ memcpy(pEntry->paDstRects, pEntry->paDstUnstretchedRects, cRects * sizeof(*pEntry->paDstUnstretchedRects));
}
#if 0//ndef IN_RING0
@@ -200,9 +213,9 @@ static DECLCALLBACK(bool) crVrScrCompositorRectsAssignerCb(PVBOXVR_COMPOSITOR pC
return true;
}
-static int crVrScrCompositorRectsCheckInit(const VBOXVR_SCR_COMPOSITOR *pcCompositor)
+static int crVrScrCompositorRectsCheckInit(PCVBOXVR_SCR_COMPOSITOR pcCompositor)
{
- VBOXVR_SCR_COMPOSITOR *pCompositor = const_cast<VBOXVR_SCR_COMPOSITOR*>(pcCompositor);
+ PVBOXVR_SCR_COMPOSITOR pCompositor = const_cast<PVBOXVR_SCR_COMPOSITOR>(pcCompositor);
if (pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED)
return VINF_SUCCESS;
@@ -217,7 +230,7 @@ static int crVrScrCompositorRectsCheckInit(const VBOXVR_SCR_COMPOSITOR *pcCompos
}
int rc = crVrScrCompositorRectsAssignBuffer(pCompositor, cRects);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
return rc;
VBOXVR_SCR_COMPOSITOR_RECTS_ASSIGNER AssignerData;
@@ -231,12 +244,15 @@ static int crVrScrCompositorRectsCheckInit(const VBOXVR_SCR_COMPOSITOR *pcCompos
}
-static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangedFlags)
+static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions,
+ VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangedFlags)
{
uint32_t fChangedFlags = 0;
PVBOXVR_COMPOSITOR_ENTRY pReplacedEntry;
- int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, pEntry ? &pEntry->Ce : NULL, cRegions, paRegions, &pReplacedEntry, &fChangedFlags);
- if (!RT_SUCCESS(rc))
+ int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, pEntry ? &pEntry->Ce : NULL, cRegions,
+ paRegions, &pReplacedEntry, &fChangedFlags);
+ if (RT_FAILURE(rc))
{
WARN(("VBoxVrCompositorEntryRegionsAdd failed, rc %d", rc));
return rc;
@@ -245,22 +261,14 @@ static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor,
VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacedScrEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacedEntry);
if (fChangedFlags & VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED)
- {
crVrScrCompositorRectsInvalidate(pCompositor);
- }
else if (fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REPLACED)
- {
Assert(pReplacedScrEntry);
- }
if (fChangedFlags & VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED)
- {
CrVrScrCompositorEntrySetAllChanged(pCompositor, true);
- }
else if ((fChangedFlags & VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED) && pEntry)
- {
CrVrScrCompositorEntrySetChanged(pEntry, true);
- }
if (pfChangedFlags)
*pfChangedFlags = fChangedFlags;
@@ -271,11 +279,12 @@ static int crVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor,
return VINF_SUCCESS;
}
-static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
+static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions, bool *pfChanged)
{
bool fChanged;
int rc = VBoxVrCompositorEntryRegionsSet(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("VBoxVrCompositorEntryRegionsSet failed, rc %d", rc));
return rc;
@@ -300,7 +309,8 @@ static int crVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor,
return VINF_SUCCESS;
}
-static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, bool *pfChanged)
+static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos, bool *pfChanged)
{
if (pfChanged)
*pfChanged = false;
@@ -308,8 +318,9 @@ static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor,
{
if (VBoxVrCompositorEntryIsInList(&pEntry->Ce))
{
- int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Rect.xLeft, pPos->y - pEntry->Rect.yTop, pfChanged);
- if (!RT_SUCCESS(rc))
+ int rc = VBoxVrCompositorEntryRegionsTranslate(&pCompositor->Compositor, &pEntry->Ce, pPos->x - pEntry->Rect.xLeft,
+ pPos->y - pEntry->Rect.yTop, pfChanged);
+ if (RT_FAILURE(rc))
{
WARN(("VBoxVrCompositorEntryRegionsTranslate failed rc %d", rc));
return rc;
@@ -327,7 +338,8 @@ static int crVrScrCompositorEntryPositionSet(PVBOXVR_SCR_COMPOSITOR pCompositor,
return VINF_SUCCESS;
}
-static int crVrScrCompositorEntryEnsureRegionsBounds(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, bool *pfChanged)
+static int crVrScrCompositorEntryEnsureRegionsBounds(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ bool *pfChanged)
{
RTRECT Rect;
Rect.xLeft = RT_MAX(pCompositor->Rect.xLeft, pEntry->Rect.xLeft);
@@ -340,7 +352,7 @@ static int crVrScrCompositorEntryEnsureRegionsBounds(PVBOXVR_SCR_COMPOSITOR pCom
*pfChanged = false;
int rc = CrVrScrCompositorEntryRegionsIntersect(pCompositor, pEntry, 1, &Rect, &fChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
WARN(("CrVrScrCompositorEntryRegionsIntersect failed, rc %d", rc));
if (pfChanged)
@@ -348,7 +360,10 @@ static int crVrScrCompositorEntryEnsureRegionsBounds(PVBOXVR_SCR_COMPOSITOR pCom
return rc;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry, uint32_t *pfChangeFlags)
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos, uint32_t cRegions, PCRTRECT paRegions,
+ bool fPosRelated, VBOXVR_SCR_COMPOSITOR_ENTRY **ppReplacedScrEntry,
+ uint32_t *pfChangeFlags)
{
int rc;
uint32_t fChangeFlags = 0;
@@ -357,7 +372,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompo
if (pPos)
{
rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, &fPosChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsAdd: crVrScrCompositorEntryPositionSet failed rc %d", rc));
return rc;
@@ -374,13 +389,13 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompo
if (cRegions && (pEntry->Rect.xLeft || pEntry->Rect.yTop))
{
- paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof (RTRECT) * cRegions);
+ paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof(RTRECT) * cRegions);
if (!paTranslatedRects)
{
WARN(("RTMemAlloc failed"));
return VERR_NO_MEMORY;
}
- memcpy (paTranslatedRects, paRegions, sizeof (RTRECT) * cRegions);
+ memcpy (paTranslatedRects, paRegions, sizeof(RTRECT) * cRegions);
for (uint32_t i = 0; i < cRegions; ++i)
{
VBoxRectTranslate(&paTranslatedRects[i], pEntry->Rect.xLeft, pEntry->Rect.yTop);
@@ -390,7 +405,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompo
}
rc = crVrScrCompositorEntryRegionsAdd(pCompositor, pEntry, cRegions, paRegions, ppReplacedScrEntry, &fChangeFlags);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryRegionsAdd failed, rc %d", rc));
goto done;
@@ -400,7 +415,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompo
{
bool fAdjusted = false;
rc = crVrScrCompositorEntryEnsureRegionsBounds(pCompositor, pEntry, &fAdjusted);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryEnsureRegionsBounds failed, rc %d", rc));
goto done;
@@ -430,7 +445,8 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsAdd(PVBOXVR_SCR_COMPOSITOR pCompo
if (fPosChanged)
{
/* means entry was in list and was moved, so regions changed */
- *pfChangeFlags = VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
+ *pfChangeFlags = VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED
+ | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
}
else
*pfChangeFlags = fChangeFlags;
@@ -444,16 +460,17 @@ done:
return rc;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTRECT *pRect)
+VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTRECT pRect)
{
- if (!memcmp(&pEntry->Rect, pRect, sizeof (*pRect)))
+ if (!memcmp(&pEntry->Rect, pRect, sizeof(*pRect)))
{
return VINF_SUCCESS;
}
RTPOINT Point = {pRect->xLeft, pRect->yTop};
bool fChanged = false;
int rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, &Point, &fChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryPositionSet failed %d", rc));
return rc;
@@ -465,7 +482,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pComposit
return VINF_SUCCESS;
rc = crVrScrCompositorEntryEnsureRegionsBounds(pCompositor, pEntry, NULL);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryEnsureRegionsBounds failed, rc %d", rc));
return rc;
@@ -474,7 +491,8 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRectSet(PVBOXVR_SCR_COMPOSITOR pComposit
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, CR_TEXDATA *pTex)
+VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ CR_TEXDATA *pTex)
{
if (pEntry->pTex == pTex)
return VINF_SUCCESS;
@@ -487,14 +505,16 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryTexAssign(PVBOXVR_SCR_COMPOSITOR pCompos
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, bool fPosRelated, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos, uint32_t cRegions, PCRTRECT paRegions,
+ bool fPosRelated, bool *pfChanged)
{
/* @todo: the fChanged sate calculation is really rough now, this is enough for now though */
bool fChanged = false, fPosChanged = false;
bool fWasInList = CrVrScrCompositorEntryIsInList(pEntry);
RTRECT *paTranslatedRects = NULL;
int rc = CrVrScrCompositorEntryRemove(pCompositor, pEntry);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsSet: CrVrScrCompositorEntryRemove failed rc %d", rc));
return rc;
@@ -503,7 +523,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompo
if (pPos)
{
rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, &fPosChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc));
return rc;
@@ -520,13 +540,13 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompo
if (cRegions && (pEntry->Rect.xLeft || pEntry->Rect.yTop))
{
- paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof (RTRECT) * cRegions);
+ paTranslatedRects = (RTRECT*)RTMemAlloc(sizeof(RTRECT) * cRegions);
if (!paTranslatedRects)
{
WARN(("RTMemAlloc failed"));
return VERR_NO_MEMORY;
}
- memcpy (paTranslatedRects, paRegions, sizeof (RTRECT) * cRegions);
+ memcpy (paTranslatedRects, paRegions, sizeof(RTRECT) * cRegions);
for (uint32_t i = 0; i < cRegions; ++i)
{
VBoxRectTranslate(&paTranslatedRects[i], pEntry->Rect.xLeft, pEntry->Rect.yTop);
@@ -536,7 +556,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompo
}
rc = crVrScrCompositorEntryRegionsSet(pCompositor, pEntry, cRegions, paRegions, &fChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryRegionsSet failed, rc %d", rc));
return rc;
@@ -545,7 +565,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompo
if (fChanged && CrVrScrCompositorEntryIsUsed(pEntry))
{
rc = crVrScrCompositorEntryEnsureRegionsBounds(pCompositor, pEntry, NULL);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryEnsureRegionsBounds failed, rc %d", rc));
return rc;
@@ -558,11 +578,12 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsSet(PVBOXVR_SCR_COMPOSITOR pCompo
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCVBOXVR_LIST pList2, bool *pfChanged)
{
bool fChanged = false;
int rc = VBoxVrCompositorEntryListIntersect(&pCompositor->Compositor, &pEntry->Ce, pList2, &fChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsIntersect: VBoxVrCompositorEntryRegionsIntersect failed rc %d", rc));
return rc;
@@ -580,11 +601,12 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersect(PVBOXVR_SCR_COMPOSITOR pCo
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRegions, PCRTRECT paRegions, bool *pfChanged)
{
bool fChanged = false;
int rc = VBoxVrCompositorEntryRegionsIntersect(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsIntersect: VBoxVrCompositorEntryRegionsIntersect failed rc %d", rc));
return rc;
@@ -599,7 +621,7 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersect(PVBOXVR_SCR_COMPOSITOR
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, PCVBOXVR_LIST pList2, bool *pfChanged)
{
VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
CrVrScrCompositorIterInit(pCompositor, &Iter);
@@ -628,7 +650,8 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryListIntersectAll(PVBOXVR_SCR_COMPOSITOR
return rc;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t cRegions,
+ PCRTRECT paRegions, bool *pfChanged)
{
VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
CrVrScrCompositorIterInit(pCompositor, &Iter);
@@ -657,17 +680,18 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsIntersectAll(PVBOXVR_SCR_COMPOSIT
return rc;
}
-VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, const RTPOINT *pPos)
+VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PCRTPOINT pPos)
{
int rc = crVrScrCompositorEntryPositionSet(pCompositor, pEntry, pPos, NULL);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsSet: crVrScrCompositorEntryPositionSet failed rc %d", rc));
return rc;
}
rc = crVrScrCompositorEntryEnsureRegionsBounds(pCompositor, pEntry, NULL);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("RegionsSet: crVrScrCompositorEntryEnsureRegionsBounds failed rc %d", rc));
return rc;
@@ -677,17 +701,20 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryPosSet(PVBOXVR_SCR_COMPOSITOR pComposito
}
/* regions are valid until the next CrVrScrCompositor call */
-VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
-{
- if (CrVrScrCompositorEntryIsUsed(pEntry))
- {
- int rc = crVrScrCompositorRectsCheckInit(pCompositor);
- if (!RT_SUCCESS(rc))
- {
- WARN(("crVrScrCompositorRectsCheckInit failed, rc %d", rc));
- return rc;
- }
- }
+VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(PCVBOXVR_SCR_COMPOSITOR pCompositor,
+ PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t *pcRegions,
+ PCRTRECT *ppaSrcRegions, PCRTRECT *ppaDstRegions,
+ PCRTRECT *ppaDstUnstretchedRects)
+{
+ if (CrVrScrCompositorEntryIsUsed(pEntry))
+ {
+ int rc = crVrScrCompositorRectsCheckInit(pCompositor);
+ if (RT_FAILURE(rc))
+ {
+ WARN(("crVrScrCompositorRectsCheckInit failed, rc %d", rc));
+ return rc;
+ }
+ }
Assert(pCompositor->cRects != VBOXVR_SCR_COMPOSITOR_RECTS_UNDEFINED);
@@ -702,7 +729,8 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRegionsGet(const VBOXVR_SCR_COMPOSITOR *
return VINF_SUCCESS;
}
-VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry)
+VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PCVBOXVR_SCR_COMPOSITOR pCompositor,
+ PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
{
return CRBLT_FOP_COMBINE(pCompositor->fFlags, pEntry->fFlags);
}
@@ -745,7 +773,8 @@ VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pComposito
return VINF_SUCCESS;
}
-VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry)
+VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_SCR_COMPOSITOR_ENTRY pNewEntry)
{
Assert(!CrVrScrCompositorEntryIsUsed(pNewEntry));
@@ -759,7 +788,9 @@ VBOXVREGDECL(bool) CrVrScrCompositorEntryReplace(PVBOXVR_SCR_COMPOSITOR pComposi
return true;
}
-static DECLCALLBACK(void) crVrScrCompositorEntryReleasedCB(const struct VBOXVR_COMPOSITOR *pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
+static DECLCALLBACK(void) crVrScrCompositorEntryReleasedCB(PCVBOXVR_COMPOSITOR pCompositor,
+ PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
{
PVBOXVR_SCR_COMPOSITOR_ENTRY pCEntry = VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pEntry);
@@ -779,15 +810,16 @@ static DECLCALLBACK(void) crVrScrCompositorEntryReleasedCB(const struct VBOXVR_C
if (pCEntry->pfnEntryReleased)
{
- PVBOXVR_SCR_COMPOSITOR_ENTRY pCReplacingEntry = pReplacingEntry ? VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacingEntry) : NULL;
+ PVBOXVR_SCR_COMPOSITOR_ENTRY pCReplacingEntry = pReplacingEntry
+ ? VBOXVR_SCR_COMPOSITOR_ENTRY_FROM_ENTRY(pReplacingEntry) : NULL;
PVBOXVR_SCR_COMPOSITOR pCConpositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCompositor);
pCEntry->pfnEntryReleased(pCConpositor, pCEntry, pCReplacingEntry);
}
}
-VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, const RTRECT *pRect, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, PCRTRECT pRect, bool *pfChanged)
{
- if (!memcmp(&pCompositor->Rect, pRect, sizeof (pCompositor->Rect)))
+ if (!memcmp(&pCompositor->Rect, pRect, sizeof(pCompositor->Rect)))
{
if (pfChanged)
*pfChanged = false;
@@ -802,7 +834,7 @@ VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, c
while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
{
int rc = crVrScrCompositorEntryEnsureRegionsBounds(pCompositor, pEntry, NULL);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorEntryEnsureRegionsBounds failed, rc %d", rc));
return rc;
@@ -812,9 +844,9 @@ VBOXVREGDECL(int) CrVrScrCompositorRectSet(PVBOXVR_SCR_COMPOSITOR pCompositor, c
return VINF_SUCCESS;
}
-VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor, const RTRECT *pRect)
+VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor, PCRTRECT pRect)
{
- memset(pCompositor, 0, sizeof (*pCompositor));
+ memset(pCompositor, 0, sizeof(*pCompositor));
VBoxVrCompositorInit(&pCompositor->Compositor, crVrScrCompositorEntryReleasedCB);
pCompositor->fFlags = CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS;
if (pRect)
@@ -882,10 +914,12 @@ VBOXVREGDECL(void) CrVrScrCompositorSetStretching(PVBOXVR_SCR_COMPOSITOR pCompos
#endif
/* regions are valid until the next CrVrScrCompositor call */
-VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(const VBOXVR_SCR_COMPOSITOR *pCompositor, uint32_t *pcRegions, const RTRECT **ppaSrcRegions, const RTRECT **ppaDstRegions, const RTRECT **ppaDstUnstretchedRects)
+VBOXVREGDECL(int) CrVrScrCompositorRegionsGet(PCVBOXVR_SCR_COMPOSITOR pCompositor, uint32_t *pcRegions,
+ PCRTRECT *ppaSrcRegions, PCRTRECT *ppaDstRegions,
+ PCRTRECT *ppaDstUnstretchedRects)
{
int rc = crVrScrCompositorRectsCheckInit(pCompositor);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("crVrScrCompositorRectsCheckInit failed, rc %d", rc));
return rc;
@@ -910,7 +944,8 @@ typedef struct VBOXVR_SCR_COMPOSITOR_VISITOR_CB
void *pvVisitor;
} VBOXVR_SCR_COMPOSITOR_VISITOR_CB, *PVBOXVR_SCR_COMPOSITOR_VISITOR_CB;
-static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
+static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry,
+ void *pvVisitor)
{
PVBOXVR_SCR_COMPOSITOR_VISITOR_CB pData = (PVBOXVR_SCR_COMPOSITOR_VISITOR_CB)pvVisitor;
PVBOXVR_SCR_COMPOSITOR pCompositor = VBOXVR_SCR_COMPOSITOR_FROM_COMPOSITOR(pCCompositor);
@@ -918,7 +953,8 @@ static DECLCALLBACK(bool) crVrScrCompositorVisitCb(PVBOXVR_COMPOSITOR pCComposit
return pData->pfnVisitor(pCompositor, pEntry, pData->pvVisitor);
}
-VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor, void *pvVisitor)
+VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PFNVBOXVRSCRCOMPOSITOR_VISITOR pfnVisitor,
+ void *pvVisitor)
{
VBOXVR_SCR_COMPOSITOR_VISITOR_CB Data;
Data.pfnVisitor = pfnVisitor;
@@ -926,22 +962,23 @@ VBOXVREGDECL(void) CrVrScrCompositorVisit(PVBOXVR_SCR_COMPOSITOR pCompositor, PF
VBoxVrCompositorVisit(&pCompositor->Compositor, crVrScrCompositorVisitCb, &Data);
}
-VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor)
+VBOXVREGDECL(int) CrVrScrCompositorClone(PCVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR pDstCompositor,
+ PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void *pvEntryFor)
{
/* for simplicity just copy from one to another */
CrVrScrCompositorInit(pDstCompositor, CrVrScrCompositorRectGet(pCompositor));
VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
- const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
+ PCVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
CrVrScrCompositorConstIterInit(pCompositor, &CIter);
int rc = VINF_SUCCESS;
uint32_t cRects;
- const RTRECT *pRects;
+ PCRTRECT paRects;
while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
{
/* get source rects, that will be non-stretched and entry pos - pased */
- rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, NULL, &pRects);
- if (!RT_SUCCESS(rc))
+ rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRects, NULL, NULL, &paRects);
+ if (RT_FAILURE(rc))
{
WARN(("CrVrScrCompositorEntryRegionsGet failed, rc %d", rc));
return rc;
@@ -954,8 +991,8 @@ VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pComposito
return VERR_INVALID_STATE;
}
- rc = CrVrScrCompositorEntryRegionsSet(pDstCompositor, pDstEntry, NULL, cRects, pRects, false, NULL);
- if (!RT_SUCCESS(rc))
+ rc = CrVrScrCompositorEntryRegionsSet(pDstCompositor, pDstEntry, NULL, cRects, paRects, false, NULL);
+ if (RT_FAILURE(rc))
{
WARN(("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc));
return rc;
@@ -965,7 +1002,7 @@ VBOXVREGDECL(int) CrVrScrCompositorClone(const VBOXVR_SCR_COMPOSITOR *pComposito
return rc;
}
-VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, const VBOXVR_LIST *pVr, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pCompositor, PCVBOXVR_LIST pVr, bool *pfChanged)
{
VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
@@ -978,7 +1015,7 @@ VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pComposi
bool fCurChanged = false;
rc = CrVrScrCompositorEntryListIntersect(pCompositor, pEntry, pVr, &fCurChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc));
break;
@@ -993,17 +1030,20 @@ VBOXVREGDECL(int) CrVrScrCompositorIntersectList(PVBOXVR_SCR_COMPOSITOR pComposi
return rc;
}
-VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(const VBOXVR_SCR_COMPOSITOR *pCompositor, const VBOXVR_LIST *pVr, PVBOXVR_SCR_COMPOSITOR pDstCompositor, PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void* pvEntryFor, bool *pfChanged)
+VBOXVREGDECL(int) CrVrScrCompositorIntersectedList(PCVBOXVR_SCR_COMPOSITOR pCompositor, PCVBOXVR_LIST pVr,
+ PVBOXVR_SCR_COMPOSITOR pDstCompositor,
+ PFNVBOXVR_SCR_COMPOSITOR_ENTRY_FOR pfnEntryFor, void *pvEntryFor,
+ bool *pfChanged)
{
- int rc = CrVrScrCompositorClone(pCompositor, pDstCompositor, pfnEntryFor, pvEntryFor);
- if (!RT_SUCCESS(rc))
+ int rc = CrVrScrCompositorClone(pCompositor, pDstCompositor, pfnEntryFor, pvEntryFor);
+ if (RT_FAILURE(rc))
{
WARN(("CrVrScrCompositorClone failed, rc %d", rc));
return rc;
}
rc = CrVrScrCompositorIntersectList(pDstCompositor, pVr, pfChanged);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
WARN(("CrVrScrCompositorIntersectList failed, rc %d", rc));
CrVrScrCompositorClear(pDstCompositor);
diff --git a/src/VBox/GuestHost/OpenGL/util/debug_opcodes.py b/src/VBox/GuestHost/OpenGL/util/debug_opcodes.py
old mode 100644
new mode 100755
diff --git a/src/VBox/GuestHost/OpenGL/util/error.c b/src/VBox/GuestHost/OpenGL/util/error.c
index 0fbaf05..d384d32 100644
--- a/src/VBox/GuestHost/OpenGL/util/error.c
+++ b/src/VBox/GuestHost/OpenGL/util/error.c
@@ -14,89 +14,136 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#ifdef VBOX
+#if 1
+
+#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
#include <iprt/string.h>
#include <iprt/stream.h>
-#ifndef IN_GUEST
-#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
-#endif
+#include <iprt/initterm.h>
#include <VBox/log.h>
-bool fWarningsEnabled = true;
-
-static void logMessage(const char *pszPrefix, const char *pszFormat, va_list va)
-{
- char *pszMessage;
- int rc = RTStrAPrintfV(&pszMessage, pszFormat, va);
- if (RT_SUCCESS(rc))
- {
- LogRel(("%s%s\n", pszPrefix, pszMessage));
-#ifdef IN_GUEST
- RTStrmPrintf(g_pStdErr, "%s%s\n", pszPrefix, pszMessage);
+#ifdef RT_OS_WINDOWS
+# include <windows.h>
+# include "cr_environment.h"
#endif
- RTStrFree(pszMessage);
- }
-}
-static void logDebug(const char *pszPrefix, const char *pszFormat, va_list va)
+#include <signal.h>
+#include <stdlib.h>
+
+static void logMessageV(const char *pszPrefix, const char *pszFormat, va_list va)
{
- char *pszMessage;
- int rc = RTStrAPrintfV(&pszMessage, pszFormat, va);
- if (RT_SUCCESS(rc))
+ va_list vaCopy;
+ if (RTR3InitIsInitialized())
{
- Log(("%s%s\n", pszPrefix, pszMessage));
- RTStrFree(pszMessage);
+ va_copy(vaCopy, va);
+ LogRel(("%s%N\n", pszPrefix, pszFormat, &vaCopy));
+ va_end(vaCopy);
}
+
+#ifdef IN_GUEST /** @todo Could be subject to pre-iprt-init issues, but hopefully not... */
+ va_copy(vaCopy, va);
+ RTStrmPrintf(g_pStdErr, "%s%N\n", pszPrefix, pszFormat, &vaCopy);
+ va_end(vaCopy);
+#endif
}
-DECLEXPORT(void) crError(const char *pszFormat, ... )
+static void logMessage(const char *pszPrefix, const char *pszFormat, ...)
{
va_list va;
va_start(va, pszFormat);
- logMessage("OpenGL Error: ", pszFormat, va);
+ logMessageV(pszPrefix, pszFormat, va);
va_end(va);
- AssertLogRelFailed();
}
-DECLEXPORT(void) crEnableWarnings(int fEnabled)
+DECLEXPORT(void) crError(const char *pszFormat, ...)
{
- fWarningsEnabled = RT_BOOL(fEnabled);
+ va_list va;
+#ifdef WINDOWS
+ DWORD dwLastErr;
+#endif
+
+#ifdef WINDOWS
+ /* Log last error on windows. */
+ dwLastErr = GetLastError();
+ if (dwLastErr != 0 && crGetenv("CR_WINDOWS_ERRORS") != NULL)
+ {
+ LPTSTR pszWindowsMessage;
+
+ SetLastError(0);
+ FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, dwLastErr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&pszWindowsMessage, 0, NULL);
+ if (pszWindowsMessage)
+ {
+ logMessage("OpenGL, Windows error: ", "%u\n%s", dwLastErr, pszWindowsMessage);
+ LocalFree(pszWindowsMessage);
+ }
+ else
+ logMessage("OpenGL, Windows error: ", "%u", dwLastErr);
+ }
+#endif
+
+ /* The message. */
+ va_start(va, pszFormat);
+ logMessageV("OpenGL Error: ", pszFormat, va);
+ va_end(va);
+
+ /* Dump core or activate the debugger in debug builds. */
+ AssertFailed();
+
+#ifdef IN_GUEST
+ /* Give things a chance to close down. */
+ raise(SIGTERM);
+ exit(1);
+#endif
}
-DECLEXPORT(void) crWarning(const char *pszFormat, ... )
+DECLEXPORT(void) crWarning(const char *pszFormat, ...)
{
- if (fWarningsEnabled)
+ if (RTR3InitIsInitialized())
{
va_list va;
va_start(va, pszFormat);
- logMessage("OpenGL Warning: ", pszFormat, va);
+ logMessageV("OpenGL Warning: ", pszFormat, va);
va_end(va);
}
}
-DECLEXPORT(void) crInfo(const char *pszFormat, ... )
+DECLEXPORT(void) crInfo(const char *pszFormat, ...)
{
- va_list va;
+ if (RTR3InitIsInitialized())
+ {
+ va_list va;
- va_start(va, pszFormat);
- logMessage("OpenGL Info: ", pszFormat, va);
- va_end(va);
+ va_start(va, pszFormat);
+ logMessageV("OpenGL Info: ", pszFormat, va);
+ va_end(va);
+ }
}
-DECLEXPORT(void) crDebug(const char *pszFormat, ... )
+DECLEXPORT(void) crDebug(const char *pszFormat, ...)
{
- va_list va;
+ if (RTR3InitIsInitialized())
+ {
+ va_list va;
- va_start(va, pszFormat);
- logDebug("OpenGL Debug: ", pszFormat, va);
- va_end(va);
+ va_start(va, pszFormat);
+#if defined(DEBUG_vgalitsy) || defined(DEBUG_galitsyn)
+ LogRel(("OpenGL Debug: %N\n", pszFormat, &va));
+#else
+ Log(("OpenGL Debug: %N\n", pszFormat, &va));
+#endif
+ va_end(va);
+ }
}
#else
-
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
@@ -705,5 +752,4 @@ BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
return TRUE;
}
#endif
-
-#endif /* !VBOX */
+#endif
diff --git a/src/VBox/GuestHost/OpenGL/util/net.c b/src/VBox/GuestHost/OpenGL/util/net.c
index 17fde06..63b5cae 100644
--- a/src/VBox/GuestHost/OpenGL/util/net.c
+++ b/src/VBox/GuestHost/OpenGL/util/net.c
@@ -423,7 +423,6 @@ crNetFreeConnection(CRConnection *conn)
}
-extern void __getHostInfo();
/**
* Start the ball rolling. give functions to handle incoming traffic
* (usually placing blocks on a queue), and a handler for dropped
@@ -449,10 +448,6 @@ void crNetInit( CRNetReceiveFunc recvFunc, CRNetCloseFunc closeFunc )
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
crError("Couldn't initialize sockets on WINDOWS");
-# ifndef VBOX
- //reinit hostname for debug messages as it's incorrect before WSAStartup gets called
- __getHostInfo();
-# endif
#endif
cr_net.use_gm = 0;
diff --git a/src/VBox/GuestHost/OpenGL/util/util.def b/src/VBox/GuestHost/OpenGL/util/util.def
index 4fa9705..cea8698 100644
--- a/src/VBox/GuestHost/OpenGL/util/util.def
+++ b/src/VBox/GuestHost/OpenGL/util/util.def
@@ -8,7 +8,6 @@ crDLLGetNoError
crDLLGet
crDLLClose
crError
-crEnableWarnings
crWarning
crDebug
crInfo
diff --git a/src/VBox/GuestHost/OpenGL/util/util.rc b/src/VBox/GuestHost/OpenGL/util/util.rc
index 794cf24..981ec44 100644
--- a/src/VBox/GuestHost/OpenGL/util/util.rc
+++ b/src/VBox/GuestHost/OpenGL/util/util.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009-2010 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,36 +21,36 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK 0x3fL
- FILEFLAGS 0x0L
- FILEOS 0x40004L
- FILETYPE 0x3L
- FILESUBTYPE 0x4L
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxOGLcrutil\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox crOpenGL crutil ICD\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxOGLcrutil\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
#ifdef VBOX_WDDM_WOW64
- VALUE "OriginalFilename", "VBoxOGLcrutil-x86.dll\0"
+ VALUE "OriginalFilename", "VBoxOGLcrutil-x86.dll\0"
#else
- VALUE "OriginalFilename", "VBoxOGLcrutil.dll\0"
+ VALUE "OriginalFilename", "VBoxOGLcrutil.dll\0"
#endif
- VALUE "ProductName", VBOX_PRODUCT " Guest Additions\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
+ VALUE "ProductName", VBOX_PRODUCT " Guest Additions\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
END
1 RCDATA
diff --git a/src/VBox/GuestHost/OpenGL/util/vreg.cpp b/src/VBox/GuestHost/OpenGL/util/vreg.cpp
index e2cea3b..f47f3d0 100644
--- a/src/VBox/GuestHost/OpenGL/util/vreg.cpp
+++ b/src/VBox/GuestHost/OpenGL/util/vreg.cpp
@@ -1,11 +1,10 @@
/* $Id: vreg.cpp $ */
-
/** @file
* Visible Regions processing API implementation
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -15,33 +14,43 @@
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include <cr_vreg.h>
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#ifdef IN_VMSVGA3D
+# include "../include/cr_vreg.h"
+# define WARN AssertMsgFailed
+#else
+# include <cr_vreg.h>
+# include <cr_error.h>
+#endif
+
#include <iprt/err.h>
#include <iprt/assert.h>
#include <iprt/asm.h>
-#include <cr_error.h>
-
#ifdef DEBUG_misha
# define VBOXVDBG_VR_LAL_DISABLE
#endif
#ifndef IN_RING0
-#include <iprt/memcache.h>
-#ifndef VBOXVDBG_VR_LAL_DISABLE
+# include <iprt/memcache.h>
+# ifndef VBOXVDBG_VR_LAL_DISABLE
static RTMEMCACHE g_VBoxVrLookasideList;
-#define vboxVrRegLaAlloc(_c) RTMemCacheAlloc((_c))
-#define vboxVrRegLaFree(_c, _e) RTMemCacheFree((_c), (_e))
-DECLINLINE(int) vboxVrLaCreate(RTMEMCACHE *pCache, size_t cbElement)
+# define vboxVrRegLaAlloc(_c) RTMemCacheAlloc((_c))
+# define vboxVrRegLaFree(_c, _e) RTMemCacheFree((_c), (_e))
+
+DECLINLINE(int) vboxVrLaCreate(PRTMEMCACHE phCache, size_t cbElement)
{
- int rc = RTMemCacheCreate(pCache, cbElement,
- 0, /* size_t cbAlignment */
- UINT32_MAX, /* uint32_t cMaxObjects */
- NULL, /* PFNMEMCACHECTOR pfnCtor*/
- NULL, /* PFNMEMCACHEDTOR pfnDtor*/
- NULL, /* void *pvUser*/
- 0 /* uint32_t fFlags*/
- );
+ int rc = RTMemCacheCreate(phCache,
+ cbElement,
+ 0 /* cbAlignment */,
+ UINT32_MAX /* cMaxObjects */,
+ NULL /* pfnCtor*/,
+ NULL /* pfnDtor*/,
+ NULL /* pvUser*/,
+ 0 /* fFlags*/);
if (!RT_SUCCESS(rc))
{
WARN(("RTMemCacheCreate failed rc %d", rc));
@@ -49,16 +58,13 @@ DECLINLINE(int) vboxVrLaCreate(RTMEMCACHE *pCache, size_t cbElement)
}
return VINF_SUCCESS;
}
-#define vboxVrLaDestroy(_c) RTMemCacheDestroy((_c))
-#endif
-#else
+# define vboxVrLaDestroy(_c) RTMemCacheDestroy((_c))
+# endif /* !VBOXVDBG_VR_LAL_DISABLE */
+
+#else /* IN_RING0 */
# ifdef RT_OS_WINDOWS
-# ifdef PAGE_SIZE
-# undef PAGE_SIZE
-# endif
-# ifdef PAGE_SHIFT
-# undef PAGE_SHIFT
-# endif
+# undef PAGE_SIZE
+# undef PAGE_SHIFT
# define VBOX_WITH_WORKAROUND_MISSING_PACK
# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
@@ -71,13 +77,13 @@ DECLINLINE(int) vboxVrLaCreate(RTMEMCACHE *pCache, size_t cbElement)
# define _interlockedbittestandreset64 _interlockedbittestandreset64_StupidDDKVsCompilerCrap
# pragma warning(disable : 4163)
# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
-# pragma warning(disable : 4103)
+# pragma warning(disable : 4103)
# endif
# include <ntddk.h>
# pragma warning(default : 4163)
# ifdef VBOX_WITH_WORKAROUND_MISSING_PACK
-# pragma pack()
-# pragma warning(default : 4103)
+# pragma pack()
+# pragma warning(default : 4103)
# endif
# undef _InterlockedExchange
# undef _InterlockedExchangeAdd
@@ -90,22 +96,22 @@ DECLINLINE(int) vboxVrLaCreate(RTMEMCACHE *pCache, size_t cbElement)
# else
# include <ntddk.h>
# endif
-#ifndef VBOXVDBG_VR_LAL_DISABLE
+# ifndef VBOXVDBG_VR_LAL_DISABLE
static LOOKASIDE_LIST_EX g_VBoxVrLookasideList;
-#define vboxVrRegLaAlloc(_c) ExAllocateFromLookasideListEx(&(_c))
-#define vboxVrRegLaFree(_c, _e) ExFreeToLookasideListEx(&(_c), (_e))
-#define VBOXWDDMVR_MEMTAG 'vDBV'
+# define vboxVrRegLaAlloc(_c) ExAllocateFromLookasideListEx(&(_c))
+# define vboxVrRegLaFree(_c, _e) ExFreeToLookasideListEx(&(_c), (_e))
+# define VBOXWDDMVR_MEMTAG 'vDBV'
DECLINLINE(int) vboxVrLaCreate(LOOKASIDE_LIST_EX *pCache, size_t cbElement)
{
NTSTATUS Status = ExInitializeLookasideListEx(pCache,
- NULL, /* PALLOCATE_FUNCTION_EX Allocate */
- NULL, /* PFREE_FUNCTION_EX Free */
- NonPagedPool,
- 0, /* ULONG Flags */
- cbElement,
- VBOXWDDMVR_MEMTAG,
- 0 /* USHORT Depth - reserved, must be null */
- );
+ NULL, /* PALLOCATE_FUNCTION_EX Allocate */
+ NULL, /* PFREE_FUNCTION_EX Free */
+ NonPagedPool,
+ 0, /* ULONG Flags */
+ cbElement,
+ VBOXWDDMVR_MEMTAG,
+ 0 /* USHORT Depth - reserved, must be null */
+ );
if (!NT_SUCCESS(Status))
{
WARN(("ExInitializeLookasideListEx failed, Status (0x%x)", Status));
@@ -114,16 +120,27 @@ DECLINLINE(int) vboxVrLaCreate(LOOKASIDE_LIST_EX *pCache, size_t cbElement)
return VINF_SUCCESS;
}
-#define vboxVrLaDestroy(_c) ExDeleteLookasideListEx(&(_c))
-#endif
-# else
+# define vboxVrLaDestroy(_c) ExDeleteLookasideListEx(&(_c))
+# endif
+# else /* !RT_OS_WINDOWS */
# error "port me!"
-# endif
-#endif
+# endif /* !RT_OS_WINDOWS */
+#endif /* IN_RING0 */
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+#define VBOXVR_INVALID_COORD (~0U)
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
static volatile int32_t g_cVBoxVrInits = 0;
-static PVBOXVR_REG vboxVrRegCreate()
+
+static PVBOXVR_REG vboxVrRegCreate(void)
{
#ifndef VBOXVDBG_VR_LAL_DISABLE
PVBOXVR_REG pReg = (PVBOXVR_REG)vboxVrRegLaAlloc(g_VBoxVrLookasideList);
@@ -133,7 +150,7 @@ static PVBOXVR_REG vboxVrRegCreate()
}
return pReg;
#else
- return (PVBOXVR_REG)RTMemAlloc(sizeof (VBOXVR_REG));
+ return (PVBOXVR_REG)RTMemAlloc(sizeof(VBOXVR_REG));
#endif
}
@@ -166,9 +183,7 @@ VBOXVREGDECL(void) VBoxVrListMoveTo(PVBOXVR_LIST pList, PVBOXVR_LIST pDstList)
VBoxVrListInit(pList);
}
-#define VBOXVR_MEMTAG 'vDBV'
-
-VBOXVREGDECL(int) VBoxVrInit()
+VBOXVREGDECL(int) VBoxVrInit(void)
{
int32_t cNewRefs = ASMAtomicIncS32(&g_cVBoxVrInits);
Assert(cNewRefs >= 1);
@@ -177,7 +192,7 @@ VBOXVREGDECL(int) VBoxVrInit()
return VINF_SUCCESS;
#ifndef VBOXVDBG_VR_LAL_DISABLE
- int rc = vboxVrLaCreate(&g_VBoxVrLookasideList, sizeof (VBOXVR_REG));
+ int rc = vboxVrLaCreate(&g_VBoxVrLookasideList, sizeof(VBOXVR_REG));
if (!RT_SUCCESS(rc))
{
WARN(("ExInitializeLookasideListEx failed, rc (%d)", rc));
@@ -188,7 +203,7 @@ VBOXVREGDECL(int) VBoxVrInit()
return VINF_SUCCESS;
}
-VBOXVREGDECL(void) VBoxVrTerm()
+VBOXVREGDECL(void) VBoxVrTerm(void)
{
int32_t cNewRefs = ASMAtomicDecS32(&g_cVBoxVrInits);
Assert(cNewRefs >= 0);
@@ -200,10 +215,10 @@ VBOXVREGDECL(void) VBoxVrTerm()
#endif
}
-typedef DECLCALLBACK(int) FNVBOXVR_CB_COMPARATOR(const VBOXVR_REG *pReg1, const VBOXVR_REG *pReg2);
+typedef DECLCALLBACK(int) FNVBOXVR_CB_COMPARATOR(PCVBOXVR_REG pReg1, PCVBOXVR_REG pReg2);
typedef FNVBOXVR_CB_COMPARATOR *PFNVBOXVR_CB_COMPARATOR;
-static DECLCALLBACK(int) vboxVrRegNonintersectedComparator(const RTRECT* pRect1, const RTRECT* pRect2)
+static DECLCALLBACK(int) vboxVrRegNonintersectedComparator(PCRTRECT pRect1, PCRTRECT pRect2)
{
Assert(!VBoxRectIsIntersect(pRect1, pRect2));
if (pRect1->yTop != pRect2->yTop)
@@ -225,15 +240,11 @@ static void vboxVrDbgListDoVerify(PVBOXVR_LIST pList)
}
}
}
-
-#define vboxVrDbgListVerify vboxVrDbgListDoVerify
+# define vboxVrDbgListVerify(_p) vboxVrDbgListDoVerify(_p)
#else
-#define vboxVrDbgListVerify(_p) do {} while (0)
+# define vboxVrDbgListVerify(_p) do {} while (0)
#endif
-static int vboxVrListUniteIntersection(PVBOXVR_LIST pList, PVBOXVR_LIST pIntersection);
-
-#define VBOXVR_INVALID_COORD (~0U)
DECLINLINE(void) vboxVrListRegAdd(PVBOXVR_LIST pList, PVBOXVR_REG pReg, PRTLISTNODE pPlace, bool fAfter)
{
@@ -254,7 +265,7 @@ DECLINLINE(void) vboxVrListRegRemove(PVBOXVR_LIST pList, PVBOXVR_REG pReg)
static void vboxVrListRegAddOrder(PVBOXVR_LIST pList, PRTLISTNODE pMemberEntry, PVBOXVR_REG pReg)
{
- do
+ for (;;)
{
if (pMemberEntry != &pList->ListHead)
{
@@ -267,7 +278,7 @@ static void vboxVrListRegAddOrder(PVBOXVR_LIST pList, PRTLISTNODE pMemberEntry,
}
vboxVrListRegAdd(pList, pReg, pMemberEntry, false);
break;
- } while (1);
+ }
}
static void vboxVrListAddNonintersected(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2)
@@ -277,7 +288,8 @@ static void vboxVrListAddNonintersected(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2
for (PRTLISTNODE pEntry2 = pList2->ListHead.pNext; pEntry2 != &pList2->ListHead; pEntry2 = pList2->ListHead.pNext)
{
PVBOXVR_REG pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
- do {
+ for (;;)
+ {
if (pEntry1 != &pList1->ListHead)
{
PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
@@ -290,13 +302,13 @@ static void vboxVrListAddNonintersected(PVBOXVR_LIST pList1, PVBOXVR_LIST pList2
vboxVrListRegRemove(pList2, pReg2);
vboxVrListRegAdd(pList1, pReg2, pEntry1, false);
break;
- } while (1);
+ }
}
Assert(VBoxVrListIsEmpty(pList2));
}
-static int vboxVrListRegIntersectSubstNoJoin(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2)
+static int vboxVrListRegIntersectSubstNoJoin(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, PCRTRECT pRect2)
{
uint32_t topLim = VBOXVR_INVALID_COORD;
uint32_t bottomLim = VBOXVR_INVALID_COORD;
@@ -368,7 +380,8 @@ static int vboxVrListRegIntersectSubstNoJoin(PVBOXVR_LIST pList1, PVBOXVR_REG pR
if (RTListIsEmpty(&List))
return VINF_SUCCESS; /* the region is covered by the pRect2 */
- PRTLISTNODE pEntry = List.pNext, pNext;
+ PRTLISTNODE pNext;
+ PRTLISTNODE pEntry = List.pNext;
for (; pEntry != &List; pEntry = pNext)
{
pNext = pEntry->pNext;
@@ -380,13 +393,16 @@ static int vboxVrListRegIntersectSubstNoJoin(PVBOXVR_LIST pList1, PVBOXVR_REG pR
return VINF_SUCCESS;
}
-/* @returns Entry to be used for continuing the rectangles iterations being made currently on the callback call.
+/**
+ * @returns Entry to be used for continuing the rectangles iterations being made currently on the callback call.
* ListHead is returned to break the current iteration
- * @param ppNext specifies next reg entry to be used for iteration. the default is pReg1->ListEntry.pNext */
-typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_INTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT * pRect2, void *pvContext, PRTLISTNODE *ppNext);
+ * @param ppNext specifies next reg entry to be used for iteration. the default is pReg1->ListEntry.pNext */
+typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_INTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1,
+ PCRTRECT pRect2, void *pvContext, PRTLISTNODE *ppNext);
typedef FNVBOXVR_CB_INTERSECTED_VISITOR *PFNVBOXVR_CB_INTERSECTED_VISITOR;
-static void vboxVrListVisitIntersected(PVBOXVR_LIST pList1, uint32_t cRects, const RTRECT *aRects, PFNVBOXVR_CB_INTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
+static void vboxVrListVisitIntersected(PVBOXVR_LIST pList1, uint32_t cRects, PCRTRECT aRects,
+ PFNVBOXVR_CB_INTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
{
PRTLISTNODE pEntry1 = pList1->ListHead.pNext;
PRTLISTNODE pNext1;
@@ -398,7 +414,7 @@ static void vboxVrListVisitIntersected(PVBOXVR_LIST pList1, uint32_t cRects, con
PVBOXVR_REG pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
for (uint32_t i = iFirst2; i < cRects; ++i)
{
- const RTRECT *pRect2 = &aRects[i];
+ PCRTRECT pRect2 = &aRects[i];
if (VBoxRectIsZero(pRect2))
continue;
@@ -409,19 +425,20 @@ static void vboxVrListVisitIntersected(PVBOXVR_LIST pList1, uint32_t cRects, con
pEntry1 = pfnVisitor (pList1, pReg1, pRect2, pvVisitor, &pNext1);
if (pEntry1 == &pList1->ListHead)
break;
- else
- pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
+ pReg1 = PVBOXVR_REG_FROM_ENTRY(pEntry1);
}
}
}
-/* @returns Entry to be iterated next. ListHead is returned to break the iteration
- *
+/**
+ * @returns Entry to be iterated next. ListHead is returned to break the
+ * iteration
*/
typedef DECLCALLBACK(PRTLISTNODE) FNVBOXVR_CB_NONINTERSECTED_VISITOR(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, void *pvContext);
typedef FNVBOXVR_CB_NONINTERSECTED_VISITOR *PFNVBOXVR_CB_NONINTERSECTED_VISITOR;
-static void vboxVrListVisitNonintersected(PVBOXVR_LIST pList1, uint32_t cRects, const RTRECT *aRects, PFNVBOXVR_CB_NONINTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
+static void vboxVrListVisitNonintersected(PVBOXVR_LIST pList1, uint32_t cRects, PCRTRECT aRects,
+ PFNVBOXVR_CB_NONINTERSECTED_VISITOR pfnVisitor, void* pvVisitor)
{
PRTLISTNODE pEntry1 = pList1->ListHead.pNext;
PRTLISTNODE pNext1;
@@ -433,7 +450,7 @@ static void vboxVrListVisitNonintersected(PVBOXVR_LIST pList1, uint32_t cRects,
uint32_t i = iFirst2;
for (; i < cRects; ++i)
{
- const RTRECT *pRect2 = &aRects[i];
+ PCRTRECT pRect2 = &aRects[i];
if (VBoxRectIsZero(pRect2))
continue;
@@ -487,7 +504,8 @@ static void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
pNext1 = pList->ListHead.pNext;
break;
}
- else if (pReg1->Rect.yBottom < pReg2->Rect.yBottom)
+
+ if (pReg1->Rect.yBottom < pReg2->Rect.yBottom)
{
pReg1->Rect.xRight = pReg2->Rect.xRight;
vboxVrDbgListVerify(pList);
@@ -498,15 +516,13 @@ static void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
pNext1 = pList->ListHead.pNext;
break;
}
- else
- {
- pReg1->Rect.xRight = pReg2->Rect.xRight;
- vboxVrDbgListVerify(pList);
- /* reset the pNext1 since it could be the pReg2 being destroyed */
- pNext1 = pEntry1->pNext;
- /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
- vboxVrRegTerm(pReg2);
- }
+
+ pReg1->Rect.xRight = pReg2->Rect.xRight;
+ vboxVrDbgListVerify(pList);
+ /* reset the pNext1 since it could be the pReg2 being destroyed */
+ pNext1 = pEntry1->pNext;
+ /* pNext2 stays the same since it is pReg2->ListEntry.pNext, which is kept intact */
+ vboxVrRegTerm(pReg2);
}
continue;
}
@@ -529,7 +545,8 @@ static void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
pNext1 = pList->ListHead.pNext;
break;
}
- else if (pReg1->Rect.xLeft == pReg2->Rect.xRight)
+
+ if (pReg1->Rect.xLeft == pReg2->Rect.xRight)
{
/* join rectangles */
vboxVrListRegRemove(pList, pReg2);
@@ -571,7 +588,8 @@ static void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
/* no more to be done for for pReg1 */
break;
}
- else if (pReg1->Rect.xRight > pReg2->Rect.xLeft)
+
+ if (pReg1->Rect.xRight > pReg2->Rect.xLeft)
{
/* no more to be done for for pReg1 */
break;
@@ -579,7 +597,8 @@ static void vboxVrListJoinRectsHV(PVBOXVR_LIST pList, bool fHorizontal)
continue;
}
- else if (pReg1->Rect.yBottom < pReg2->Rect.yTop)
+
+ if (pReg1->Rect.yBottom < pReg2->Rect.yTop)
{
/* no more to be done for for pReg1 */
break;
@@ -599,9 +618,11 @@ typedef struct VBOXVR_CBDATA_SUBST
{
int rc;
bool fChanged;
-} VBOXVR_CBDATA_SUBST, *PVBOXVR_CBDATA_SUBST;
+} VBOXVR_CBDATA_SUBST;
+typedef VBOXVR_CBDATA_SUBST *PVBOXVR_CBDATA_SUBST;
-static DECLCALLBACK(PRTLISTNODE) vboxVrListSubstNoJoinCb(PVBOXVR_LIST pList, PVBOXVR_REG pReg1, const RTRECT *pRect2, void *pvContext, PRTLISTNODE *ppNext)
+static DECLCALLBACK(PRTLISTNODE) vboxVrListSubstNoJoinCb(PVBOXVR_LIST pList, PVBOXVR_REG pReg1, PCRTRECT pRect2,
+ void *pvContext, PRTLISTNODE *ppNext)
{
PVBOXVR_CBDATA_SUBST pData = (PVBOXVR_CBDATA_SUBST)pvContext;
/* store the prev to get the new pNext out of it*/
@@ -624,7 +645,7 @@ static DECLCALLBACK(PRTLISTNODE) vboxVrListSubstNoJoinCb(PVBOXVR_LIST pList, PVB
return &pList->ListHead;
}
-static int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
+static int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT aRects, bool *pfChanged)
{
if (pfChanged)
*pfChanged = false;
@@ -650,28 +671,26 @@ static int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, const RTRE
}
#if 0
-static const RTRECT * vboxVrRectsOrder(uint32_t cRects, const RTRECT * aRects)
+static PCRTRECT vboxVrRectsOrder(uint32_t cRects, PCRTRECT aRects)
{
-#ifdef DEBUG
+#ifdef VBOX_STRICT
+ for (uint32_t i = 0; i < cRects; ++i)
{
- for (uint32_t i = 0; i < cRects; ++i)
+ PRTRECT pRectI = &aRects[i];
+ for (uint32_t j = i + 1; j < cRects; ++j)
{
- RTRECT *pRectI = &aRects[i];
- for (uint32_t j = i + 1; j < cRects; ++j)
- {
- RTRECT *pRectJ = &aRects[j];
- Assert(!VBoxRectIsIntersect(pRectI, pRectJ));
- }
+ PRTRECT pRectJ = &aRects[j];
+ Assert(!VBoxRectIsIntersect(pRectI, pRectJ));
}
}
#endif
- RTRECT * pRects = (RTRECT *)aRects;
+ PRTRECT pRects = (PRTRECT)aRects;
/* check if rects are ordered already */
for (uint32_t i = 0; i < cRects - 1; ++i)
{
- RTRECT *pRect1 = &pRects[i];
- RTRECT *pRect2 = &pRects[i+1];
+ PRTRECT pRect1 = &pRects[i];
+ PRTRECT pRect2 = &pRects[i+1];
if (vboxVrRegNonintersectedComparator(pRect1, pRect2) < 0)
continue;
@@ -679,20 +698,21 @@ static const RTRECT * vboxVrRectsOrder(uint32_t cRects, const RTRECT * aRects)
if (pRects == aRects)
{
- pRects = (RTRECT *)RTMemAlloc(sizeof (RTRECT) * cRects);
+ pRects = (PRTRECT)RTMemAlloc(sizeof(RTRECT) * cRects);
if (!pRects)
{
WARN(("RTMemAlloc failed!"));
return NULL;
}
- memcpy(pRects, aRects, sizeof (RTRECT) * cRects);
+ memcpy(pRects, aRects, sizeof(RTRECT) * cRects);
}
Assert(pRects != aRects);
int j = (int)i - 1;
- do {
+ for (;;)
+ {
RTRECT Tmp = *pRect1;
*pRect1 = *pRect2;
*pRect2 = Tmp;
@@ -705,7 +725,7 @@ static const RTRECT * vboxVrRectsOrder(uint32_t cRects, const RTRECT * aRects)
pRect2 = pRect1--;
--j;
- } while (1);
+ }
}
return pRects;
@@ -739,7 +759,8 @@ static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinNonintersectedCb(PVBOX
return pNext;
}
-static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinIntersectedCb(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, const RTRECT *pRect2, void *pvContext, PRTLISTNODE *ppNext)
+static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinIntersectedCb(PVBOXVR_LIST pList1, PVBOXVR_REG pReg1, PCRTRECT pRect2,
+ void *pvContext, PPRTLISTNODE ppNext)
{
PVBOXVR_CBDATA_SUBST pData = (PVBOXVR_CBDATA_SUBST)pvContext;
pData->fChanged = true;
@@ -762,7 +783,7 @@ static DECLCALLBACK(PRTLISTNODE) vboxVrListIntersectNoJoinIntersectedCb(PVBOXVR_
return &pReg1->ListEntry;
}
-static int vboxVrListIntersectNoJoin(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged)
+static int vboxVrListIntersectNoJoin(PVBOXVR_LIST pList, PCVBOXVR_LIST pList2, bool *pfChanged)
{
bool fChanged = false;
*pfChanged = false;
@@ -790,8 +811,8 @@ static int vboxVrListIntersectNoJoin(PVBOXVR_LIST pList, const VBOXVR_LIST *pLis
for (const RTLISTNODE *pEntry2 = pList2->ListHead.pNext; pEntry2 != &pList2->ListHead; pEntry2 = pEntry2->pNext)
{
- const VBOXVR_REG *pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
- const RTRECT *pRect2 = &pReg2->Rect;
+ PCVBOXVR_REG pReg2 = PVBOXVR_REG_FROM_ENTRY(pEntry2);
+ PCRTRECT pRect2 = &pReg2->Rect;
if (!VBoxRectIsIntersect(&RegRect1, pRect2))
continue;
@@ -854,7 +875,7 @@ static int vboxVrListIntersectNoJoin(PVBOXVR_LIST pList, const VBOXVR_LIST *pLis
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pList2, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, PCVBOXVR_LIST pList2, bool *pfChanged)
{
if (pfChanged)
*pfChanged = false;
@@ -874,7 +895,7 @@ VBOXVREGDECL(int) VBoxVrListIntersect(PVBOXVR_LIST pList, const VBOXVR_LIST *pLi
return rc;
}
-VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT aRects, bool *pfChanged)
{
if (pfChanged)
*pfChanged = false;
@@ -915,10 +936,10 @@ VBOXVREGDECL(int) VBoxVrListRectsIntersect(PVBOXVR_LIST pList, uint32_t cRects,
return rc;
}
-VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrListRectsSubst(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT aRects, bool *pfChanged)
{
#if 0
- const RTRECT * pRects = vboxVrRectsOrder(cRects, aRects);
+ PCRTRECT pRects = vboxVrRectsOrder(cRects, aRects);
if (!pRects)
{
WARN(("vboxVrRectsOrder failed!"));
@@ -952,15 +973,13 @@ done:
return rc;
}
-VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT aRects, bool *pfChanged)
{
if (pfChanged)
*pfChanged = false;
if (!cRects && VBoxVrListIsEmpty(pList))
- {
return VINF_SUCCESS;
- }
/* @todo: fChanged will have false alarming here, fix if needed */
VBoxVrListClear(pList);
@@ -978,7 +997,7 @@ VBOXVREGDECL(int) VBoxVrListRectsSet(PVBOXVR_LIST pList, uint32_t cRects, const
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, PCRTRECT aRects, bool *pfChanged)
{
uint32_t cCovered = 0;
@@ -986,18 +1005,16 @@ VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const
*pfChanged = false;
#if 0
-#ifdef DEBUG
- {
+#ifdef VBOX_STRICT
for (uint32_t i = 0; i < cRects; ++i)
{
- RTRECT *pRectI = &aRects[i];
+ PRTRECT pRectI = &aRects[i];
for (uint32_t j = i + 1; j < cRects; ++j)
{
- RTRECT *pRectJ = &aRects[j];
+ PRTRECT pRectJ = &aRects[j];
Assert(!VBoxRectIsIntersect(pRectI, pRectJ));
}
}
- }
#endif
#endif
@@ -1029,7 +1046,7 @@ VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const
VBOXVR_LIST DiffList;
VBoxVrListInit(&DiffList);
- RTRECT * pListRects = NULL;
+ PRTRECT pListRects = NULL;
uint32_t cAllocatedRects = 0;
bool fNeedRectreate = true;
bool fChanged = false;
@@ -1056,11 +1073,8 @@ VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const
fChanged = true;
continue;
}
- else
- {
- Assert(VBoxVrListIsEmpty(&DiffList));
- vboxVrListRegAdd(&DiffList, pReg, &DiffList.ListHead, false);
- }
+ Assert(VBoxVrListIsEmpty(&DiffList));
+ vboxVrListRegAdd(&DiffList, pReg, &DiffList.ListHead, false);
if (cAllocatedRects < cListRects)
{
@@ -1068,7 +1082,7 @@ VBOXVREGDECL(int) VBoxVrListRectsAdd(PVBOXVR_LIST pList, uint32_t cRects, const
Assert(fNeedRectreate);
if (pListRects)
RTMemFree(pListRects);
- pListRects = (RTRECT *)RTMemAlloc(sizeof (RTRECT) * cAllocatedRects);
+ pListRects = (RTRECT *)RTMemAlloc(sizeof(RTRECT) * cAllocatedRects);
if (!pListRects)
{
WARN(("RTMemAlloc failed!"));
@@ -1142,10 +1156,12 @@ VBOXVREGDECL(int) VBoxVrListCmp(const VBOXVR_LIST *pList1, const VBOXVR_LIST *pL
PVBOXVR_REG pReg1, pReg2;
for (pReg1 = RTListNodeGetNext(&pList1->ListHead, VBOXVR_REG, ListEntry),
- pReg2 = RTListNodeGetNext(&pList2->ListHead, VBOXVR_REG, ListEntry);
- !RTListNodeIsDummy(&pList1->ListHead, pReg1, VBOXVR_REG, ListEntry);
- pReg1 = RT_FROM_MEMBER(pReg1->ListEntry.pNext, VBOXVR_REG, ListEntry),
- pReg2 = RT_FROM_MEMBER(pReg2->ListEntry.pNext, VBOXVR_REG, ListEntry))
+ pReg2 = RTListNodeGetNext(&pList2->ListHead, VBOXVR_REG, ListEntry);
+
+ !RTListNodeIsDummy(&pList1->ListHead, pReg1, VBOXVR_REG, ListEntry);
+
+ pReg1 = RT_FROM_MEMBER(pReg1->ListEntry.pNext, VBOXVR_REG, ListEntry),
+ pReg2 = RT_FROM_MEMBER(pReg2->ListEntry.pNext, VBOXVR_REG, ListEntry) )
{
Assert(!RTListNodeIsDummy(&pList2->ListHead, pReg2, VBOXVR_REG, ListEntry));
cTmp = VBoxRectCmp(&pReg1->Rect, &pReg2->Rect);
@@ -1156,10 +1172,10 @@ VBOXVREGDECL(int) VBoxVrListCmp(const VBOXVR_LIST *pList1, const VBOXVR_LIST *pL
return 0;
}
-VBOXVREGDECL(int) VBoxVrListClone(const VBOXVR_LIST *pList, VBOXVR_LIST *pDstList)
+VBOXVREGDECL(int) VBoxVrListClone(PCVBOXVR_LIST pList, PVBOXVR_LIST pDstList)
{
VBoxVrListInit(pDstList);
- const VBOXVR_REG *pReg;
+ PCVBOXVR_REG pReg;
RTListForEach(&pList->ListHead, pReg, const VBOXVR_REG, ListEntry)
{
PVBOXVR_REG pDstReg = vboxVrRegCreate();
@@ -1203,7 +1219,8 @@ VBOXVREGDECL(void) VBoxVrCompositorClear(PVBOXVR_COMPOSITOR pCompositor)
VBoxVrCompositorRegionsClear(pCompositor, NULL);
}
-DECLINLINE(void) vboxVrCompositorEntryRelease(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
+DECLINLINE(void) vboxVrCompositorEntryRelease(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
{
if (--pEntry->cRefs)
{
@@ -1228,13 +1245,15 @@ DECLINLINE(void) vboxVrCompositorEntryAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXV
vboxVrCompositorEntryAddRef(pEntry);
}
-DECLINLINE(void) vboxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
+DECLINLINE(void) vboxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
{
RTListNodeRemove(&pEntry->Node);
vboxVrCompositorEntryRelease(pCompositor, pEntry, pReplacingEntry);
}
-static void vboxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
+static void vboxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pReplacingEntry)
{
VBoxVrListMoveTo(&pEntry->Vr, &pReplacingEntry->Vr);
@@ -1269,7 +1288,8 @@ VBOXVREGDECL(bool) VBoxVrCompositorEntryRemove(PVBOXVR_COMPOSITOR pCompositor, P
return true;
}
-VBOXVREGDECL(bool) VBoxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, PVBOXVR_COMPOSITOR_ENTRY pNewEntry)
+VBOXVREGDECL(bool) VBoxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PVBOXVR_COMPOSITOR_ENTRY pNewEntry)
{
if (!VBoxVrCompositorEntryIsInList(pEntry))
return false;
@@ -1279,7 +1299,8 @@ VBOXVREGDECL(bool) VBoxVrCompositorEntryReplace(PVBOXVR_COMPOSITOR pCompositor,
return true;
}
-static int vboxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT * paRects, bool *pfChanged)
+static int vboxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRects, PCRTRECT paRects, bool *pfChanged)
{
bool fChanged;
vboxVrCompositorEntryAddRef(pEntry);
@@ -1302,10 +1323,17 @@ static int vboxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVB
return rc;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, PVBOXVR_COMPOSITOR_ENTRY *ppReplacedEntry, uint32_t *pfChangeFlags)
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRects, PCRTRECT paRects, PVBOXVR_COMPOSITOR_ENTRY *ppReplacedEntry,
+ uint32_t *pfChangeFlags)
{
- bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryWasInList = false;
- PVBOXVR_COMPOSITOR_ENTRY pCur, pNext, pReplacedEntry = NULL;
+ bool fOthersChanged = false;
+ bool fCurChanged = false;
+ bool fEntryChanged = false;
+ bool fEntryWasInList = false;
+ PVBOXVR_COMPOSITOR_ENTRY pCur;
+ PVBOXVR_COMPOSITOR_ENTRY pNext;
+ PVBOXVR_COMPOSITOR_ENTRY pReplacedEntry = NULL;
int rc = VINF_SUCCESS;
if (pEntry)
@@ -1364,16 +1392,14 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor
*ppReplacedEntry = pReplacedEntry;
break;
}
+
+ rc = vboxVrCompositorEntryRegionsSubst(pCompositor, pCur, cRects, paRects, &fCurChanged);
+ if (RT_SUCCESS(rc))
+ fOthersChanged |= fCurChanged;
else
{
- rc = vboxVrCompositorEntryRegionsSubst(pCompositor, pCur, cRects, paRects, &fCurChanged);
- if (RT_SUCCESS(rc))
- fOthersChanged |= fCurChanged;
- else
- {
- WARN(("vboxVrCompositorEntryRegionsSubst failed, rc %d", rc));
- return rc;
- }
+ WARN(("vboxVrCompositorEntryRegionsSubst failed, rc %d", rc));
+ return rc;
}
}
}
@@ -1394,7 +1420,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor
if (fOthersChanged)
{
Assert(!pReplacedEntry);
- fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
+ fFlags = VBOXVR_COMPOSITOR_CF_ENTRY_REGIONS_CHANGED | VBOXVR_COMPOSITOR_CF_REGIONS_CHANGED
+ | VBOXVR_COMPOSITOR_CF_OTHER_ENTRIES_REGIONS_CHANGED;
}
else if (pReplacedEntry)
{
@@ -1421,7 +1448,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsAdd(PVBOXVR_COMPOSITOR pCompositor
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT * paRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRects, PCRTRECT paRects, bool *pfChanged)
{
if (!pEntry)
{
@@ -1450,7 +1478,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSubst(PVBOXVR_COMPOSITOR pComposit
return rc;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRects, PCRTRECT paRects, bool *pfChanged)
{
if (!pEntry)
{
@@ -1483,7 +1512,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsSet(PVBOXVR_COMPOSITOR pCompositor
return VINF_SUCCESS;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, const VBOXVR_LIST *pList2, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ PCVBOXVR_LIST pList2, bool *pfChanged)
{
int rc = VINF_SUCCESS;
bool fChanged = false;
@@ -1515,7 +1545,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersect(PVBOXVR_COMPOSITOR pComposi
return rc;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, uint32_t cRects, const RTRECT *paRects, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ uint32_t cRects, PCRTRECT paRects, bool *pfChanged)
{
int rc = VINF_SUCCESS;
bool fChanged = false;
@@ -1547,7 +1578,7 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersect(PVBOXVR_COMPOSITOR pComp
return rc;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, const VBOXVR_LIST *pList2, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pCompositor, PCVBOXVR_LIST pList2, bool *pfChanged)
{
VBOXVR_COMPOSITOR_ITERATOR Iter;
VBoxVrCompositorIterInit(pCompositor, &Iter);
@@ -1576,7 +1607,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryListIntersectAll(PVBOXVR_COMPOSITOR pComp
return rc;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pCompositor, uint32_t cRegions, PCRTRECT paRegions,
+ bool *pfChanged)
{
VBOXVR_COMPOSITOR_ITERATOR Iter;
VBoxVrCompositorIterInit(pCompositor, &Iter);
@@ -1605,7 +1637,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsIntersectAll(PVBOXVR_COMPOSITOR pC
return rc;
}
-VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry, int32_t x, int32_t y, bool *pfChanged)
+VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pEntry,
+ int32_t x, int32_t y, bool *pfChanged)
{
if (!pEntry)
{
@@ -1617,8 +1650,8 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pComp
vboxVrCompositorEntryAddRef(pEntry);
- if ((!x && !y)
- || !VBoxVrCompositorEntryIsInList(pEntry))
+ if ( (!x && !y)
+ || !VBoxVrCompositorEntryIsInList(pEntry))
{
if (pfChanged)
*pfChanged = false;
@@ -1633,7 +1666,7 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pComp
PVBOXVR_COMPOSITOR_ENTRY pCur;
uint32_t cRects = 0;
- RTRECT *paRects = NULL;
+ PRTRECT paRects = NULL;
int rc = VINF_SUCCESS;
RTListForEach(&pCompositor->List, pCur, VBOXVR_COMPOSITOR_ENTRY, Node)
{
@@ -1646,7 +1679,7 @@ VBOXVREGDECL(int) VBoxVrCompositorEntryRegionsTranslate(PVBOXVR_COMPOSITOR pComp
{
cRects = VBoxVrListRectsCount(&pEntry->Vr);
Assert(cRects);
- paRects = (RTRECT*)RTMemAlloc(cRects * sizeof (RTRECT));
+ paRects = (RTRECT*)RTMemAlloc(cRects * sizeof(RTRECT));
if (!paRects)
{
WARN(("RTMemAlloc failed!"));
@@ -1690,3 +1723,4 @@ VBOXVREGDECL(void) VBoxVrCompositorVisit(PVBOXVR_COMPOSITOR pCompositor, PFNVBOX
return;
}
}
+
diff --git a/src/VBox/HostDrivers/Support/Makefile.kmk b/src/VBox/HostDrivers/Support/Makefile.kmk
index 819eae5..993628a 100644
--- a/src/VBox/HostDrivers/Support/Makefile.kmk
+++ b/src/VBox/HostDrivers/Support/Makefile.kmk
@@ -84,7 +84,8 @@ VBOX_SUP_WIN_CERTS := \
SpcRootMicrosoft3=SpcRoot-MicrosoftRootCertificateAuthority2010-28cc3a25bfba44ac449a9b586b4339aa.taf \
SpcRootMicrosoft4=SpcRoot-MicrosoftRootCertificateAuthority2011-3f8bc8b5fc9fb29643b569d66c42e144.taf \
SpcRootMicrosoft5=SpcRoot-MicrosoftDigitalMediaAuthority2005-6eff330eb6e7569740680870104baaba.taf \
- NtRootMicrosoft6=NtRoot-MicrosoftCodeVerificationRoot-729404101f3e0ca347837fca175a8438.taf \
+ SpcRootMicrosoft6=SpcRoot-MicrosoftDevelopmentRootCertificateAuthority2014-078f0a9d03df119e434e4fec1bf0235a.taf \
+ NtRootMicrosoft7=NtRoot-MicrosoftCodeVerificationRoot-729404101f3e0ca347837fca175a8438.taf \
TimeRootMicrosoft0=Timestamp-CopyrightC1997MicrosoftCorp-01.taf \
TrustedCertVBox0=Trusted-OracleCorporationVirtualBox-51ca009816fdbd80f120e015ee75823e.taf
VBOX_SUP_WIN_CERT_NAMES := $(foreach cert,$(VBOX_SUP_WIN_CERTS),$(firstword $(subst =,$(SPACE) ,$(cert))))
@@ -117,7 +118,7 @@ $$(VBOX_SUP_WIN_CERTS_FILE): $(MAKEFILE_CURRENT) \
"$(VBOX_PATH_SUPR3_CERTIFICATES)/$(lastword $(subst =,$(SP) ,$(cert)))" \
"$@")
# The build certificate.
-if "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING)
+if "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING) && defined(VBOX_SIGNING_MODE)
$(VBOX_RTSIGNTOOL) extract-exe-signer-cert --exe $(VBOX_RTSIGNTOOL) --output "$@.cer" --der
$(VBOX_BIN2C) -ascii --append SUPBuildCert "$@.cer" $@
$(QUIET)$(RM) -f -- $@.cer
@@ -410,6 +411,8 @@ VBoxSupLib_DEFS = \
$(if $(VBOX_WITHOUT_DEBUGGER_CHECKS),VBOX_WITHOUT_DEBUGGER_CHECKS,)
VBoxSupLib_SOURCES = \
$(KBUILD_TARGET)/VBoxSupLib-$(KBUILD_TARGET).cpp
+VBoxSupLib_SOURCES.win = \
+ win/VBoxSupLib.rc
VBoxSupLib_LIBS.win.x86 = \
$(PATH_TOOL_$(TEMPLATE_VBOXR3STATIC_TOOL.win.x86)_LIB)/libcmt$(VBOX_VCC_CRT_TYPE).lib # for __chkstk
VBoxSupLib_LIBS.win.amd64 = \
diff --git a/src/VBox/HostDrivers/Support/SUPDrv.c b/src/VBox/HostDrivers/Support/SUPDrv.c
index 68bf229..faf4bdc 100644
--- a/src/VBox/HostDrivers/Support/SUPDrv.c
+++ b/src/VBox/HostDrivers/Support/SUPDrv.c
@@ -114,6 +114,7 @@ static int supdrvMemRelease(PSUPDRVSESSION pSession, RTHCUINTPT
static int supdrvIOCtl_LdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPLDROPEN pReq);
static int supdrvIOCtl_LdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPLDRLOAD pReq);
static int supdrvIOCtl_LdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPLDRFREE pReq);
+static int supdrvIOCtl_LdrLockDown(PSUPDRVDEVEXT pDevExt);
static int supdrvIOCtl_LdrGetSymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPLDRGETSYMBOL pReq);
static int supdrvIDC_LdrGetSymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPDRVIDCREQGETSYM pReq);
static int supdrvLdrSetVMMR0EPs(PSUPDRVDEVEXT pDevExt, void *pvVMMR0, void *pvVMMR0EntryInt, void *pvVMMR0EntryFast, void *pvVMMR0EntryEx);
@@ -130,7 +131,7 @@ static DECLCALLBACK(void) supdrvGipSyncTimer(PRTTIMER pTimer, void *pvUser, ui
static DECLCALLBACK(void) supdrvGipAsyncTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
static DECLCALLBACK(void) supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser);
static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys,
- uint64_t u64NanoTS, unsigned uUpdateHz, unsigned cCpus);
+ uint64_t u64NanoTS, unsigned uUpdateHz, unsigned uUpdateIntervalNS, unsigned cCpus);
static DECLCALLBACK(void) supdrvGipInitOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2);
static void supdrvGipTerm(PSUPGLOBALINFOPAGE pGip);
static void supdrvGipUpdate(PSUPDRVDEVEXT pDevExt, uint64_t u64NanoTS, uint64_t u64TSC, RTCPUID idCpu, uint64_t iTick);
@@ -145,6 +146,9 @@ static int supdrvIOCtl_ResumeSuspendedKbds(void);
*******************************************************************************/
DECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage = NULL;
+/** Whether the host system has an invariant TSC or not */
+static bool g_fIsInvariantTsc;
+
/**
* Array of the R0 SUP API.
*/
@@ -1670,6 +1674,16 @@ static int supdrvIOCtlInnerUnrestricted(uintptr_t uIOCtl, PSUPDRVDEVEXT pDevExt,
return 0;
}
+ case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_LDR_LOCK_DOWN):
+ {
+ /* validate */
+ REQ_CHECK_SIZES(SUP_IOCTL_LDR_LOCK_DOWN);
+
+ /* execute */
+ pReqHdr->rc = supdrvIOCtl_LdrLockDown(pDevExt);
+ return 0;
+ }
+
case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_LDR_GET_SYMBOL):
{
/* validate */
@@ -3843,6 +3857,49 @@ static DECLCALLBACK(void) supdrvGipReInitCpuCallback(RTCPUID idCpu, void *pvUser
/**
+ * Increase the timer freqency on hosts where this is possible (NT).
+ *
+ * The idea is that more interrupts is better for us... Also, it's better than
+ * we increase the timer frequence, because we might end up getting inaccuract
+ * callbacks if someone else does it.
+ *
+ * @param pDevExt Sets u32SystemTimerGranularityGrant if increased.
+ */
+static void supdrvGipRequestHigherTimerFrequencyFromSystem(PSUPDRVDEVEXT pDevExt)
+{
+ if (pDevExt->u32SystemTimerGranularityGrant == 0)
+ {
+ uint32_t u32SystemResolution;
+ if ( RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 976563 /* 1024 HZ */, &u32SystemResolution))
+ || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1000000 /* 1000 HZ */, &u32SystemResolution))
+ || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1953125 /* 512 HZ */, &u32SystemResolution))
+ || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 2000000 /* 500 HZ */, &u32SystemResolution))
+ )
+ {
+ Assert(RTTimerGetSystemGranularity() <= u32SystemResolution);
+ pDevExt->u32SystemTimerGranularityGrant = u32SystemResolution;
+ }
+ }
+}
+
+
+/**
+ * Undoes supdrvGipRequestHigherTimerFrequencyFromSystem.
+ *
+ * @param pDevExt Clears u32SystemTimerGranularityGrant.
+ */
+static void supdrvGipReleaseHigherTimerFrequencyFromSystem(PSUPDRVDEVEXT pDevExt)
+{
+ if (pDevExt->u32SystemTimerGranularityGrant)
+ {
+ int rc2 = RTTimerReleaseSystemGranularity(pDevExt->u32SystemTimerGranularityGrant);
+ AssertRC(rc2);
+ pDevExt->u32SystemTimerGranularityGrant = 0;
+ }
+}
+
+
+/**
* Maps the GIP into userspace and/or get the physical address of the GIP.
*
* @returns IPRT status code.
@@ -3906,27 +3963,14 @@ SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS
{
PSUPGLOBALINFOPAGE pGipR0 = pDevExt->pGip;
uint64_t u64NanoTS;
- uint32_t u32SystemResolution;
- unsigned i;
LogFlow(("SUPR0GipMap: Resumes GIP updating\n"));
- /*
- * Try bump up the system timer resolution.
- * The more interrupts the better...
- */
- if ( RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 976563 /* 1024 HZ */, &u32SystemResolution))
- || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1000000 /* 1000 HZ */, &u32SystemResolution))
- || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 1953125 /* 512 HZ */, &u32SystemResolution))
- || RT_SUCCESS_NP(RTTimerRequestSystemGranularity( 2000000 /* 500 HZ */, &u32SystemResolution))
- )
- {
- Assert(RTTimerGetSystemGranularity() <= u32SystemResolution);
- pDevExt->u32SystemTimerGranularityGrant = u32SystemResolution;
- }
+ supdrvGipRequestHigherTimerFrequencyFromSystem(pDevExt);
if (pGipR0->aCPUs[0].u32TransactionId != 2 /* not the first time */)
{
+ unsigned i;
for (i = 0; i < RT_ELEMENTS(pGipR0->aCPUs); i++)
ASMAtomicUoWriteU32(&pGipR0->aCPUs[i].u32TransactionId,
(pGipR0->aCPUs[i].u32TransactionId + GIP_UPDATEHZ_RECALC_FREQ * 2)
@@ -4027,13 +4071,7 @@ SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession)
#ifndef DO_NOT_START_GIP
rc = RTTimerStop(pDevExt->pGipTimer); AssertRC(rc); rc = VINF_SUCCESS;
#endif
-
- if (pDevExt->u32SystemTimerGranularityGrant)
- {
- int rc2 = RTTimerReleaseSystemGranularity(pDevExt->u32SystemTimerGranularityGrant);
- AssertRC(rc2);
- pDevExt->u32SystemTimerGranularityGrant = 0;
- }
+ supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt);
}
}
@@ -4443,6 +4481,14 @@ static int supdrvIOCtl_LdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, P
}
/* (not found - add it!) */
+ /* If the loader interface is locked down, make userland fail early */
+ if (pDevExt->fLdrLockedDown)
+ {
+ supdrvLdrUnlock(pDevExt);
+ Log(("supdrvIOCtl_LdrOpen: Not adding '%s' to image list, loader interface is locked down!\n", pReq->u.In.szName));
+ return VERR_PERMISSION_DENIED;
+ }
+
/*
* Allocate memory.
*/
@@ -4608,6 +4654,14 @@ static int supdrvIOCtl_LdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, P
return VERR_ALREADY_LOADED;
}
+ /* If the loader interface is locked down, don't load new images */
+ if (pDevExt->fLdrLockedDown)
+ {
+ supdrvLdrUnlock(pDevExt);
+ Log(("SUP_IOCTL_LDR_LOAD: Not loading '%s' image bits, loader interface is locked down!\n", pImage->szName));
+ return VERR_PERMISSION_DENIED;
+ }
+
switch (pReq->u.In.eEPType)
{
case SUPLDRLOADEP_NOTHING:
@@ -4869,6 +4923,28 @@ static int supdrvIOCtl_LdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, P
/**
+ * Lock down the image loader interface.
+ *
+ * @returns IPRT status code.
+ * @param pDevExt Device globals.
+ */
+static int supdrvIOCtl_LdrLockDown(PSUPDRVDEVEXT pDevExt)
+{
+ LogFlow(("supdrvIOCtl_LdrLockDown:\n"));
+
+ supdrvLdrLock(pDevExt);
+ if (!pDevExt->fLdrLockedDown)
+ {
+ pDevExt->fLdrLockedDown = true;
+ Log(("supdrvIOCtl_LdrLockDown: Image loader interface locked down\n"));
+ }
+ supdrvLdrUnlock(pDevExt);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
* Gets the address of a symbol in an open image.
*
* @returns IPRT status code.
@@ -5138,6 +5214,13 @@ static void supdrvLdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
PSUPDRVLDRIMAGE pImagePrev;
LogFlow(("supdrvLdrFree: pImage=%p\n", pImage));
+ /*
+ * Warn if we're releasing images while the image loader interface is
+ * locked down -- we won't be able to reload them!
+ */
+ if (pDevExt->fLdrLockedDown)
+ Log(("supdrvLdrFree: Warning: unloading '%s' image, while loader interface is locked down!\n", pImage->szName));
+
/* find it - arg. should've used doubly linked list. */
Assert(pDevExt->pLdrImages);
pImagePrev = NULL;
@@ -5436,6 +5519,28 @@ static int supdrvIOCtl_LoggerSettings(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSes
/**
+ * Determines whether the host system has an invariant TSC.
+ *
+ * @remarks Once, called use g_fIsInvariantTsc. It is not
+ * expected to change at runtime.
+ */
+static void supdrvDetermineInvariantTsc(void)
+{
+ if (ASMHasCpuId())
+ {
+ uint32_t uEax, uEbx, uEcx, uEdx;
+ ASMCpuId(0x80000000, &uEax, &uEbx, &uEcx, &uEdx);
+ if (uEax >= 0x80000007)
+ {
+ ASMCpuId(0x80000007, &uEax, &uEbx, &uEcx, &uEdx);
+ if (uEdx & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR)
+ g_fIsInvariantTsc = true;
+ }
+ }
+}
+
+
+/**
* Creates the GIP.
*
* @returns VBox status code.
@@ -5481,14 +5586,17 @@ static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt)
pGip = (PSUPGLOBALINFOPAGE)RTR0MemObjAddress(pDevExt->GipMemObj); AssertPtr(pGip);
HCPhysGip = RTR0MemObjGetPagePhysAddr(pDevExt->GipMemObj, 0); Assert(HCPhysGip != NIL_RTHCPHYS);
+ supdrvDetermineInvariantTsc();
+
/*
* Find a reasonable update interval and initialize the structure.
*/
+ supdrvGipRequestHigherTimerFrequencyFromSystem(pDevExt);
u32Interval = u32SystemResolution = RTTimerGetSystemGranularity();
while (u32Interval < 10000000 /* 10 ms */)
u32Interval += u32SystemResolution;
- supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), 1000000000 / u32Interval /*=Hz*/, cCpus);
+ supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), RT_NS_1SEC / u32Interval /*=Hz*/, u32Interval, cCpus);
/*
* Create the timer.
@@ -5517,6 +5625,8 @@ static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt)
* We're good.
*/
Log(("supdrvGipCreate: %u ns interval.\n", u32Interval));
+ supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt);
+
g_pSUPGlobalInfoPage = pGip;
return VINF_SUCCESS;
}
@@ -5533,7 +5643,7 @@ static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt)
OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc));
Assert(!pDevExt->pGipTimer);
}
- supdrvGipDestroy(pDevExt);
+ supdrvGipDestroy(pDevExt); /* Releases timer frequency increase too. */
return rc;
}
@@ -5581,11 +5691,7 @@ static void supdrvGipDestroy(PSUPDRVDEVEXT pDevExt)
* Finally, make sure we've release the system timer resolution request
* if one actually succeeded and is still pending.
*/
- if (pDevExt->u32SystemTimerGranularityGrant)
- {
- rc = RTTimerReleaseSystemGranularity(pDevExt->u32SystemTimerGranularityGrant); AssertRC(rc);
- pDevExt->u32SystemTimerGranularityGrant = 0;
- }
+ supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt);
}
@@ -5596,10 +5702,14 @@ static void supdrvGipDestroy(PSUPDRVDEVEXT pDevExt)
*/
static DECLCALLBACK(void) supdrvGipSyncTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick)
{
- RTCCUINTREG fOldFlags = ASMIntDisableFlags(); /* No interruptions please (real problem on S10). */
- PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
- uint64_t u64TSC = ASMReadTSC();
- uint64_t NanoTS = RTTimeSystemNanoTS();
+ RTCCUINTREG fOldFlags;
+ uint64_t u64TSC;
+ uint64_t NanoTS;
+ PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
+
+ fOldFlags = ASMIntDisableFlags(); /* No interruptions please (real problem on S10). */
+ u64TSC = ASMReadTSC();
+ NanoTS = RTTimeSystemNanoTS();
supdrvGipUpdate(pDevExt, NanoTS, u64TSC, NIL_RTCPUID, iTick);
@@ -6029,15 +6139,16 @@ static void supdrvGipInitCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pCpu, uint64_t
/**
* Initializes the GIP data.
*
- * @param pDevExt Pointer to the device instance data.
- * @param pGip Pointer to the read-write kernel mapping of the GIP.
- * @param HCPhys The physical address of the GIP.
- * @param u64NanoTS The current nanosecond timestamp.
- * @param uUpdateHz The update frequency.
- * @param cCpus The CPU count.
+ * @param pDevExt Pointer to the device instance data.
+ * @param pGip Pointer to the read-write kernel mapping of the GIP.
+ * @param HCPhys The physical address of the GIP.
+ * @param u64NanoTS The current nanosecond timestamp.
+ * @param uUpdateHz The update frequency.
+ * @param uUpdateIntervalNS The update interval in nanoseconds.
+ * @param cCpus The CPU count.
*/
static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys,
- uint64_t u64NanoTS, unsigned uUpdateHz, unsigned cCpus)
+ uint64_t u64NanoTS, unsigned uUpdateHz, unsigned uUpdateIntervalNS, unsigned cCpus)
{
size_t const cbGip = RT_ALIGN_Z(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]), PAGE_SIZE);
unsigned i;
@@ -6057,8 +6168,8 @@ static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPH
pGip->cCpus = (uint16_t)cCpus;
pGip->cPages = (uint16_t)(cbGip / PAGE_SIZE);
pGip->u32UpdateHz = uUpdateHz;
- pGip->u32UpdateIntervalNS = 1000000000 / uUpdateHz;
- pGip->u64NanoTSLastUpdateHz = u64NanoTS;
+ pGip->u32UpdateIntervalNS = uUpdateIntervalNS;
+ pGip->u64NanoTSLastUpdateHz = 0;
RTCpuSetEmpty(&pGip->OnlineCpuSet);
RTCpuSetEmpty(&pGip->PresentCpuSet);
RTMpGetSet(&pGip->PossibleCpuSet);
@@ -6149,7 +6260,6 @@ static void supdrvGipDoUpdateCpu(PSUPDRVDEVEXT pDevExt, PSUPGIPCPU pGipCpu, uint
/*
* Calc TSC delta.
*/
- /** @todo validate the NanoTS delta, don't trust the OS to call us when it should... */
u64TSCDelta = u64TSC - pGipCpu->u64TSC;
ASMAtomicWriteU64(&pGipCpu->u64TSC, u64TSC);
@@ -6177,6 +6287,36 @@ static void supdrvGipDoUpdateCpu(PSUPDRVDEVEXT pDevExt, PSUPGIPCPU pGipCpu, uint
}
/*
+ * Validate the NanoTS deltas between timer fires with an arbitrary threshold of 0.5%.
+ * Wait until we have at least one full history since the above history reset. The
+ * assumption is that the majority of the previous history values will be tolerable.
+ * See @bugref{6710} comment #67.
+ */
+ if ( u32TransactionId > 23 /* 7 + (8 * 2) */
+ && g_fIsInvariantTsc
+ && pGip->u32Mode == SUPGIPMODE_SYNC_TSC)
+ {
+ uint32_t uNanoTsThreshold = pGip->u32UpdateIntervalNS / 200;
+ if ( pGipCpu->u32PrevUpdateIntervalNS > pGip->u32UpdateIntervalNS + uNanoTsThreshold
+ || pGipCpu->u32PrevUpdateIntervalNS < pGip->u32UpdateIntervalNS - uNanoTsThreshold)
+ {
+ uint32_t u32;
+ u32 = pGipCpu->au32TSCHistory[0];
+ u32 += pGipCpu->au32TSCHistory[1];
+ u32 += pGipCpu->au32TSCHistory[2];
+ u32 += pGipCpu->au32TSCHistory[3];
+ u32 >>= 2;
+ u64TSCDelta = pGipCpu->au32TSCHistory[4];
+ u64TSCDelta += pGipCpu->au32TSCHistory[5];
+ u64TSCDelta += pGipCpu->au32TSCHistory[6];
+ u64TSCDelta += pGipCpu->au32TSCHistory[7];
+ u64TSCDelta >>= 2;
+ u64TSCDelta += u32;
+ u64TSCDelta >>= 1;
+ }
+ }
+
+ /*
* TSC History.
*/
Assert(RT_ELEMENTS(pGipCpu->au32TSCHistory) == 8);
@@ -6227,7 +6367,8 @@ static void supdrvGipDoUpdateCpu(PSUPDRVDEVEXT pDevExt, PSUPGIPCPU pGipCpu, uint
/*
* CpuHz.
*/
- u64CpuHz = ASMMult2xU32RetU64(u32UpdateIntervalTSC, pGip->u32UpdateHz);
+ u64CpuHz = ASMMult2xU32RetU64(u32UpdateIntervalTSC, RT_NS_1SEC);
+ u64CpuHz /= pGip->u32UpdateIntervalNS;
ASMAtomicWriteU64(&pGipCpu->u64CpuHz, u64CpuHz);
}
@@ -6283,15 +6424,16 @@ static void supdrvGipUpdate(PSUPDRVDEVEXT pDevExt, uint64_t u64NanoTS, uint64_t
{
#ifdef RT_ARCH_AMD64 /** @todo fix 64-bit div here to work on x86 linux. */
uint64_t u64Delta = u64NanoTS - pGip->u64NanoTSLastUpdateHz;
- uint32_t u32UpdateHz = (uint32_t)((UINT64_C(1000000000) * GIP_UPDATEHZ_RECALC_FREQ) / u64Delta);
+ uint32_t u32UpdateHz = (uint32_t)((RT_NS_1SEC_64 * GIP_UPDATEHZ_RECALC_FREQ) / u64Delta);
if (u32UpdateHz <= 2000 && u32UpdateHz >= 30)
{
+ uint64_t u64Interval = u64Delta / GIP_UPDATEHZ_RECALC_FREQ;
ASMAtomicWriteU32(&pGip->u32UpdateHz, u32UpdateHz);
- ASMAtomicWriteU32(&pGip->u32UpdateIntervalNS, 1000000000 / u32UpdateHz);
+ ASMAtomicWriteU32(&pGip->u32UpdateIntervalNS, (uint32_t)u64Interval);
}
#endif
}
- ASMAtomicWriteU64(&pGip->u64NanoTSLastUpdateHz, u64NanoTS);
+ ASMAtomicWriteU64(&pGip->u64NanoTSLastUpdateHz, u64NanoTS | 1);
}
/*
diff --git a/src/VBox/HostDrivers/Support/SUPDrvIOC.h b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
index 17b05a3..7bdee56 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvIOC.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvIOC.h
@@ -1,4 +1,4 @@
-/* $Revision: 96490 $ */
+/* $Revision: 98021 $ */
/** @file
* VirtualBox Support Driver - IOCtl definitions.
*/
@@ -210,7 +210,7 @@ typedef SUPREQHDR *PSUPREQHDR;
* @todo Pending work on next major version change:
* - Remove RTSpinlockReleaseNoInts.
*/
-#define SUPDRV_IOC_VERSION 0x001a0008
+#define SUPDRV_IOC_VERSION 0x001a0009
/** SUP_IOCTL_COOKIE. */
typedef struct SUPCOOKIE
@@ -475,6 +475,17 @@ typedef struct SUPLDRFREE
/** @} */
+/** @name SUP_IOCTL_LDR_LOCK_DOWN
+ * Lock down the image loader interface.
+ * @{
+ */
+#define SUP_IOCTL_LDR_LOCK_DOWN SUP_CTL_CODE_SIZE(38, SUP_IOCTL_LDR_LOCK_DOWN_SIZE)
+#define SUP_IOCTL_LDR_LOCK_DOWN_SIZE sizeof(SUPREQHDR)
+#define SUP_IOCTL_LDR_LOCK_DOWN_SIZE_IN sizeof(SUPREQHDR)
+#define SUP_IOCTL_LDR_LOCK_DOWN_SIZE_OUT sizeof(SUPREQHDR)
+/** @} */
+
+
/** @name SUP_IOCTL_LDR_GET_SYMBOL
* Get address of a symbol within an image.
* @{
diff --git a/src/VBox/HostDrivers/Support/SUPDrvInternal.h b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
index 950e9e2..f7dbd28 100644
--- a/src/VBox/HostDrivers/Support/SUPDrvInternal.h
+++ b/src/VBox/HostDrivers/Support/SUPDrvInternal.h
@@ -548,6 +548,8 @@ typedef struct SUPDRVDEVEXT
/** Linked list of loaded code. */
PSUPDRVLDRIMAGE volatile pLdrImages;
+ /** Set if the image loading interface got disabled after loading all needed images */
+ bool fLdrLockedDown;
/** @name These members for detecting whether an API caller is in ModuleInit.
* Certain APIs are only permitted from ModuleInit, like for instance tracepoint
diff --git a/src/VBox/HostDrivers/Support/SUPLib.cpp b/src/VBox/HostDrivers/Support/SUPLib.cpp
index beb357f..a032787 100644
--- a/src/VBox/HostDrivers/Support/SUPLib.cpp
+++ b/src/VBox/HostDrivers/Support/SUPLib.cpp
@@ -279,7 +279,7 @@ SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession)
strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x001a0000
- ? 0x001a0008
+ ? 0x001a0009
: SUPDRV_IOC_VERSION & 0xffff0000;
CookieReq.u.In.u32MinVersion = uMinVersion;
rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
@@ -1038,6 +1038,31 @@ SUPR3DECL(int) supR3PageUnlock(void *pvStart)
}
+SUPR3DECL(int) SUPR3LockDownLoader(PRTERRINFO pErrInfo)
+{
+ /* fake */
+ if (RT_UNLIKELY(g_u32FakeMode))
+ return VINF_SUCCESS;
+
+ /*
+ * Lock down the module loader interface.
+ */
+ SUPREQHDR ReqHdr;
+ ReqHdr.u32Cookie = g_u32Cookie;
+ ReqHdr.u32SessionCookie = g_u32SessionCookie;
+ ReqHdr.cbIn = SUP_IOCTL_LDR_LOCK_DOWN_SIZE_IN;
+ ReqHdr.cbOut = SUP_IOCTL_LDR_LOCK_DOWN_SIZE_OUT;
+ ReqHdr.fFlags = SUPREQHDR_FLAGS_DEFAULT;
+ ReqHdr.rc = VERR_INTERNAL_ERROR;
+ int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_LOCK_DOWN, &ReqHdr, SUP_IOCTL_LDR_LOCK_DOWN_SIZE);
+ if (RT_FAILURE(rc))
+ return RTErrInfoSetF(pErrInfo, rc,
+ "SUPR3LockDownLoader: SUP_IOCTL_LDR_LOCK_DOWN ioctl returned %Rrc", rc);
+
+ return ReqHdr.rc;
+}
+
+
/**
* Fallback for SUPR3PageAllocEx on systems where RTR0MemObjPhysAllocNC isn't
* supported.
diff --git a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
index 4ef40f9..6696d11 100644
--- a/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
+++ b/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
@@ -1,4 +1,4 @@
-/* $Rev: 95888 $ */
+/* $Rev: 98176 $ */
/** @file
* VBoxDrv - The VirtualBox Support Driver - Linux specifics.
*/
@@ -48,6 +48,12 @@
# include <iprt/power.h>
# define VBOX_WITH_SUSPEND_NOTIFICATION
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
+# include <asm/smap.h>
+#else
+static inline void clac(void) { }
+static inline void stac(void) { }
+#endif
#include <linux/sched.h>
#ifdef CONFIG_DEVFS_FS
@@ -622,6 +628,7 @@ static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned
#endif
{
PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFilp->private_data;
+ int rc;
/*
* Deal with the two high-speed IOCtl that takes it's arguments from
@@ -632,12 +639,15 @@ static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned
|| uCmd == SUP_IOCTL_FAST_DO_HM_RUN
|| uCmd == SUP_IOCTL_FAST_DO_NOP)
&& pSession->fUnrestricted == true))
- return supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, pSession);
+ {
+ stac();
+ rc = supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, pSession);
+ clac();
+ return rc;
+ }
return VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg, pSession);
#else /* !HAVE_UNLOCKED_IOCTL */
-
- int rc;
unlock_kernel();
if (RT_LIKELY( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN
|| uCmd == SUP_IOCTL_FAST_DO_HM_RUN
@@ -715,7 +725,9 @@ static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned
/*
* Process the IOCtl.
*/
+ stac();
rc = supdrvIOCtl(uCmd, &g_DevExt, pSession, pHdr, cbBuf);
+ clac();
/*
* Copy ioctl data and output buffer back to user space.
diff --git a/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp b/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
index 37dfe0f..a3599e3 100644
--- a/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
+++ b/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
@@ -31,6 +31,8 @@
#include <VBox/err.h>
#include <VBox/param.h>
#include <iprt/asm.h>
+#include <iprt/x86.h>
+#include <iprt/asm-amd64-x86.h>
#include <iprt/assert.h>
#include <iprt/alloc.h>
#include <iprt/thread.h>
@@ -40,6 +42,28 @@
#include <iprt/getopt.h>
+/**
+ * Checks whether the CPU advertises an invariant TSC or not.
+ *
+ * @returns true if invariant, false otherwise.
+ */
+bool tstIsInvariantTsc(void)
+{
+ if (ASMHasCpuId())
+ {
+ uint32_t uEax, uEbx, uEcx, uEdx;
+ ASMCpuId(0x80000000, &uEax, &uEbx, &uEcx, &uEdx);
+ if (uEax >= 0x80000007)
+ {
+ ASMCpuId(0x80000007, &uEax, &uEbx, &uEcx, &uEdx);
+ if (uEdx & X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR)
+ return true;
+ }
+ }
+ return false;
+}
+
+
int main(int argc, char **argv)
{
RTR3InitExe(argc, &argv, 0);
@@ -63,6 +87,7 @@ int main(int argc, char **argv)
int ch;
uint64_t uCpuHzRef = 0;
uint64_t uCpuHzOverallDeviation = 0;
+ int64_t iCpuHzMaxDeviation = 0;
uint32_t cCpuHzOverallDevCnt = 0;
RTGETOPTUNION ValueUnion;
RTGETOPTSTATE GetState;
@@ -144,14 +169,16 @@ int main(int argc, char **argv)
RTStrPrintf(szCpuHzDeviation, sizeof(szCpuHzDeviation), "%17s ", "?");
else
{
- if (pCpu->u32TransactionId > 7)
+ if (pCpu->u32TransactionId > 23 + (8 * 2) + 1) /* Wait until the history validation code takes effect. */
{
+ if (RT_ABS(iCpuHzDeviation) > RT_ABS(iCpuHzMaxDeviation))
+ iCpuHzMaxDeviation = iCpuHzDeviation;
uCpuHzOverallDeviation += uCpuHzDeviation;
cCpuHzOverallDevCnt++;
}
uint32_t uPct = (uint32_t)(uCpuHzDeviation * 100000 / uCpuHzRef + 5);
RTStrPrintf(szCpuHzDeviation, sizeof(szCpuHzDeviation), "%10RI64%3d.%02d%% ",
- iCpuHzDeviation, uPct / 1000, (uPct % 1000) / 10);
+ iCpuHzDeviation, uPct / 1000, (uPct % 1000) / 10);
}
}
else
@@ -198,10 +225,14 @@ int main(int argc, char **argv)
RTThreadSleep(1);
}
}
- if (uCpuHzRef)
+ RTPrintf("CPUID.Invariant-TSC: %RTbool\n", tstIsInvariantTsc());
+ if ( uCpuHzRef
+ && cCpuHzOverallDevCnt)
{
- uint32_t uPct = (uint32_t)(uCpuHzOverallDeviation * 100000 / cCpuHzOverallDevCnt / uCpuHzRef + 5);
- RTPrintf("Overall CpuHz deviation: %d.%02d%%\n", uPct / 1000, (uPct % 1000) / 10);
+ uint32_t uPct = (uint32_t)(uCpuHzOverallDeviation * 100000 / cCpuHzOverallDevCnt / uCpuHzRef + 5);
+ uint32_t uMaxPct = (uint32_t)(RT_ABS(iCpuHzMaxDeviation) * 100000 / uCpuHzRef + 5);
+ RTPrintf("Average CpuHz deviation: %d.%02d%%\n", uPct / 1000, (uPct % 1000) / 10);
+ RTPrintf("Maximum CpuHz deviation: %d.%02d%% (%RI64 ticks)\n", uMaxPct / 1000, (uMaxPct % 1000) / 10, iCpuHzMaxDeviation);
}
}
else
diff --git a/src/VBox/HostDrivers/Support/win/Certificates/SpcRoot-MicrosoftDevelopmentRootCertificateAuthority2014-078f0a9d03df119e434e4fec1bf0235a.taf b/src/VBox/HostDrivers/Support/win/Certificates/SpcRoot-MicrosoftDevelopmentRootCertificateAuthority2014-078f0a9d03df119e434e4fec1bf0235a.taf
new file mode 100644
index 0000000..f2fa96a
Binary files /dev/null and b/src/VBox/HostDrivers/Support/win/Certificates/SpcRoot-MicrosoftDevelopmentRootCertificateAuthority2014-078f0a9d03df119e434e4fec1bf0235a.taf differ
diff --git a/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp b/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
index 4d296a1..c8a15ed 100644
--- a/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
@@ -1232,11 +1232,12 @@ DECLHIDDEN(int) supHardenedWinVerifyImageByHandle(HANDLE hFile, PCRTUTF16 pwszNa
/*
* Open the image.
*/
- RTLDRMOD hLdrMod;
- RTLDRARCH enmArch = fFlags & SUPHNTVI_F_RC_IMAGE ? RTLDRARCH_X86_32 : RTLDRARCH_HOST;
+ RTLDRMOD hLdrMod;
+ RTLDRARCH enmArch = fFlags & SUPHNTVI_F_RC_IMAGE ? RTLDRARCH_X86_32 : RTLDRARCH_HOST;
+ uint32_t fLdrFlags = RTLDR_O_FOR_VALIDATION | RTLDR_O_IGNORE_ARCH_IF_NO_CODE;
if (fFlags & SUPHNTVI_F_IGNORE_ARCHITECTURE)
- enmArch = RTLDRARCH_WHATEVER;
- rc = RTLdrOpenWithReader(&pNtViRdr->Core, RTLDR_O_FOR_VALIDATION, enmArch, &hLdrMod, pErrInfo);
+ fLdrFlags |= RTLDR_O_IGNORE_ARCH_IF_NO_CODE;
+ rc = RTLdrOpenWithReader(&pNtViRdr->Core, fLdrFlags, enmArch, &hLdrMod, pErrInfo);
if (RT_SUCCESS(rc))
{
/*
diff --git a/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp b/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
index 87418c4..32c747c 100644
--- a/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
+++ b/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
@@ -1796,6 +1796,7 @@ supR3HardenedMonitor_LdrLoadDll(PWSTR pwszSearchPath, PULONG pfFlags, PUNICODE_S
*/
NTSTATUS rcNtResolve = STATUS_SUCCESS;
bool fSkipValidation = false;
+ bool fCheckIfLoaded = false;
WCHAR wszPath[260];
static UNICODE_STRING const s_DefaultSuffix = RTNT_CONSTANT_UNISTR(L".dll");
UNICODE_STRING UniStrStatic = { 0, (USHORT)sizeof(wszPath) - sizeof(WCHAR), wszPath };
@@ -1932,6 +1933,8 @@ supR3HardenedMonitor_LdrLoadDll(PWSTR pwszSearchPath, PULONG pfFlags, PUNICODE_S
/*
* Search for the DLL. Only System32 is allowed as the target of
* a search on the API level, all VBox calls will have full paths.
+ * If the DLL is not in System32, we will resort to check if it's
+ * refering to an already loaded DLL (fCheckIfLoaded).
*/
AssertCompile(sizeof(g_System32WinPath.awcBuffer) <= sizeof(wszPath));
cwc = g_System32WinPath.UniStr.Length / sizeof(RTUTF16); Assert(cwc > 2);
@@ -1954,6 +1957,7 @@ supR3HardenedMonitor_LdrLoadDll(PWSTR pwszSearchPath, PULONG pfFlags, PUNICODE_S
memcpy(&wszPath[cwc], L".dll", 5 * sizeof(WCHAR));
cwc += 4;
}
+ fCheckIfLoaded = true;
}
ResolvedName.Buffer = wszPath;
@@ -2030,9 +2034,27 @@ supR3HardenedMonitor_LdrLoadDll(PWSTR pwszSearchPath, PULONG pfFlags, PUNICODE_S
else
{
DWORD dwErr = RtlGetLastWin32Error();
- SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: error opening '%ls': %u (NtPath=%.*ls; Input=%.*ls)\n",
+
+ /*
+ * Deal with special case where the caller (first case was MS LifeCam)
+ * is using LoadLibrary instead of GetModuleHandle to find a loaded DLL.
+ */
+ NTSTATUS rcNtGetDll = STATUS_SUCCESS;
+ if ( fCheckIfLoaded
+ && ( rcNt == STATUS_OBJECT_NAME_NOT_FOUND
+ || rcNt == STATUS_OBJECT_PATH_NOT_FOUND))
+ {
+ rcNtGetDll = LdrGetDllHandle(NULL /*DllPath*/, NULL /*pfFlags*/, pOrgName, phMod);
+ if (NT_SUCCESS(rcNtGetDll))
+ {
+ RtlRestoreLastWin32Error(dwSavedLastError);
+ return rcNtGetDll;
+ }
+ }
+
+ SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: error opening '%ls': %u (NtPath=%.*ls; Input=%.*ls; rcNtGetDll=%#x\n",
wszPath, dwErr, NtPathUniStr.Length / sizeof(RTUTF16), NtPathUniStr.Buffer,
- pOrgName->Length / sizeof(WCHAR), pOrgName->Buffer));
+ pOrgName->Length / sizeof(WCHAR), pOrgName->Buffer, rcNtGetDll));
}
RTNtPathFree(&NtPathUniStr, &hRootDir);
}
@@ -4085,11 +4107,17 @@ static void supR3HardenedWinDoReSpawn(int iWhich)
/*
* Apply anti debugger notification trick to the thread. (Also done in
* supR3HardenedWinInit.) This may fail with STATUS_ACCESS_DENIED and
- * maybe other errors.
+ * maybe other errors. (Unfortunately, recent (SEP 12.1) of symantec's
+ * sysplant.sys driver will cause process deadlocks and a shutdown/reboot
+ * denial of service problem if we hide the initial thread, so we postpone
+ * this action if we've detected SEP.)
*/
- rcNt = NtSetInformationThread(This.hThread, ThreadHideFromDebugger, NULL, 0);
- if (!NT_SUCCESS(rcNt))
- SUP_DPRINTF(("supR3HardenedWinReSpawn: NtSetInformationThread/ThreadHideFromDebugger failed: %#x (harmless)\n", rcNt));
+ if (!(g_fSupAdversaries & (SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT | SUPHARDNT_ADVERSARY_SYMANTEC_N360)))
+ {
+ rcNt = NtSetInformationThread(This.hThread, ThreadHideFromDebugger, NULL, 0);
+ if (!NT_SUCCESS(rcNt))
+ SUP_DPRINTF(("supR3HardenedWinReSpawn: NtSetInformationThread/ThreadHideFromDebugger failed: %#x (harmless)\n", rcNt));
+ }
#endif
/*
@@ -5078,6 +5106,8 @@ static uint32_t supR3HardenedWinFindAdversaries(void)
const char *pszDriver;
} s_aDrivers[] =
{
+ { SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT, "SysPlant" },
+
{ SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SRTSPX" },
{ SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SymDS" },
{ SUPHARDNT_ADVERSARY_SYMANTEC_N360, "SymEvent" },
@@ -5164,9 +5194,9 @@ static uint32_t supR3HardenedWinFindAdversaries(void)
PCRTUTF16 pwszFile;
} s_aFiles[] =
{
- { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\SysPlant.sys" },
- { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\sysfer.dll" },
- { SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\sysferThunk.dll" },
+ { SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT, L"\\SystemRoot\\System32\\drivers\\SysPlant.sys" },
+ { SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT, L"\\SystemRoot\\System32\\sysfer.dll" },
+ { SUPHARDNT_ADVERSARY_SYMANTEC_SYSPLANT, L"\\SystemRoot\\System32\\sysferThunk.dll" },
{ SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\ccsetx64.sys" },
{ SUPHARDNT_ADVERSARY_SYMANTEC_N360, L"\\SystemRoot\\System32\\drivers\\N360x64\\1505000.013\\ironx64.sys" },
diff --git a/src/VBox/HostDrivers/Support/win/VBoxDrv.rc b/src/VBox/HostDrivers/Support/win/VBoxDrv.rc
index 15c3490..c3543e2 100644
--- a/src/VBox/HostDrivers/Support/win/VBoxDrv.rc
+++ b/src/VBox/HostDrivers/Support/win/VBoxDrv.rc
@@ -1,10 +1,10 @@
/* $Id: VBoxDrv.rc $ */
/** @file
- * VirtualBox Support Driver - Windows Resource File.
+ * VBoxDrv - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -24,37 +24,37 @@
* terms and conditions of either the GPL or the CDDL or both.
*/
-#include <Windows.h>
+#include <windows.h>
#include <VBox/version.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0x0L
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DRV
- FILESUBTYPE VFT2_DRV_SYSTEM
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DRV
+ FILESUBTYPE VFT2_DRV_SYSTEM
BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox Support Driver\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxDrv.sys\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename", "VBoxDrv.sys\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Support Driver\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxDrv\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxDrv.sys\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
END
diff --git a/src/VBox/HostDrivers/Support/win/VBoxSupLib.rc b/src/VBox/HostDrivers/Support/win/VBoxSupLib.rc
new file mode 100644
index 0000000..6aba492
--- /dev/null
+++ b/src/VBox/HostDrivers/Support/win/VBoxSupLib.rc
@@ -0,0 +1,59 @@
+/* $Id: VBoxSupLib.rc $ */
+/** @file
+ * VBoxSupLib - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Kernel Support\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxSupLib\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxSupLib.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostDrivers/Support/win/import-template-ntdll.h b/src/VBox/HostDrivers/Support/win/import-template-ntdll.h
index a9318c4..18c705f 100644
--- a/src/VBox/HostDrivers/Support/win/import-template-ntdll.h
+++ b/src/VBox/HostDrivers/Support/win/import-template-ntdll.h
@@ -60,6 +60,7 @@ SUPHARNT_IMPORT_SYSCALL(NtQueryVolumeInformationFile, 20)
SUPHARNT_IMPORT_STDCALL_EARLY(LdrInitializeThunk, 12)
SUPHARNT_IMPORT_STDCALL_EARLY_OPTIONAL(LdrRegisterDllNotification, 16)
+SUPHARNT_IMPORT_STDCALL_EARLY(LdrGetDllHandle, 16)
SUPHARNT_IMPORT_STDCALL(RtlAddAccessAllowedAce, 16)
SUPHARNT_IMPORT_STDCALL(RtlAddAccessDeniedAce, 16)
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.rc
similarity index 79%
copy from src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
copy to src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.rc
index c05f8c2..410b408 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/VBoxNetFlt.rc
@@ -1,9 +1,9 @@
-/* $Id: VBoxNetFlt-win.rc $ */
+/* $Id: VBoxNetFlt.rc $ */
/** @file
* VBoxNetFlt - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -17,13 +17,8 @@
#include <windows.h>
#include <VBox/version.h>
-#ifndef VBOXNETADP
-# define DESCRIPTION_STR "VirtualBox Bridged Networking Driver\0"
-# define FILENAME_STR "VBoxNetFlt.sys\0"
-#else
-# define DESCRIPTION_STR "VirtualBox Host-Only Network Adapter Driver\0"
-# define FILENAME_STR "VBoxNetAdp.sys\0"
-#endif
+#define DESCRIPTION_STR "VirtualBox NDIS 6.0 Lightweight Filter Driver\0"
+#define FILENAME_STR "VBoxNetLwf"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
@@ -43,9 +38,9 @@ BEGIN
VALUE "CompanyName", VBOX_RC_COMPANY_NAME
VALUE "FileDescription", DESCRIPTION_STR
VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", FILENAME_STR
+ VALUE "InternalName", FILENAME_STR "\0"
VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename", FILENAME_STR
+ VALUE "OriginalFilename", FILENAME_STR ".sys\0"
VALUE "ProductName", VBOX_PRODUCT "\0"
VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp
index 398d6cc..7d5c3d0 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/cfg/VBoxNetCfg.cpp
@@ -239,16 +239,20 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc,
static HRESULT vboxNetCfgWinQueryInstaller(IN INetCfg *pNetCfg, IN const GUID *pguidClass, INetCfgClassSetup **ppSetup)
{
+ NonStandardLogFlow(("vboxNetCfgWinQueryInstaller: enter \n"));
HRESULT hr = pNetCfg->QueryNetCfgClass(pguidClass, IID_INetCfgClassSetup, (void**)ppSetup);
if (FAILED(hr))
NonStandardLogFlow(("QueryNetCfgClass failed, hr (0x%x)\n", hr));
+ NonStandardLogFlow(("vboxNetCfgWinQueryInstaller: leave \n"));
return hr;
}
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallComponent(IN INetCfg *pNetCfg, IN LPCWSTR pszwComponentId, IN const GUID *pguidClass,
OUT INetCfgComponent **ppComponent)
{
+ NonStandardLogFlow(("VBoxNetCfgWinInstallComponent: enter \n"));
INetCfgClassSetup *pSetup;
+
HRESULT hr = vboxNetCfgWinQueryInstaller(pNetCfg, pguidClass, &pSetup);
if (FAILED(hr))
{
@@ -278,6 +282,8 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinInstallComponent(IN INetCfg *pNetCfg, I
NonStandardLogFlow(("Install failed, hr (0x%x)\n", hr));
pSetup->Release();
+
+ NonStandardLogFlow(("VBoxNetCfgWinInstallComponent: leave \n"));
return hr;
}
@@ -285,6 +291,7 @@ static HRESULT vboxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWS
IN LPCWSTR const *apInfPaths, IN UINT cInfPaths,
OUT INetCfgComponent **ppComponent)
{
+ NonStandardLogFlow(("vboxNetCfgWinInstallInfAndComponent: enter \n"));
HRESULT hr = S_OK;
UINT cFilesProcessed = 0;
@@ -299,6 +306,7 @@ static HRESULT vboxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWS
NonStandardLogFlow(("VBoxNetCfgWinInfInstall failed, hr (0x%x)\n", hr));
break;
}
+ NonStandardLogFlow(("Installing INF file \"%ws\" has been done \n", apInfPaths[cFilesProcessed]));
}
if (SUCCEEDED(hr))
@@ -325,6 +333,7 @@ static HRESULT vboxNetCfgWinInstallInfAndComponent(IN INetCfg *pNetCfg, IN LPCWS
NonStandardLogFlow(("Rollback complete\n"));
}
+ NonStandardLogFlow(("vboxNetCfgWinInstallInfAndComponent: leave \n"));
return hr;
}
@@ -547,9 +556,11 @@ static BOOL vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback(HDEVINFO hDevInfo,
{
case VBOXNECTFGWINPROPCHANGE_TYPE_DISABLE:
PcParams.StateChange = DICS_DISABLE;
+ NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: Change type (DICS_DISABLE): %d\n", pPc->enmPcType));
break;
case VBOXNECTFGWINPROPCHANGE_TYPE_ENABLE:
PcParams.StateChange = DICS_ENABLE;
+ NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: Change type (DICS_ENABLE): %d\n", pPc->enmPcType));
break;
default:
NonStandardLogFlow(("vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback: Unexpected prop change type: %d\n", pPc->enmPcType));
@@ -683,6 +694,7 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnumNetDevices(LPCWSTR pwszPnPId,
if (cCurId >= cPnPId)
{
+ NonStandardLogFlow(("!wcsnicmp(pCurId = (%S), pwszPnPId = (%S), cPnPId = (%d))", pCurId, pwszPnPId, cPnPId));
pCurId += cCurId - cPnPId;
if (!wcsnicmp(pCurId, pwszPnPId, cPnPId))
{
@@ -722,6 +734,7 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinPropChangeAllNetDevicesOfId(IN LPCWSTR
VBOXNECTFGWINPROPCHANGE Pc;
Pc.enmPcType = enmPcType;
Pc.hr = S_OK;
+ NonStandardLogFlow(("Calling VBoxNetCfgWinEnumNetDevices with lpszPnPId =(%S) and vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback", lpszPnPId));
HRESULT hr = VBoxNetCfgWinEnumNetDevices(lpszPnPId, vboxNetCfgWinPropChangeAllNetDevicesOfIdCallback, &Pc);
if (!SUCCEEDED(hr))
{
@@ -2052,7 +2065,7 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc)
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc,
IN LPCWSTR const *apInfFullPaths, IN UINT cInfFullPaths)
{
- HRESULT hr = vboxNetCfgWinNetFltUninstall(pNc, SUOI_FORCEDELETE);
+ HRESULT hr = S_OK;
if (SUCCEEDED(hr))
{
NonStandardLog("NetFlt will be installed ...\n");
@@ -2065,6 +2078,22 @@ VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc,
return hr;
}
+#define VBOXNETCFGWIN_NETADP_ID L"sun_VBoxNetAdp"
+static HRESULT vboxNetCfgWinNetAdpUninstall(IN INetCfg *pNc, DWORD InfRmFlags)
+{
+ HRESULT hr = S_OK;
+ NonStandardLog("Finding NetAdp driver package and trying to uninstall it ...\n");
+
+ VBoxDrvCfgInfUninstallAllF(L"Net", VBOXNETCFGWIN_NETADP_ID, InfRmFlags);
+ NonStandardLog("NetAdp driver package has been uninstalled \n");
+ return hr;
+}
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetAdpUninstall(IN INetCfg *pNc)
+{
+ return vboxNetCfgWinNetAdpUninstall(pNc, SUOI_FORCEDELETE);
+}
+
#define VBOX_CONNECTION_NAME L"VirtualBox Host-Only Network"
VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostonlyConnectionName(PCWSTR DevName, WCHAR *pBuf, PULONG pcbBuf)
{
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf
index 5aedeaa..da89d9c 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetAdp.inf
@@ -72,7 +72,7 @@ ServiceBinary = %12%\VBoxNetAdp.sys
LoadOrderGroup = NDIS
[VBoxNetAdp.AddReg]
-;HKR, , BusNumber, 0, "0"
+HKR, , *NdisDeviceType, 0x00010001, 1 ; NDIS_DEVICE_TYPE_ENDPOINT
HKR, Ndi, Service, 0, "VBoxNetAdp"
HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
index c05f8c2..589da16 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFlt-win.rc
@@ -3,7 +3,7 @@
* VBoxNetFlt - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -19,39 +19,39 @@
#ifndef VBOXNETADP
# define DESCRIPTION_STR "VirtualBox Bridged Networking Driver\0"
-# define FILENAME_STR "VBoxNetFlt.sys\0"
+# define FILENAME_STR "VBoxNetFlt"
#else
# define DESCRIPTION_STR "VirtualBox Host-Only Network Adapter Driver\0"
-# define FILENAME_STR "VBoxNetAdp.sys\0"
+# define FILENAME_STR "VBoxNetAdp"
#endif
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0x0L
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DRV
- FILESUBTYPE VFT2_DRV_NETWORK
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DRV
+ FILESUBTYPE VFT2_DRV_NETWORK
BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", DESCRIPTION_STR
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", FILENAME_STR
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename", FILENAME_STR
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", DESCRIPTION_STR
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", FILENAME_STR "\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", FILENAME_STR ".sys\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
END
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc
index 2555355..34cfac4 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc
+++ b/src/VBox/HostDrivers/VBoxNetFlt/win/nobj/VBoxNetFltNobj.rc
@@ -1,10 +1,9 @@
/* $Id: VBoxNetFltNobj.rc $ */
/** @file
- * VBoxNetFltNobj.h - Notify Object for Bridged Networking Driver.
- * Resource file
+ * VBoxNetFltNobj - Resource file containing version info and icon.
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -20,7 +19,7 @@
#include "VBoxNetFltNobjRc.h"
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -29,7 +28,7 @@ VS_VERSION_INFO VERSIONINFO
#else
FILEFLAGS 0 // final version
#endif
- FILEOS VOS__WINDOWS32
+ FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
@@ -37,14 +36,14 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox Bridged Networking Driver Notify Object v1.1\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxNetFltNobj.dll\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename","VBoxNetFltNobj.dll\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Bridged Networking Driver Notify Object v1.1\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxNetFltNobj\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxNetFltNobj.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc
index d5342a6..b2a995d 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc
+++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,30 +21,30 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0x0L
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DRV
- FILESUBTYPE VFT2_DRV_SYSTEM
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DRV
+ FILESUBTYPE VFT2_DRV_SYSTEM
BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox USB Driver\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxUSB.sys\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename", "VBoxUSB.sys\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox USB Driver\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxUSB\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxUSB.sys\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
END
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc
index 06a6d21..af4365f 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc
+++ b/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2011-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -21,30 +21,30 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS 0x0L
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DRV
- FILESUBTYPE VFT2_DRV_SYSTEM
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DRV
+ FILESUBTYPE VFT2_DRV_SYSTEM
BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox USB Monitor Driver\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxUSBMon.sys\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename", "VBoxUSBMon.sys\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox USB Monitor Driver\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxUSBMon\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxUSBMon.sys\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
END
diff --git a/src/VBox/HostDrivers/linux/export_modules b/src/VBox/HostDrivers/linux/export_modules
index 5233ca3..7e0b6a7 100755
--- a/src/VBox/HostDrivers/linux/export_modules
+++ b/src/VBox/HostDrivers/linux/export_modules
@@ -50,13 +50,15 @@ VBOX_SVN_REV=`sed -e 's/^ *VBOX_SVN_REV_FALLBACK *:= \+\$(patsubst *%:,, *\$Rev:
mkdir $PATH_TMP || exit 1
# Create auto-generated version file, needed by all modules
-echo "#ifndef __version_generated_h__" > $PATH_TMP/version-generated.h
-echo "#define __version_generated_h__" >> $PATH_TMP/version-generated.h
+echo "#ifndef ___version_generated_h___" > $PATH_TMP/version-generated.h
+echo "#define ___version_generated_h___" >> $PATH_TMP/version-generated.h
echo "" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_MAJOR $VBOX_VERSION_MAJOR" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_MINOR $VBOX_VERSION_MINOR" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_BUILD $VBOX_VERSION_BUILD" >> $PATH_TMP/version-generated.h
+echo "#define VBOX_VERSION_STRING_RAW \"$VBOX_VERSION_MAJOR.$VBOX_VERSION_MINOR.$VBOX_VERSION_BUILD\"" >> $PATH_TMP/version-generated.h
echo "#define VBOX_VERSION_STRING \"$VBOX_VERSION_STRING\"" >> $PATH_TMP/version-generated.h
+echo "#define VBOX_API_VERSION_STRING \"${VBOX_VERSION_MAJOR}_${VBOX_VERSION_MINOR}\"" >> $PATH_TMP/version-generated.h
echo "" >> $PATH_TMP/version-generated.h
echo "#endif" >> $PATH_TMP/version-generated.h
@@ -69,8 +71,8 @@ echo "" >> $PATH_TMP/revision-generated.h
echo "#endif" >> $PATH_TMP/revision-generated.h
# Create auto-generated product file, needed by all modules
-echo "#ifndef __product_generated_h__" > $PATH_TMP/product-generated.h
-echo "#define __product_generated_h__" >> $PATH_TMP/product-generated.h
+echo "#ifndef ___product_generated_h___" > $PATH_TMP/product-generated.h
+echo "#define ___product_generated_h___" >> $PATH_TMP/product-generated.h
echo "" >> $PATH_TMP/product-generated.h
echo "#define VBOX_VENDOR \"$VBOX_VENDOR\"" >> $PATH_TMP/product-generated.h
echo "#define VBOX_VENDOR_SHORT \"$VBOX_VENDOR_SHORT\"" >> $PATH_TMP/product-generated.h
diff --git a/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp b/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
index b6021b0..4d66a26 100644
--- a/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
+++ b/src/VBox/HostDrivers/win/cfg/VBoxDrvCfg.cpp
@@ -351,6 +351,7 @@ static HRESULT vboxDrvCfgInfQueryFirstPnPId(HINF hInf, LPWSTR *lppszPnPId)
LPWSTR lpszModels;
LPWSTR lpszPnPId;
HRESULT hr = vboxDrvCfgInfQueryModelsSectionName(hInf, &lpszModels, NULL);
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryModelsSectionName returned lpszModels = (%S)", lpszModels));
if (hr != S_OK)
{
NonStandardLogCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for Manufacturer failed, hr=0x%x\n", hr));
@@ -366,6 +367,7 @@ static HRESULT vboxDrvCfgInfQueryFirstPnPId(HINF hInf, LPWSTR *lppszPnPId)
else
{
hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, 2, &lpszPnPId, NULL);
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) returned lpszPnPId (%S) \n", lpszModels, lpszPnPId));
if (hr != S_OK)
{
NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) failed, hr=0x%x\n", lpszModels, hr));
@@ -391,22 +393,45 @@ static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR lpszInfPath, IN DWORD fCopyStyle,
WCHAR aMediaLocation[_MAX_DIR];
WCHAR aDir[_MAX_DIR];
+ NonStandardLogRelCrap((__FUNCTION__ ":enter"));
+ NonStandardLogRelCrap((__FUNCTION__ ": lpszInfPath=%S \n", lpszInfPath));
+
+
+ NonStandardLogRelCrap((__FUNCTION__ ": call _wsplitpath(%S, aMediaLocation, aDir, NULL, NULL)\n", lpszInfPath));
_wsplitpath(lpszInfPath, aMediaLocation, aDir, NULL, NULL);
+ NonStandardLogRelCrap((__FUNCTION__ ": after _wsplitpath(...) aMediaLocation=%S and aDir=%S\n", aMediaLocation, aDir));
+
+ NonStandardLogRelCrap((__FUNCTION__ ": call wcscat(%S, %S)", aMediaLocation, aDir));
wcscat(aMediaLocation, aDir);
- if (!SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,
- lpszDstName, cbDstName, pcbDstNameSize,
- lpszDstNameComponent))
+ NonStandardLogRelCrap((__FUNCTION__ ": before call SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,\
+ lpszDstName, cbDstName, pcbDstNameSize, lpszDstNameComponent)\n"));
+ bool b = SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,
+ lpszDstName, cbDstName, pcbDstNameSize,
+ lpszDstNameComponent);
+ NonStandardLogRelCrap((__FUNCTION__ ": after call SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle,\
+ lpszDstName, cbDstName, pcbDstNameSize, lpszDstNameComponent)\n"));
+ NonStandardLogRelCrap((__FUNCTION__ ": lpszInfPath=%S \
+ fCopyStyle=%ld \
+ lpszDstName=%S \
+ cbDstName=%ld \
+ pcbDstNameSize=%ld \
+ \n", lpszInfPath,fCopyStyle,lpszDstName,cbDstName,pcbDstNameSize));
+
+ if (!b)
{
DWORD dwErr = GetLastError();
HRESULT hr = HRESULT_FROM_WIN32(dwErr);
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail dwErr=%ld\n", dwErr));
if (fCopyStyle != SP_COPY_REPLACEONLY || hr != VBOXDRVCFG_S_INFEXISTS)
{
- NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail dwErr=%ld\n", dwErr));
+ NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail (with \"fCopyStyle != SP_COPY_REPLACEONLY || hr != VBOXDRVCFG_S_INFEXISTS)\" dwErr=%ld\n", dwErr));
}
+ NonStandardLogRelCrap((__FUNCTION__ ":return error dwErr=%ld\n", dwErr));
return hr;
}
+ NonStandardLogRelCrap((__FUNCTION__ ":return S_OK\n"));
return S_OK;
}
@@ -487,6 +512,7 @@ static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId,
if (pDrvDetail->InfFileName)
{
list.add(pDrvDetail->InfFileName);
+ NonStandardLogRelCrap((__FUNCTION__": %S added to list", pDrvDetail->InfFileName));
}
}
}
@@ -504,6 +530,7 @@ static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId,
DWORD dwErr = GetLastError();
if (dwErr == ERROR_NO_MORE_ITEMS)
{
+ NonStandardLogRelCrap((__FUNCTION__": dwErr == ERROR_NO_MORE_ITEMS -> search was finished "));
break;
}
@@ -556,6 +583,7 @@ VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidC
{
VBoxDrvCfgStringList list(128);
HRESULT hr = vboxDrvCfgCollectInfsSetupDi(pGuidClass, lpszPnPId, list);
+ NonStandardLogRelCrap((__FUNCTION__": vboxDrvCfgCollectInfsSetupDi returned %d devices with PnPId %S and class name %S", list.size(), lpszPnPId, lpszClassName));
if (hr == S_OK)
{
INFENUM_CONTEXT Context;
@@ -574,7 +602,7 @@ VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidC
pRel = pInf;
vboxDrvCfgInfEnumerationCallback(pRel, &Context);
-// NonStandardLogRelCrap(("inf : %S\n", list.get(i)));
+ NonStandardLogRelCrap((__FUNCTION__": inf = %S\n", list.get(i)));
}
}
return hr;
@@ -632,7 +660,8 @@ static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt)
{
PINFENUM_CONTEXT pContext = (PINFENUM_CONTEXT)pCtxt;
DWORD dwErr;
-// NonStandardLogRelCrap(("vboxDrvCfgInfEnumerationCallback: pFileName (%S)\n", pFileName));
+ NonStandardLogRelCrap((__FUNCTION__": lpszFileName (%S)\n", lpszFileName));
+ NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.lpszClassName = (%S)", pContext->InfInfo.lpszClassName));
HINF hInf = SetupOpenInfFileW(lpszFileName, pContext->InfInfo.lpszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
if (hInf == INVALID_HANDLE_VALUE)
@@ -643,12 +672,17 @@ static bool vboxDrvCfgInfEnumerationCallback(LPCWSTR lpszFileName, PVOID pCtxt)
{
NonStandardLogCrap((__FUNCTION__ ": SetupOpenInfFileW err dwErr=%ld\n", dwErr));
}
-
+ else
+ {
+ NonStandardLogCrap((__FUNCTION__ ": dwErr == ERROR_CLASS_MISMATCH"));
+ }
return true;
}
LPWSTR lpszPnPId;
HRESULT hr = vboxDrvCfgInfQueryFirstPnPId(hInf, &lpszPnPId);
+ NonStandardLogRelCrap((__FUNCTION__ ": vboxDrvCfgInfQueryFirstPnPId returned lpszPnPId = (%S)", lpszPnPId));
+ NonStandardLogRelCrap((__FUNCTION__ ": pContext->InfInfo.lpszPnPId = (%S)", pContext->InfInfo.lpszPnPId));
if (hr == S_OK)
{
if (!wcsicmp(pContext->InfInfo.lpszPnPId, lpszPnPId))
@@ -693,6 +727,7 @@ VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(LPCWSTR lpszClassName, LPCWS
Context.InfInfo.lpszPnPId = lpszPnPId;
Context.Flags = Flags;
Context.hr = S_OK;
+ NonStandardLogRelCrap((__FUNCTION__": Calling vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context)"));
hr = vboxDrvCfgEnumFiles(wszInfDirPath, vboxDrvCfgInfEnumerationCallback, &Context);
NonStandardAssert(hr == S_OK);
if (hr == S_OK)
diff --git a/src/VBox/HostDrivers/win/load.sh b/src/VBox/HostDrivers/win/load.sh
index 0ae87d4..54fccf8 100755
--- a/src/VBox/HostDrivers/win/load.sh
+++ b/src/VBox/HostDrivers/win/load.sh
@@ -1,10 +1,10 @@
#!/bin/bash
## @file
-# For development, builds and loads all the host drivers.
+# For development, loads the support driver.
#
#
-# Copyright (C) 2010-2012 Oracle Corporation
+# Copyright (C) 2010-2014 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -15,7 +15,7 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
-if test -n "$Path" -a test -z "$PATH"; then
+if test -n "$Path" -a -z "$PATH"; then
export PATH="$Path"
fi
@@ -65,12 +65,14 @@ done
#
# Invoke the installer.
#
-for inst in SUPInstall.exe;
-do
- if test -f ${MY_DIR}/$inst; then
- ${MY_DIR}/$inst
- fi
-done
+if test "$1" != "-u" -a "$1" != "--uninstall"; then
+ for inst in SUPInstall.exe;
+ do
+ if test -f ${MY_DIR}/$inst; then
+ ${MY_DIR}/$inst
+ fi
+ done
+fi
echo "load.sh: Successfully installed SUPDrv (aka VBoxDrv)"
exit 0
diff --git a/src/VBox/HostDrivers/win/loadall.sh b/src/VBox/HostDrivers/win/loadall.sh
index 446cd47..7ff8a75 100755
--- a/src/VBox/HostDrivers/win/loadall.sh
+++ b/src/VBox/HostDrivers/win/loadall.sh
@@ -1,10 +1,10 @@
#!/bin/bash
## @file
-# For development, builds and loads all the host drivers.
+# For development, loads all the host drivers.
#
#
-# Copyright (C) 2010-2012 Oracle Corporation
+# Copyright (C) 2010-2014 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
@@ -15,6 +15,10 @@
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
+if test -n "$Path" -a -z "$PATH"; then
+ export PATH="$Path"
+fi
+
MY_DIR=`cd "${0}/.." && cmd /c cd | kmk_sed -e 's,\\\\,/,g' `
if [ ! -d "${MY_DIR}" ]; then
echo "Cannot find ${MY_DIR} or it's not a directory..."
@@ -61,12 +65,14 @@ done
#
# Invoke the installers.
#
-for inst in SUPInstall.exe USBInstall.exe NetFltInstall.exe ; #NetAdpInstall.exe; - busted
-do
- if test -f ${MY_DIR}/$inst; then
- ${MY_DIR}/$inst
- fi
-done
+if test "$1" != "-u" -a "$1" != "--uninstall"; then
+ for inst in SUPInstall.exe USBInstall.exe NetFltInstall.exe ; #NetAdpInstall.exe; - busted
+ do
+ if test -f ${MY_DIR}/$inst; then
+ ${MY_DIR}/$inst
+ fi
+ done
+fi
echo "load.sh: Successfully installed all drivers"
exit 0
diff --git a/src/VBox/HostServices/DragAndDrop/Makefile.kmk b/src/VBox/HostServices/DragAndDrop/Makefile.kmk
index 2d0ee30..7e9ccc8 100644
--- a/src/VBox/HostServices/DragAndDrop/Makefile.kmk
+++ b/src/VBox/HostServices/DragAndDrop/Makefile.kmk
@@ -39,6 +39,9 @@ VBoxDragAndDropSvc_SOURCES = \
service.cpp \
dndmanager.cpp
+VBoxDragAndDropSvc_SOURCES.win = \
+ VBoxDragAndDropSvc.rc
+
VBoxDragAndDropSvc_LIBS = \
$(LIB_VMM) \
$(LIB_RUNTIME) \
diff --git a/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.rc b/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.rc
new file mode 100644
index 0000000..338baca
--- /dev/null
+++ b/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxDragAndDropSvc.rc $ */
+/** @file
+ * VBoxDragAndDropSvc - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Drag and Drop Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxDragAndDropSvc\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxDragAndDropSvc.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/GuestControl/Makefile.kmk b/src/VBox/HostServices/GuestControl/Makefile.kmk
index 0351929..1a7e60f 100644
--- a/src/VBox/HostServices/GuestControl/Makefile.kmk
+++ b/src/VBox/HostServices/GuestControl/Makefile.kmk
@@ -37,6 +37,9 @@ VBoxGuestControlSvc_SOURCES = \
gctrl.cpp \
service.cpp
+VBoxGuestControlSvc_SOURCES.win = \
+ VBoxGuestControlSvc.rc
+
VBoxGuestControlSvc_LIBS = \
$(LIB_VMM) \
$(LIB_RUNTIME) \
diff --git a/src/VBox/HostServices/GuestControl/VBoxGuestControlSvc.rc b/src/VBox/HostServices/GuestControl/VBoxGuestControlSvc.rc
new file mode 100644
index 0000000..5940905
--- /dev/null
+++ b/src/VBox/HostServices/GuestControl/VBoxGuestControlSvc.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxGuestControlSvc.rc $ */
+/** @file
+ * VBoxGuestControlSvc - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Guest Control Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxGuestControl\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxGuestControl.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/GuestProperties/Makefile.kmk b/src/VBox/HostServices/GuestProperties/Makefile.kmk
index cf56b67..8472a1f 100644
--- a/src/VBox/HostServices/GuestProperties/Makefile.kmk
+++ b/src/VBox/HostServices/GuestProperties/Makefile.kmk
@@ -36,6 +36,9 @@ VBoxGuestPropSvc_INCS.win = \
VBoxGuestPropSvc_SOURCES = \
service.cpp
+VBoxGuestPropSvc_SOURCES.win = \
+ VBoxGuestPropSvc.rc
+
VBoxGuestPropSvc_LIBS = \
$(LIB_VMM) \
$(LIB_RUNTIME) \
diff --git a/src/VBox/HostServices/GuestProperties/VBoxGuestPropSvc.rc b/src/VBox/HostServices/GuestProperties/VBoxGuestPropSvc.rc
new file mode 100644
index 0000000..413891f
--- /dev/null
+++ b/src/VBox/HostServices/GuestProperties/VBoxGuestPropSvc.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxGuestPropSvc.rc $ */
+/** @file
+ * VBoxGuestPropSvc - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Guest Properties Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxGuestPropSvc\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxGuestPropSvc.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/HostChannel/Makefile.kmk b/src/VBox/HostServices/HostChannel/Makefile.kmk
index 02bb715..4ec07d8 100644
--- a/src/VBox/HostServices/HostChannel/Makefile.kmk
+++ b/src/VBox/HostServices/HostChannel/Makefile.kmk
@@ -31,6 +31,9 @@ VBoxHostChannel_SOURCES = \
service.cpp \
HostChannel.cpp
+VBoxHostChannel_SOURCES.win = \
+ VBoxHostChannel.rc
+
VBoxHostChannel_LIBS = \
$(LIB_VMM) \
$(LIB_RUNTIME)
diff --git a/src/VBox/HostServices/HostChannel/VBoxHostChannel.rc b/src/VBox/HostServices/HostChannel/VBoxHostChannel.rc
new file mode 100644
index 0000000..766c2cb
--- /dev/null
+++ b/src/VBox/HostServices/HostChannel/VBoxHostChannel.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxHostChannel.rc $ */
+/** @file
+ * VBoxHostChannel - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Host Channel Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxHostChannel\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxHostChannel.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/SharedClipboard/Makefile.kmk b/src/VBox/HostServices/SharedClipboard/Makefile.kmk
index 9e73b99..c8c3184 100644
--- a/src/VBox/HostServices/SharedClipboard/Makefile.kmk
+++ b/src/VBox/HostServices/SharedClipboard/Makefile.kmk
@@ -33,7 +33,8 @@ VBoxSharedClipboard_INCS.win = \
VBoxSharedClipboard_SOURCES = \
service.cpp
VBoxSharedClipboard_SOURCES.win = \
- VBoxClipboard-win.cpp
+ VBoxClipboard-win.cpp \
+ VBoxSharedClipboard.rc
VBoxSharedClipboard_SOURCES.darwin = \
darwin.cpp \
$(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp \
diff --git a/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboard.rc b/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboard.rc
new file mode 100644
index 0000000..7b46928
--- /dev/null
+++ b/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboard.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxSharedClipboard.rc $ */
+/** @file
+ * VBoxSharedClipboard - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Shared Clipboard Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxSharedClipboard\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxSharedClipboard.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/SharedFolders/Makefile.kmk b/src/VBox/HostServices/SharedFolders/Makefile.kmk
index 7878aa2..9bbafa7 100644
--- a/src/VBox/HostServices/SharedFolders/Makefile.kmk
+++ b/src/VBox/HostServices/SharedFolders/Makefile.kmk
@@ -41,6 +41,8 @@ VBoxSharedFolders_SOURCES = \
shflhandle.cpp \
vbsf.cpp \
mappings.cpp
+VBoxSharedFolders_SOURCES.win = \
+ VBoxSharedFolders.rc
VBoxSharedFolders_LIBS = \
$(LIB_VMM) \
diff --git a/src/VBox/HostServices/SharedFolders/VBoxSharedFolders.rc b/src/VBox/HostServices/SharedFolders/VBoxSharedFolders.rc
new file mode 100644
index 0000000..f9b9621
--- /dev/null
+++ b/src/VBox/HostServices/SharedFolders/VBoxSharedFolders.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxSharedFolders.rc $ */
+/** @file
+ * VBoxSharedFolders - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Shared Folders Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxSharedFolders\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxSharedFolders.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
index fed6fb3..24ad8c1 100644
--- a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
+++ b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
@@ -62,6 +62,8 @@ VBoxSharedCrOpenGL_INCS += \
endif
VBoxSharedCrOpenGL_SOURCES = \
crserver/crservice.cpp
+VBoxSharedCrOpenGL_SOURCES.win = \
+ crserver/VBoxSharedCrOpenGL.rc
VBoxSharedCrOpenGL_LDFLAGS.darwin = -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxSharedCrOpenGL.dylib
VBoxSharedCrOpenGL_LIBS = \
$(PATH_STAGE_LIB)/VBoxOGLcrserverlib$(VBOX_SUFF_LIB) \
@@ -257,7 +259,10 @@ VBoxOGLrenderspu_SOURCES = \
render/renderspu.c \
render/renderspu_config.c \
render/renderspu_init.c
-VBoxOGLrenderspu_SOURCES.win = render/renderspu_wgl.c render/render.def
+VBoxOGLrenderspu_SOURCES.win = \
+ render/renderspu_wgl.c \
+ render/render.def \
+ render/VBoxOGLrenderspu.rc
VBoxOGLrenderspu_SOURCES.linux = render/renderspu_glx.c
VBoxOGLrenderspu_SOURCES.solaris = render/renderspu_glx.c
VBoxOGLrenderspu_SOURCES.freebsd = render/renderspu_glx.c
@@ -307,6 +312,7 @@ if ( defined(VBOX_WITH_QTGUI) \
PROGRAMS += VBoxTestOGL
VBoxTestOGL_TEMPLATE = $(if $(VBOX_WITH_VIDEOHWACCEL),$(if $(VBOX_WITH_HARDENING),VBOXQT4GUI,VBOXQT4GUIEXE),VBOXMAINEXE)
VBoxTestOGL_SOURCES = OpenGLTest/OpenGLTestApp.cpp
+ VBoxTestOGL_SOURCES.win = OpenGLTest/VBoxTestOGL.rc
VBoxTestOGL_LIBS = \
$(if $(VBOX_WITH_CROGL), \
$(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \
diff --git a/src/VBox/HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp b/src/VBox/HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp
index 65c8c73..b9472f7 100644
--- a/src/VBox/HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp
@@ -121,26 +121,38 @@ bool RTCALL VBoxOglIs3DAccelerationSupported()
CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask (display);
CGLPixelFormatObj pixelFormat = NULL;
GLint numPixelFormats = 0;
+ CGLError rcCgl;
CGLPixelFormatAttribute attribs[] = {
kCGLPFADisplayMask,
(CGLPixelFormatAttribute)cglDisplayMask,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
- kCGLPFAWindow,
VBoxOglIsOfflineRenderingAppropriate() ? kCGLPFAAllowOfflineRenderers : (CGLPixelFormatAttribute)NULL,
(CGLPixelFormatAttribute)NULL
};
display = CGMainDisplayID();
cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(display);
- CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats);
+ rcCgl = CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats);
+ if (rcCgl != kCGLNoError)
+ {
+ LogRel(("OpenGL Info: 3D test unable to choose pixel format (rcCgl=0x%X)\n", rcCgl));
+ return false;
+ }
if (pixelFormat)
{
CGLContextObj cglContext = 0;
- CGLCreateContext(pixelFormat, NULL, &cglContext);
+ rcCgl = CGLCreateContext(pixelFormat, NULL, &cglContext);
CGLDestroyPixelFormat(pixelFormat);
+
+ if (rcCgl != kCGLNoError)
+ {
+ LogRel(("OpenGL Info: 3D test unable to create context (rcCgl=0x%X)\n", rcCgl));
+ return false;
+ }
+
if (cglContext)
{
GLboolean isSupported = GL_TRUE;
@@ -156,15 +168,20 @@ bool RTCALL VBoxOglIs3DAccelerationSupported()
{
isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_texture_rectangle", strExt);
if (!isSupported)
- LogRel(("OpenGL Info: GL_EXT_texture_rectangle extension not supported\n"));
+ LogRel(("OpenGL Info: 3D test found that GL_EXT_texture_rectangle extension not supported\n"));
}
else
- LogRel(("OpenGL Info: GL_EXT_framebuffer_object extension not supported\n"));
+ LogRel(("OpenGL Info: 3D test found that GL_EXT_framebuffer_object extension not supported\n"));
#endif /* VBOX_WITH_COCOA_QT */
CGLDestroyContext(cglContext);
+ LogRel(("OpenGL Info: 3D test %spassed\n", isSupported == GL_TRUE ? "" : "not "));
return isSupported == GL_TRUE ? true : false;
}
+ else
+ LogRel(("OpenGL Info: 3D test unable to create context (internal error)\n"));
}
+ else
+ LogRel(("OpenGL Info: 3D test unable to choose pixel format (internal error)\n"));
return false;
}
diff --git a/src/VBox/HostServices/SharedOpenGL/OpenGLTest/VBoxTestOGL.rc b/src/VBox/HostServices/SharedOpenGL/OpenGLTest/VBoxTestOGL.rc
new file mode 100644
index 0000000..45675ec
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/OpenGLTest/VBoxTestOGL.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxTestOGL.rc $ */
+/** @file
+ * VBoxTestOGL - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox OpenGL Test Tool\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxTestOGL\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxTestOGL.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/SharedOpenGL/crserver/VBoxSharedCrOpenGL.rc b/src/VBox/HostServices/SharedOpenGL/crserver/VBoxSharedCrOpenGL.rc
new file mode 100644
index 0000000..bdabdc4
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/crserver/VBoxSharedCrOpenGL.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxSharedCrOpenGL.rc $ */
+/** @file
+ * VBoxSharedCrOpenGL - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox crOpenGL Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxSharedCrOpenGL\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxSharedCrOpenGL.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
index a0d0abd..e9d41d9 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
@@ -57,6 +57,30 @@ setDefaults(void)
cr_server.pfnNotifyEventCB = NULL;
}
+/* Check if host reports minimal OpenGL capabilities.
+ * For example, on Windows host this may happen if host has no graphics
+ * card drivers installed or drivers were not properly signed or VBox
+ * is running via remote desktop session etc. Currently, we take care
+ * about Windows host only when specific RENDERER and VERSION strings
+ * returned in this case. Later this check should be expanded to the
+ * rest of hosts. */
+static bool crServerHasInsufficientCaps()
+{
+ const char *sRealRender;
+ const char *sRealVersion;
+
+ if (!cr_server.head_spu)
+ return true;
+
+ sRealRender = cr_server.head_spu->dispatch_table.GetString(GL_REAL_RENDERER);
+ sRealVersion = cr_server.head_spu->dispatch_table.GetString(GL_REAL_VERSION);
+
+ if (sRealRender && RTStrCmp(sRealRender, "GDI Generic") == 0)
+ if (sRealVersion && RTStrCmp(sRealVersion, "1.1.0") == 0)
+ return true;
+ return false;
+}
+
void crServerSetVBoxConfiguration()
{
CRMuralInfo *defaultMural;
@@ -181,6 +205,12 @@ void crServerSetVBoxConfiguration()
;
}
+ if (crServerHasInsufficientCaps())
+ {
+ crDebug("Cfg: report minimal OpenGL capabilities");
+ cr_server.u32Caps |= CR_VBOX_CAP_HOST_CAPS_NOT_SUFFICIENT;
+ }
+
crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)",
cr_server.u32Caps,
cr_server.fVisualBitsDefault);
@@ -332,6 +362,12 @@ void crServerSetVBoxConfigurationHGCM()
;
}
+ if (crServerHasInsufficientCaps())
+ {
+ crDebug("Cfg: report minimal OpenGL capabilities");
+ cr_server.u32Caps |= CR_VBOX_CAP_HOST_CAPS_NOT_SUFFICIENT;
+ }
+
crInfo("Cfg: u32Caps(%#x), fVisualBitsDefault(%#x)",
cr_server.u32Caps,
cr_server.fVisualBitsDefault);
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch_header.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_dispatch_header.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_get.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_get.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
index 7c6a4f4..9c22e7d 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
@@ -571,7 +571,10 @@ GLboolean crVBoxServerInit(void)
crServerSetVBoxConfigurationHGCM();
if (!cr_server.head_spu)
+ {
+ crStateDestroy();
return GL_FALSE;
+ }
crServerInitDispatch();
crServerInitTmpCtxDispatch();
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_retval.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_retval.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/render/VBoxOGLrenderspu.rc b/src/VBox/HostServices/SharedOpenGL/render/VBoxOGLrenderspu.rc
new file mode 100644
index 0000000..e349828
--- /dev/null
+++ b/src/VBox/HostServices/SharedOpenGL/render/VBoxOGLrenderspu.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxOGLrenderspu.rc $ */
+/** @file
+ * VBoxOGLrenderspu - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxOGLrenderspu\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxOGLrenderspu.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.h b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.h
index d3121df..8bc01a6 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.h
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.h
@@ -21,8 +21,13 @@
#include <iprt/cdefs.h>
#include <VBox/VBoxCocoa.h>
#include <OpenGL/OpenGL.h>
-#include <cr_vreg.h>
-#include <cr_compositor.h>
+#ifdef IN_VMSVGA3D
+# include "../../../GuestHost/OpenGL/include/cr_vreg.h"
+# include "../../../GuestHost/OpenGL/include/cr_compositor.h"
+#else
+# include <cr_vreg.h>
+# include <cr_compositor.h>
+#endif
RT_C_DECLS_BEGIN
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
index 5afe2b8..bcce371 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
@@ -1,6 +1,9 @@
/* $Id: renderspu_cocoa_helper.m $ */
/** @file
- * VirtualBox OpenGL Cocoa Window System Helper Implementation.
+ * VirtualBox OpenGL Cocoa Window System Helper Implementation.
+ *
+ * This source file is shared between the SharedOpenGL HGCM service and the
+ * SVGA3d emulation.
*/
/*
@@ -15,30 +18,6 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
-#include "renderspu_cocoa_helper.h"
-
-#import <Cocoa/Cocoa.h>
-#undef PVM
-
-#include "chromium.h" /* For the visual bits of chromium */
-
-#include <iprt/thread.h>
-#include <iprt/string.h>
-#include <iprt/mem.h>
-#include <iprt/time.h>
-#include <iprt/assert.h>
-#include <VBox/VBoxOGLTest.h>
-
-#include <cr_vreg.h>
-#include <cr_error.h>
-#include <cr_blitter.h>
-#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
-# include <cr_pixeldata.h>
-#endif
-
-
-#include "renderspu.h"
-
/** @page pg_opengl_cocoa OpenGL - Cocoa Window System Helper
*
* How this works:
@@ -82,98 +61,112 @@
* other third party GUI), overwrite our NSOpenGLContext. So we always ask if
* this is our own one, before use. Really neat concept of Objective-C/Cocoa
* ;)
+ *
*/
-/* Debug macros */
-#define FBO 1 /* Disable this to see how the output is without the FBO in the middle of the processing chain. */
-#if 0
-# define CR_RENDER_FORCE_PRESENT_MAIN_THREAD /* force present schedule to main thread */
-# define SHOW_WINDOW_BACKGROUND 1 /* Define this to see the window background even if the window is clipped */
-# define DEBUG_VERBOSE /* Define this to get some debug info about the messages flow. */
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#ifdef IN_VMSVGA3D
+# define LOG_GROUP LOG_GROUP_DEV_VMSVGA
#endif
+#include "renderspu_cocoa_helper.h"
-#ifdef DEBUG_VERBOSE
-# error "should be disabled!"
-# define DEBUG_INFO(text) do { \
- crWarning text ; \
- Assert(0); \
- } while (0)
-
-# define DEBUG_MSG(text) \
- printf text
+#import <Cocoa/Cocoa.h>
+#undef PVM /* sys/param.h (included via Cocoa.h) pollutes the namespace with this define. */
-# define DEBUG_WARN(text) do { \
- crWarning text ; \
- Assert(0); \
- } while (0)
+#ifndef IN_VMSVGA3D
+# include "chromium.h" /* For the visual bits of chromium */
+#endif
-# define DEBUG_MSG_1(text) \
- DEBUG_MSG(text)
+#include <iprt/assert.h>
+#include <iprt/critsect.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/time.h>
+#include <iprt/thread.h>
+#include <VBox/VBoxOGLTest.h>
+#include <VBox/log.h>
+
+#ifdef IN_VMSVGA3D
+# include "DevVGA-SVGA3d-cocoa.h"
+# include <OpenGL/OpenGL.h>
+# include <OpenGL/gl3.h>
+# include <OpenGL/gl3ext.h>
+# include <OpenGL/glext.h>
#else
+# include <cr_vreg.h>
+# include <cr_error.h>
+# include <cr_blitter.h>
+# ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
+# include <cr_pixeldata.h>
+# endif
+# include "renderspu.h"
+#endif
-# define DEBUG_INFO(text) do { \
- crInfo text ; \
- } while (0)
-
-# define DEBUG_MSG(text) \
- do {} while (0)
-
-# define DEBUG_WARN(text) do { \
- crWarning text ; \
- } while (0)
-# define DEBUG_MSG_1(text) \
- do {} while (0)
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+/* Debug macros */
+/** @def FBO
+ * Disable this to see how the output is without the FBO in the middle of the processing chain. */
+# define FBO 1
+/** @def CR_RENDER_FORCE_PRESENT_MAIN_THREAD
+ * Force present schedule to main thread. */
+/** @def SHOW_WINDOW_BACKGROUND
+ * Define this to see the window background even if the window is clipped. */
+/** @def DEBUG_VERBOSE
+ * Define this to get some debug info about the messages flow. */
+#if 0 || defined(DOXYGEN_RUNNING)
+# define CR_RENDER_FORCE_PRESENT_MAIN_THREAD
+# define SHOW_WINDOW_BACKGROUND 1
+# define DEBUG_VERBOSE
#endif
+#ifdef DEBUG_VERBOSE
+# error "should be disabled!"
+# ifdef IN_VMSVGA3D
+# define DEBUG_INFO(text) do { LogRel(text); AssertFailed(); } while (0)
+# define DEBUG_WARN(text) do { LogRel(text); AssertFailed(); } while (0)
+# else
+# define DEBUG_INFO(text) do { LogRel(text); AssertFailed(); } while (0)
+# define DEBUG_WARN(text) do { LogRel(text); AssertFailed(); } while (0)
+# endif
-#define DEBUG_FUNC_ENTER() do { \
- DEBUG_MSG(("==>%s\n", __PRETTY_FUNCTION__)); \
- } while (0)
-
-#define DEBUG_FUNC_LEAVE() do { \
- DEBUG_MSG(("<==%s\n", __PRETTY_FUNCTION__)); \
- } while (0)
+# define DEBUG_MSG(text) do { LogRel(text); } while (0)
+# define DEBUG_MSG_1(text) do { LogRel(text); } while (0)
-#ifdef DEBUG_poetzsch
-# define CHECK_GL_ERROR()\
- do \
- { \
- checkGLError(__FILE__, __LINE__); \
- }while (0);
+#else
- static void checkGLError(char *file, int line)
- {
- GLenum g = glGetError();
- if (g != GL_NO_ERROR)
- {
- char *errStr;
- switch (g)
- {
- case GL_INVALID_ENUM: errStr = RTStrDup("GL_INVALID_ENUM"); break;
- case GL_INVALID_VALUE: errStr = RTStrDup("GL_INVALID_VALUE"); break;
- case GL_INVALID_OPERATION: errStr = RTStrDup("GL_INVALID_OPERATION"); break;
- case GL_STACK_OVERFLOW: errStr = RTStrDup("GL_STACK_OVERFLOW"); break;
- case GL_STACK_UNDERFLOW: errStr = RTStrDup("GL_STACK_UNDERFLOW"); break;
- case GL_OUT_OF_MEMORY: errStr = RTStrDup("GL_OUT_OF_MEMORY"); break;
- case GL_TABLE_TOO_LARGE: errStr = RTStrDup("GL_TABLE_TOO_LARGE"); break;
- default: errStr = RTStrDup("UNKNOWN"); break;
- }
- DEBUG_MSG(("%s:%d: glError %d (%s)\n", file, line, g, errStr));
- RTMemFree(errStr);
- }
- }
+# ifdef IN_VMSVGA3D
+# define DEBUG_INFO(text) do { LogRel(text); } while (0)
+# define DEBUG_WARN(text) do { LogRel(text); } while (0)
+# else
+# define DEBUG_INFO(text) do { crInfo text; } while (0)
+# define DEBUG_WARN(text) do { crWarning text; } while (0)
+#endif
+# define DEBUG_MSG(text) do {} while (0)
+# define DEBUG_MSG_1(text) do {} while (0)
+
+#endif
+#ifdef IN_VMSVGA3D
+# define DEBUG_MSG_NOT_VMSVGA3D(a_TextArgs) do {} while (0)
+# define COCOA_LOG_FLOW(a_TextArgs) LogFlow(a_TextArgs)
#else
-# define CHECK_GL_ERROR()\
- do {} while (0)
+# define DEBUG_MSG_NOT_VMSVGA3D(a_TextArgs) DEBUG_MSG(a_TextArgs)
+# define COCOA_LOG_FLOW(a_TextArgs) DEBUG_MSG(a_TextArgs)
#endif
-#define GL_SAVE_STATE \
- do \
- { \
+
+#define DEBUG_FUNC_ENTER() DEBUG_MSG(("==>%s\n", __PRETTY_FUNCTION__))
+#define DEBUG_FUNC_LEAVE() DEBUG_MSG(("<==%s\n", __PRETTY_FUNCTION__))
+
+# define DEBUG_GL_SAVE_STATE() \
+ do { \
glPushAttrib(GL_ALL_ATTRIB_BITS); \
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); \
glMatrixMode(GL_PROJECTION); \
@@ -184,12 +177,10 @@
glPushMatrix(); \
glMatrixMode(GL_MODELVIEW); \
glPushMatrix(); \
- } \
- while(0);
+ } while(0)
-#define GL_RESTORE_STATE \
- do \
- { \
+#define DEBUG_GL_RESTORE_STATE() \
+ do { \
glMatrixMode(GL_MODELVIEW); \
glPopMatrix(); \
glMatrixMode(GL_COLOR); \
@@ -200,27 +191,155 @@
glPopMatrix(); \
glPopClientAttrib(); \
glPopAttrib(); \
- } \
- while(0);
+ } while (0)
+
+#ifdef DEBUG_poetzsch
+# define DEBUG_CHECK_GL_ERROR() do { checkGLError(__FILE__, __LINE__); } while(0);
+
+static void checkGLError(char *pszFile, int iLine)
+{
+ GLenum uGlErr = glGetError();
+ if (uGlErr != GL_NO_ERROR)
+ {
+ const char *errStr;
+ switch (uGlErr)
+ {
+ case GL_INVALID_ENUM: errStr = "GL_INVALID_ENUM"; break;
+ case GL_INVALID_VALUE: errStr = "GL_INVALID_VALUE"; break;
+ case GL_INVALID_OPERATION: errStr = "GL_INVALID_OPERATION"; break;
+ case GL_STACK_OVERFLOW: errStr = "GL_STACK_OVERFLOW"; break;
+ case GL_STACK_UNDERFLOW: errStr = "GL_STACK_UNDERFLOW"; break;
+ case GL_OUT_OF_MEMORY: errStr = "GL_OUT_OF_MEMORY"; break;
+ case GL_TABLE_TOO_LARGE: errStr = "GL_TABLE_TOO_LARGE"; break;
+ default: errStr = "UNKNOWN"; break;
+ }
+ DEBUG_MSG(("%s:%d: glError %d (%s)\n", pszFile, iLine, uGlErr, errStr));
+ }
+}
+#else
+# define DEBUG_CHECK_GL_ERROR() do {} while (0)
+#endif
+
+
+#ifdef IN_VMSVGA3D
+
+/*
+ * VMSVGA3D compatibility glue.
+ */
+
+# define CR_RGB_BIT RT_BIT_32(0)
+
+# define CR_ALPHA_BIT RT_BIT_32(1)
+# define CR_DEPTH_BIT RT_BIT_32(2)
+# define CR_STENCIL_BIT RT_BIT_32(3)
+# define CR_ACCUM_BIT RT_BIT_32(4)
+# define CR_DOUBLE_BIT RT_BIT_32(5)
+# define CR_STEREO_BIT RT_BIT_32(6)
+# define CR_MULTISAMPLE_BIT RT_BIT_32(7)
+
+# define CR_OVERLAY_BIT RT_BIT_32(8)
+# define CR_PBUFFER_BIT RT_BIT_32(9)
+# define VMSVGA3D_NON_DEFAULT_PROFILE_BIT RT_BIT_32(31)
+# define CR_ALL_BITS UINT32_C(0x800003ff)
+
+typedef struct WindowInfo
+{
+ uint32_t volatile cRefs;
+ RTCRITSECT CompositorLock;
+ PCVBOXVR_SCR_COMPOSITOR pCompositor;
+
+ //NativeNSViewRef window;
+ //NativeNSViewRef nativeWindow; /**< for render_to_app_window */
+ NativeNSOpenGLContextRef *currentCtx;
+} WindowInfo;
+
+static void vmsvga3DWinInfoDestroy(WindowInfo *pWinInfo)
+{
+ /** @todo */
+}
+
+DECLINLINE(void) renderspuWinRetain(WindowInfo *pWinInfo)
+{
+ ASMAtomicIncU32(&pWinInfo->cRefs);
+}
+
+DECLINLINE(void) renderspuWinRelease(WindowInfo *pWinInfo)
+{
+ uint32_t cRefs = ASMAtomicDecU32(&pWinInfo->cRefs);
+ if (!cRefs)
+ vmsvga3DWinInfoDestroy(pWinInfo);
+}
+
+static int renderspuVBoxCompositorLock(WindowInfo *pWinInfo, PCVBOXVR_SCR_COMPOSITOR *ppCompositor)
+{
+ int rc = RTCritSectEnter(&pWinInfo->CompositorLock);
+ AssertRCReturn(rc, rc);
+ if (ppCompositor)
+ *ppCompositor = pWinInfo->pCompositor;
+ return VINF_SUCCESS;
+}
+
+static int renderspuVBoxCompositorUnlock(WindowInfo *pWinInfo)
+{
+ int rc = RTCritSectLeave(&pWinInfo->CompositorLock);
+ AssertRC(rc);
+ return rc;
+}
+
+static PCVBOXVR_SCR_COMPOSITOR renderspuVBoxCompositorAcquire(WindowInfo *pWinInfo)
+{
+ int rc = RTCritSectEnter(&pWinInfo->CompositorLock);
+ AssertRCReturn(rc, NULL);
+
+ PCVBOXVR_SCR_COMPOSITOR pCompositor = pWinInfo->pCompositor;
+ if (pCompositor)
+ {
+ Assert(!CrVrScrCompositorIsEmpty(pWinInfo->pCompositor));
+ return pCompositor;
+ }
+
+ /* if no compositor is set, release the lock and return */
+ RTCritSectLeave(&pWinInfo->CompositorLock);
+ return NULL;
+}
+
+static void renderspuVBoxCompositorRelease(WindowInfo *pWinInfo)
+{
+ Assert(pWinInfo->pCompositor);
+ Assert(!CrVrScrCompositorIsEmpty(pWinInfo->pCompositor));
+ int rc = RTCritSectLeave(&pWinInfo->CompositorLock);
+ AssertRC(rc);
+}
+
+
+#endif /* IN_VMSVGA3D */
+
-static NSOpenGLContext * vboxCtxGetCurrent()
+
+static NSOpenGLContext *vboxCtxGetCurrent(void)
{
+#ifdef IN_VMSVGA3D
+ return [NSOpenGLContext currentContext];
+#else
GET_CONTEXT(pCtxInfo);
if (pCtxInfo)
{
Assert(pCtxInfo->context);
return pCtxInfo->context;
}
-
return nil;
+#endif
}
-static bool vboxCtxSyncCurrentInfo()
+static bool vboxCtxSyncCurrentInfo(void)
{
+#ifdef IN_VMSVGA3D
+ return false;
+#else
+ bool fAdjusted = false;
GET_CONTEXT(pCtxInfo);
NSOpenGLContext *pCtx = [NSOpenGLContext currentContext];
NSView *pView = pCtx ? [pCtx view] : nil;
- bool fAdjusted = false;
if (pCtxInfo)
{
WindowInfo *pWinInfo = pCtxInfo->currentWindow;
@@ -232,48 +351,53 @@ static bool vboxCtxSyncCurrentInfo()
fAdjusted = true;
}
}
- else
- {
- if (pCtx)
+ else if (pCtx)
{
[NSOpenGLContext clearCurrentContext];
fAdjusted = true;
}
- }
return fAdjusted;
+#endif
}
+
+/**
+ * State carrying structure for use with vboxCtxEnter and vboxCtxLeave
+ */
typedef struct VBOX_CR_RENDER_CTX_INFO
{
bool fIsValid;
NSOpenGLContext *pCtx;
NSView *pView;
-} VBOX_CR_RENDER_CTX_INFO, *PVBOX_CR_RENDER_CTX_INFO;
+} VBOX_CR_RENDER_CTX_INFO;
+/** Pointer to render context info for use with vboxCtxEnter/Leave. */
+typedef VBOX_CR_RENDER_CTX_INFO *PVBOX_CR_RENDER_CTX_INFO;
-static void vboxCtxEnter(NSOpenGLContext*pCtx, PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
+static void vboxCtxEnter(NSOpenGLContext*pNewCtx, PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
{
NSOpenGLContext *pOldCtx = vboxCtxGetCurrent();
- NSView *pOldView = (pOldCtx ? [pOldCtx view] : nil);
- NSView *pView = [pCtx view];
- bool fNeedCtxSwitch = (pOldCtx != pCtx || pOldView != pView);
- Assert(pCtx);
- // Assert(pOldCtx == m_pGLCtx);
- // Assert(pOldView == self);
- // Assert(fNeedCtxSwitch);
- if (fNeedCtxSwitch)
+ NSView *pOldView = pOldCtx ? [pOldCtx view] : nil;
+ NSView *pNewView = [pNewCtx view];
+
+ Assert(pNewCtx);
+
+ if (pOldCtx != pNewCtx
+ || pOldView != pNewView)
{
if(pOldCtx != nil)
glFlush();
- [pCtx makeCurrentContext];
+ [pNewCtx makeCurrentContext];
pCtxInfo->fIsValid = true;
pCtxInfo->pCtx = pOldCtx;
- pCtxInfo->pView = pView;
+ /** @todo r=bird: Why do we save the NEW VIEW here? vboxCtxLeave calls it 'pOldView'. Bug? */
+ pCtxInfo->pView = pNewView;
}
else
{
+ /* No context switch necessary. */
pCtxInfo->fIsValid = false;
}
}
@@ -288,6 +412,11 @@ static void vboxCtxLeave(PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
glFlush();
if (pOldCtx != nil)
{
+ /* vboxCtxEnter saves the new view, not the old. So, what we actually
+ do here is switching the view of the old context to that of the new
+ one (wrt vboxCtxEnter) before making it current. */
+ /** @todo r=bird: Figure out what we really want to do here, and either rename
+ * pOldView or fix the code. */
if ([pOldCtx view] != pOldView)
{
[pOldCtx setView: pOldView];
@@ -295,10 +424,10 @@ static void vboxCtxLeave(PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
[pOldCtx makeCurrentContext];
-#ifdef DEBUG
+#ifdef VBOX_STRICT
{
NSOpenGLContext *pTstOldCtx = [NSOpenGLContext currentContext];
- NSView *pTstOldView = (pTstOldCtx ? [pTstOldCtx view] : nil);
+ NSView *pTstOldView = pTstOldCtx ? [pTstOldCtx view] : nil;
Assert(pTstOldCtx == pOldCtx);
Assert(pTstOldView == pOldView);
}
@@ -311,11 +440,12 @@ static void vboxCtxLeave(PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
}
}
-/** Custom OpenGL context class.
+/**
+ * Custom OpenGL context class.
*
- * This implementation doesn't allow to set a view to the
- * context, but save the view for later use. Also it saves a copy of the
- * pixel format used to create that context for later use. */
+ * This implementation doesn't allow to set a view to the context, but save the
+ * view for later use. Also it saves a copy of the pixel format used to create
+ * that context for later use. */
@interface OverlayOpenGLContext: NSOpenGLContext
{
@private
@@ -325,55 +455,49 @@ static void vboxCtxLeave(PVBOX_CR_RENDER_CTX_INFO pCtxInfo)
- (NSOpenGLPixelFormat*)openGLPixelFormat;
@end
+/**
+ * Abstrack task class.
+ */
@interface VBoxTask : NSObject
{
}
- (void)run;
@end
- at interface VBoxTaskPerformSelector : VBoxTask
+ at implementation VBoxTask
+/** Run method that the child classes must reimplement.
+ * This will abort the process. */
+- (void)run
{
- at private
- id m_Object;
- SEL m_Selector;
- id m_Arg;
+ AssertReleaseFailed();
}
-- (id)initWithObject:(id)aObject selector:(SEL)aSelector arg:(id)aArg;
-- (void)run;
-- (void)dealloc;
@end
-#if 0
-typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
-
- at interface VBoxTaskCallback: VBoxTask
-{
- at private
- PFNVBOXTASKCALLBACK m_pfnCb;
- void *m_pvCb;
-}
-- (id)initWithCb:(PFNVBOXTASKCALLBACK)pfnCb arg:(void*)pvCb;
-- (void)run;
- at end
-#endif
- at interface VBoxTaskComposite: VBoxTask
+/**
+ * Generic task class for executing a given method select.
+ */
+ at interface VBoxTaskPerformSelector : VBoxTask
{
@private
- NSUInteger m_CurIndex;
- RTCRITSECT m_Lock;
- NSMutableArray *m_pArray;
+ id m_Object;
+ SEL m_Selector;
+ id m_Arg;
}
-- (id)init;
-- (void)add:(VBoxTask*)pTask;
+- (id)initWithObject:(id)aObject selector:(SEL)aSelector arg:(id)aArg;
- (void)run;
- (void)dealloc;
@end
- at implementation VBoxTask
- at end
-
@implementation VBoxTaskPerformSelector
+
+/**
+ * Initializes a VBoxTaskPerformSelector.
+ *
+ * @param aObject The object (reference not consumed).
+ * @param aSelector The method selector.
+ * @param aArg The method argument (reference not consumed).
+ */
- (id)initWithObject:(id)aObject selector:(SEL)aSelector arg:(id)aArg
{
self = [super init];
@@ -406,6 +530,23 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
}
@end
+
+/**
+ *
+ */
+ at interface VBoxTaskComposite : VBoxTask
+{
+ at private
+ NSUInteger m_CurIndex;
+ RTCRITSECT m_Lock;
+ NSMutableArray *m_pArray;
+}
+- (id)init;
+- (void)add:(VBoxTask *)pTask;
+- (void)run;
+- (void)dealloc;
+ at end
+
@implementation VBoxTaskComposite
- (id)init
{
@@ -428,6 +569,11 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
return self;
}
+/**
+ * Adds a task to the composite task object.
+ *
+ * @param pTask Task to add. Reference is NOT consumed.
+ */
- (void)add:(VBoxTask*)pTask
{
[pTask retain];
@@ -448,6 +594,9 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
{
for(;;)
{
+ /*
+ * Dequeue a task.
+ */
int rc = RTCritSectEnter(&m_Lock);
if (RT_FAILURE(rc))
{
@@ -470,6 +619,9 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
++m_CurIndex;
+ /*
+ * Remove the first 1025 empty entires.
+ */
if (m_CurIndex > 1024)
{
NSRange range;
@@ -480,6 +632,9 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
}
RTCritSectLeave(&m_Lock);
+ /*
+ * Run the task and release it.
+ */
[pTask run];
[pTask release];
}
@@ -502,6 +657,11 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
}
@end
+
+/**
+ *
+ *
+ */
@interface VBoxMainThreadTaskRunner : NSObject
{
@private
@@ -530,31 +690,19 @@ typedef DECLCALLBACKPTR(void, PFNVBOXTASKCALLBACK)(void *pvCb);
+ (VBoxMainThreadTaskRunner*) globalInstance
{
- static dispatch_once_t dispatchOnce;
- static VBoxMainThreadTaskRunner *pRunner = nil;
- dispatch_once(&dispatchOnce, ^{
- pRunner = [[VBoxMainThreadTaskRunner alloc] init];
+ static dispatch_once_t s_DispatchOnce;
+ static VBoxMainThreadTaskRunner *s_pRunner = nil;
+ dispatch_once(&s_DispatchOnce, ^{
+ s_pRunner = [[VBoxMainThreadTaskRunner alloc] init];
});
- return pRunner;
-}
-
-typedef struct CR_RCD_RUN
-{
- VBoxMainThreadTaskRunner *pRunner;
-} CR_RCD_RUN;
-
-static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
-{
- DEBUG_FUNC_ENTER();
- CR_RCD_RUN * pRun = (CR_RCD_RUN*)pvCb;
- [pRun->pRunner runTasks];
- DEBUG_FUNC_LEAVE();
+ return s_pRunner;
}
- (void)add:(VBoxTask*)pTask
{
DEBUG_FUNC_ENTER();
[m_pTasks add:pTask];
+ /** @todo r=bird: Unbalanced [self retain]. */
[self retain];
if (![self runTasksSyncIfPossible])
@@ -566,6 +714,13 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
DEBUG_FUNC_LEAVE();
}
+/**
+ * Adds a task calling an object method (selector).
+ *
+ * @param aObject The object (reference not consumed)..
+ * @param aSelector The method selector.
+ * @param aArg The method argument (reference not consumed).
+ */
- (void)addObj:(id)aObject selector:(SEL)aSelector arg:(id)aArg
{
VBoxTaskPerformSelector *pSelTask = [[VBoxTaskPerformSelector alloc] initWithObject:aObject selector:aSelector arg:aArg];
@@ -573,45 +728,84 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
[pSelTask release];
}
+
+/**
+ * Internal method for running the pending tasks.
+ */
- (void)runTasks
{
- BOOL fIsMain = [NSThread isMainThread];
- Assert(fIsMain);
- if (fIsMain)
+ if ([NSThread isMainThread])
{
[m_pTasks run];
+ /** @todo r=bird: This release and the retain in the add method aren't
+ * necessarily balanced if there are more than one call to add().
+ *
+ * This could probably end up deleting the singleton prematurely and leave
+ * globalInstance() returning pointers to a stale object in freed memory,
+ * quite possibly causing crashes or/and heap corruption. */
[self release];
}
else
{
DEBUG_WARN(("run tasks called not on main thread!\n"));
+#ifndef DEBUG_VERBOSE
+ AssertFailed();
+#endif
[self performSelectorOnMainThread:@selector(runTasks) withObject:nil waitUntilDone:YES];
}
}
+/**
+ * Callback for calling runTasks via renderspuCalloutClient.
+ * @param pvUser The VBoxMainThreadTaskRunner singleton.
+ */
+static DECLCALLBACK(void) VBoxMainThreadTaskRunner_RcdRunCallback(void *pvUser)
+{
+ DEBUG_FUNC_ENTER();
+ VBoxMainThreadTaskRunner *pRunner = (VBoxMainThreadTaskRunner *)pvUser;
+ Assert(pRunner == [VBoxMainThreadTaskRunner globalInstance]);
+ [pRunner runTasks];
+ DEBUG_FUNC_LEAVE();
+}
+
+/**
+ * Runs pending tasks synchronously, if possible in the current context.
+ *
+ * @returns true if executed tasks, false if not possible.
+ */
- (bool)runTasksSyncIfPossible
{
+#ifndef IN_VMSVGA3D
+ /*
+ * Call on main thread (?) via renderspuCalloutClient (whatever that is).
+ */
if (renderspuCalloutAvailable())
{
- CR_RCD_RUN Run;
- Run.pRunner = self;
Assert(![NSThread isMainThread]);
- renderspuCalloutClient(vboxRcdRun, &Run);
+ renderspuCalloutClient(VBoxMainThreadTaskRunner_RcdRunCallback, self);
return true;
}
+#endif
+ /*
+ * Run directly if on main thread.
+ */
if ([NSThread isMainThread])
{
[self runTasks];
return true;
}
+ /* Not possible. */
return false;
}
- (void)dealloc
{
+ /** @todo r=bird: WTF is the point of the deallocator. The object is a singelton
+ * stored in an inaccessible static variable! */
[m_pTasks release];
+ m_pTasks = nil;
[super dealloc];
}
@@ -619,14 +813,16 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
@class DockOverlayView;
-/** The custom view class.
- * This is the main class of the cocoa OpenGL implementation. It
- * manages an frame buffer object for the rendering of the guest
- * applications. The guest applications render in this frame buffer which
- * is bind to an OpenGL texture. To display the guest content, an secondary
- * shared OpenGL context of the main OpenGL context is created. The secondary
- * context is marked as non opaque & the texture is displayed on an object
- * which is composed out of the several visible region rectangles. */
+/**
+ * The custom view class.
+ *
+ * This is the main class of the cocoa OpenGL implementation. It manages a
+ * frame buffer object for the rendering of the guest applications. The guest
+ * applications render in this frame buffer which is bound to an OpenGL texture.
+ * To display the guest content, a secondary shared OpenGL context of the main
+ * OpenGL context is created. The secondary context is marked as non-opaque and
+ * the texture is displayed on an object which is composed out of the several
+ * visible region rectangles. */
@interface OverlayView: NSView
{
@private
@@ -635,7 +831,7 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
NSOpenGLContext *m_pGLCtx;
NSOpenGLContext *m_pSharedGLCtx;
- RTTHREAD mThread;
+ RTTHREAD m_Thread;
GLuint m_FBOId;
@@ -645,15 +841,20 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
GLfloat m_FBOThumbScaleX;
GLfloat m_FBOThumbScaleY;
- uint64_t m_uiDockUpdateTime;
+ uint64_t m_msDockUpdateTS;
- /* For clipping */
- GLint m_cClipRects;
- GLint *m_paClipRects;
+ /** @name For clipping
+ * @remarks appears to be unused and a complete waste of time + heap.
+ * @{ */
+ GLint m_cClipRects;
+ GLint *m_paClipRects;
+ /** @} */
- /* Position/Size tracking */
+ /** @name Position/Size tracking
+ * @{ */
NSPoint m_Pos;
NSSize m_Size;
+ /** @} */
/** This is necessary for clipping on the root window */
NSRect m_RootRect;
@@ -687,6 +888,7 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
- (void)vboxSetSize:(NSSize)size;
- (NSSize)size;
- (void)updateViewportCS;
+- (NSRect)safeConvertToScreen:(NSRect *)pRect;
- (void)vboxReshapePerform;
- (void)vboxReshapeOnResizePerform;
- (void)vboxReshapeOnReparentPerform;
@@ -719,7 +921,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
- (void)cleanupData;
@end
-/** Helper view.
+/**
+ * Helper view.
*
* This view is added as a sub view of the parent view to track
* main window changes. Whenever the main window is changed
@@ -735,7 +938,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
-(id)initWithOverlayWindow:(OverlayWindow*)pOverlayWindow;
@end
-/** Custom window class.
+/**
+ * Custom window class.
*
* This is the overlay window which contains our custom NSView.
* Its a direct child of the Qt Main window. It marks its background
@@ -754,6 +958,10 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
- (void)parentWindowChanged:(NSWindow*)pWindow;
@end
+
+/**
+ * Dock overlay view class.
+ */
@interface DockOverlayView: NSView
{
NSBitmapImageRep *m_ThumbBitmap;
@@ -778,7 +986,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
if (self)
{
- /* We need a lock cause the thumb image could be accessed from the main
+ /*
+ * We need a lock cause the thumb image could be accessed from the main
* thread when someone is calling display on the dock tile & from the
* OpenGL thread when the thumbnail is updated. */
m_Lock = [[NSLock alloc] init];
@@ -872,9 +1081,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
- (void)drawRect:(NSRect)aRect
{
- DEBUG_FUNC_ENTER();
NSRect frame;
-
+ DEBUG_FUNC_ENTER();
[self lock];
#ifdef SHOW_WINDOW_BACKGROUND
[[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.7] set];
@@ -918,6 +1126,7 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
m_pView = NULL;
self = [super initWithFormat:format shareContext:share];
+ Assert(self != nil);
if (self)
m_pPixelFormat = format;
@@ -1000,7 +1209,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
return m_pPixelFormat;
}
- at end
+ at end /* @implementation OverlayOpenGLContext */
+
/********************************************************************************
*
@@ -1050,7 +1260,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
NSWindow *pParentWin = nil;
- if((self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]))
+ self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ if (self)
{
m_pParentView = pParentView;
m_pOverlayView = pOverlayView;
@@ -1118,7 +1329,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
DEBUG_MSG(("OWIN(%p): parentWindowFrameChanged\n", (void*)self));
- /* Reposition this window with the help of the OverlayView. Perform the
+ /*
+ * Reposition this window with the help of the OverlayView. Perform the
* call in the OpenGL thread. */
/*
[m_pOverlayView performSelector:@selector(vboxReshapePerform) onThread:m_Thread withObject:nil waitUntilDone:YES];
@@ -1153,7 +1365,8 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
object:pWindow];
/* Add us self as child window */
[pWindow addChildWindow:self ordered:NSWindowAbove];
- /* Reshape the overlay view after a short waiting time to let the main
+ /*
+ * Reshape the overlay view after a short waiting time to let the main
* window resize itself properly. */
/*
[m_pOverlayView performSelector:@selector(vboxReshapePerform) withObject:nil afterDelay:0.2];
@@ -1172,7 +1385,9 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
DEBUG_FUNC_LEAVE();
}
- at end
+ at end /* @implementation OverlayWindow */
+
+
/********************************************************************************
*
@@ -1183,13 +1398,14 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
- (id)initWithFrame:(NSRect)frame thread:(RTTHREAD)aThread parentView:(NSView*)pParentView winInfo:(WindowInfo*)pWinInfo
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p aThread=%p pParentView=%p pWinInfo=%p\n", __PRETTY_FUNCTION__, (void *)self,
+ (void *)aThread, (void *)pParentView, (void *)pWinInfo));
m_pParentView = pParentView;
/* Make some reasonable defaults */
m_pGLCtx = nil;
m_pSharedGLCtx = nil;
- mThread = aThread;
+ m_Thread = aThread;
m_FBOId = 0;
m_cClipRects = 0;
m_paClipRects = NULL;
@@ -1207,16 +1423,13 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
self = [super initWithFrame:frame];
- DEBUG_MSG(("OVIW(%p): init OverlayView\n", (void*)self));
-
- DEBUG_FUNC_LEAVE();
-
+ COCOA_LOG_FLOW(("%s: returns self=%p\n", __PRETTY_FUNCTION__, (void *)self));
return self;
}
- (void)cleanupData
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
[self deleteDockTile];
@@ -1240,39 +1453,40 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
[self clearVisibleRegions];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)dealloc
{
- DEBUG_FUNC_ENTER();
-
- DEBUG_MSG(("OVIW(%p): dealloc OverlayView\n", (void*)self));
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void*)self));
[self cleanupData];
[super dealloc];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)drawRect:(NSRect)aRect
{
+ COCOA_LOG_FLOW(("%s: self=%p aRect=%d,%d %d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)aRect.origin.x, (int)aRect.origin.y,
+ (int)aRect.size.width, (int)aRect.size.height));
+
[self vboxTryDrawUI];
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)setGLCtx:(NSOpenGLContext*)pCtx
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p pCtx=%p (old=%p)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCtx, m_pGLCtx));
- DEBUG_MSG(("OVIW(%p): setGLCtx: new ctx: %p\n", (void*)self, (void*)pCtx));
- if (m_pGLCtx == pCtx)
+ /*
+ * Only do something if the context changes.
+ */
+ if (m_pGLCtx != pCtx)
{
- DEBUG_FUNC_LEAVE();
- return;
- }
-
- /* ensure the context drawable is cleared to avoid holding a reference to inexistent view */
+ /* Ensure the context drawable is cleared to avoid holding a reference to inexistent view. */
if (m_pGLCtx)
{
[m_pGLCtx clearDrawable];
@@ -1283,129 +1497,109 @@ static DECLCALLBACK(void) vboxRcdRun(void *pvCb)
m_pGLCtx = pCtx;
if (pCtx)
[pCtx retain];
+ }
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (NSOpenGLContext*)glCtx
{
- DEBUG_FUNC_ENTER();
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: self=%p returns %p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pGLCtx));
return m_pGLCtx;
}
- (NSView*)parentView
{
- DEBUG_FUNC_ENTER();
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: self=%p returns %p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pParentView));
return m_pParentView;
}
- (void)setParentView:(NSView*)pView
{
- DEBUG_FUNC_ENTER();
-
- DEBUG_MSG(("OVIW(%p): setParentView: new view: %p\n", (void*)self, (void*)pView));
+ COCOA_LOG_FLOW(("%s: self=%p pView=%p (old=%p)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pView, m_pParentView));
m_pParentView = pView;
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)setOverlayWin:(NSWindow*)pWin
{
- DEBUG_FUNC_ENTER();
-
- DEBUG_MSG(("OVIW(%p): setOverlayWin: new win: %p\n", (void*)self, (void*)pWin));
+ COCOA_LOG_FLOW(("%s: self=%p pWin=%p (old=%p)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pWin, m_pOverlayWin));
m_pOverlayWin = pWin;
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (NSWindow*)overlayWin
{
- DEBUG_FUNC_ENTER();
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: self=%p returns %p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pOverlayWin));
return m_pOverlayWin;
}
- (void)vboxSetPosUI:(NSPoint)pos
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p pos=%d,%d (old pos=%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, (int)pos.x, (int)pos.y,
+ (int)m_Pos.x, (int)m_Pos.y));
+
+ DEBUG_MSG(("vboxSetPosUI: [%d, %d].\n", (int)pos.x, (int)pos.y));
m_Pos = pos;
if (m_fEverSized)
[self vboxReshapePerform];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetPosUIObj:(NSValue*)pPos
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p pPos=%p (%d,%d) (old pos=%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, pPos,
+ (int)[pPos pointValue].x, (int)[pPos pointValue].y, (int)m_Pos.x, (int)m_Pos.y));
NSPoint pos = [pPos pointValue];
[self vboxSetPosUI:pos];
- DEBUG_FUNC_LEAVE();
-}
-
-typedef struct CR_RCD_SETPOS
-{
- OverlayView *pView;
- NSPoint pos;
-} CR_RCD_SETPOS;
-
-static DECLCALLBACK(void) vboxRcdSetPos(void *pvCb)
-{
- DEBUG_FUNC_ENTER();
-
- CR_RCD_SETPOS * pPos = (CR_RCD_SETPOS*)pvCb;
- [pPos->pView vboxSetPosUI:pPos->pos];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetPos:(NSPoint)pos
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p pos=%d,%d (old pos=%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, (int)pos.x, (int)pos.y,
+ (int)m_Pos.x, (int)m_Pos.y));
- DEBUG_MSG(("OVIW(%p): vboxSetPos: new pos: %d, %d\n", (void*)self, (int)pos.x, (int)pos.y));
VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
NSValue *pPos = [NSValue valueWithPoint:pos];
[pRunner addObj:self selector:@selector(vboxSetPosUIObj:) arg:pPos];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (NSPoint)pos
{
- DEBUG_FUNC_ENTER();
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: self=%p returns %d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)m_Pos.x, (int)m_Pos.y));
return m_Pos;
}
- (bool)isEverSized
{
- DEBUG_FUNC_ENTER();
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: self=%p returns %d\n", __PRETTY_FUNCTION__, (void *)self, m_fEverSized));
return m_fEverSized;
}
- (void)vboxDestroy
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
BOOL fIsMain = [NSThread isMainThread];
NSWindow *pWin = nil;
Assert(fIsMain);
- /* Hide the view early */
+ /* Hide the view early. */
[self setHidden: YES];
pWin = [self window];
@@ -1420,7 +1614,7 @@ static DECLCALLBACK(void) vboxRcdSetPos(void *pvCb)
/* We can NOT run synchronously with the main thread since this may lead to a deadlock,
caused by main thread waiting xpcom thread, xpcom thread waiting to main hgcm thread,
and main hgcm thread waiting for us, this is why use waitUntilDone:NO,
- which should cause no harm */
+ which should cause no harm. */
[pWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
}
@@ -1433,26 +1627,29 @@ static DECLCALLBACK(void) vboxRcdSetPos(void *pvCb)
/* We can NOT run synchronously with the main thread since this may lead to a deadlock,
caused by main thread waiting xpcom thread, xpcom thread waiting to main hgcm thread,
and main hgcm thread waiting for us, this is why use waitUntilDone:NO.
- We need to avoid concurrency though, so we cleanup some data right away via a cleanupData call */
+ We need to avoid concurrency though, so we cleanup some data right away via a cleanupData call. */
[self performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
}
renderspuWinRelease(m_pWinInfo);
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetSizeUIObj:(NSValue*)pSize
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p pSize=%p (%d,%d)\n", __PRETTY_FUNCTION__, (void *)self, (void *)pSize,
+ (int)[pSize sizeValue].width, (int)[pSize sizeValue].height));
+
NSSize size = [pSize sizeValue];
[self vboxSetSizeUI:size];
- DEBUG_FUNC_LEAVE();
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetSizeUI:(NSSize)size
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p size=%d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)size.width, (int)size.height));
m_Size = size;
m_fEverSized = true;
@@ -1462,59 +1659,45 @@ static DECLCALLBACK(void) vboxRcdSetPos(void *pvCb)
/* ensure window contents is updated after that */
[self vboxTryDrawUI];
- DEBUG_FUNC_LEAVE();
-}
-typedef struct CR_RCD_SETSIZE
-{
- OverlayView *pView;
- NSSize size;
-} CR_RCD_SETSIZE;
-
-static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
-{
- DEBUG_FUNC_ENTER();
- CR_RCD_SETSIZE * pSetSize = (CR_RCD_SETSIZE*)pvCb;
- [pSetSize->pView vboxSetSizeUI:pSetSize->size];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetSize:(NSSize)size
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p size=%d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)size.width, (int)size.height));
VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
NSValue *pSize = [NSValue valueWithSize:size];
[pRunner addObj:self selector:@selector(vboxSetSizeUIObj:) arg:pSize];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (NSSize)size
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p returns %d,%d\n", __PRETTY_FUNCTION__, (void *)self, (int)m_Size.width, (int)m_Size.height));
return m_Size;
- DEBUG_FUNC_LEAVE();
}
- (void)updateViewportCS
{
- DEBUG_FUNC_ENTER();
- DEBUG_MSG(("OVIW(%p): updateViewport\n", (void*)self));
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
- /* Update the viewport for our OpenGL view */
+ /* Update the viewport for our OpenGL view. */
[m_pSharedGLCtx update];
[self vboxBlitterSyncWindow];
- /* Clear background to transparent */
+ /* Clear background to transparent. */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- DEBUG_FUNC_LEAVE();
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxReshapeOnResizePerform
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
[self vboxReshapePerform];
[self createDockTile];
@@ -1533,100 +1716,136 @@ static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
m_fNeedCtxUpdate = true;
}
#endif
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxReshapeOnReparentPerform
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+ [self vboxReshapePerform];
[self createDockTile];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
+}
+
+- (NSRect)safeConvertToScreen:(NSRect *)pRect
+{
+ NSRect resultingRect = NSZeroRect;
+
+ NSWindow *pWindow = [m_pParentView window];
+ if (pWindow)
+ {
+ if ([pWindow respondsToSelector:@selector(convertRectToScreen:)])
+ {
+ NSMethodSignature *pSignature = [pWindow methodSignatureForSelector:@selector(convertRectToScreen:)];
+ if (pSignature)
+ {
+ NSInvocation *pInvocation = [NSInvocation invocationWithMethodSignature:pSignature];
+ if (pInvocation)
+ {
+ [pInvocation setSelector:@selector(convertRectToScreen:)];
+ [pInvocation setTarget:pWindow];
+ [pInvocation setArgument:pRect atIndex:2];
+ [pInvocation invoke];
+ [pInvocation getReturnValue:&resultingRect];
+
+ DEBUG_MSG(("safeConvertToScreen: convert [X, Y, WxH]: [%d, %d, %dx%d] -> [%d, %d, %dx%d]\n",
+ (int)pRect ->origin.x, (int)pRect ->origin.y, (int)pRect ->size.width, (int)pRect ->size.width,
+ (int)resultingRect.origin.x, (int)resultingRect.origin.y, (int)resultingRect.size.width, (int)resultingRect.size.width));
+
+ return resultingRect;
+ }
+ }
+ }
+
+ /* If we failed, let's use deprecated @selector(convertBaseToScreen:). It is a bit hacky,
+ * but what to do if we stick to SDK 10.6. */
+ resultingRect.origin = [[m_pParentView window] convertBaseToScreen:pRect->origin];
+ resultingRect.size = pRect->size;
+ }
+ else
+ /* Should never happen. */
+ DEBUG_WARN(("safeConvertToScreen: parent widget has no window.\n"));
+
+ DEBUG_MSG(("safeConvertToScreen (deprecated method): convert [X, Y, WxH]: [%d, %d, %dx%d] -> [%d, %d, %dx%d]\n",
+ (int)pRect ->origin.x, (int)pRect ->origin.y, (int)pRect ->size.width, (int)pRect ->size.width,
+ (int)resultingRect.origin.x, (int)resultingRect.origin.y, (int)resultingRect.size.width, (int)resultingRect.size.width));
+
+ return resultingRect;
}
- (void)vboxReshapePerform
{
- DEBUG_FUNC_ENTER();
- NSRect parentFrame = NSZeroRect;
- NSPoint parentPos = NSZeroPoint;
- NSPoint childPos = NSZeroPoint;
- NSRect childFrame = NSZeroRect;
- NSRect newFrame = NSZeroRect;
-
- DEBUG_MSG(("OVIW(%p): vboxReshapePerform\n", (void*)self));
-
- parentFrame = [m_pParentView frame];
- DEBUG_MSG(("FIXED parentFrame [%f:%f], [%f:%f]\n", parentFrame.origin.x, parentFrame.origin.y, parentFrame.size.width, parentFrame.size.height));
- parentPos = parentFrame.origin;
- parentPos.y += parentFrame.size.height;
- DEBUG_MSG(("FIXED(view) parentPos [%f:%f]\n", parentPos.x, parentPos.y));
- parentPos = [m_pParentView convertPoint:parentPos toView:nil];
- DEBUG_MSG(("FIXED parentPos(win) [%f:%f]\n", parentPos.x, parentPos.y));
- parentPos = [[m_pParentView window] convertBaseToScreen:parentPos];
- DEBUG_MSG(("FIXED parentPos(screen) [%f:%f]\n", parentPos.x, parentPos.y));
- parentFrame.origin = parentPos;
-
- childPos = NSMakePoint(m_Pos.x, m_Pos.y + m_Size.height);
- DEBUG_MSG(("FIXED(view) childPos [%f:%f]\n", childPos.x, childPos.y));
- childPos = [m_pParentView convertPoint:childPos toView:nil];
- DEBUG_MSG(("FIXED(win) childPos [%f:%f]\n", childPos.x, childPos.y));
- childPos = [[m_pParentView window] convertBaseToScreen:childPos];
- DEBUG_MSG(("FIXED childPos(screen) [%f:%f]\n", childPos.x, childPos.y));
- childFrame = NSMakeRect(childPos.x, childPos.y, m_Size.width, m_Size.height);
- DEBUG_MSG(("FIXED childFrame [%f:%f], [%f:%f]\n", childFrame.origin.x, childFrame.origin.y, childFrame.size.width, childFrame.size.height));
-
- /* We have to make sure that the overlay window will not be displayed out
- * of the parent window. So intersect both frames & use the result as the new
- * frame for the window. */
- newFrame = NSIntersectionRect(parentFrame, childFrame);
-
- DEBUG_MSG(("[%#p]: parentFrame pos[%f : %f] size[%f : %f]\n",
- (void*)self,
- parentFrame.origin.x, parentFrame.origin.y,
- parentFrame.size.width, parentFrame.size.height));
- DEBUG_MSG(("[%#p]: childFrame pos[%f : %f] size[%f : %f]\n",
- (void*)self,
- childFrame.origin.x, childFrame.origin.y,
- childFrame.size.width, childFrame.size.height));
-
- DEBUG_MSG(("[%#p]: newFrame pos[%f : %f] size[%f : %f]\n",
- (void*)self,
- newFrame.origin.x, newFrame.origin.y,
- newFrame.size.width, newFrame.size.height));
-
- /* Later we have to correct the texture position in the case the window is
+ COCOA_LOG_FLOW(("%s: self=%p - m_DockTileView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_DockTileView));
+
+ /* NOTE: Please consider the next naming convention for variables.
+ *
+ * Rectangle variables:
+ *
+ * <object to represent><coordinate system>:
+ * <object to represent>:
+ * parentFrame - a frame of the parent container (NSView) object
+ * childFrame - a frame required to display guest content
+ * windowFrame - resulting window frame constructed as an intersection of parentFrame and childFrame
+ * <coordinate system>:
+ * VCS - View Coordinate System
+ * WCS - Window Coordinate System
+ * SCS - Screen Coordinate System
+ *
+ * The same convention applied to offset variables naming as well which are of format:
+ *
+ * <object to represent><coordinate><coordinate system>.
+ *
+ * https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html
+ */
+
+ NSRect parentFrameVCS, parentFrameWCS, parentFrameSCS;
+ NSRect childFrameWCS, childFrameSCS;
+ NSRect windowFrameSCS;
+ CGFloat childFrameXWCS, childFrameYWCS;
+
+ /* We need to construct a new window frame (windowFrameSCS) for entire NSWindow object in
+ * screen coordinates. In order to make 3D overlay window to do not overlap Cocoa and Qt GUI elements (titlebar,
+ * Qt statusbar, scroll bars etc) let's do the next. Get parent view visible area (parentFrameSCS) in (NS)Screen
+ * coordinates. Then get the area required to diaplay guest content (childFrameSCS) in (NS)Screen coordinates as well.
+ * The intersection of these two areas in screen coordinates will be a new frame for entire NSWindow object. */
+
+ parentFrameVCS = [m_pParentView frame];
+ parentFrameWCS = [m_pParentView convertRect:parentFrameVCS toView:nil];
+ parentFrameSCS = [self safeConvertToScreen:&parentFrameWCS];
+
+ /* Choose childFrame origin in a bit special way. Its pop-left corner should stick to its parent top-left corner. */
+ childFrameXWCS = parentFrameWCS.origin.x + m_Pos.x;
+ childFrameYWCS = parentFrameWCS.origin.y - m_Pos.y - (m_Size.height - parentFrameWCS.size.height);
+ childFrameWCS = NSMakeRect(childFrameXWCS, childFrameYWCS, m_Size.width, m_Size.height);
+ childFrameSCS = [self safeConvertToScreen:&childFrameWCS];
+
+ windowFrameSCS = NSIntersectionRect(parentFrameSCS, childFrameSCS);
+
+ DEBUG_MSG(("vboxReshapePerform: a new overlay frame [%d, %d, %dx%d] has been constructed from intersection of window frame "
+ "[%d, %d, %dx%d] and guest content rectangle [%d, %d, %dx%d]; m_Pos=[%d, %d], m_Size=%dx%d.\n",
+ (int)windowFrameSCS .origin.x, (int)windowFrameSCS .origin.y, (int)windowFrameSCS .size.width, (int)windowFrameSCS .size.width,
+ (int)parentFrameSCS.origin.x, (int)parentFrameSCS.origin.y, (int)parentFrameSCS.size.width, (int)parentFrameSCS.size.width,
+ (int)childFrameSCS .origin.x, (int)childFrameSCS .origin.y, (int)childFrameSCS .size.width, (int)childFrameSCS .size.width,
+ (int)m_Pos.x, (int)m_Pos.y, (int)m_Size.width, (int)m_Size.height));
+
+ /* @todo galitsyn: drop this!
+ * Later we have to correct the texture position in the case the window is
* out of the parents window frame. So save the shift values for later use. */
- m_RootRect.origin.x = newFrame.origin.x - childFrame.origin.x;
- m_RootRect.origin.y = childFrame.size.height + childFrame.origin.y - (newFrame.size.height + newFrame.origin.y);
- m_RootRect.size = newFrame.size;
- m_yInvRootOffset = newFrame.origin.y - childFrame.origin.y;
-
- DEBUG_MSG(("[%#p]: m_RootRect pos[%f : %f] size[%f : %f]\n",
- (void*)self,
- m_RootRect.origin.x, m_RootRect.origin.y,
- m_RootRect.size.width, m_RootRect.size.height));
+ m_RootRect.origin.x = windowFrameSCS.origin.x - childFrameSCS.origin.x;
+ m_RootRect.origin.y = childFrameSCS.size.height + childFrameSCS.origin.y - (windowFrameSCS.size.height + windowFrameSCS.origin.y);
+ m_RootRect.size = windowFrameSCS.size;
+ m_yInvRootOffset = windowFrameSCS.origin.y - childFrameSCS.origin.y;
-
- /*
- NSScrollView *pScrollView = [[[m_pParentView window] contentView] enclosingScrollView];
- if (pScrollView)
- {
- NSRect scrollRect = [pScrollView documentVisibleRect];
- NSRect scrollRect = [m_pParentView visibleRect];
- printf ("sc rect: %d %d %d %d\n", (int) scrollRect.origin.x,(int) scrollRect.origin.y,(int) scrollRect.size.width,(int) scrollRect.size.height);
- NSRect b = [[m_pParentView superview] bounds];
- printf ("bound rect: %d %d %d %d\n", (int) b.origin.x,(int) b.origin.y,(int) b.size.width,(int) b.size.height);
- newFrame.origin.x += scrollRect.origin.x;
- newFrame.origin.y += scrollRect.origin.y;
- }
- */
+ DEBUG_MSG(("vboxReshapePerform: [%#p]: m_RootRect pos[%d : %d] size[%d : %d]\n",
+ (void*)self, (int)m_RootRect.origin.x, (int)m_RootRect.origin.y, (int)m_RootRect.size.width, (int)m_RootRect.size.height));
/* Set the new frame. */
- [[self window] setFrame:newFrame display:YES];
+ [[self window] setFrame:windowFrameSCS display:YES];
- /* Inform the dock tile view as well */
+ /* Inform the dock tile view as well. */
[self reshapeDockTile];
- /* Make sure the context is updated according */
+ /* Make sure the context is updated accordingly. */
/* [self updateViewport]; */
if (m_pSharedGLCtx)
{
@@ -1637,12 +1856,12 @@ static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
vboxCtxLeave(&CtxInfo);
}
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)createDockTile
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
NSView *pDockScreen = nil;
[self deleteDockTile];
@@ -1655,24 +1874,26 @@ static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
[self reshapeDockTile];
[pDockScreen addSubview:m_DockTileView];
}
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns - m_DockTileView\n", __PRETTY_FUNCTION__, (void *)m_DockTileView));
}
- (void)deleteDockTile
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p - m_DockTileView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_DockTileView));
+
if (m_DockTileView != nil)
{
[m_DockTileView removeFromSuperview];
[m_DockTileView release];
m_DockTileView = nil;
}
- DEBUG_FUNC_LEAVE();
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)makeCurrentFBO
{
- DEBUG_MSG(("OVIW(%p): makeCurrentFBO\n", (void*)self));
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
if (m_pGLCtx)
{
@@ -1682,14 +1903,15 @@ static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
if([NSOpenGLContext currentContext] != 0)
glFlush();
[m_pGLCtx setView: self];
- CHECK_GL_ERROR();
+ DEBUG_CHECK_GL_ERROR();
}
+
/*
if ([NSOpenGLContext currentContext] != m_pGLCtx)
*/
{
[m_pGLCtx makeCurrentContext];
- CHECK_GL_ERROR();
+ DEBUG_CHECK_GL_ERROR();
if (m_fNeedCtxUpdate == true)
{
[m_pGLCtx update];
@@ -1704,45 +1926,54 @@ static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
}
}
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (bool)vboxSharedCtxCreate
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+
if (m_pSharedGLCtx)
{
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns true (m_pSharedGLCtx=%p)\n", __PRETTY_FUNCTION__, (void *)m_pSharedGLCtx));
return true;
}
Assert(!m_pBlitter);
- m_pBlitter = RTMemAlloc(sizeof (*m_pBlitter));
- if (!m_pBlitter)
+ m_pBlitter = RTMemAlloc(sizeof(*m_pBlitter));
+ if (RT_UNLIKELY(!m_pBlitter))
{
DEBUG_WARN(("m_pBlitter allocation failed"));
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns false - m_pBlitter allocation failed\n", __PRETTY_FUNCTION__));
return false;
}
- int rc = CrBltInit(m_pBlitter, NULL, false, false, &render_spu.GlobalShaders, &render_spu.blitterDispatch);
- if (RT_SUCCESS(rc))
- {
- DEBUG_MSG(("blitter created successfully for view 0x%p\n", (void*)self));
- }
- else
+ int rc = CrBltInit(m_pBlitter, NULL, false /*fCreateNewCtx*/, false /*fForceDrawBlt*/,
+#ifdef IN_VMSVGA3D
+ NULL /** @todo */, NULL /** @todo */
+#else
+ &render_spu.GlobalShaders, &render_spu.blitterDispatch
+#endif
+ );
+ if (RT_FAILURE(rc))
{
DEBUG_WARN(("CrBltInit failed, rc %d", rc));
RTMemFree(m_pBlitter);
m_pBlitter = NULL;
- DEBUG_FUNC_LEAVE();
+
+ COCOA_LOG_FLOW(("%s: returns false - CrBltInit failed with rc=%Rrc\n", __PRETTY_FUNCTION__, rc));
return false;
}
-
- GLint opaque = 0;
+
+ COCOA_LOG_FLOW(("%s: blitter (%p) created successfully for view 0x%p\n", (void *)m_pBlitter, (void *)self));
+
/* Create a shared context out of the main context. Use the same pixel format. */
- NSOpenGLContext *pSharedGLCtx = [[NSOpenGLContext alloc] initWithFormat:[(OverlayOpenGLContext*)m_pGLCtx openGLPixelFormat] shareContext:m_pGLCtx];
+ NSOpenGLPixelFormat *pPixelFormat = [(OverlayOpenGLContext *)m_pGLCtx openGLPixelFormat];
+ NSOpenGLContext *pSharedGLCtx = [[NSOpenGLContext alloc] initWithFormat:pPixelFormat shareContext:m_pGLCtx];
/* Set the new context as non opaque */
+ GLint opaque = 0;
[pSharedGLCtx setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
/* Set this view as the drawable for the new context */
[pSharedGLCtx setView: self];
@@ -1750,87 +1981,66 @@ static DECLCALLBACK(void) vboxRcdSetSize(void *pvCb)
m_pSharedGLCtx = pSharedGLCtx;
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns true - new m_pSharedGLCtx=%p\n", __PRETTY_FUNCTION__, (void *)m_pSharedGLCtx));
return true;
}
- (void)vboxTryDraw
{
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+
glFlush();
- DEBUG_MSG(("My[%p]: Draw\n", self));
- /* issue to the gui thread */
+ /* Issue to the gui thread. */
[self performSelectorOnMainThread:@selector(vboxTryDrawUI) withObject:nil waitUntilDone:NO];
-}
-typedef struct CR_RCD_SETVISIBLE
-{
- OverlayView *pView;
- BOOL fVisible;
-} CR_RCD_SETVISIBLE;
-
-static DECLCALLBACK(void) vboxRcdSetVisible(void *pvCb)
-{
- DEBUG_FUNC_ENTER();
- CR_RCD_SETVISIBLE * pVisible = (CR_RCD_SETVISIBLE*)pvCb;
-
- [pVisible->pView vboxSetVisibleUI:pVisible->fVisible];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetVisible:(GLboolean)fVisible
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p fVisible=%d\n", __PRETTY_FUNCTION__, (void *)self, fVisible));
VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
- NSNumber* pVisObj = [NSNumber numberWithBool:fVisible];
+ NSNumber *pVisObj = [NSNumber numberWithBool:fVisible];
[pRunner addObj:self selector:@selector(vboxSetVisibleUIObj:) arg:pVisObj];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxSetVisibleUI:(GLboolean)fVisible
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p fVisible=%d\n", __PRETTY_FUNCTION__, (void *)self, fVisible));
+
[self setHidden: !fVisible];
- DEBUG_FUNC_LEAVE();
-}
-- (void)vboxSetVisibleUIObj:(NSNumber*)pVisible
-{
- DEBUG_FUNC_ENTER();
- BOOL fVisible = [pVisible boolValue];
- [self vboxSetVisibleUI:fVisible];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
-typedef struct CR_RCD_REPARENT
+- (void)vboxSetVisibleUIObj:(NSNumber *)pVisibleObj
{
- OverlayView *pView;
- NSView *pParent;
-} CR_RCD_REPARENT;
+ COCOA_LOG_FLOW(("%s: self=%p pVisibleObj=%p(%d)\n", __PRETTY_FUNCTION__,
+ (void *)self, (void *)pVisibleObj, [pVisibleObj boolValue]));
-static DECLCALLBACK(void) vboxRcdReparent(void *pvCb)
-{
- DEBUG_FUNC_ENTER();
- CR_RCD_REPARENT * pReparent = (CR_RCD_REPARENT*)pvCb;
- [pReparent->pView vboxReparentUI:pReparent->pParent];
- DEBUG_FUNC_LEAVE();
+ BOOL fVisible = [pVisibleObj boolValue];
+ [self vboxSetVisibleUI:fVisible];
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxReparent:(NSView*)pParentView
{
- DEBUG_FUNC_ENTER();
-
+ COCOA_LOG_FLOW(("%s: self=%p pParentView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pParentView));
+
VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
[pRunner addObj:self selector:@selector(vboxReparentUI:) arg:pParentView];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxReparentUI:(NSView*)pParentView
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p pParentView=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pParentView));
/* Make sure the window is removed from any previous parent window. */
if ([[self overlayWin] parentWindow] != nil)
{
@@ -1848,39 +2058,55 @@ static DECLCALLBACK(void) vboxRcdReparent(void *pvCb)
[self vboxReshapeOnReparentPerform];
}
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)vboxTryDrawUI
{
- DEBUG_MSG(("My[%p]: DrawUI\n", self));
- const VBOXVR_SCR_COMPOSITOR *pCompositor;
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
if ([self isHidden])
{
- DEBUG_INFO(("request to draw on a hidden view"));
+ COCOA_LOG_FLOW(("%s: returns - request to draw on a hidden view\n", __PRETTY_FUNCTION__));
return;
}
if ([[self overlayWin] parentWindow] == nil)
{
- DEBUG_INFO(("request to draw a view w/o a parent"));
+ COCOA_LOG_FLOW(("%s: returns - request to draw a view w/o a parent\n", __PRETTY_FUNCTION__));
return;
}
+
+#ifdef IN_VMSVGA3D
+ if (!m_pSharedGLCtx)
+ {
+ Assert(!m_fDataVisible);
+ Assert(!m_fCleanupNeeded);
+ if (![self vboxSharedCtxCreate])
+ {
+ COCOA_LOG_FLOW(("%s: returns - vboxSharedCtxCreate failed\n", __PRETTY_FUNCTION__));
+ return;
+ }
+ Assert(m_pSharedGLCtx);
+ }
+#endif
+ const VBOXVR_SCR_COMPOSITOR *pCompositor;
int rc = renderspuVBoxCompositorLock(m_pWinInfo, &pCompositor);
if (RT_FAILURE(rc))
{
- DEBUG_WARN(("renderspuVBoxCompositorLock failed\n"));
+ COCOA_LOG_FLOW(("%s: returns - renderspuVBoxCompositorLock failed (%Rrc)\n", __PRETTY_FUNCTION__, rc));
return;
}
+#ifndef IN_VMSVGA3D
if (!pCompositor && !m_fCleanupNeeded)
{
- DEBUG_MSG(("My[%p]: noCompositorUI\n", self));
renderspuVBoxCompositorUnlock(m_pWinInfo);
+ COCOA_LOG_FLOW(("%s: returns - noCompositorUI\n", __PRETTY_FUNCTION__));
return;
}
+#endif
VBOXVR_SCR_COMPOSITOR TmpCompositor;
@@ -1893,7 +2119,7 @@ static DECLCALLBACK(void) vboxRcdReparent(void *pvCb)
renderspuVBoxCompositorRelease(m_pWinInfo);
if (![self vboxSharedCtxCreate])
{
- DEBUG_WARN(("vboxSharedCtxCreate failed\n"));
+ COCOA_LOG_FLOW(("%s: returns - vboxSharedCtxCreate failed\n", __PRETTY_FUNCTION__));
return;
}
@@ -1903,87 +2129,98 @@ static DECLCALLBACK(void) vboxRcdReparent(void *pvCb)
Assert(!m_fDataVisible);
Assert(!m_fCleanupNeeded);
if (!pCompositor)
+ {
+ COCOA_LOG_FLOW(("%s: returns - Failed to reacquire compositor\n", __PRETTY_FUNCTION__));
return;
+ }
}
}
else
{
- DEBUG_MSG(("My[%p]: NeedCleanup\n", self));
+ DEBUG_MSG(("%s: NeedCleanup\n", __PRETTY_FUNCTION__));
+#ifndef IN_VMSVGA3D /** @todo VMSVGA3 */
Assert(m_fCleanupNeeded);
+#endif
CrVrScrCompositorInit(&TmpCompositor, NULL);
pCompositor = &TmpCompositor;
}
if ([self lockFocusIfCanDraw])
{
+ COCOA_LOG_FLOW(("%s: Calling vboxPresent\n", __PRETTY_FUNCTION__));
[self vboxPresent:pCompositor];
[self unlockFocus];
}
+#ifndef IN_VMSVGA3D /** @todo VMSVGA3 */
else if (!m_pWinInfo->visible)
{
- DEBUG_MSG(("My[%p]: NotVisible\n", self));
+ COCOA_LOG_FLOW(("%s: NotVisible\n", __PRETTY_FUNCTION__));
m_fCleanupNeeded = false;
}
+#endif
else
{
- DEBUG_MSG(("My[%p]: Reschedule\n", self));
+ COCOA_LOG_FLOW(("%s: Reschedule\n", __PRETTY_FUNCTION__));
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(vboxTryDrawUI) userInfo:nil repeats:NO];
}
renderspuVBoxCompositorUnlock(m_pWinInfo);
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (void)swapFBO
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p - m_pGLCtx=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)m_pGLCtx));
[m_pGLCtx flushBuffer];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
-- (void)vboxPresent:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
+- (void)vboxPresent:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
{
- VBOX_CR_RENDER_CTX_INFO CtxInfo;
-
- DEBUG_MSG(("OVIW(%p): renderFBOToView\n", (void*)self));
-
- Assert(pCompositor);
+ COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
+ /*DEBUG_MSG(("OVIW(%p): renderFBOToView\n", (void *)self));*/
+ AssertPtr(pCompositor);
+ VBOX_CR_RENDER_CTX_INFO CtxInfo;
vboxCtxEnter(m_pSharedGLCtx, &CtxInfo);
[self vboxPresentCS:pCompositor];
vboxCtxLeave(&CtxInfo);
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
-- (void)vboxPresentCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
+- (void)vboxPresentCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
{
- {
- if ([m_pSharedGLCtx view] != self)
- {
- DEBUG_MSG(("OVIW(%p): not current view of shared ctx! Switching ...\n", (void*)self));
- [m_pSharedGLCtx setView: self];
- m_fNeedViewportUpdate = true;
- }
-
- if (m_fNeedViewportUpdate)
- {
- [self updateViewportCS];
- m_fNeedViewportUpdate = false;
- }
-
- m_fCleanupNeeded = false;
-
- /* Render FBO content to the dock tile when necessary. */
- [self vboxPresentToDockTileCS:pCompositor];
- /* change to #if 0 to see thumbnail image */
+ COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
+ if ([m_pSharedGLCtx view] != self)
+ {
+ COCOA_LOG_FLOW(("%s: Not current view of shared ctx! Switching... (self=%p, view=%p, m_pSharedGLCtx)\n",
+ __PRETTY_FUNCTION__, (void *)self, (void *)[m_pSharedGLCtx view], (void *)m_pSharedGLCtx));
+ [m_pSharedGLCtx setView: self];
+ m_fNeedViewportUpdate = true;
+ }
+
+ if (m_fNeedViewportUpdate)
+ {
+ [self updateViewportCS];
+ m_fNeedViewportUpdate = false;
+ }
+
+ m_fCleanupNeeded = false;
+
+ /* Render FBO content to the dock tile when necessary. */
+ [self vboxPresentToDockTileCS:pCompositor];
+
+ /* change to #if 0 to see thumbnail image */
#if 1
[self vboxPresentToViewCS:pCompositor];
#else
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
[m_pSharedGLCtx flushBuffer];
#endif
-
- }
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
DECLINLINE(void) vboxNSRectToRect(const NSRect *pR, RTRECT *pRect)
@@ -2010,11 +2247,11 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
pRect->yBottom = (int)((pR->origin.y + pR->size.height) * yStretch);
}
-- (void)vboxPresentToViewCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
+- (void)vboxPresentToViewCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
{
NSRect r = [self frame];
- float xStretch, yStretch;
- DEBUG_MSG(("OVIW(%p): rF2V frame: [%i, %i, %i, %i]\n", (void*)self, (int)r.origin.x, (int)r.origin.y, (int)r.size.width, (int)r.size.height));
+ COCOA_LOG_FLOW(("%s: self=%p - r={%d,%d %d,%d}\n", __PRETTY_FUNCTION__, (void *)self,
+ (int)r.origin.x, (int)r.origin.y, (int)r.size.width, (int)r.size.height));
#if 1 /* Set to 0 to see the docktile instead of the real output */
VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
@@ -2030,6 +2267,8 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
m_fDataVisible = false;
+ float xStretch;
+ float yStretch;
CrVrScrCompositorGetStretching(pCompositor, &xStretch, &yStretch);
while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
@@ -2040,14 +2279,15 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
if (RT_SUCCESS(rc))
{
- uint32_t i;
- int rc = CrBltEnter(m_pBlitter);
+ rc = CrBltEnter(m_pBlitter);
if (RT_SUCCESS(rc))
{
+ uint32_t i;
for (i = 0; i < cRegions; ++i)
{
- const RTRECT * pSrcRect = &paSrcRegions[i];
- const RTRECT * pDstRect = &paDstRegions[i];
+ const CR_TEXDATA *pTexData;
+ PCRTRECT pSrcRect = &paSrcRegions[i];
+ PCRTRECT pDstRect = &paDstRegions[i];
RTRECT DstRect, RestrictDstRect;
RTRECT SrcRect, RestrictSrcRect;
@@ -2069,7 +2309,7 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
pSrcRect = &SrcRect;
pDstRect = &DstRect;
- const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
+ pTexData = CrVrScrCompositorEntryTexGet(pEntry);
CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags | CRBLT_F_NOALPHA);
@@ -2080,11 +2320,14 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
else
{
DEBUG_WARN(("CrBltEnter failed rc %d", rc));
+# ifndef DEBUG_VERBOSE
+ AssertMsgFailed(("CrBltEnter failed rc %Rrc", rc));
+# endif
}
}
else
{
- Assert(0);
+ AssertMsgFailed(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %Rrc\n", rc));
DEBUG_MSG_1(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d\n", rc));
}
}
@@ -2094,22 +2337,26 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
*/
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
[m_pSharedGLCtx flushBuffer];
+
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
-- (void)presentComposition:(const VBOXVR_SCR_COMPOSITOR_ENTRY*)pChangedEntry
+- (void)presentComposition:(PCVBOXVR_SCR_COMPOSITOR_ENTRY)pChangedEntry
{
+ COCOA_LOG_FLOW(("%s: self=%p pChangedEntry=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pChangedEntry));
[self vboxTryDraw];
}
- (void)vboxBlitterSyncWindow
{
- CR_BLITTER_WINDOW WinInfo;
- NSRect r;
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+ CR_BLITTER_WINDOW WinInfo;
+ NSRect r;
if (!m_pBlitter)
return;
- memset(&WinInfo, 0, sizeof (WinInfo));
+ RT_ZERO(WinInfo);
r = [self frame];
WinInfo.width = r.size.width;
@@ -2127,25 +2374,27 @@ DECLINLINE(void) vboxNSRectToRectStretched(const NSRect *pR, RTRECT *pRect, floa
#ifdef VBOX_WITH_CRDUMPER_THUMBNAIL
static int g_cVBoxTgaCtr = 0;
#endif
-- (void)vboxPresentToDockTileCS:(const VBOXVR_SCR_COMPOSITOR*)pCompositor
+- (void)vboxPresentToDockTileCS:(PCVBOXVR_SCR_COMPOSITOR)pCompositor
{
- NSRect r = [self frame];
- NSRect rr = NSZeroRect;
- GLint i = 0;
+ COCOA_LOG_FLOW(("%s: self=%p pCompositor=%p\n", __PRETTY_FUNCTION__, (void *)self, (void *)pCompositor));
+ NSRect r = [self frame];
+ NSRect rr = NSZeroRect;
NSDockTile *pDT = nil;
- float xStretch, yStretch;
+ float xStretch;
+ float yStretch;
if ([m_DockTileView thumbBitmap] != nil)
{
- /* Only update after at least 200 ms, cause glReadPixels is
+ /*
+ * Only update after at least 200 ms, cause glReadPixels is
* heavy performance wise. */
- uint64_t uiNewTime = RTTimeMilliTS();
+ uint64_t msTS = RTTimeSystemMilliTS();
VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
- if (uiNewTime - m_uiDockUpdateTime > 200)
+ if (msTS - m_msDockUpdateTS > 200)
{
- m_uiDockUpdateTime = uiNewTime;
+ m_msDockUpdateTS = msTS;
#if 0
/* todo: check this for optimization */
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
@@ -2176,20 +2425,23 @@ static int g_cVBoxTgaCtr = 0;
while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
{
uint32_t cRegions;
- const RTRECT *paSrcRegions, *paDstRegions;
+ PCRTRECT paSrcRegions;
+ PCRTRECT paDstRegions;
int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
if (RT_SUCCESS(rc))
{
- uint32_t i;
- int rc = CrBltEnter(m_pBlitter);
+ rc = CrBltEnter(m_pBlitter);
if (RT_SUCCESS(rc))
{
+ uint32_t i;
for (i = 0; i < cRegions; ++i)
{
- const RTRECT * pSrcRect = &paSrcRegions[i];
- const RTRECT * pDstRect = &paDstRegions[i];
- RTRECT SrcRect, DstRect, RestrictSrcRect, RestrictDstRect;
+ const CR_TEXDATA *pTexData;
+ PCRTRECT pSrcRect = &paSrcRegions[i];
+ PCRTRECT pDstRect = &paDstRegions[i];
+ RTRECT DstRect, RestrictDstRect;
+ RTRECT SrcRect, RestrictSrcRect;
vboxNSRectToRect(&m_RootRect, &RestrictDstRect);
VBoxRectIntersected(&RestrictDstRect, pDstRect, &DstRect);
@@ -2211,7 +2463,7 @@ static int g_cVBoxTgaCtr = 0;
pSrcRect = &SrcRect;
pDstRect = &DstRect;
- const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
+ pTexData = CrVrScrCompositorEntryTexGet(pEntry);
CrBltBlitTexMural(m_pBlitter, true, CrTdTexGet(pTexData), pSrcRect, pDstRect, 1, fFlags);
}
@@ -2220,12 +2472,15 @@ static int g_cVBoxTgaCtr = 0;
else
{
DEBUG_WARN(("CrBltEnter failed rc %d", rc));
+#ifndef DEBUG_VERBOSE
+ AssertMsgFailed(("CrBltEnter failed rc %Rrc", rc));
+#endif
}
}
else
{
- Assert(0);
DEBUG_MSG_1(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d\n", rc));
+ AssertMsgFailed(("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %Rrc\n", rc));
}
}
@@ -2233,6 +2488,7 @@ static int g_cVBoxTgaCtr = 0;
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
glReadBuffer(GL_BACK);
+
/* Here the magic of reading the FBO content in our own buffer
* happens. We have to lock this access, in the case the dock
* is updated currently. */
@@ -2259,14 +2515,12 @@ static int g_cVBoxTgaCtr = 0;
- (void)clearVisibleRegions
{
- DEBUG_FUNC_ENTER();
if(m_paClipRects)
{
RTMemFree(m_paClipRects);
m_paClipRects = NULL;
}
m_cClipRects = 0;
- DEBUG_FUNC_LEAVE();
}
- (GLboolean)vboxNeedsEmptyPresent
@@ -2280,13 +2534,11 @@ static int g_cVBoxTgaCtr = 0;
return GL_FALSE;
}
-- (void)setVisibleRegions:(GLint)cRects paRects:(const GLint*)paRects
+- (void)setVisibleRegions:(GLint)cRects paRects:(const GLint *)paRects
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s: self=%p cRects=%d paRects=%p\n", __PRETTY_FUNCTION__, (void *)self, cRects, (void *)paRects));
GLint cOldRects = m_cClipRects;
- DEBUG_MSG_1(("OVIW(%p): setVisibleRegions: cRects=%d\n", (void*)self, cRects));
-
[self clearVisibleRegions];
if (cRects > 0)
@@ -2297,41 +2549,44 @@ static int g_cVBoxTgaCtr = 0;
DEBUG_MSG_1(("OVIW(%p): setVisibleRegions: %d - %d %d %d %d\n", (void*)self, i, paRects[i * 4], paRects[i * 4 + 1], paRects[i * 4 + 2], paRects[i * 4 + 3]));
#endif
- m_paClipRects = (GLint*)RTMemAlloc(sizeof(GLint) * 4 * cRects);
- m_cClipRects = cRects;
- memcpy(m_paClipRects, paRects, sizeof(GLint) * 4 * cRects);
+ m_paClipRects = (GLint *)RTMemDup(paRects, sizeof(GLint) * 4 * cRects);
+ m_cClipRects = cRects;
}
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns\n", __PRETTY_FUNCTION__));
}
- (NSView*)dockTileScreen
{
- DEBUG_FUNC_ENTER();
- NSView *contentView = [[[NSApplication sharedApplication] dockTile] contentView];
- NSView *screenContent = nil;
- /* First try the new variant which checks if this window is within the
- screen which is previewed in the dock. */
- if ([contentView respondsToSelector:@selector(screenContentWithParentView:)])
- screenContent = [contentView performSelector:@selector(screenContentWithParentView:) withObject:(id)m_pParentView];
- /* If it fails, fall back to the old variant (VBox...) */
- else if ([contentView respondsToSelector:@selector(screenContent)])
- screenContent = [contentView performSelector:@selector(screenContent)];
-
- DEBUG_FUNC_LEAVE();
- return screenContent;
+ COCOA_LOG_FLOW(("%s: self=%p\n", __PRETTY_FUNCTION__, (void *)self));
+ NSView *pContentView = [[[NSApplication sharedApplication] dockTile] contentView];
+ NSView *pScreenContent = nil;
+ /*
+ * First try the new variant which checks if this window is within the
+ * screen which is previewed in the dock.
+ */
+ if ([pContentView respondsToSelector:@selector(screenContentWithParentView:)])
+ pScreenContent = [pContentView performSelector:@selector(screenContentWithParentView:) withObject:(id)m_pParentView];
+ /*
+ * If it fails, fall back to the old variant (VBox...).
+ */
+ else if ([pContentView respondsToSelector:@selector(screenContent)])
+ pScreenContent = [pContentView performSelector:@selector(screenContent)];
+
+ COCOA_LOG_FLOW(("%s: returns %p (pContentView=%p)\n", __PRETTY_FUNCTION__, (void *)pScreenContent, (void *)pContentView));
+ return pScreenContent;
}
- (void)reshapeDockTile
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("%s:\n", __PRETTY_FUNCTION__));
NSRect newFrame = NSZeroRect;
-
NSView *pView = [self dockTileScreen];
if (pView != nil)
{
NSRect dockFrame = [pView frame];
- /* todo: this is not correct, we should use framebuffer size here, while parent view frame size may differ in case of scrolling */
+ /** @todo This is not correct, we should use framebuffer size here, while
+ * parent view frame size may differ in case of scrolling. */
NSRect parentFrame = [m_pParentView frame];
m_FBOThumbScaleX = (float)dockFrame.size.width / parentFrame.size.width;
@@ -2344,10 +2599,12 @@ static int g_cVBoxTgaCtr = 0;
*/
[m_DockTileView setFrame: newFrame];
}
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("%s: returns - newFrame={%d,%d %d,%d} pView=%d\n", __PRETTY_FUNCTION__, (int)newFrame.origin.x,
+ (int)newFrame.origin.y, (int)newFrame.size.width, (int)newFrame.size.height, (void *)pView));
}
- at end
+ at end /* @implementation OverlayView */
+
/********************************************************************************
*
@@ -2356,41 +2613,49 @@ static int g_cVBoxTgaCtr = 0;
********************************************************************************/
void cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, NativeNSOpenGLContextRef pSharedCtx)
{
- DEBUG_FUNC_ENTER();
- NSOpenGLPixelFormat *pFmt = nil;
-
+ COCOA_LOG_FLOW(("cocoaGLCtxCreate: ppCtx=%p fVisParams=%#x pSharedCtx=%p\n", (void *)ppCtx, fVisParams, (void *)pSharedCtx));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
+ NSOpenGLPixelFormat *pFmt = nil;
NSOpenGLPixelFormatAttribute attribs[24] =
{
- NSOpenGLPFAWindow,
+#ifdef IN_VMSVGA3D
+ NSOpenGLPFAOpenGLProfile, (NSOpenGLPixelFormatAttribute)0,
+#endif
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24
};
- int i = 4;
+ int i = 3;
+
+#ifdef IN_VMSVGA3D
+ if (fVisParams & VMSVGA3D_NON_DEFAULT_PROFILE_BIT)
+ attribs[1] = VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE >= 3.2 ? NSOpenGLProfileVersionLegacy : NSOpenGLProfileVersion3_2Core;
+ else
+ attribs[1] = VBOX_VMSVGA3D_DEFAULT_OGL_PROFILE >= 3.2 ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy;
+#endif
if (fVisParams & CR_ALPHA_BIT)
{
- DEBUG_MSG(("CR_ALPHA_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_ALPHA_BIT requested\n"));
attribs[i++] = NSOpenGLPFAAlphaSize;
attribs[i++] = 8;
}
if (fVisParams & CR_DEPTH_BIT)
{
- DEBUG_MSG(("CR_DEPTH_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_DEPTH_BIT requested\n"));
attribs[i++] = NSOpenGLPFADepthSize;
attribs[i++] = 24;
}
if (fVisParams & CR_STENCIL_BIT)
{
- DEBUG_MSG(("CR_STENCIL_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_STENCIL_BIT requested\n"));
attribs[i++] = NSOpenGLPFAStencilSize;
attribs[i++] = 8;
}
if (fVisParams & CR_ACCUM_BIT)
{
- DEBUG_MSG(("CR_ACCUM_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_ACCUM_BIT requested\n"));
attribs[i++] = NSOpenGLPFAAccumSize;
if (fVisParams & CR_ALPHA_BIT)
attribs[i++] = 32;
@@ -2399,7 +2664,7 @@ void cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, Na
}
if (fVisParams & CR_MULTISAMPLE_BIT)
{
- DEBUG_MSG(("CR_MULTISAMPLE_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_MULTISAMPLE_BIT requested\n"));
attribs[i++] = NSOpenGLPFASampleBuffers;
attribs[i++] = 1;
attribs[i++] = NSOpenGLPFASamples;
@@ -2407,20 +2672,20 @@ void cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, Na
}
if (fVisParams & CR_DOUBLE_BIT)
{
- DEBUG_MSG(("CR_DOUBLE_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_DOUBLE_BIT requested\n"));
attribs[i++] = NSOpenGLPFADoubleBuffer;
}
if (fVisParams & CR_STEREO_BIT)
{
/* We don't support that.
- DEBUG_MSG(("CR_STEREO_BIT requested\n"));
+ COCOA_LOG_FLOW((" CR_STEREO_BIT requested\n"));
attribs[i++] = NSOpenGLPFAStereo;
*/
}
if (VBoxOglIsOfflineRenderingAppropriate())
{
- DEBUG_MSG(("Offline rendering is enabled\n"));
+ COCOA_LOG_FLOW((" Offline rendering is enabled\n"));
attribs[i++] = NSOpenGLPFAAllowOfflineRenderers;
}
@@ -2433,6 +2698,7 @@ void cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, Na
if (pFmt)
{
*ppCtx = [[OverlayOpenGLContext alloc] initWithFormat:pFmt shareContext:pSharedCtx];
+ Assert(*ppCtx);
/* Enable multi threaded OpenGL engine */
/*
@@ -2441,25 +2707,27 @@ void cocoaGLCtxCreate(NativeNSOpenGLContextRef *ppCtx, GLbitfield fVisParams, Na
if (err != kCGLNoError)
printf ("Couldn't enable MT OpenGL engine!\n");
*/
-
- DEBUG_MSG(("New context %X\n", (uint)*ppCtx));
+ }
+ else
+ {
+ AssertFailed();
+ *ppCtx = NULL;
}
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaGLCtxDestroy: returns *ppCtx=%p\n", (void *)*ppCtx));
}
void cocoaGLCtxDestroy(NativeNSOpenGLContextRef pCtx)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaGLCtxDestroy: pCtx=%p\n", (void *)pCtx));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
[pCtx release];
/*[pCtx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];*/
[pPool release];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaGLCtxDestroy: returns\n"));
}
/********************************************************************************
@@ -2467,53 +2735,62 @@ void cocoaGLCtxDestroy(NativeNSOpenGLContextRef pCtx)
* View management
*
********************************************************************************/
-typedef struct CR_RCD_CREATEVIEW
+static OverlayView *vboxViewCreate(WindowInfo *pWinInfo, NativeNSViewRef pParentView)
{
- WindowInfo *pWinInfo;
- NSView *pParentView;
- GLbitfield fVisParams;
- /* out */
- OverlayView *pView;
-} CR_RCD_CREATEVIEW;
+ COCOA_LOG_FLOW(("vboxViewCreate: pWinInfo=%p pParentView=%p\n", pWinInfo, (void *)pParentView));
-static OverlayView * vboxViewCreate(WindowInfo *pWinInfo, NativeNSViewRef pParentView)
-{
- DEBUG_FUNC_ENTER();
- /* Create our worker view */
- OverlayView* pView = [[OverlayView alloc] initWithFrame:NSZeroRect thread:RTThreadSelf() parentView:pParentView winInfo:pWinInfo];
+ /* Create our worker view. */
+ OverlayView *pView = [[OverlayView alloc] initWithFrame:NSZeroRect
+ thread:RTThreadSelf()
+ parentView:pParentView
+ winInfo:pWinInfo];
if (pView)
{
/* We need a real window as container for the view */
[[OverlayWindow alloc] initWithParentView:pParentView overlayView:pView];
/* Return the freshly created overlay view */
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("vboxViewCreate: returns %p\n", (void *)pView));
return pView;
}
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("vboxViewCreate: returns NULL\n"));
return NULL;
}
+#ifndef IN_VMSVGA3D
+
+typedef struct CR_RCD_CREATEVIEW
+{
+ WindowInfo *pWinInfo;
+ NSView *pParentView;
+ GLbitfield fVisParams;
+ /* out */
+ OverlayView *pView;
+} CR_RCD_CREATEVIEW;
+
static DECLCALLBACK(void) vboxRcdCreateView(void *pvCb)
{
- DEBUG_FUNC_ENTER();
- CR_RCD_CREATEVIEW * pCreateView = (CR_RCD_CREATEVIEW*)pvCb;
+ CR_RCD_CREATEVIEW *pCreateView = (CR_RCD_CREATEVIEW *)pvCb;
pCreateView->pView = vboxViewCreate(pCreateView->pWinInfo, pCreateView->pParentView);
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("vboxRcdCreateView: returns pView=%p\n", (void *)pCreateView->pView));
}
+#endif /* !IN_VMSVGA3D */
+
void cocoaViewCreate(NativeNSViewRef *ppView, WindowInfo *pWinInfo, NativeNSViewRef pParentView, GLbitfield fVisParams)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewCreate: ppView=%p pWinInfo=%p pParentView=%p fVisParams=%#x\n",
+ (void *)ppView, (void *)pWinInfo, (void *)pParentView, fVisParams));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
/* make sure all tasks are run, to preserve the order */
+ VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
[pRunner runTasksSyncIfPossible];
renderspuWinRetain(pWinInfo);
+#ifndef IN_VMSVGA3D
if (renderspuCalloutAvailable())
{
CR_RCD_CREATEVIEW CreateView;
@@ -2525,8 +2802,9 @@ void cocoaViewCreate(NativeNSViewRef *ppView, WindowInfo *pWinInfo, NativeNSView
*ppView = CreateView.pView;
}
else
+#endif
{
- DEBUG_MSG(("no callout available on createWindow\n"));
+ DEBUG_MSG_NOT_VMSVGA3D(("no callout available on createWindow\n"));
#if 0
dispatch_sync(dispatch_get_main_queue(), ^{
#endif
@@ -2540,127 +2818,113 @@ void cocoaViewCreate(NativeNSViewRef *ppView, WindowInfo *pWinInfo, NativeNSView
renderspuWinRelease(pWinInfo);
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewCreate: returns *ppView=%p\n", (void *)*ppView));
}
void cocoaViewReparent(NativeNSViewRef pView, NativeNSViewRef pParentView)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewReparent: pView=%p pParentView=%p\n", (void *)pView, (void *)pParentView));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- OverlayView* pOView = (OverlayView*)pView;
-
+ OverlayView *pOView = (OverlayView *)pView;
if (pOView)
- {
[pOView vboxReparent:pParentView];
- }
[pPool release];
-
- DEBUG_FUNC_LEAVE();
-}
-
-typedef struct CR_RCD_DESTROYVIEW
-{
- OverlayView *pView;
-} CR_RCD_DESTROYVIEW;
-
-static DECLCALLBACK(void) vboxRcdDestroyView(void *pvCb)
-{
- DEBUG_FUNC_ENTER();
- CR_RCD_DESTROYVIEW * pDestroyView = (CR_RCD_DESTROYVIEW*)pvCb;
- [pDestroyView->pView vboxDestroy];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewReparent: returns\n"));
}
void cocoaViewDestroy(NativeNSViewRef pView)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewDestroy: pView=%p\n", (void *)pView));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
[pRunner addObj:pView selector:@selector(vboxDestroy) arg:nil];
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewDestroy: returns\n"));
}
void cocoaViewShow(NativeNSViewRef pView, GLboolean fShowIt)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewShow: pView=%p fShowIt=%d\n", (void *)pView, fShowIt));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- [(OverlayView*)pView vboxSetVisible:fShowIt];
+ [(OverlayView *)pView vboxSetVisible:fShowIt];
[pPool release];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewShow: returns\n"));
}
void cocoaViewDisplay(NativeNSViewRef pView)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewDisplay: pView=%p\n", (void *)pView));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
+#ifndef IN_VMSVGA3D
DEBUG_WARN(("cocoaViewDisplay should never happen!\n"));
DEBUG_MSG_1(("cocoaViewDisplay %p\n", (void*)pView));
- [(OverlayView*)pView swapFBO];
+#endif
+ [(OverlayView *)pView swapFBO];
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewDisplay: returns\n"));
}
void cocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewSetPosition: pView=%p pParentView=%p x=%d y=%d\n", (void *)pView, (void *)pParentView, x, y));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- [(OverlayView*)pView vboxSetPos:NSMakePoint(x, y)];
+ [(OverlayView *)pView vboxSetPos:NSMakePoint(x, y)];
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewSetPosition: returns\n"));
}
-void cocoaViewSetSize(NativeNSViewRef pView, int w, int h)
+void cocoaViewSetSize(NativeNSViewRef pView, int cx, int cy)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewSetSize: pView=%p cx=%d cy=%d\n", (void *)pView, cx, cy));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- [(OverlayView*)pView vboxSetSize:NSMakeSize(w, h)];
+ [(OverlayView *)pView vboxSetSize:NSMakeSize(cx, cy)];
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewSetSize: returns\n"));
}
+#ifndef IN_VMSVGA3D
+
typedef struct CR_RCD_GETGEOMETRY
{
OverlayView *pView;
NSRect rect;
} CR_RCD_GETGEOMETRY;
-static DECLCALLBACK(void) vboxRcdGetGeomerty(void *pvCb)
+static DECLCALLBACK(void) vboxRcdGetGeomerty(void *pvUser)
{
- DEBUG_FUNC_ENTER();
- CR_RCD_GETGEOMETRY * pGetGeometry = (CR_RCD_GETGEOMETRY*)pvCb;
+ CR_RCD_GETGEOMETRY *pGetGeometry = (CR_RCD_GETGEOMETRY *)pvUser;
pGetGeometry->rect = [[pGetGeometry->pView window] frame];
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("vboxRcdGetGeomerty: (x,y)=(%d,%d) (cx,cy)=(%d,%d)\n", pGetGeometry->rect.origin.x, pGetGeometry->rect.origin.y,
+ pGetGeometry->rect.size.width, pGetGeometry->rect.size.height));
}
-void cocoaViewGetGeometry(NativeNSViewRef pView, int *pX, int *pY, int *pW, int *pH)
+#endif /* !IN_VMSVGA3D */
+
+void cocoaViewGetGeometry(NativeNSViewRef pView, int *px, int *py, int *pcx, int *pcy)
{
- DEBUG_FUNC_ENTER();
- NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
+ COCOA_LOG_FLOW(("cocoaViewGetGeometry: pView=%p px=%p py=%p pcx=%p pcy=%p\n",
+ (void *)pView, (void *)px, (void *)py, (void *)pcx, (void *)pcy));
+ NSAutoreleasePool *pPool;
+ pPool = [[NSAutoreleasePool alloc] init];
- NSRect frame;
- VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
/* make sure all tasks are run, to preserve the order */
+ VBoxMainThreadTaskRunner *pRunner = [VBoxMainThreadTaskRunner globalInstance];
[pRunner runTasksSyncIfPossible];
-
+ NSRect frame;
+#ifndef IN_VMSVGA3D
if (renderspuCalloutAvailable())
{
CR_RCD_GETGEOMETRY GetGeometry;
@@ -2669,32 +2933,35 @@ void cocoaViewGetGeometry(NativeNSViewRef pView, int *pX, int *pY, int *pW, int
frame = GetGeometry.rect;
}
else
+#endif
{
- DEBUG_MSG(("no callout available on getGeometry\n"));
+ DEBUG_MSG_NOT_VMSVGA3D(("no callout available on getGeometry\n"));
frame = [[pView window] frame];
}
- *pX = frame.origin.x;
- *pY = frame.origin.y;
- *pW = frame.size.width;
- *pH = frame.size.height;
+ *px = frame.origin.x;
+ *py = frame.origin.y;
+ *pcx = frame.size.width;
+ *pcy = frame.size.height;
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewGetGeometry: returns *px=%d, *py=%d, *pcx=%d, *pcy=%d\n", *px, *py, *pcx, *pcy));
}
-void cocoaViewPresentComposition(NativeNSViewRef pView, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
+void cocoaViewPresentComposition(NativeNSViewRef pView, PCVBOXVR_SCR_COMPOSITOR_ENTRY pChangedEntry)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewPresentComposition: pView=%p pChangedEntry=%p\n", (void *)pView, (void *)pChangedEntry));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
NSOpenGLContext *pCtx;
/* view should not necesserily have a context set */
- pCtx = [(OverlayView*)pView glCtx];
+ pCtx = [(OverlayView *)pView glCtx];
if (!pCtx)
{
- ContextInfo * pCtxInfo = renderspuDefaultSharedContextAcquire();
+#ifdef IN_VMSVGA3D /** @todo VMSVGA3 */
+ pCtx = NULL;
+#else
+ ContextInfo *pCtxInfo = renderspuDefaultSharedContextAcquire();
if (!pCtxInfo)
{
DEBUG_WARN(("renderspuDefaultSharedContextAcquire returned NULL"));
@@ -2705,28 +2972,26 @@ void cocoaViewPresentComposition(NativeNSViewRef pView, const struct VBOXVR_SCR_
}
pCtx = pCtxInfo->context;
+#endif
- [(OverlayView*)pView setGLCtx:pCtx];
+ [(OverlayView *)pView setGLCtx:pCtx];
}
- [(OverlayView*)pView presentComposition:pChangedEntry];
+ [(OverlayView *)pView presentComposition:pChangedEntry];
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewPresentComposition: returns\n"));
}
void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
{
- DEBUG_FUNC_ENTER();
+ COCOA_LOG_FLOW(("cocoaViewMakeCurrentContext: pView=%p pCtx=%p\n", (void *)pView, (void *)pCtx));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- DEBUG_MSG(("cocoaViewMakeCurrentContext(%p, %p)\n", (void*)pView, (void*)pCtx));
-
if (pView)
{
- [(OverlayView*)pView setGLCtx:pCtx];
- [(OverlayView*)pView makeCurrentFBO];
+ [(OverlayView *)pView setGLCtx:pCtx];
+ [(OverlayView *)pView makeCurrentFBO];
}
else
{
@@ -2734,33 +2999,95 @@ void cocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef
}
[pPool release];
-
- DEBUG_FUNC_LEAVE();
+ COCOA_LOG_FLOW(("cocoaViewMakeCurrentContext: returns\n"));
}
GLboolean cocoaViewNeedsEmptyPresent(NativeNSViewRef pView)
{
- DEBUG_FUNC_ENTER();
-
+ COCOA_LOG_FLOW(("cocoaViewNeedsEmptyPresent: pView=%p\n", (void *)pView));
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- GLboolean fNeedsPresent = [(OverlayView*)pView vboxNeedsEmptyPresent];
+ GLboolean fNeedsPresent = [(OverlayView *)pView vboxNeedsEmptyPresent];
[pPool release];
-
- DEBUG_FUNC_LEAVE();
-
+ COCOA_LOG_FLOW(("cocoaViewNeedsEmptyPresent: returns %d\n", fNeedsPresent));
return fNeedsPresent;
}
-void cocoaViewSetVisibleRegion(NativeNSViewRef pView, GLint cRects, const GLint* paRects)
+void cocoaViewSetVisibleRegion(NativeNSViewRef pView, GLint cRects, const GLint *paRects)
+{
+ COCOA_LOG_FLOW(("cocoaViewSetVisibleRegion: pView=%p cRects=%d paRects=%p)\n", (void *)pView, cRects, (void const *)paRects));
+ NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
+
+ [(OverlayView *)pView setVisibleRegions:cRects paRects:paRects];
+
+ [pPool release];
+ COCOA_LOG_FLOW(("cocoaViewSetVisibleRegion: returns\n"));
+}
+
+
+#ifdef IN_VMSVGA3D
+/*
+ * VMSVGA3D interface.
+ */
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaCreateContext(NativeNSOpenGLContextRef *ppCtx, NativeNSOpenGLContextRef pSharedCtx,
+ bool fOtherProfile)
+{
+ cocoaGLCtxCreate(ppCtx, CR_ALPHA_BIT | CR_DEPTH_BIT | CR_DOUBLE_BIT | (fOtherProfile ? VMSVGA3D_NON_DEFAULT_PROFILE_BIT : 0),
+ pSharedCtx);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyContext(NativeNSOpenGLContextRef pCtx)
+{
+ cocoaGLCtxDestroy(pCtx);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaCreateView(NativeNSViewRef *ppView, NativeNSViewRef pParentView)
{
+ /** @todo share WinInfo with caller and maintain it better. */
+ WindowInfo *pWinInfo = (WindowInfo *)RTMemAllocZ(sizeof(WindowInfo));
+ AssertLogRelReturnVoid(pWinInfo);
+ pWinInfo->cRefs = 1;
+ RTCritSectInit(&pWinInfo->CompositorLock);
+
+ cocoaViewCreate(ppView, pWinInfo, pParentView, 0 /* fVisParams - ignored */);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaDestroyView(NativeNSViewRef pView)
+{
+ cocoaViewDestroy(pView);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaViewSetPosition(NativeNSViewRef pView, NativeNSViewRef pParentView, int x, int y)
+{
+ cocoaViewSetPosition(pView, pParentView, x, y);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaViewSetSize(NativeNSViewRef pView, int w, int h)
+{
+ cocoaViewSetSize(pView, w, h);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaViewMakeCurrentContext(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
+{
+ cocoaViewMakeCurrentContext(pView, pCtx);
+}
+
+VMSVGA3D_DECL(void) vmsvga3dCocoaSwapBuffers(NativeNSViewRef pView, NativeNSOpenGLContextRef pCtx)
+{
+# if 1
+ Assert([(OverlayView *)pView glCtx] == pCtx);
+ cocoaViewDisplay(pView);
+# else
DEBUG_FUNC_ENTER();
NSAutoreleasePool *pPool = [[NSAutoreleasePool alloc] init];
- [(OverlayView*)pView setVisibleRegions:cRects paRects:paRects];
+ [pCtx flushBuffer];
[pPool release];
-
DEBUG_FUNC_LEAVE();
+# endif
}
+
+#endif /* IN_VMSVGA3D */
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_extend.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_extend.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_header.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack_header.py
old mode 100644
new mode 100755
diff --git a/src/VBox/HostServices/auth/Makefile.kmk b/src/VBox/HostServices/auth/Makefile.kmk
index 5b001ff..02ce75e 100644
--- a/src/VBox/HostServices/auth/Makefile.kmk
+++ b/src/VBox/HostServices/auth/Makefile.kmk
@@ -28,7 +28,7 @@ VBoxAuth_TEMPLATE = VBOXR3
VBoxAuth_SOURCES.linux = pam/VBoxAuthPAM.c
VBoxAuth_SOURCES.solaris = pam/VBoxAuthPAM.c
VBoxAuth_SOURCES.freebsd = pam/VBoxAuthPAM.c
-VBoxAuth_SOURCES.win = winlogon/winlogon.cpp
+VBoxAuth_SOURCES.win = winlogon/winlogon.cpp winlogon/VBoxAuth.rc
VBoxAuth_SOURCES.darwin = directoryservice/directoryservice.cpp
VBoxAuth_LIBS.linux = $(LIB_RUNTIME) dl
VBoxAuth_LIBS.solaris = $(LIB_RUNTIME) dl
@@ -44,6 +44,7 @@ ifndef VBOX_ONLY_SDK
endif
VBoxAuthSimple_TEMPLATE = VBOXMAINCLIENTDLL
VBoxAuthSimple_SOURCES = simple/VBoxAuthSimple.cpp
+VBoxAuthSimple_SOURCES.win = simple/VBoxAuthSimple.rc
# Install the SDK samples.
INSTALLS += VBoxAuth-samples
diff --git a/src/VBox/HostServices/auth/simple/VBoxAuthSimple.rc b/src/VBox/HostServices/auth/simple/VBoxAuthSimple.rc
new file mode 100644
index 0000000..f6bfe3b
--- /dev/null
+++ b/src/VBox/HostServices/auth/simple/VBoxAuthSimple.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxAuthSimple.rc $ */
+/** @file
+ * VBoxAuthSimple - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Simple Authentication Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxAuthSimple\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxAuthSimple.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/HostServices/auth/winlogon/VBoxAuth.rc b/src/VBox/HostServices/auth/winlogon/VBoxAuth.rc
new file mode 100644
index 0000000..79df11c
--- /dev/null
+++ b/src/VBox/HostServices/auth/winlogon/VBoxAuth.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxAuth.rc $ */
+/** @file
+ * VBoxAuth - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Authentication Host Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxAuth\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxAuth.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Installer/darwin/Makefile.kmk b/src/VBox/Installer/darwin/Makefile.kmk
index 27d85e0..c796c3e 100644
--- a/src/VBox/Installer/darwin/Makefile.kmk
+++ b/src/VBox/Installer/darwin/Makefile.kmk
@@ -409,7 +409,8 @@ if defined(VBOX_WITH_PYTHON) && !defined(VBOX_WITHOUT_VBOXPYTHON_FOR_OSX_10_7)
endif
ifdef VBOX_WITH_VMSVGA3D
VBOX_DI_VBAPP_DYLIBS += \
- MacOS/VBoxSVGA3D.dylib
+ MacOS/VBoxSVGA3D.dylib \
+ MacOS/VBoxSVGA3DObjC.dylib
endif
VBOX_DI_VBAPP_DYLIBS.x86 := \
diff --git a/src/VBox/Installer/linux/distributions_rpm b/src/VBox/Installer/linux/distributions_rpm
index 75501ed..575d3fa 100644
--- a/src/VBox/Installer/linux/distributions_rpm
+++ b/src/VBox/Installer/linux/distributions_rpm
@@ -4,6 +4,10 @@ openSUSE113 = OPENSUSE_11_3
sles11.0 = SLES_11_0
sles10.1 = SLES_10_1
mdv2011.0 = MANDRIVA_2011_0
+fedora22 = FEDORA_22
+fedora21 = FEDORA_21
+fedora20 = FEDORA_20
+fedora19 = FEDORA_19
fedora18 = FEDORA_18
fedora17 = FEDORA_17
fedora16 = FEDORA_16
diff --git a/src/VBox/Installer/linux/rpm/rules b/src/VBox/Installer/linux/rpm/rules
index 88a377c..3a60467 100755
--- a/src/VBox/Installer/linux/rpm/rules
+++ b/src/VBox/Installer/linux/rpm/rules
@@ -84,7 +84,7 @@ ifneq ($(MAKECMDGOALS),clean)
$(error Cannot detect package distribution (rpmrel=$(rpmrel)))
endif
- ifeq ($(filter-out el5 el6 ol5 ol6 el7 centos5 centos6 fedora15 fedora16 fedora17 fedora18,$(rpmrel)),)
+ ifeq ($(filter-out el5 el6 ol5 ol6 el7 centos5 centos6 fedora17 fedora18 fedora19 fedora20 fedora21 fedora22,$(rpmrel)),)
rpmspec := rpm_redhat
endif
ifeq ($(filter-out openSUSE110 openSUSE111 openSUSE112 openSUSE113 openSUSE114 openSUSE123 sles10.1 sles11.0,$(rpmrel)),)
@@ -152,7 +152,7 @@ bld_flags := AUTOCFG=$(current)/rpm/AutoConfig.kmk \
PATH_OUT=$(builddir) \
VBOX_WITHOUT_EXTPACK_PUEL_PACKING=1 \
VBOX_WITHOUT_EXTPACK_VNC_PACKING=1 \
- $(if $(filter el5 el6 sles10.1,$(rpmrel)),,VBOX_WITH_VMSVGA3D=1) \
+ $(if $(filter el5 el6 sles10.1 sles11.0,$(rpmrel)),,VBOX_WITH_VMSVGA3D=1) \
VBOX_DO_STRIP= \
VBOX_WITH_MULTIVERSION_PYTHON= \
$(doc_dir) \
@@ -163,7 +163,7 @@ bld_flags := AUTOCFG=$(current)/rpm/AutoConfig.kmk \
$(if $(VERBOSE),--print-directory KBUILD_VERBOSE=2,--no-print-directory) \
$(if $(STAGEDISO),VBOX_WITHOUT_ADDITIONS=1,) \
$(if $(BLEEDING_EDGE),VBOX_BLEEDING_EDGE=$(BLEEDING_EDGE),) \
- $(if $(filter el5 ol5 centos5 sles10.1 sles11.0,$(rpmrel)),,VBOX_WITH_SYSFS_BY_DEFAULT=1)
+ $(if $(filter el5 ol5 centos5 sles10.1,$(rpmrel)),,VBOX_WITH_SYSFS_BY_DEFAULT=1)
rpm/configure-stamp:
cd $(vboxroot) && ./configure --odir=$(current)/rpm $(cfg_flags)
diff --git a/src/VBox/Installer/linux/run-inst.sh b/src/VBox/Installer/linux/run-inst.sh
index 9c32ef9..3834ac6 100755
--- a/src/VBox/Installer/linux/run-inst.sh
+++ b/src/VBox/Installer/linux/run-inst.sh
@@ -299,7 +299,9 @@ done
# uninstall any previous installation
INSTALL_DIR=""
uninstalled=0
-test -r "$CONFIG_DIR/$CONFIG" && . "$CONFIG_DIR/$CONFIG"
+test -r "$CONFIG_DIR/$CONFIG" &&
+ eval `grep ^INSTALL_DIR= "$CONFIG_DIR/$CONFIG"` 2>/dev/null &&
+ eval `grep ^UNINSTALLER= "$CONFIG_DIR/$CONFIG"` 2>/dev/null
if test -n "$INSTALL_DIR" -a -x "$INSTALL_DIR/$UNINSTALLER"; then
"$INSTALL_DIR/$UNINSTALLER" $NO_CLEANUP 1>&2 ||
abort "Failed to remove existing installation. Aborting..."
diff --git a/src/VBox/Installer/linux/vboxdrv-pardus.py b/src/VBox/Installer/linux/vboxdrv-pardus.py
old mode 100644
new mode 100755
diff --git a/src/VBox/Installer/win/InstallHelper/Makefile.kmk b/src/VBox/Installer/win/InstallHelper/Makefile.kmk
index d2c2f26..43564e3 100644
--- a/src/VBox/Installer/win/InstallHelper/Makefile.kmk
+++ b/src/VBox/Installer/win/InstallHelper/Makefile.kmk
@@ -29,6 +29,7 @@ endif
VBoxInstallHelper_SOURCES = \
VBoxInstallHelper.cpp \
VBoxInstallHelper.def \
+ VBoxInstallHelper.rc \
VBoxCommon.cpp
ifndef VBOX_OSE
VBoxInstallHelper_SOURCES += internal/VBoxSerial.cpp
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
index 8ab7111..5f3d765 100644
--- a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
+++ b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
@@ -498,6 +498,22 @@ UINT __stdcall InstallBranding(MSIHANDLE hModule)
static MSIHANDLE g_hCurrentModule = NULL;
+static VOID vboxDrvLoggerCallback(VBOXDRVCFG_LOG_SEVERITY enmSeverity, char * msg, void * pvContext)
+{
+ switch (enmSeverity)
+ {
+ case VBOXDRVCFG_LOG_SEVERITY_FLOW:
+ case VBOXDRVCFG_LOG_SEVERITY_REGULAR:
+ break;
+ case VBOXDRVCFG_LOG_SEVERITY_REL:
+ if (g_hCurrentModule)
+ logString(g_hCurrentModule, (LPCSTR)msg);
+ break;
+ default:
+ break;
+ }
+}
+
static VOID netCfgLoggerCallback(LPCSTR szString)
{
if (g_hCurrentModule)
@@ -523,6 +539,8 @@ static VOID netCfgLoggerEnable(MSIHANDLE hModule)
g_hCurrentModule = hModule;
VBoxNetCfgWinSetLogging((LOG_ROUTINE)netCfgLoggerCallback);
+ /* uncomment next line if you want to add logging information from VBoxDrvCfg.cpp */
+ VBoxDrvCfgLoggerSet(vboxDrvLoggerCallback, NULL);
}
static UINT errorConvertFromHResult(MSIHANDLE hModule, HRESULT hr)
@@ -949,11 +967,13 @@ UINT __stdcall RemoveHostOnlyInterfaces(MSIHANDLE hModule)
HRESULT hr = VBoxNetCfgWinRemoveAllNetDevicesOfId(NETADP_ID);
if (SUCCEEDED(hr))
{
- hr = VBoxDrvCfgInfUninstallAllSetupDi(&GUID_DEVCLASS_NET, NETADP_ID, L"Net", 0/* could be SUOI_FORCEDELETE */);
+ hr = VBoxDrvCfgInfUninstallAllSetupDi(&GUID_DEVCLASS_NET, L"Net", NETADP_ID, SUOI_FORCEDELETE/* could be SUOI_FORCEDELETE */);
if (FAILED(hr))
{
logStringW(hModule, L"RemoveHostOnlyInterfaces: NetAdp uninstalled successfully, but failed to remove INF files");
}
+ else
+ logStringW(hModule, L"RemoveHostOnlyInterfaces: NetAdp uninstalled successfully");
}
else
logStringW(hModule, L"RemoveHostOnlyInterfaces: NetAdp uninstall failed, hr = 0x%x", hr);
@@ -980,11 +1000,7 @@ UINT __stdcall StopHostOnlyInterfaces(MSIHANDLE hModule)
HRESULT hr = VBoxNetCfgWinPropChangeAllNetDevicesOfId(NETADP_ID, VBOXNECTFGWINPROPCHANGE_TYPE_DISABLE);
if (SUCCEEDED(hr))
- {
- hr = VBoxDrvCfgInfUninstallAllSetupDi(&GUID_DEVCLASS_NET, NETADP_ID, L"Net", 0/* could be SUOI_FORCEDELETE */);
- if (FAILED(hr))
- logStringW(hModule, L"StopHostOnlyInterfaces: VBoxDrvCfgInfUninstallAllSetupDi failed, hr = 0x%x", hr);
- }
+ logStringW(hModule, L"StopHostOnlyInterfaces: Disabling host interfaces was successful, hr = 0x%x", hr);
else
logStringW(hModule, L"StopHostOnlyInterfaces: Disabling host interfaces failed, hr = 0x%x", hr);
@@ -1075,6 +1091,51 @@ UINT __stdcall UpdateHostOnlyInterfaces(MSIHANDLE hModule)
return ERROR_SUCCESS;
}
+UINT __stdcall UninstallNetAdp(MSIHANDLE hModule)
+{
+#ifdef VBOX_WITH_NETFLT
+ INetCfg *pNetCfg;
+ UINT uErr;
+
+ netCfgLoggerEnable(hModule);
+
+ BOOL bOldIntMode = SetupSetNonInteractiveMode(FALSE);
+
+ __try
+ {
+ logStringW(hModule, L"Uninstalling NetAdp");
+
+ uErr = doNetCfgInit(hModule, &pNetCfg, TRUE);
+ if (uErr == ERROR_SUCCESS)
+ {
+ HRESULT hr = VBoxNetCfgWinNetAdpUninstall(pNetCfg);
+ if (hr != S_OK)
+ logStringW(hModule, L"UninstallNetAdp: VBoxNetCfgWinUninstallComponent failed, error = 0x%x", hr);
+
+ uErr = errorConvertFromHResult(hModule, hr);
+
+ VBoxNetCfgWinReleaseINetCfg(pNetCfg, TRUE);
+
+ logStringW(hModule, L"Uninstalling NetAdp done, error = 0x%x", uErr);
+ }
+ else
+ logStringW(hModule, L"UninstallNetAdp: doNetCfgInit failed, error = 0x%x", uErr);
+ }
+ __finally
+ {
+ if (bOldIntMode)
+ {
+ /* The prev mode != FALSE, i.e. non-interactive. */
+ SetupSetNonInteractiveMode(bOldIntMode);
+ }
+ netCfgLoggerDisable();
+ }
+#endif /* VBOX_WITH_NETFLT */
+
+ /* Never fail the install even if we did not succeed. */
+ return ERROR_SUCCESS;
+}
+
static bool isTAPDevice(const WCHAR *pwszGUID)
{
HKEY hNetcard;
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
index ec2e025..c408e3d 100644
--- a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
+++ b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
@@ -29,4 +29,5 @@ EXPORTS
StopHostOnlyInterfaces
UpdateHostOnlyInterfaces
RemoveHostOnlyInterfaces
+ UninstallNetAdp
diff --git a/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.rc b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.rc
new file mode 100644
index 0000000..772403b
--- /dev/null
+++ b/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxInstallHelper.rc $ */
+/** @file
+ * VBoxInstallHelper - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Installation Helper\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxInstallHelper\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxInstallHelper.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Installer/win/VBoxMergeNetAdpCA.wxi b/src/VBox/Installer/win/VBoxMergeNetAdpCA.wxi
index 4990746..9dcbe5a 100644
--- a/src/VBox/Installer/win/VBoxMergeNetAdpCA.wxi
+++ b/src/VBox/Installer/win/VBoxMergeNetAdpCA.wxi
@@ -22,5 +22,6 @@
<CustomAction Id="ca_StopHostOnlyInterfaces" BinaryKey="VBoxInstallHelper" DllEntry="StopHostOnlyInterfaces" Execute="deferred" Return="check" Impersonate="no"/>
<CustomAction Id="ca_UpdateHostOnlyInterfacesArgs" Property="ca_UpdateHostOnlyInterfaces" Value="[msm_VBoxNetworkAdpFolder]" Execute="immediate"/>
<CustomAction Id="ca_UpdateHostOnlyInterfaces" BinaryKey="VBoxInstallHelper" DllEntry="UpdateHostOnlyInterfaces" Execute="deferred" Return="check" Impersonate="no"/>
-
+ <CustomAction Id="ca_UninstallNetAdp" BinaryKey="VBoxInstallHelper" DllEntry="UninstallNetAdp" Execute="deferred" Return="check" Impersonate="no"/>
+ <CustomAction Id="ca_UninstallNetAdpArgs" Property="ca_UninstallNetAdp" Value="[msm_VBoxNetworkAdpFolder]" Execute="immediate"/>
</Include>
diff --git a/src/VBox/Installer/win/VBoxMergeNetAdpSeq.wxi b/src/VBox/Installer/win/VBoxMergeNetAdpSeq.wxi
index 452422f..af7ffb7 100644
--- a/src/VBox/Installer/win/VBoxMergeNetAdpSeq.wxi
+++ b/src/VBox/Installer/win/VBoxMergeNetAdpSeq.wxi
@@ -29,7 +29,7 @@
<?if $(env.VBOX_WITH_MSM_INSTALL) = "yes" ?>
<![CDATA[NOT Installed]]>
<?else ?>
- <![CDATA[&VBoxNetworkAdp=3]]>
+ <![CDATA[(NOT Installed)AND (&VBoxNetworkAdp=3)]]>
<?endif ?>
</Custom>
<!-- Don't remove the host-only interfaces on update, only on uninstall -->
@@ -38,8 +38,14 @@
</Custom>
<!-- First stop the existing host-only interfaces on update ... -->
<Custom Action="ca_StopHostOnlyInterfaces" After="InstallInitialize" >
- <![CDATA[(UPGRADINGPRODUCTCODE) OR (REMOVE="ALL")]]>
+ <![CDATA[(UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")]]>
</Custom>
+ <Custom Action="ca_UninstallNetAdpArgs" Before="ca_UninstallNetAdp" >
+ <![CDATA[(UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")]]>
+ </Custom>
+ <Custom Action="ca_UninstallNetAdp" After="ca_StopHostOnlyInterfaces" >
+ <![CDATA[(UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")]]>
+ </Custom>
<?endif ?>
</Include>
diff --git a/src/VBox/Installer/win/VirtualBox.wxs b/src/VBox/Installer/win/VirtualBox.wxs
index 84fe508..0018e12 100644
--- a/src/VBox/Installer/win/VirtualBox.wxs
+++ b/src/VBox/Installer/win/VirtualBox.wxs
@@ -188,7 +188,8 @@
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="$(var.Property_ProgramFiles)" Name="PFiles">
- <Directory Id="INSTALLDIR" Name="$(env.VBOX_PRODUCT)">
+ <Directory Id="VENDOR" Name="$(env.VBOX_VENDOR_SHORT)">
+ <Directory Id="INSTALLDIR" Name="VirtualBox">
<?if $(env.VBOX_WITH_MSM_INSTALL) = "yes" ?>
<Merge Id="msm_VBoxApp" Language="!(loc.LANG)" SourceFile="$(var.Property_VBoxMergeApp)" DiskId="1" />
<?if $(env.VBOX_WITH_32_ON_64_MAIN_API) = "yes" ?>
@@ -291,9 +292,9 @@
<RegistryValue Root="HKCU" Key="$(var.Property_RegKeyInstall)"
Type="string" Value="installed" KeyPath="yes" />
</Component>
-
- </Directory>
- </Directory>
+ </Directory><!-- INSTALLDIR -->
+ </Directory><!-- $(env.VBOX_VENDOR_SHORT) -->
+ </Directory><!-- $(var.Property_ProgramFiles) -->
</Directory> <!-- TARGETDIR -->
<!-- Note: Feature IDs *must not* be renamed to use any prefixes or such,
@@ -446,8 +447,8 @@
<!-- First install the new version and then remove the old version. This is more efficient -->
<RemoveExistingProducts After="InstallValidate"><![CDATA[PREVIOUSVERSIONSINSTALLED OR NEWERVERSIONDETECTED]]></RemoveExistingProducts>
- <Custom Action="ca_OriginalTargetDir" After="FileCost"><![CDATA[(NOT INSTALLDIR) AND (NOT EXISTINGINSTALLDIR)]]></Custom>
- <Custom Action="ca_DefaultTargetDir" Before="FileCost" ><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
+ <Custom Action="ca_OriginalTargetDir" After="FileCost"><![CDATA[NOT INSTALLDIR]]></Custom>
+ <Custom Action="ca_DefaultTargetDir" Before="FileCost" ><![CDATA[NOT INSTALLDIR AND EXISTINGINSTALLDIR]]></Custom>
<!-- Check + unininstall old TAP instances - we don't need them anymore -->
<Custom Action="ca_UninstallTAPInstances" Before="InstallFiles" >1</Custom>
diff --git a/src/VBox/Main/Makefile.kmk b/src/VBox/Main/Makefile.kmk
index 5cd9fcb..cbd49df 100644
--- a/src/VBox/Main/Makefile.kmk
+++ b/src/VBox/Main/Makefile.kmk
@@ -322,6 +322,9 @@ VBoxSVC_LIBS.solaris = \
socket \
$(LIB_VMM)
+VBoxSVC_LIBS.win += \
+ $(PATH_SDK_$(VBOX_WINPSDK)_LIB)/dnsapi.lib
+
VBoxSVC_INTERMEDIATES = \
$(VBOX_MAIN_PREREQS) \
$(VBOX_XML_SCHEMADEFS_H) \
@@ -880,6 +883,8 @@ ifdef VBOX_WITH_EXTPACK
VBoxExtPackHelperApp_SOURCES = \
src-helper-apps/VBoxExtPackHelperApp.cpp \
src-all/ExtPackUtil.cpp
+ VBoxExtPackHelperApp_SOURCES.win = \
+ src-helper-apps/VBoxExtPackHelperApp.rc
VBoxExtPackHelperApp_LIBS = \
$(LIB_RUNTIME)
endif # VBOX_WITH_EXTPACK
diff --git a/src/VBox/Main/cbinding/Makefile.kmk b/src/VBox/Main/cbinding/Makefile.kmk
index 1f5c4ef..0d7118d 100644
--- a/src/VBox/Main/cbinding/Makefile.kmk
+++ b/src/VBox/Main/cbinding/Makefile.kmk
@@ -106,6 +106,8 @@ if !defined(VBOX_ONLY_SDK)
VBoxCAPI_DEFS = IN_VBOXCAPI
VBoxCAPI_SOURCES = \
VBoxCAPI.cpp
+ VBoxCAPI_SOURCES.win = \
+ VBoxCAPI.rc
VBoxCAPI_INCS = \
$(CAPIHeaders_0_OUTDIR)
VBoxCAPI_INTERMEDIATES = \
diff --git a/src/VBox/Main/cbinding/VBoxCAPI.cpp b/src/VBox/Main/cbinding/VBoxCAPI.cpp
index 9ad2ccd..34338fc 100644
--- a/src/VBox/Main/cbinding/VBoxCAPI.cpp
+++ b/src/VBox/Main/cbinding/VBoxCAPI.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009-2014 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -85,6 +85,18 @@ VBoxUtf8ToUtf16(const char *pszString, BSTR *ppwszString)
}
static void
+VBoxUtf8Clear(char *pszString)
+{
+ RT_BZERO(pszString, strlen(pszString));
+}
+
+static void
+VBoxUtf16Clear(BSTR pwszString)
+{
+ RT_BZERO(pwszString, RTUtf16Len(pwszString) * sizeof(RTUTF16));
+}
+
+static void
VBoxUtf16Free(BSTR pwszString)
{
#ifdef VBOX_WITH_XPCOM
@@ -759,6 +771,9 @@ VBoxGetCAPIFunctions(unsigned uVersion)
VBoxProcessEventQueue,
VBoxInterruptEventQueueProcessing,
+ VBoxUtf8Clear,
+ VBoxUtf16Clear,
+
VBOX_CAPI_VERSION
};
@@ -766,100 +781,6 @@ VBoxGetCAPIFunctions(unsigned uVersion)
return &s_Functions;
/*
- * Legacy interface version 4.0.
- */
- static const struct VBOXCAPIV4
- {
- /** The size of the structure. */
- unsigned cb;
- /** The structure version. */
- unsigned uVersion;
-
- unsigned int (*pfnGetVersion)(void);
- unsigned int (*pfnGetAPIVersion)(void);
-
- HRESULT (*pfnClientInitialize)(const char *pszVirtualBoxClientIID,
- IVirtualBoxClient **ppVirtualBoxClient);
- HRESULT (*pfnClientThreadInitialize)(void);
- HRESULT (*pfnClientThreadUninitialize)(void);
- void (*pfnClientUninitialize)(void);
-
- void (*pfnComInitialize)(const char *pszVirtualBoxIID,
- IVirtualBox **ppVirtualBox,
- const char *pszSessionIID,
- ISession **ppSession);
-
- void (*pfnComUninitialize)(void);
-
- void (*pfnComUnallocString)(BSTR pwsz);
-
- int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
- int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
- void (*pfnUtf8Free)(char *pszString);
- void (*pfnUtf16Free)(BSTR pwszString);
-
- SAFEARRAY *(*pfnSafeArrayCreateVector)(VARTYPE vt, LONG lLbound, ULONG cElements);
- SAFEARRAY *(*pfnSafeArrayOutParamAlloc)(void);
- HRESULT (*pfnSafeArrayCopyInParamHelper)(SAFEARRAY *psa, const void *pv, ULONG cb);
- HRESULT (*pfnSafeArrayCopyOutParamHelper)(void **ppv, ULONG *pcb, VARTYPE vt, SAFEARRAY *psa);
- HRESULT (*pfnSafeArrayCopyOutIfaceParamHelper)(IUnknown ***ppaObj, ULONG *pcObj, SAFEARRAY *psa);
- HRESULT (*pfnSafeArrayDestroy)(SAFEARRAY *psa);
-
-#ifdef VBOX_WITH_XPCOM
- void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
-#endif /* VBOX_WITH_XPCOM */
- HRESULT (*pfnGetException)(IErrorInfo **ppException);
- HRESULT (*pfnClearException)(void);
- int (*pfnProcessEventQueue)(LONG64 iTimeoutMS);
- int (*pfnInterruptEventQueueProcessing)(void);
-
- /** Tail version, same as uVersion. */
- unsigned uEndVersion;
- } s_Functions_v4_0 =
- {
- sizeof(s_Functions_v4_0),
- 0x00040000U,
-
- VBoxVersion,
- VBoxAPIVersion,
-
- VBoxClientInitialize,
- VBoxClientThreadInitialize,
- VBoxClientThreadUninitialize,
- VBoxClientUninitialize,
-
- VBoxComInitialize,
- VBoxComUninitialize,
-
- VBoxComUnallocString,
-
- VBoxUtf16ToUtf8,
- VBoxUtf8ToUtf16,
- VBoxUtf8Free,
- VBoxUtf16Free,
-
- VBoxSafeArrayCreateVector,
- VBoxSafeArrayOutParamAlloc,
- VBoxSafeArrayCopyInParamHelper,
- VBoxSafeArrayCopyOutParamHelper,
- VBoxSafeArrayCopyOutIfaceParamHelper,
- VBoxSafeArrayDestroy,
-
-#ifdef VBOX_WITH_XPCOM
- VBoxGetEventQueue,
-#endif /* VBOX_WITH_XPCOM */
- VBoxGetException,
- VBoxClearException,
- VBoxProcessEventQueue,
- VBoxInterruptEventQueueProcessing,
-
- 0x00040000U
- };
-
- if ((uVersion & 0xffff0000U) == 0x00040000U)
- return (PCVBOXCAPI)&s_Functions_v4_0;
-
- /*
* Legacy interface version 3.0.
*/
static const struct VBOXCAPIV3
@@ -877,22 +798,22 @@ VBoxGetCAPIFunctions(unsigned uVersion)
IVirtualBoxClient **ppVirtualBoxClient);
void (*pfnClientUninitialize)(void);
- void (*pfnComInitialize)(const char *pszVirtualBoxIID,
- IVirtualBox **ppVirtualBox,
- const char *pszSessionIID,
- ISession **ppSession);
+ void (*pfnComInitialize)(const char *pszVirtualBoxIID,
+ IVirtualBox **ppVirtualBox,
+ const char *pszSessionIID,
+ ISession **ppSession);
- void (*pfnComUninitialize)(void);
+ void (*pfnComUninitialize)(void);
- void (*pfnComUnallocMem)(void *pv);
+ void (*pfnComUnallocMem)(void *pv);
- int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
- int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
- void (*pfnUtf8Free)(char *pszString);
- void (*pfnUtf16Free)(BSTR pwszString);
+ int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
+ int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
+ void (*pfnUtf8Free)(char *pszString);
+ void (*pfnUtf16Free)(BSTR pwszString);
#ifdef VBOX_WITH_XPCOM
- void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
+ void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
#endif /* VBOX_WITH_XPCOM */
HRESULT (*pfnGetException)(IErrorInfo **ppException);
HRESULT (*pfnClearException)(void);
@@ -944,22 +865,22 @@ VBoxGetCAPIFunctions(unsigned uVersion)
unsigned int (*pfnGetVersion)(void);
- void (*pfnComInitialize)(const char *pszVirtualBoxIID,
- IVirtualBox **ppVirtualBox,
- const char *pszSessionIID,
- ISession **ppSession);
+ void (*pfnComInitialize)(const char *pszVirtualBoxIID,
+ IVirtualBox **ppVirtualBox,
+ const char *pszSessionIID,
+ ISession **ppSession);
- void (*pfnComUninitialize)(void);
+ void (*pfnComUninitialize)(void);
- void (*pfnComUnallocMem)(void *pv);
- void (*pfnUtf16Free)(BSTR pwszString);
- void (*pfnUtf8Free)(char *pszString);
+ void (*pfnComUnallocMem)(void *pv);
+ void (*pfnUtf16Free)(BSTR pwszString);
+ void (*pfnUtf8Free)(char *pszString);
- int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
- int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
+ int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
+ int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
#ifdef VBOX_WITH_XPCOM
- void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
+ void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
#endif /* VBOX_WITH_XPCOM */
/** Tail version, same as uVersion. */
@@ -1003,15 +924,15 @@ VBoxGetCAPIFunctions(unsigned uVersion)
unsigned int (*pfnGetVersion)(void);
- void (*pfnComInitialize)(IVirtualBox **virtualBox, ISession **session);
- void (*pfnComUninitialize)(void);
+ void (*pfnComInitialize)(IVirtualBox **virtualBox, ISession **session);
+ void (*pfnComUninitialize)(void);
- void (*pfnComUnallocMem)(void *pv);
- void (*pfnUtf16Free)(BSTR pwszString);
- void (*pfnUtf8Free)(char *pszString);
+ void (*pfnComUnallocMem)(void *pv);
+ void (*pfnUtf16Free)(BSTR pwszString);
+ void (*pfnUtf8Free)(char *pszString);
- int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
- int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
+ int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
+ int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
/** Tail version, same as uVersion. */
unsigned uEndVersion;
diff --git a/src/VBox/Main/cbinding/VBoxCAPI.rc b/src/VBox/Main/cbinding/VBoxCAPI.rc
new file mode 100644
index 0000000..63121f3
--- /dev/null
+++ b/src/VBox/Main/cbinding/VBoxCAPI.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxCAPI.rc $ */
+/** @file
+ * VBoxCAPI - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox C Bindings\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxCAPI\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxCAPI.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Main/cbinding/VBoxCAPIGlue.c b/src/VBox/Main/cbinding/VBoxCAPIGlue.c
index 500cb38..a42351e 100644
--- a/src/VBox/Main/cbinding/VBoxCAPIGlue.c
+++ b/src/VBox/Main/cbinding/VBoxCAPIGlue.c
@@ -1,10 +1,10 @@
-/* $Revision: 96259 $ */
+/* $Revision: 97956 $ */
/** @file
* Glue code for dynamically linking to VBoxCAPI.
*/
/*
- * Copyright (C) 2008-2014 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -163,66 +163,74 @@ static int tryLoadLibrary(const char *pszHome, int fSetAppHome)
#ifndef WIN32
g_hVBoxCAPI = dlopen(szName, RTLD_NOW | RTLD_LOCAL);
+#else /* WIN32 */
+ g_hVBoxCAPI = LoadLibraryExA(szName, NULL /* hFile */, 0 /* dwFlags */);
+#endif /* WIN32 */
if (g_hVBoxCAPI)
{
PFNVBOXGETCAPIFUNCTIONS pfnGetFunctions;
+#ifndef WIN32
pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)(uintptr_t)
dlsym(g_hVBoxCAPI, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME);
-#ifdef VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME
+# ifdef VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME
if (!pfnGetFunctions)
pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)(uintptr_t)
dlsym(g_hVBoxCAPI, VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME);
-#endif /* VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME */
- if (pfnGetFunctions)
- {
- g_pVBoxFuncs = pfnGetFunctions(VBOX_CAPI_VERSION);
- if (g_pVBoxFuncs)
- {
- g_pfnGetFunctions = pfnGetFunctions;
- return 0;
- }
-
- /* bail out */
- setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
- szName, VBOX_CAPI_VERSION);
- }
- else
- setErrMsg(1, "dlsym(%.80s/%.32s): %.128s",
- szName, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME, dlerror());
- dlclose(g_hVBoxCAPI);
- g_hVBoxCAPI = NULL;
- }
- else
- setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror());
-#else /* !WIN32 */
- g_hVBoxCAPI = LoadLibraryExA(szName, NULL /* hFile */, 0 /* dwFlags */);
- if (g_hVBoxCAPI)
- {
- PFNVBOXGETCAPIFUNCTIONS pfnGetFunctions;
+# endif /* VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME */
+#else /* WIN32 */
pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)
GetProcAddress(g_hVBoxCAPI, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME);
+#endif /* WIN32 */
if (pfnGetFunctions)
{
g_pVBoxFuncs = pfnGetFunctions(VBOX_CAPI_VERSION);
if (g_pVBoxFuncs)
{
- g_pfnGetFunctions = pfnGetFunctions;
- return 0;
+ if ( ( VBOX_CAPI_MAJOR(g_pVBoxFuncs->uVersion)
+ == VBOX_CAPI_MAJOR(VBOX_CAPI_VERSION))
+ && ( VBOX_CAPI_MINOR(g_pVBoxFuncs->uVersion)
+ >= VBOX_CAPI_MINOR(VBOX_CAPI_VERSION)))
+ {
+ g_pfnGetFunctions = pfnGetFunctions;
+ return 0;
+ }
+ setErrMsg(1, "%.80s: pfnGetFunctions(%#x) returned incompatible version %#x",
+ szName, VBOX_CAPI_VERSION, g_pVBoxFuncs->uVersion);
+ g_pVBoxFuncs = NULL;
+ }
+ else
+ {
+ /* bail out */
+ setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
+ szName, VBOX_CAPI_VERSION);
}
-
- /* bail out */
- setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
- szName, VBOX_CAPI_VERSION);
}
else
+ {
+#ifndef WIN32
+ setErrMsg(1, "dlsym(%.80s/%.32s): %.128s",
+ szName, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME, dlerror());
+#else /* WIN32 */
setErrMsg(1, "GetProcAddress(%.80s/%.32s): %d",
szName, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME, GetLastError());
+#endif /* WIN32 */
+ }
+
+#ifndef WIN32
+ dlclose(g_hVBoxCAPI);
+#else /* WIN32 */
FreeLibrary(g_hVBoxCAPI);
+#endif /* WIN32 */
g_hVBoxCAPI = NULL;
}
else
+ {
+#ifndef WIN32
+ setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror());
+#else /* WIN32 */
setErrMsg(0, "LoadLibraryEx(%.80s): %d", szName, GetLastError());
-#endif /* !WIN32 */
+#endif /* WIN32 */
+ }
return -1;
}
diff --git a/src/VBox/Main/cbinding/capiidl.xsl b/src/VBox/Main/cbinding/capiidl.xsl
index a450a19..b8b8d00 100644
--- a/src/VBox/Main/cbinding/capiidl.xsl
+++ b/src/VBox/Main/cbinding/capiidl.xsl
@@ -1533,7 +1533,29 @@ typedef struct VBOXCAPI
*/
int (*pfnInterruptEventQueueProcessing)(void);
- /** Tail version, same as uVersion. */
+ /**
+ * Clear memory used by a UTF-8 string. Must be zero terminated.
+ * Can be used for any UTF-8 or ASCII/ANSI string.
+ *
+ * @param pszString input/output string
+ */
+ void (*pfnUtf8Clear)(char *pszString);
+ /**
+ * Clear memory used by a UTF-16 string. Must be zero terminated.
+ * Can be used for any UTF-16 or UCS-2 string.
+ *
+ * @param pwszString input/output string
+ */
+ void (*pfnUtf16Clear)(BSTR pwszString);
+
+ /** Tail version, same as uVersion.
+ *
+ * This should only be accessed if for some reason an API client needs
+ * exactly the version it requested, or if cb is used to calculate the
+ * address of this field. It may move as the structure before this is
+ * allowed to grow as long as all the data from earlier minor versions
+ * remains at the same place.
+ */
unsigned uEndVersion;
} VBOXCAPI;
/** Pointer to a const VBOXCAPI function table. */
@@ -1550,9 +1572,17 @@ typedef VBOXCAPI const *PCVBOXXPCOM;
#define VBOXXPCOMC VBOXCAPI
#endif /* !WIN32 */
+/** Extract the C API style major version.
+ * Useful for comparing the interface version in VBOXCAPI::uVersion. */
+#define VBOX_CAPI_MAJOR(x) (((x) & 0xffff0000U) >> 16)
+
+/** Extract the C API style major version.
+ * Useful for comparing the interface version in VBOXCAPI::uVersion. */
+#define VBOX_CAPI_MINOR(x) ((x) & 0x0000ffffU)
+
/** The current interface version.
* For use with VBoxGetCAPIFunctions and to be found in VBOXCAPI::uVersion. */
-#define VBOX_CAPI_VERSION 0x00040000U
+#define VBOX_CAPI_VERSION 0x00040001U
#ifndef WIN32
/** Backwards compatibility: The current interface version.
diff --git a/src/VBox/Main/glue/com.cpp b/src/VBox/Main/glue/com.cpp
index 66ca152..9a6366f 100644
--- a/src/VBox/Main/glue/com.cpp
+++ b/src/VBox/Main/glue/com.cpp
@@ -254,7 +254,8 @@ int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir)
for (unsigned i = 0; i < RT_ELEMENTS(apcszUserHome); ++i)
{
vrc = composeHomePath(aDir, aDirLen, apcszUserHome[i]);
- if (RTDirExists(aDir))
+ if ( RT_SUCCESS(vrc)
+ && RTDirExists(aDir))
{
fFound = true;
break;
diff --git a/src/VBox/Main/glue/vboxapi.py b/src/VBox/Main/glue/vboxapi.py
old mode 100644
new mode 100755
index 3cda567..8fdfd12
--- a/src/VBox/Main/glue/vboxapi.py
+++ b/src/VBox/Main/glue/vboxapi.py
@@ -6,7 +6,7 @@ VirtualBox Python API Glue.
__copyright__ = \
"""
-Copyright (C) 2009-2013 Oracle Corporation
+Copyright (C) 2009-2015 Oracle Corporation
This file is part of VirtualBox Open Source Edition (OSE), as
available from http://www.virtualbox.org. This file is free software;
@@ -16,7 +16,7 @@ Foundation, in version 2 as it comes in the "COPYING" file of the
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
"""
-__version__ = "$Revision: 91042 $"
+__version__ = "$Revision: 98155 $"
# Note! To set Python bitness on OSX use 'export VERSIONER_PYTHON_PREFER_32_BIT=yes'
@@ -875,9 +875,9 @@ class PlatformWEBSERVICE(PlatformBase):
def deinit(self):
try:
- disconnect()
+ self.disconnect()
except:
- pass
+ pass
def queryInterface(self, oIUnknown, sClassName):
d = {}
@@ -990,10 +990,6 @@ class VirtualBoxManager(object):
self.vbox = None
else:
raise e
- ## @deprecated
- # This used to refer to a session manager class with only one method
- # called getSessionObject. The method has moved into this call.
- self.mgr = self;
def __del__(self):
self.deinit()
@@ -1005,6 +1001,13 @@ class VirtualBoxManager(object):
"""
return 3;
+ @property
+ def mgr(self):
+ """
+ This used to be an attribute referring to a session manager class with
+ only one method called getSessionObject. It moved into this class.
+ """
+ return self;
#
# Wrappers for self.platform methods.
@@ -1071,11 +1074,11 @@ class VirtualBoxManager(object):
def openMachineSession(self, oIMachine, fPermitSharing = True):
"""
- Attemts to open the a session to the machine.
+ Attempts to open the a session to the machine.
Returns a session object on success.
Raises exception on failure.
"""
- oSession = self.mgr.getSessionObject(self.vbox);
+ oSession = self.getSessionObject(self.vbox);
if fPermitSharing:
type = self.constants.LockType_Shared;
else:
diff --git a/src/VBox/Main/include/ConsoleImpl.h b/src/VBox/Main/include/ConsoleImpl.h
index 030a601..46217f1 100644
--- a/src/VBox/Main/include/ConsoleImpl.h
+++ b/src/VBox/Main/include/ConsoleImpl.h
@@ -289,6 +289,7 @@ public:
void onRuntimeError(BOOL aFatal, IN_BSTR aErrorID, IN_BSTR aMessage);
HRESULT onShowWindow(BOOL aCheck, BOOL *aCanShow, LONG64 *aWinId);
void onVRDEServerInfoChange();
+ HRESULT i_sendACPIMonitorHotPlugEvent();
static const PDMDRVREG DrvStatusReg;
@@ -300,6 +301,7 @@ public:
// Called from event listener
HRESULT onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort);
+ HRESULT onNATDnsChanged();
// Mouse interface
VMMDevMouseInterface *getVMMDevMouseInterface();
@@ -325,6 +327,8 @@ public:
private:
+ void notifyNatDnsChange(PUVM pUVM, const char *pszDevice, ULONG ulInstanceMax);
+
/**
* Base template for AutoVMCaller and SafeVMPtr. Template arguments
* have the same meaning as arguments of Console::addVMCaller().
@@ -653,6 +657,7 @@ private:
IMedium *pMedium,
MachineState_T aMachineState,
HRESULT *phrc);
+ int configMediumProperties(PCFGMNODE pCur, IMedium *pMedium, bool *pfHostIP);
static DECLCALLBACK(int) reconfigureMediumAttachment(Console *pThis,
PUVM pUVM,
const char *pcszDevice,
@@ -766,6 +771,8 @@ private:
size_t *pcbKey);
static DECLCALLBACK(int) i_pdmIfSecKey_KeyRelease(PPDMISECKEY pInterface, const char *pszId);
+ static DECLCALLBACK(int) i_pdmIfSecKeyHlp_KeyMissingNotify(PPDMISECKEYHLP pInterface);
+
int mcAudioRefs;
volatile uint32_t mcVRDPClients;
uint32_t mu32SingleRDPClientId; /* The id of a connected client in the single connection mode. */
@@ -931,6 +938,12 @@ private:
Console *pConsole;
} *mpIfSecKey;
+ /** Pointer to the key helpers -> provider (that's us) callbacks. */
+ struct MYPDMISECKEYHLP : public PDMISECKEYHLP
+ {
+ Console *pConsole;
+ } *mpIfSecKeyHlp;
+
/* Note: FreeBSD needs this whether netflt is used or not. */
#if ((defined(RT_OS_LINUX) && !defined(VBOX_WITH_NETFLT)) || defined(RT_OS_FREEBSD))
Utf8Str maTAPDeviceName[8];
diff --git a/src/VBox/Main/include/DisplayImpl.h b/src/VBox/Main/include/DisplayImpl.h
index 585f6b2..e21e1be 100644
--- a/src/VBox/Main/include/DisplayImpl.h
+++ b/src/VBox/Main/include/DisplayImpl.h
@@ -126,6 +126,8 @@ public:
ULONG *pcy, ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin) = 0;
virtual void getFramebufferDimensions(int32_t *px1, int32_t *py1,
int32_t *px2, int32_t *py2) = 0;
+ virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved) = 0;
+ virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y) = 0;
};
class VMMDev;
@@ -163,6 +165,9 @@ public:
int handleDisplayResize(unsigned uScreenId, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t w, uint32_t h, uint16_t flags);
void handleDisplayUpdateLegacy(int x, int y, int cx, int cy);
void handleDisplayUpdate(unsigned uScreenId, int x, int y, int w, int h);
+ void i_handleUpdateVMMDevSupportsGraphics(bool fSupportsGraphics);
+ void i_handleUpdateGuestVBVACapabilities(uint32_t fNewCapabilities);
+ void i_handleUpdateVBVAInputMapping(int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy);
#ifdef VBOX_WITH_VIDEOHWACCEL
int handleVHWACommandProcess(PVBOXVHWACMD pCommand);
#endif
@@ -227,6 +232,8 @@ public:
STDMETHOD(SetSeamlessMode)(BOOL enabled);
STDMETHOD(CompleteVHWACommand)(BYTE *pCommand);
+ virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved);
+ virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y);
STDMETHOD(ViewportChanged)(ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height);
@@ -285,6 +292,10 @@ private:
static DECLCALLBACK(void) displayVBVAUpdateEnd(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, int32_t x, int32_t y, uint32_t cx, uint32_t cy);
static DECLCALLBACK(int) displayVBVAResize(PPDMIDISPLAYCONNECTOR pInterface, const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM);
static DECLCALLBACK(int) displayVBVAMousePointerShape(PPDMIDISPLAYCONNECTOR pInterface, bool fVisible, bool fAlpha, uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy, const void *pvShape);
+ static DECLCALLBACK(void) i_displayVBVAGuestCapabilityUpdate(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities);
+
+ static DECLCALLBACK(void) i_displayVBVAInputMappingUpdate(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin,
+ uint32_t cx, uint32_t cy);
#endif
#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
@@ -314,7 +325,20 @@ private:
bool mfVMMDevInited;
unsigned mcMonitors;
+ /** Input mapping rectangle top left X relative to the first screen. */
+ int32_t xInputMappingOrigin;
+ /** Input mapping rectangle top left Y relative to the first screen. */
+ int32_t yInputMappingOrigin;
+ uint32_t cxInputMapping; /**< Input mapping rectangle width. */
+ uint32_t cyInputMapping; /**< Input mapping rectangle height. */
DISPLAYFBINFO maFramebuffers[SchemaDefs::MaxGuestMonitors];
+ /** Does the VMM device have the "supports graphics" capability set?
+ * Does not go into the saved state as it is refreshed on restore. */
+ bool mfVMMDevSupportsGraphics;
+ /** Mirror of the current guest VBVA capabilities. */
+ uint32_t mfGuestVBVACapabilities;
+ /** Mirror of the current host cursor capabilities. */
+ uint32_t mfHostCursorCapabilities;
/* arguments of the last handleDisplayResize() call */
void *mLastAddress;
@@ -334,6 +358,10 @@ private:
VBVAMEMORY *mpPendingVbvaMemory;
bool mfPendingVideoAccelEnable;
bool mfMachineRunning;
+
+ /** Accelerate3DEnabled = true && GraphicsControllerType == VBoxVGA. */
+ bool mfIsCr3DEnabled;
+
#ifdef VBOX_WITH_CROGL
bool mfCrOglDataHidden;
#endif
@@ -398,6 +426,8 @@ private:
int videoAccelEnable(bool fEnable, VBVAMEMORY *pVbvaMemory);
void videoAccelFlush(void);
+ void i_updateGuestGraphicsFacility(void);
+
#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
int crOglWindowsShow(bool fShow);
#endif
diff --git a/src/VBox/Main/include/DisplayUtils.h b/src/VBox/Main/include/DisplayUtils.h
index 7b8d9f8..e69784e 100644
--- a/src/VBox/Main/include/DisplayUtils.h
+++ b/src/VBox/Main/include/DisplayUtils.h
@@ -22,6 +22,8 @@ using namespace com;
#define sSSMDisplayVer 0x00010001
#define sSSMDisplayVer2 0x00010002
#define sSSMDisplayVer3 0x00010003
+#define sSSMDisplayVer4 0x00010004
+#define sSSMDisplayVer5 0x00010005
int readSavedGuestScreenInfo(const Utf8Str &strStateFilePath, uint32_t u32ScreenId,
uint32_t *pu32OriginX, uint32_t *pu32OriginY,
diff --git a/src/VBox/Main/include/MediumImpl.h b/src/VBox/Main/include/MediumImpl.h
index 0808876..5109ddf 100644
--- a/src/VBox/Main/include/MediumImpl.h
+++ b/src/VBox/Main/include/MediumImpl.h
@@ -301,7 +301,8 @@ private:
static DECLCALLBACK(int) vdTcpSocketCreate(uint32_t fFlags, PVDSOCKET pSock);
static DECLCALLBACK(int) vdTcpSocketDestroy(VDSOCKET Sock);
- static DECLCALLBACK(int) vdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort);
+ static DECLCALLBACK(int) vdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort,
+ RTMSINTERVAL cMillies);
static DECLCALLBACK(int) vdTcpClientClose(VDSOCKET Sock);
static DECLCALLBACK(bool) vdTcpIsClientConnected(VDSOCKET Sock);
static DECLCALLBACK(int) vdTcpSelectOne(VDSOCKET Sock, RTMSINTERVAL cMillies);
diff --git a/src/VBox/Main/include/MouseImpl.h b/src/VBox/Main/include/MouseImpl.h
index 21dde0e..2742057 100644
--- a/src/VBox/Main/include/MouseImpl.h
+++ b/src/VBox/Main/include/MouseImpl.h
@@ -98,8 +98,9 @@ private:
uint32_t fContact);
HRESULT reportMultiTouchEventToDevice(uint8_t cContacts, const uint64_t *pau64Contacts, uint32_t u32ScanTime);
HRESULT reportAbsEventToVMMDev(int32_t x, int32_t y);
- HRESULT reportAbsEvent(int32_t x, int32_t y, int32_t dz, int32_t dw,
- uint32_t fButtons, bool fUsesVMMDevEvent);
+ HRESULT i_reportAbsEventToInputDevices(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons,
+ bool fUsesVMMDevEvent);
+ HRESULT i_reportAbsEventToDisplayDevice(int32_t x, int32_t y);
HRESULT convertDisplayRes(LONG x, LONG y, int32_t *pxAdj, int32_t *pyAdj,
bool *pfValid);
HRESULT putEventMultiTouch(LONG aCount, LONG64 *paContacts, ULONG aScanTime);
diff --git a/src/VBox/Main/src-all/Global.cpp b/src/VBox/Main/src-all/Global.cpp
index f28113e..eca370b 100644
--- a/src/VBox/Main/src-all/Global.cpp
+++ b/src/VBox/Main/src-all/Global.cpp
@@ -67,15 +67,15 @@ const Global::OSType Global::sOSTypes[] =
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", "WindowsXP_64", "Windows XP (64 bit)",
VBOXOSTYPE_WinXP_x64, VBOXOSHINT_64BIT | VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET,
- 192, 16, 10 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ 512, 16, 10 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", "Windows2003", "Windows 2003 (32 bit)",
VBOXOSTYPE_Win2k3, VBOXOSHINT_USBTABLET,
- 256, 16, 20 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ 512, 16, 20 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", "Windows2003_64", "Windows 2003 (64 bit)",
VBOXOSTYPE_Win2k3_x64, VBOXOSHINT_64BIT | VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET,
- 256, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ 512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", "WindowsVista", "Windows Vista (32 bit)",
VBOXOSTYPE_WinVista, VBOXOSHINT_USBTABLET,
@@ -121,6 +121,14 @@ const Global::OSType Global::sOSTypes[] =
VBOXOSTYPE_Win2k12_x64, VBOXOSHINT_64BIT | VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET,
2048,128, 25 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
+ { "Windows", "Microsoft Windows", "Windows10", "Windows 10 (32 bit)",
+ VBOXOSTYPE_Win10, VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET | VBOXOSHINT_PAE,
+ 1024,128, 32 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
+ { "Windows", "Microsoft Windows", "Windows10_64", "Windows 10 (64 bit)",
+ VBOXOSTYPE_Win10_x64, VBOXOSHINT_64BIT | VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET,
+ 2048,128, 32 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", "WindowsNT", "Other Windows (32 bit)",
VBOXOSTYPE_WinNT, VBOXOSHINT_NONE,
512, 16, 20 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index 69e3109..b3d6e2b 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -342,6 +342,12 @@ public:
}
break;
+ case VBoxEventType_OnHostNameResolutionConfigurationChange:
+ {
+ mConsole->onNATDnsChanged();
+ break;
+ }
+
case VBoxEventType_OnHostPCIDevicePlug:
{
// handle if needed
@@ -412,6 +418,7 @@ Console::Console()
#endif
, mBusMgr(NULL)
, mpIfSecKey(NULL)
+ , mpIfSecKeyHlp(NULL)
, mVMStateChangeCallbackDisabled(false)
, mfUseHostClipboard(true)
, mMachineState(MachineState_PoweredOff)
@@ -456,6 +463,13 @@ HRESULT Console::FinalConstruct()
pIfSecKey->pConsole = this;
mpIfSecKey = pIfSecKey;
+ MYPDMISECKEYHLP *pIfSecKeyHlp = (MYPDMISECKEYHLP *)RTMemAllocZ(sizeof(*mpIfSecKeyHlp) + sizeof(Console *));
+ if (!pIfSecKeyHlp)
+ return E_OUTOFMEMORY;
+ pIfSecKeyHlp->pfnKeyMissingNotify = Console::i_pdmIfSecKeyHlp_KeyMissingNotify;
+ pIfSecKeyHlp->pConsole = this;
+ mpIfSecKeyHlp = pIfSecKeyHlp;
+
return BaseFinalConstruct();
}
@@ -604,6 +618,7 @@ HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl, Loc
mVmListener = aVmListener;
com::SafeArray<VBoxEventType_T> eventTypes;
eventTypes.push_back(VBoxEventType_OnNATRedirect);
+ eventTypes.push_back(VBoxEventType_OnHostNameResolutionConfigurationChange);
eventTypes.push_back(VBoxEventType_OnHostPCIDevicePlug);
eventTypes.push_back(VBoxEventType_OnExtraDataChanged);
rc = pES->RegisterListener(aVmListener, ComSafeArrayAsInParam(eventTypes), true);
@@ -686,6 +701,12 @@ void Console::uninit()
mpIfSecKey = NULL;
}
+ if (mpIfSecKeyHlp)
+ {
+ RTMemFree((void *)mpIfSecKeyHlp);
+ mpIfSecKeyHlp = NULL;
+ }
+
if (mNvram)
{
delete mNvram;
@@ -2313,7 +2334,7 @@ STDMETHODIMP Console::Reset()
if (!ptrVM.isOk())
return ptrVM.rc();
- /* release the lock before a VMR3* call (EMT will call us back)! */
+ /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
alock.release();
int vrc = VMR3Reset(ptrVM.rawUVM());
@@ -2419,13 +2440,15 @@ HRESULT Console::doCPURemove(ULONG aCpu, PUVM pUVM)
vrc = VMR3ReqCallU(pUVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
(PFNRT)unplugCpu, 3,
this, pUVM, (VMCPUID)aCpu);
- if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
- {
+
+ /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
+ alock.release();
+
+ if (vrc == VERR_TIMEOUT)
vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
- AssertRC(vrc);
- if (RT_SUCCESS(vrc))
- vrc = pReq->iStatus;
- }
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
VMR3ReqFree(pReq);
if (RT_SUCCESS(vrc))
@@ -2526,23 +2549,16 @@ HRESULT Console::doCPUAdd(ULONG aCpu, PUVM pUVM)
(PFNRT)plugCpu, 3,
this, pUVM, aCpu);
- /* release the lock before a VMR3* call (EMT will call us back)! */
+ /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
alock.release();
- if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
- {
+ if (vrc == VERR_TIMEOUT)
vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
- AssertRC(vrc);
- if (RT_SUCCESS(vrc))
- vrc = pReq->iStatus;
- }
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
VMR3ReqFree(pReq);
- rc = RT_SUCCESS(vrc) ? S_OK :
- setError(VBOX_E_VM_ERROR,
- tr("Could not add CPU to the machine (%Rrc)"),
- vrc);
-
if (RT_SUCCESS(vrc))
{
/* Notify the guest if possible. */
@@ -2552,6 +2568,10 @@ HRESULT Console::doCPUAdd(ULONG aCpu, PUVM pUVM)
vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
/** @todo warning if the guest doesn't support it */
}
+ else
+ rc = setError(VBOX_E_VM_ERROR,
+ tr("Could not add CPU to the machine (%Rrc)"),
+ vrc);
LogFlowThisFunc(("mMachineState=%d, rc=%Rhrc\n", mMachineState, rc));
LogFlowThisFuncLeave();
@@ -3692,16 +3712,14 @@ HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForc
(PFNRT)changeRemovableMedium, 8,
this, pUVM, pszDevice, uInstance, enmBus, fUseHostIOCache, aMediumAttachment, fForce);
- /* release the lock before waiting for a result (EMT will call us back!) */
+ /* release the lock before waiting for a result (EMT might wait for it, @bugref{7648})! */
alock.release();
- if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
- {
+ if (vrc == VERR_TIMEOUT)
vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
- AssertRC(vrc);
- if (RT_SUCCESS(vrc))
- vrc = pReq->iStatus;
- }
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
VMR3ReqFree(pReq);
if (fResume)
@@ -3885,16 +3903,14 @@ HRESULT Console::doStorageDeviceAttach(IMediumAttachment *aMediumAttachment, PUV
(PFNRT)attachStorageDevice, 8,
this, pUVM, pszDevice, uInstance, enmBus, fUseHostIOCache, aMediumAttachment, fSilent);
- /* release the lock before waiting for a result (EMT will call us back!) */
+ /* release the lock before waiting for a result (EMT might wait for it, @bugref{7648})! */
alock.release();
- if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
- {
+ if (vrc == VERR_TIMEOUT)
vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
- AssertRC(vrc);
- if (RT_SUCCESS(vrc))
- vrc = pReq->iStatus;
- }
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
VMR3ReqFree(pReq);
if (fResume)
@@ -4068,16 +4084,14 @@ HRESULT Console::doStorageDeviceDetach(IMediumAttachment *aMediumAttachment, PUV
(PFNRT)detachStorageDevice, 7,
this, pUVM, pszDevice, uInstance, enmBus, aMediumAttachment, fSilent);
- /* release the lock before waiting for a result (EMT will call us back!) */
+ /* release the lock before waiting for a result (EMT might wait for it, @bugref{7648})! */
alock.release();
- if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
- {
+ if (vrc == VERR_TIMEOUT)
vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
- AssertRC(vrc);
- if (RT_SUCCESS(vrc))
- vrc = pReq->iStatus;
- }
+ AssertRC(vrc);
+ if (RT_SUCCESS(vrc))
+ vrc = pReq->iStatus;
VMR3ReqFree(pReq);
if (fResume)
@@ -4388,6 +4402,98 @@ HRESULT Console::onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
return rc;
}
+
+/*
+ * IHostNameResolutionConfigurationChangeEvent
+ *
+ * Currently this event doesn't carry actual resolver configuration,
+ * so we have to go back to VBoxSVC and ask... This is not ideal.
+ */
+HRESULT Console::onNATDnsChanged()
+{
+ HRESULT hrc;
+
+ AutoCaller autoCaller(this);
+ AssertComRCReturnRC(autoCaller.rc());
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+#if 0 /* XXX: We don't yet pass this down to pfnNotifyDnsChanged */
+ ComPtr<IVirtualBox> pVirtualBox;
+ hrc = mMachine->COMGETTER(Parent)(pVirtualBox.asOutParam());
+ if (FAILED(hrc))
+ return S_OK;
+
+ ComPtr<IHost> pHost;
+ hrc = pVirtualBox->COMGETTER(Host)(pHost.asOutParam());
+ if (FAILED(hrc))
+ return S_OK;
+
+ SafeArray<BSTR> aNameServers;
+ hrc = pHost->COMGETTER(NameServers)(ComSafeArrayAsOutParam(aNameServers));
+ if (FAILED(hrc))
+ return S_OK;
+
+ const size_t cNameServers = aNameServers.size();
+ Log(("DNS change - %zu nameservers\n", cNameServers));
+
+ for (size_t i = 0; i < cNameServers; ++i)
+ {
+ com::Utf8Str strNameServer(aNameServers[i]);
+ Log(("- nameserver[%zu] = \"%s\"\n", i, strNameServer.c_str()));
+ }
+
+ com::Bstr domain;
+ pHost->COMGETTER(DomainName)(domain.asOutParam());
+ Log(("domain name = \"%s\"\n", com::Utf8Str(domain).c_str()));
+#endif /* 0 */
+
+ ChipsetType_T enmChipsetType;
+ hrc = mMachine->COMGETTER(ChipsetType)(&enmChipsetType);
+ if (!FAILED(hrc))
+ {
+ SafeVMPtrQuiet ptrVM(this);
+ if (ptrVM.isOk())
+ {
+ ULONG ulInstanceMax = (ULONG)Global::getMaxNetworkAdapters(enmChipsetType);
+
+ notifyNatDnsChange(ptrVM.rawUVM(), "pcnet", ulInstanceMax);
+ notifyNatDnsChange(ptrVM.rawUVM(), "e1000", ulInstanceMax);
+ notifyNatDnsChange(ptrVM.rawUVM(), "virtio-net", ulInstanceMax);
+ }
+ }
+
+ return S_OK;
+}
+
+
+/*
+ * This routine walks over all network device instances, checking if
+ * device instance has DrvNAT attachment and triggering DrvNAT DNS
+ * change callback.
+ */
+void Console::notifyNatDnsChange(PUVM pUVM, const char *pszDevice, ULONG ulInstanceMax)
+{
+ Log(("notifyNatDnsChange: looking for DrvNAT attachment on %s device instances\n", pszDevice));
+ for (ULONG ulInstance = 0; ulInstance < ulInstanceMax; ulInstance++)
+ {
+ PPDMIBASE pBase;
+ int rc = PDMR3QueryDriverOnLun(pUVM, pszDevice, ulInstance, 0 /* iLun */, "NAT", &pBase);
+ if (RT_FAILURE(rc))
+ continue;
+
+ Log(("Instance %s#%d has DrvNAT attachment; do actual notify\n", pszDevice, ulInstance));
+ if (pBase)
+ {
+ PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
+ pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID);
+ if (pNetNatCfg && pNetNatCfg->pfnNotifyDnsChanged)
+ pNetNatCfg->pfnNotifyDnsChanged(pNetNatCfg);
+ }
+ }
+}
+
+
VMMDevMouseInterface *Console::getVMMDevMouseInterface()
{
return m_pVMMDev;
@@ -4534,7 +4640,7 @@ HRESULT Console::clearDiskEncryptionKeysOnAllAttachments(void)
pIMedium = (PPDMIMEDIA)pIBase->pfnQueryInterface(pIBase, PDMIMEDIA_IID);
if (pIMedium)
{
- rc = pIMedium->pfnSetSecKeyIf(pIMedium, NULL);
+ rc = pIMedium->pfnSetSecKeyIf(pIMedium, NULL, mpIfSecKeyHlp);
Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
}
}
@@ -4651,7 +4757,7 @@ HRESULT Console::configureEncryptionForDisk(const char *pszUuid)
return setError(E_FAIL, tr("could not query medium interface of controller"));
else
{
- rc = pIMedium->pfnSetSecKeyIf(pIMedium, mpIfSecKey);
+ rc = pIMedium->pfnSetSecKeyIf(pIMedium, mpIfSecKey, mpIfSecKeyHlp);
if (RT_FAILURE(rc))
return setError(E_FAIL, tr("Failed to set the encryption key (%Rrc)"), rc);
}
@@ -4737,6 +4843,11 @@ HRESULT Console::consoleParseDiskEncryption(const char *psz, const char **ppszEn
/* Add the key to the map */
m_mapSecretKeys.insert(std::make_pair(Utf8Str(pszUuid), pKey));
hrc = configureEncryptionForDisk(pszUuid);
+ if (FAILED(hrc))
+ {
+ /* Delete the key from the map. */
+ m_mapSecretKeys.erase(Utf8Str(pszUuid));
+ }
}
else
hrc = setError(E_FAIL,
@@ -4822,18 +4933,9 @@ HRESULT Console::doNetworkAdapterChange(PUVM pUVM,
* here to make requests from under the lock in order to serialize them.
*/
PVMREQ pReq;
- int vrc = VMR3ReqCallU(pUVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
- (PFNRT)changeNetworkAttachment, 6,
- this, pUVM, pszDevice, uInstance, uLun, aNetworkAdapter);
-
- if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
- {
- vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT);
- AssertRC(vrc);
- if (RT_SUCCESS(vrc))
- vrc = pReq->iStatus;
- }
- VMR3ReqFree(pReq);
+ int vrc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/,
+ (PFNRT)changeNetworkAttachment, 6,
+ this, pUVM, pszDevice, uInstance, uLun, aNetworkAdapter);
if (fResume)
resumeAfterConfigChange(pUVM);
@@ -5242,6 +5344,47 @@ void Console::onVRDEServerInfoChange()
fireVRDEServerInfoChangedEvent(mEventSource);
}
+HRESULT Console::i_sendACPIMonitorHotPlugEvent()
+{
+ LogFlowThisFuncEnter();
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ if ( mMachineState != MachineState_Running
+ && mMachineState != MachineState_Teleporting
+ && mMachineState != MachineState_LiveSnapshotting)
+ return setInvalidMachineStateError();
+
+ /* get the VM handle. */
+ SafeVMPtr ptrVM(this);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+
+ // no need to release lock, as there are no cross-thread callbacks
+
+ /* get the acpi device interface and press the sleep button. */
+ PPDMIBASE pBase;
+ int vrc = PDMR3QueryDeviceLun(ptrVM.rawUVM(), "acpi", 0, 0, &pBase);
+ if (RT_SUCCESS(vrc))
+ {
+ Assert(pBase);
+ PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
+ if (pPort)
+ vrc = pPort->pfnMonitorHotPlugEvent(pPort);
+ else
+ vrc = VERR_PDM_MISSING_INTERFACE;
+ }
+
+ HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
+ setError(VBOX_E_PDM_ERROR,
+ tr("Sending monitor hot-plug event failed (%Rrc)"),
+ vrc);
+
+ LogFlowThisFunc(("rc=%Rhrc\n", rc));
+ LogFlowThisFuncLeave();
+ return rc;
+}
+
HRESULT Console::onVideoCaptureChange()
{
AutoCaller autoCaller(this);
@@ -6115,7 +6258,7 @@ HRESULT Console::pause(Reason_T aReason)
if (!ptrVM.isOk())
return ptrVM.rc();
- /* release the lock before a VMR3* call (EMT will call us back)! */
+ /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
alock.release();
LogFlowThisFunc(("Sending PAUSE request...\n"));
@@ -6174,7 +6317,7 @@ HRESULT Console::resume(Reason_T aReason)
if (!ptrVM.isOk())
return ptrVM.rc();
- /* release the lock before a VMR3* call (EMT will call us back)! */
+ /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
alock.release();
LogFlowThisFunc(("Sending RESUME request...\n"));
@@ -6253,7 +6396,7 @@ HRESULT Console::saveState(Reason_T aReason, IProgress **aProgress)
if (!ptrVM.isOk())
return ptrVM.rc();
- /* release the lock before a VMR3* call (EMT will call us back)! */
+ /* release the lock before a VMR3* call (EMT might wait for it, @bugref{7648})! */
alock.release();
VMSUSPENDREASON enmReason = VMSUSPENDREASON_USER;
if (aReason == Reason_HostSuspend)
@@ -7478,7 +7621,7 @@ HRESULT Console::powerDown(IProgress *aProgress /*= NULL*/)
{
LogFlowThisFunc(("Shutdown HGCM...\n"));
- /* Leave the lock since EMT will call us back as addVMCaller() */
+ /* Leave the lock since EMT might wait for it and will call us back as addVMCaller() */
alock.release();
m_pVMMDev->hgcmShutdown();
@@ -8348,6 +8491,16 @@ DECLCALLBACK(void) Console::vmstateChangeCallback(PUVM pUVM, VMSTATE enmState, V
break;
}
+ case VMSTATE_POWERING_ON:
+ {
+ /*
+ * We have to set the secret key helper interface for the VD drivers to
+ * get notified about missing keys.
+ */
+ that->clearDiskEncryptionKeysOnAllAttachments();
+ break;
+ }
+
default: /* shut up gcc */
break;
}
@@ -8807,7 +8960,7 @@ HRESULT Console::attachToTapInterface(INetworkAdapter *networkAdapter)
rc = setError(E_FAIL,
tr("General failure attaching to host interface"));
}
- LogFlowThisFunc(("rc=%d\n", rc));
+ LogFlowThisFunc(("rc=%Rhrc\n", rc));
return rc;
}
@@ -9009,16 +9162,6 @@ Console::setVMRuntimeErrorCallback(PUVM pUVM, void *pvUser, uint32_t fFlags,
LogRel(("Console: VM runtime error: fatal=%RTbool, errorID=%s message=\"%s\"\n",
fFatal, pszErrorId, message.c_str()));
- /* Set guest property if the reason of the error is a missing DEK for a disk. */
- if (!RTStrCmp(pszErrorId, "DrvVD_DEKMISSING"))
- {
- that->mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw());
- that->mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw(),
- Bstr("1").raw(), Bstr("RDONLYGUEST").raw());
- that->mMachine->SaveSettings();
- }
-
-
that->onRuntimeError(BOOL(fFatal), Bstr(pszErrorId).raw(), Bstr(message).raw());
LogFlowFuncLeave(); NOREF(pUVM);
@@ -9979,6 +10122,9 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser)
* don't release the lock since reconfigureMediumAttachment
* isn't going to need the Console lock.
*/
+
+ /* TODO: do alock.release here as EMT might wait on it! See other places
+ * where we do VMR3ReqCall requests. See @bugref{7648}. */
vrc = VMR3ReqCallWaitU(ptrVM.rawUVM(), VMCPUID_ANY,
(PFNRT)reconfigureMediumAttachment, 13,
that, ptrVM.rawUVM(), pcszDevice, lInstance, enmBus, fUseHostIOCache,
@@ -10366,6 +10512,22 @@ Console::i_pdmIfSecKey_KeyRelease(PPDMISECKEY pInterface, const char *pszId)
return VERR_NOT_FOUND;
}
+/**
+ * @interface_method_impl{PDMISECKEYHLP,pfnKeyMissingNotify}
+ */
+/*static*/ DECLCALLBACK(int)
+Console::i_pdmIfSecKeyHlp_KeyMissingNotify(PPDMISECKEYHLP pInterface)
+{
+ Console *pConsole = ((MYPDMISECKEYHLP *)pInterface)->pConsole;
+
+ /* Set guest property only, the VM is paused in the media driver calling us. */
+ pConsole->mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw());
+ pConsole->mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/DekMissing").raw(),
+ Bstr("1").raw(), Bstr("RDONLYGUEST").raw());
+ pConsole->mMachine->SaveSettings();
+
+ return VINF_SUCCESS;
+}
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index f858b2d..19fe8c0 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -991,9 +991,10 @@ int Console::configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
/* Expose CMPXCHG16B. Currently a hack. */
if ( osTypeId == "Windows81_64"
- || osTypeId == "Windows2012_64")
+ || osTypeId == "Windows2012_64"
+ || osTypeId == "Windows10_64")
{
- LogRel(("Enabling CMPXCHG16B for Windows 8.1 / 2k12 guests\n"));
+ LogRel(("Enabling CMPXCHG16B for Windows 8.1 / 2k12 or newer guests\n"));
InsertConfigInteger(pCPUM, "CMPXCHG16B", true);
}
@@ -1511,9 +1512,9 @@ int Console::configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
/*
* VGA.
*/
- GraphicsControllerType_T graphicsController;
- hrc = pMachine->COMGETTER(GraphicsControllerType)(&graphicsController); H();
- switch (graphicsController)
+ GraphicsControllerType_T enmGraphicsController;
+ hrc = pMachine->COMGETTER(GraphicsControllerType)(&enmGraphicsController); H();
+ switch (enmGraphicsController)
{
case GraphicsControllerType_Null:
break;
@@ -1521,15 +1522,15 @@ int Console::configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
#ifdef VBOX_WITH_VMSVGA
case GraphicsControllerType_VMSVGA:
#endif
- rc = configGraphicsController(pDevices, graphicsController, pBusMgr, pMachine, biosSettings,
+ rc = configGraphicsController(pDevices, enmGraphicsController, pBusMgr, pMachine, biosSettings,
RT_BOOL(fHMEnabled));
if (FAILED(rc))
return rc;
break;
default:
- AssertMsgFailed(("Invalid graphicsController=%d\n", graphicsController));
+ AssertMsgFailed(("Invalid enmGraphicsController=%d\n", enmGraphicsController));
return VMR3SetError(pUVM, VERR_INVALID_PARAMETER, RT_SRC_POS,
- N_("Invalid graphics controller type '%d'"), graphicsController);
+ N_("Invalid graphics controller type '%d'"), enmGraphicsController);
}
/*
@@ -2749,7 +2750,11 @@ int Console::configConstructorInner(PUVM pUVM, PVM pVM, AutoWriteLock *pAlock)
BOOL fEnabled3D = false;
hrc = pMachine->COMGETTER(Accelerate3DEnabled)(&fEnabled3D); H();
- if (fEnabled3D)
+ if ( fEnabled3D
+# ifdef VBOX_WITH_VMSVGA3D
+ && enmGraphicsController == GraphicsControllerType_VBoxVGA
+# endif
+ )
{
BOOL fSupports3D = VBoxOglIs3DAccelerationSupported();
if (!fSupports3D)
@@ -3237,7 +3242,7 @@ int Console::configDumpAPISettingsTweaks(IVirtualBox *pVirtualBox, IMachine *pMa
}
int Console::configGraphicsController(PCFGMNODE pDevices,
- const GraphicsControllerType_T graphicsController,
+ const GraphicsControllerType_T enmGraphicsController,
BusAssignmentManager *pBusMgr,
const ComPtr<IMachine> &pMachine,
const ComPtr<IBIOSSettings> &biosSettings,
@@ -3271,7 +3276,7 @@ int Console::configGraphicsController(PCFGMNODE pDevices,
#endif
#ifdef VBOX_WITH_VMSVGA
- if (graphicsController == GraphicsControllerType_VMSVGA)
+ if (enmGraphicsController == GraphicsControllerType_VMSVGA)
{
InsertConfigInteger(pCfg, "VMSVGAEnabled", true);
#ifdef VBOX_WITH_VMSVGA3D
@@ -3774,6 +3779,22 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst,
fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
AssertRCReturn(rc, rc);
+ /*
+ * Make the secret key helper interface known to the VD driver if it is attached,
+ * so we can get notified about missing keys.
+ */
+ PPDMIBASE pIBase = NULL;
+ rc = PDMR3QueryDriverOnLun(pUVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
+ if (RT_SUCCESS(rc) && pIBase)
+ {
+ PPDMIMEDIA pIMedium = (PPDMIMEDIA)pIBase->pfnQueryInterface(pIBase, PDMIMEDIA_IID);
+ if (pIMedium)
+ {
+ rc = pIMedium->pfnSetSecKeyIf(pIMedium, NULL, mpIfSecKeyHlp);
+ Assert(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED);
+ }
+ }
+
/* There is no need to handle removable medium mounting, as we
* unconditionally replace everthing including the block driver level.
* This means the new medium will be picked up automatically. */
@@ -4014,49 +4035,7 @@ int Console::configMedium(PCFGMNODE pLunL0,
/* Pass all custom parameters. */
bool fHostIP = true;
- SafeArray<BSTR> names;
- SafeArray<BSTR> values;
- hrc = pMedium->GetProperties(Bstr().raw(),
- ComSafeArrayAsOutParam(names),
- ComSafeArrayAsOutParam(values)); H();
-
- if (names.size() != 0)
- {
- PCFGMNODE pVDC;
- InsertConfigNode(pCfg, "VDConfig", &pVDC);
- for (size_t ii = 0; ii < names.size(); ++ii)
- {
- if (values[ii] && *values[ii])
- {
- /* Put properties of filters in a separate config node. */
- Utf8Str name = names[ii];
- Utf8Str value = values[ii];
- size_t offSlash = name.find("/", 0);
- if ( offSlash != name.npos
- && !name.startsWith("Special/"))
- {
- com::Utf8Str strFilter;
- com::Utf8Str strKey;
-
- hrc = strFilter.assignEx(name, 0, offSlash); H();
- hrc = strKey.assignEx(name, offSlash + 1, name.length() - offSlash - 1); /* Skip slash */ H();
-
- PCFGMNODE pCfgFilterConfig = CFGMR3GetChild(pVDC, strFilter.c_str());
- if (!pCfgFilterConfig)
- InsertConfigNode(pVDC, strFilter.c_str(), &pCfgFilterConfig);
-
- InsertConfigString(pCfgFilterConfig, strKey.c_str(), value);
- }
- else
- {
- InsertConfigString(pVDC, name.c_str(), value);
- if ( name.compare("HostIPStack") == 0
- && value.compare("0") == 0)
- fHostIP = false;
- }
- }
- }
- }
+ hrc = configMediumProperties(pCfg, pMedium, &fHostIP); H();
/* Create an inverted list of parents. */
uImage--;
@@ -4083,30 +4062,8 @@ int Console::configMedium(PCFGMNODE pLunL0,
InsertConfigInteger(pCur, "MergeTarget", 1);
}
- /* Pass all custom parameters. */
- SafeArray<BSTR> aNames;
- SafeArray<BSTR> aValues;
- hrc = pMedium->GetProperties(NULL,
- ComSafeArrayAsOutParam(aNames),
- ComSafeArrayAsOutParam(aValues)); H();
-
- if (aNames.size() != 0)
- {
- PCFGMNODE pVDC;
- InsertConfigNode(pCur, "VDConfig", &pVDC);
- for (size_t ii = 0; ii < aNames.size(); ++ii)
- {
- if (aValues[ii] && *aValues[ii])
- {
- Utf8Str name = aNames[ii];
- Utf8Str value = aValues[ii];
- InsertConfigString(pVDC, name.c_str(), value);
- if ( name.compare("HostIPStack") == 0
- && value.compare("0") == 0)
- fHostIP = false;
- }
- }
- }
+ /* Configure medium properties. */
+ hrc = configMediumProperties(pCur, pMedium, &fHostIP); H();
/* next */
pParent = pCur;
@@ -4131,6 +4088,68 @@ int Console::configMedium(PCFGMNODE pLunL0,
}
/**
+ * Adds the medium properties to the CFGM tree.
+ *
+ * @returns VBox status code.
+ * @param pCur The current CFGM node.
+ * @param pMedium The medium object to configure.
+ * @param pfHostIP Where to return the value of the \"HostIPStack\" property if found.
+ */
+int Console::configMediumProperties(PCFGMNODE pCur, IMedium *pMedium, bool *pfHostIP)
+{
+ /* Pass all custom parameters. */
+ SafeArray<BSTR> aNames;
+ SafeArray<BSTR> aValues;
+ HRESULT hrc = pMedium->GetProperties(NULL, ComSafeArrayAsOutParam(aNames),
+ ComSafeArrayAsOutParam(aValues));
+
+ if ( SUCCEEDED(hrc)
+ && aNames.size() != 0)
+ {
+ PCFGMNODE pVDC;
+ InsertConfigNode(pCur, "VDConfig", &pVDC);
+ for (size_t ii = 0; ii < aNames.size(); ++ii)
+ {
+ if (aValues[ii] && *aValues[ii])
+ {
+ Utf8Str name = aNames[ii];
+ Utf8Str value = aValues[ii];
+ size_t offSlash = name.find("/", 0);
+ if ( offSlash != name.npos
+ && !name.startsWith("Special/"))
+ {
+ com::Utf8Str strFilter;
+ com::Utf8Str strKey;
+
+ hrc = strFilter.assignEx(name, 0, offSlash);
+ if (FAILED(hrc))
+ break;
+
+ hrc = strKey.assignEx(name, offSlash + 1, name.length() - offSlash - 1); /* Skip slash */
+ if (FAILED(hrc))
+ break;
+
+ PCFGMNODE pCfgFilterConfig = CFGMR3GetChild(pVDC, strFilter.c_str());
+ if (!pCfgFilterConfig)
+ InsertConfigNode(pVDC, strFilter.c_str(), &pCfgFilterConfig);
+
+ InsertConfigString(pCfgFilterConfig, strKey.c_str(), value);
+ }
+ else
+ {
+ InsertConfigString(pVDC, name.c_str(), value);
+ if ( name.compare("HostIPStack") == 0
+ && value.compare("0") == 0)
+ *pfHostIP = false;
+ }
+ }
+ }
+ }
+
+ return hrc;
+}
+
+/**
* Construct the Network configuration tree
*
* @returns VBox status code.
diff --git a/src/VBox/Main/src-client/DisplayImpl.cpp b/src/VBox/Main/src-client/DisplayImpl.cpp
index 6525c92..fc723bb 100644
--- a/src/VBox/Main/src-client/DisplayImpl.cpp
+++ b/src/VBox/Main/src-client/DisplayImpl.cpp
@@ -19,6 +19,7 @@
#include "DisplayUtils.h"
#include "ConsoleImpl.h"
#include "ConsoleVRDPServer.h"
+#include "GuestImpl.h"
#include "VMMDev.h"
#include "AutoCaller.h"
@@ -95,7 +96,7 @@ static int g_stam = 0;
/////////////////////////////////////////////////////////////////////////////
Display::Display()
- : mParent(NULL)
+ : mParent(NULL), mfIsCr3DEnabled(false)
{
}
@@ -143,6 +144,9 @@ HRESULT Display::FinalConstruct()
#ifdef VBOX_WITH_HGSMI
mu32UpdateVBVAFlags = 0;
+ mfVMMDevSupportsGraphics = false;
+ mfGuestVBVACapabilities = 0;
+ mfHostCursorCapabilities = 0;
#endif
#ifdef VBOX_WITH_VPX
mpVideoRecCtx = NULL;
@@ -327,9 +331,9 @@ Display::displaySSMSaveScreenshot(PSSMHANDLE pSSM, void *pvUser)
#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
BOOL f3DSnapshot = FALSE;
- BOOL is3denabled;
- that->mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
- if (is3denabled && that->mCrOglCallbacks.pfnHasData())
+ if ( that->mfIsCr3DEnabled
+ && that->mCrOglCallbacks.pfnHasData
+ && that->mCrOglCallbacks.pfnHasData())
{
VMMDev *pVMMDev = that->mParent->getVMMDev();
if (pVMMDev)
@@ -528,6 +532,12 @@ Display::displaySSMSave(PSSMHANDLE pSSM, void *pvUser)
SSMR3PutS32(pSSM, that->maFramebuffers[i].yOrigin);
SSMR3PutU32(pSSM, that->maFramebuffers[i].flags);
}
+ SSMR3PutS32(pSSM, that->xInputMappingOrigin);
+ SSMR3PutS32(pSSM, that->yInputMappingOrigin);
+ SSMR3PutU32(pSSM, that->cxInputMapping);
+ SSMR3PutU32(pSSM, that->cyInputMapping);
+ SSMR3PutU32(pSSM, that->mfGuestVBVACapabilities);
+ SSMR3PutU32(pSSM, that->mfHostCursorCapabilities);
}
DECLCALLBACK(int)
@@ -535,9 +545,11 @@ Display::displaySSMLoad(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32
{
Display *that = static_cast<Display*>(pvUser);
- if (!( uVersion == sSSMDisplayVer
- || uVersion == sSSMDisplayVer2
- || uVersion == sSSMDisplayVer3))
+ if ( uVersion != sSSMDisplayVer
+ && uVersion != sSSMDisplayVer2
+ && uVersion != sSSMDisplayVer3
+ && uVersion != sSSMDisplayVer4
+ && uVersion != sSSMDisplayVer5)
return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
@@ -552,7 +564,9 @@ Display::displaySSMLoad(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32
SSMR3GetU32(pSSM, &that->maFramebuffers[i].u32MaxFramebufferSize);
SSMR3GetU32(pSSM, &that->maFramebuffers[i].u32InformationSize);
if ( uVersion == sSSMDisplayVer2
- || uVersion == sSSMDisplayVer3)
+ || uVersion == sSSMDisplayVer3
+ || uVersion == sSSMDisplayVer4
+ || uVersion == sSSMDisplayVer5)
{
uint32_t w;
uint32_t h;
@@ -561,7 +575,9 @@ Display::displaySSMLoad(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32
that->maFramebuffers[i].w = w;
that->maFramebuffers[i].h = h;
}
- if (uVersion == sSSMDisplayVer3)
+ if ( uVersion == sSSMDisplayVer3
+ || uVersion == sSSMDisplayVer4
+ || uVersion == sSSMDisplayVer5)
{
int32_t xOrigin;
int32_t yOrigin;
@@ -575,6 +591,19 @@ Display::displaySSMLoad(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32
that->maFramebuffers[i].fDisabled = (that->maFramebuffers[i].flags & VBVA_SCREEN_F_DISABLED) != 0;
}
}
+ if ( uVersion == sSSMDisplayVer4
+ || uVersion == sSSMDisplayVer5)
+ {
+ SSMR3GetS32(pSSM, &that->xInputMappingOrigin);
+ SSMR3GetS32(pSSM, &that->yInputMappingOrigin);
+ SSMR3GetU32(pSSM, &that->cxInputMapping);
+ SSMR3GetU32(pSSM, &that->cyInputMapping);
+ }
+ if (uVersion == sSSMDisplayVer5)
+ {
+ SSMR3GetU32(pSSM, &that->mfGuestVBVACapabilities);
+ SSMR3GetU32(pSSM, &that->mfHostCursorCapabilities);
+ }
return VINF_SUCCESS;
}
@@ -653,6 +682,13 @@ HRESULT Display::init(Console *aParent)
es->RegisterListener(this, ComSafeArrayAsInParam(eventTypes), true);
}
+ /* Cache the 3D settings. */
+ BOOL fIs3DEnabled = FALSE;
+ mParent->machine()->COMGETTER(Accelerate3DEnabled)(&fIs3DEnabled);
+ GraphicsControllerType_T enmGpuType = (GraphicsControllerType_T)GraphicsControllerType_VBoxVGA;
+ mParent->machine()->COMGETTER(GraphicsControllerType)(&enmGpuType);
+ mfIsCr3DEnabled = fIs3DEnabled && enmGpuType == GraphicsControllerType_VBoxVGA;
+
/* Confirm a successful initialization */
autoInitSpan.setSucceeded();
@@ -700,9 +736,11 @@ void Display::uninit()
int Display::registerSSM(PUVM pUVM)
{
/* Version 2 adds width and height of the framebuffer; version 3 adds
- * the framebuffer offset in the virtual desktop and the framebuffer flags.
+ * the framebuffer offset in the virtual desktop and the framebuffer flags;
+ * version 4 adds guest to host input event mapping and version 5 adds
+ * guest VBVA and host cursor capabilities.
*/
- int rc = SSMR3RegisterExternal(pUVM, "DisplayData", 0, sSSMDisplayVer3,
+ int rc = SSMR3RegisterExternal(pUVM, "DisplayData", 0, sSSMDisplayVer5,
mcMonitors * sizeof(uint32_t) * 8 + sizeof(uint32_t),
NULL, NULL, NULL,
NULL, displaySSMSave, NULL,
@@ -750,12 +788,8 @@ int Display::crOglWindowsShow(bool fShow)
if (!mhCrOglSvc)
{
- /* no 3D */
-#ifdef DEBUG
- BOOL is3denabled;
- mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
- Assert(!is3denabled);
-#endif
+ /* No 3D or the VMSVGA3d kind. */
+ Assert(!mfIsCr3DEnabled);
return VERR_INVALID_STATE;
}
@@ -872,10 +906,7 @@ int Display::notifyCroglResize(const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN
if (maFramebuffers[pScreen->u32ViewIndex].fRenderThreadMode)
return VINF_SUCCESS; /* nop it */
- BOOL is3denabled;
- mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
-
- if (is3denabled)
+ if (mfIsCr3DEnabled)
{
int rc = VERR_INVALID_STATE;
if (mhCrOglSvc)
@@ -883,8 +914,8 @@ int Display::notifyCroglResize(const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN
VMMDev *pVMMDev = mParent->getVMMDev();
if (pVMMDev)
{
- VBOXCRCMDCTL_HGCM *pCtl =
- (VBOXCRCMDCTL_HGCM*)RTMemAlloc(sizeof (CRVBOXHGCMDEVRESIZE) + sizeof (VBOXCRCMDCTL_HGCM));
+ VBOXCRCMDCTL_HGCM *pCtl;
+ pCtl = (VBOXCRCMDCTL_HGCM*)RTMemAlloc(sizeof(CRVBOXHGCMDEVRESIZE) + sizeof(VBOXCRCMDCTL_HGCM));
if (pCtl)
{
CRVBOXHGCMDEVRESIZE *pData = (CRVBOXHGCMDEVRESIZE*)(pCtl+1);
@@ -898,7 +929,7 @@ int Display::notifyCroglResize(const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN
pCtl->aParms[0].u.pointer.size = sizeof (*pData);
rc = crCtlSubmit(&pCtl->Hdr, sizeof (*pCtl), displayCrCmdFree, pCtl);
- if (!RT_SUCCESS(rc))
+ if (RT_FAILURE(rc))
{
AssertMsgFailed(("crCtlSubmit failed rc %d\n", rc));
RTMemFree(pCtl);
@@ -1271,6 +1302,61 @@ void Display::handleDisplayUpdate (unsigned uScreenId, int x, int y, int w, int
}
}
+void Display::i_updateGuestGraphicsFacility(void)
+{
+ Guest* pGuest = mParent->getGuest();
+ AssertPtrReturnVoid(pGuest);
+ /* The following is from GuestImpl.cpp. */
+ /** @todo A nit: The timestamp is wrong on saved state restore. Would be better
+ * to move the graphics and seamless capability -> facility translation to
+ * VMMDev so this could be saved. */
+ RTTIMESPEC TimeSpecTS;
+ RTTimeNow(&TimeSpecTS);
+
+ if ( mfVMMDevSupportsGraphics
+ || (mfGuestVBVACapabilities & VBVACAPS_VIDEO_MODE_HINTS) != 0)
+ pGuest->setAdditionsStatus(VBoxGuestFacilityType_Graphics,
+ VBoxGuestFacilityStatus_Active,
+ 0 /*fFlags*/, &TimeSpecTS);
+ else
+ pGuest->setAdditionsStatus(VBoxGuestFacilityType_Graphics,
+ VBoxGuestFacilityStatus_Inactive,
+ 0 /*fFlags*/, &TimeSpecTS);
+}
+
+void Display::i_handleUpdateVMMDevSupportsGraphics(bool fSupportsGraphics)
+{
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ if (mfVMMDevSupportsGraphics == fSupportsGraphics)
+ return;
+ mfVMMDevSupportsGraphics = fSupportsGraphics;
+ i_updateGuestGraphicsFacility();
+ /* The VMMDev interface notifies the console. */
+}
+
+void Display::i_handleUpdateGuestVBVACapabilities(uint32_t fNewCapabilities)
+{
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ bool fNotify = (fNewCapabilities & VBVACAPS_VIDEO_MODE_HINTS) != 0;
+
+ mfGuestVBVACapabilities = fNewCapabilities;
+ if (!fNotify)
+ return;
+ i_updateGuestGraphicsFacility();
+ /* Tell the console about it */
+ mParent->onAdditionsStateChange();
+}
+
+void Display::i_handleUpdateVBVAInputMapping(int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy)
+{
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ xInputMappingOrigin = xOrigin;
+ yInputMappingOrigin = yOrigin;
+ cxInputMapping = cx;
+ cyInputMapping = cy;
+}
+
/**
* Returns the upper left and lower right corners of the virtual framebuffer.
* The lower right is "exclusive" (i.e. first pixel beyond the framebuffer),
@@ -1299,24 +1385,67 @@ void Display::getFramebufferDimensions(int32_t *px1, int32_t *py1,
x2 = mpDrv->IConnector.cx + (int32_t)maFramebuffers[0].xOrigin;
y2 = mpDrv->IConnector.cy + (int32_t)maFramebuffers[0].yOrigin;
}
- for (unsigned i = 1; i < mcMonitors; ++i)
+ if (cxInputMapping && cyInputMapping)
{
- if (!maFramebuffers[i].fDisabled)
+ x1 = xInputMappingOrigin;
+ y1 = yInputMappingOrigin;
+ x2 = xInputMappingOrigin + cxInputMapping;
+ y2 = xInputMappingOrigin + cyInputMapping;
+ }
+ else
+ for (unsigned i = 1; i < mcMonitors; ++i)
{
- x1 = RT_MIN(x1, maFramebuffers[i].xOrigin);
- y1 = RT_MIN(y1, maFramebuffers[i].yOrigin);
- x2 = RT_MAX(x2, maFramebuffers[i].xOrigin
- + (int32_t)maFramebuffers[i].w);
- y2 = RT_MAX(y2, maFramebuffers[i].yOrigin
- + (int32_t)maFramebuffers[i].h);
+ if (!maFramebuffers[i].fDisabled)
+ {
+ x1 = RT_MIN(x1, maFramebuffers[i].xOrigin);
+ y1 = RT_MIN(y1, maFramebuffers[i].yOrigin);
+ x2 = RT_MAX(x2, maFramebuffers[i].xOrigin + (int32_t)maFramebuffers[i].w);
+ y2 = RT_MAX(y2, maFramebuffers[i].yOrigin + (int32_t)maFramebuffers[i].h);
+ }
}
- }
*px1 = x1;
*py1 = y1;
*px2 = x2;
*py2 = y2;
}
+HRESULT Display::i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved)
+{
+ /* Do we need this to access mParent? I presume that the safe VM pointer
+ * ensures that mpDrv will remain valid. */
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ uint32_t fHostCursorCapabilities = (mfHostCursorCapabilities | fCapabilitiesAdded)
+ & ~fCapabilitiesRemoved;
+
+ Console::SafeVMPtr ptrVM(mParent);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+ if (mfHostCursorCapabilities == fHostCursorCapabilities)
+ return S_OK;
+ CHECK_CONSOLE_DRV(mpDrv);
+ alock.release(); /* Release before calling up for lock order reasons. */
+ mpDrv->pUpPort->pfnReportHostCursorCapabilities (mpDrv->pUpPort, fCapabilitiesAdded, fCapabilitiesRemoved);
+ mfHostCursorCapabilities = fHostCursorCapabilities;
+ return S_OK;
+}
+
+HRESULT Display::i_reportHostCursorPosition(int32_t x, int32_t y)
+{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ uint32_t xAdj = (uint32_t)RT_MAX(x - xInputMappingOrigin, 0);
+ uint32_t yAdj = (uint32_t)RT_MAX(y - yInputMappingOrigin, 0);
+ xAdj = RT_MIN(xAdj, cxInputMapping);
+ yAdj = RT_MIN(yAdj, cyInputMapping);
+
+ Console::SafeVMPtr ptrVM(mParent);
+ if (!ptrVM.isOk())
+ return ptrVM.rc();
+ CHECK_CONSOLE_DRV(mpDrv);
+ alock.release(); /* Release before calling up for lock order reasons. */
+ mpDrv->pUpPort->pfnReportHostCursorPosition(mpDrv->pUpPort, xAdj, yAdj);
+ return S_OK;
+}
+
static bool displayIntersectRect(RTRECT *prectResult,
const RTRECT *prect1,
const RTRECT *prect2)
@@ -1444,17 +1573,13 @@ int Display::handleSetVisibleRegion(uint32_t cRect, PRTRECT pRect)
}
#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
- BOOL is3denabled = FALSE;
-
- mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
-
VMMDev *vmmDev = mParent->getVMMDev();
- if (is3denabled && vmmDev)
+ if (mfIsCr3DEnabled && vmmDev)
{
if (mhCrOglSvc)
{
- VBOXCRCMDCTL_HGCM *pCtl = (VBOXCRCMDCTL_HGCM*)RTMemAlloc(RT_MAX(cRect, 1) * sizeof (RTRECT)
- + sizeof (VBOXCRCMDCTL_HGCM));
+ VBOXCRCMDCTL_HGCM *pCtl;
+ pCtl = (VBOXCRCMDCTL_HGCM*)RTMemAlloc(RT_MAX(cRect, 1) * sizeof(RTRECT) + sizeof(VBOXCRCMDCTL_HGCM));
if (pCtl)
{
RTRECT *pRectsCopy = (RTRECT*)(pCtl+1);
@@ -2418,10 +2543,7 @@ STDMETHODIMP Display::SetFramebuffer(ULONG aScreenId, IFramebuffer *aFramebuffer
#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
{
- BOOL is3denabled;
- mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
-
- if (is3denabled)
+ if (mfIsCr3DEnabled)
{
VBOXCRCMDCTL_HGCM data;
data.Hdr.enmType = VBOXCRCMDCTL_TYPE_HGCM;
@@ -2522,6 +2644,27 @@ STDMETHODIMP Display::SetVideoModeHint(ULONG aDisplay, BOOL aEnabled,
* will call EMT. */
alock.release();
+ /* We always send the hint to the graphics card in case the guest enables
+ * support later. For now we notify exactly when support is enabled. */
+ mpDrv->pUpPort->pfnSendModeHint(mpDrv->pUpPort, aWidth, aHeight,
+ aBitsPerPixel, aDisplay,
+ aChangeOrigin ? aOriginX : ~0,
+ aChangeOrigin ? aOriginY : ~0,
+ RT_BOOL(aEnabled),
+ mfGuestVBVACapabilities
+ & VBVACAPS_VIDEO_MODE_HINTS);
+ if ( mfGuestVBVACapabilities & VBVACAPS_VIDEO_MODE_HINTS
+ && !(mfGuestVBVACapabilities & VBVACAPS_IRQ))
+ {
+ HRESULT hrc = mParent->i_sendACPIMonitorHotPlugEvent();
+ if (FAILED(hrc))
+ return hrc;
+ }
+
+ /* We currently never suppress the VMMDev hint if the guest has requested
+ * it. Specifically the video graphics driver may not be responsible for
+ * screen positioning in the guest virtual desktop, and the component
+ * responsible may want to get the hint from VMMDev. */
VMMDev *pVMMDev = mParent->getVMMDev();
if (pVMMDev)
{
@@ -2555,12 +2698,8 @@ STDMETHODIMP Display::SetSeamlessMode (BOOL enabled)
#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
if (!enabled)
{
- BOOL is3denabled = FALSE;
-
- mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
-
VMMDev *vmmDev = mParent->getVMMDev();
- if (is3denabled && vmmDev)
+ if (mfIsCr3DEnabled && vmmDev)
{
VBOXCRCMDCTL_HGCM *pData = (VBOXCRCMDCTL_HGCM*)RTMemAlloc(sizeof (VBOXCRCMDCTL_HGCM));
if (!pData)
@@ -2592,9 +2731,9 @@ STDMETHODIMP Display::SetSeamlessMode (BOOL enabled)
BOOL Display::displayCheckTakeScreenshotCrOgl(Display *pDisplay, ULONG aScreenId, uint8_t *pu8Data,
uint32_t u32Width, uint32_t u32Height)
{
- BOOL is3denabled;
- pDisplay->mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
- if (is3denabled && pDisplay->mCrOglCallbacks.pfnHasData())
+ if ( pDisplay->mfIsCr3DEnabled
+ && pDisplay->mCrOglCallbacks.pfnHasData
+ && pDisplay->mCrOglCallbacks.pfnHasData())
{
VMMDev *pVMMDev = pDisplay->mParent->getVMMDev();
if (pVMMDev)
@@ -3485,18 +3624,10 @@ STDMETHODIMP Display::CompleteVHWACommand(BYTE *pCommand)
STDMETHODIMP Display::ViewportChanged(ULONG aScreenId, ULONG x, ULONG y, ULONG width, ULONG height)
{
-#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
+ AssertMsgReturn(aScreenId < mcMonitors, ("aScreendId=%d mcMonitors=%d\n", aScreenId, mcMonitors), E_INVALIDARG);
- if (mcMonitors <= aScreenId)
- {
- AssertMsgFailed(("invalid screen id\n"));
- return E_INVALIDARG;
- }
-
- BOOL is3denabled;
- mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
-
- if (is3denabled)
+#if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
+ if (mfIsCr3DEnabled)
{
int rc = crViewportNotify(aScreenId, x, y, width, height);
if (RT_FAILURE(rc))
@@ -3514,9 +3645,7 @@ STDMETHODIMP Display::ViewportChanged(ULONG aScreenId, ULONG x, ULONG y, ULONG w
#ifdef VBOX_WITH_VMSVGA
/* The driver might not have been constructed yet */
if (mpDrv)
- {
mpDrv->pUpPort->pfnSetViewPort(mpDrv->pUpPort, aScreenId, x, y, width, height);
- }
#endif
return S_OK;
@@ -3684,7 +3813,7 @@ void Display::destructCrHgsmiData(void)
mhCrOglSvc = NULL;
RTCritSectRwLeaveExcl(&mCrOglLock);
}
-#endif
+#endif /* VBOX_WITH_CRHGSMI */
/**
* Changes the current frame buffer. Called on EMT to avoid both
@@ -3804,7 +3933,7 @@ DECLCALLBACK(void) Display::displayUpdateCallback(PPDMIDISPLAYCONNECTOR pInterfa
* @see PDMIDISPLAYCONNECTOR::pfnRefresh
* @thread EMT
*/
-DECLCALLBACK(void) Display::displayRefreshCallback(PPDMIDISPLAYCONNECTOR pInterface)
+/*static */DECLCALLBACK(void) Display::displayRefreshCallback(PPDMIDISPLAYCONNECTOR pInterface)
{
PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
@@ -3898,13 +4027,12 @@ DECLCALLBACK(void) Display::displayRefreshCallback(PPDMIDISPLAYCONNECTOR pInterf
{
do {
# if defined(VBOX_WITH_HGCM) && defined(VBOX_WITH_CROGL)
- BOOL is3denabled;
- pDisplay->mParent->machine()->COMGETTER(Accelerate3DEnabled)(&is3denabled);
- if (is3denabled)
+ if (pDisplay->mfIsCr3DEnabled)
{
if (ASMAtomicCmpXchgU32(&pDisplay->mfCrOglVideoRecState, CRVREC_STATE_SUBMITTED, CRVREC_STATE_IDLE))
{
- if (pDisplay->mCrOglCallbacks.pfnHasData())
+ if ( pDisplay->mCrOglCallbacks.pfnHasData
+ && pDisplay->mCrOglCallbacks.pfnHasData())
{
/* submit */
VBOXCRCMDCTL_HGCM *pData = &pDisplay->mCrOglScreenshotCtl;
@@ -3918,8 +4046,7 @@ DECLCALLBACK(void) Display::displayRefreshCallback(PPDMIDISPLAYCONNECTOR pInterf
int rc = pDisplay->crCtlSubmit(&pData->Hdr, sizeof (*pData), Display::displayVRecCompletion, pDisplay);
if (RT_SUCCESS(rc))
break;
- else
- AssertMsgFailed(("crCtlSubmit failed rc %d\n", rc));
+ AssertMsgFailed(("crCtlSubmit failed rc %d\n", rc));
}
/* no 3D data available, or error has occured,
@@ -4512,7 +4639,8 @@ int Display::crCtlSubmitSyncIfHasDataForScreen(uint32_t u32ScreenID, struct VBOX
int rc = RTCritSectRwEnterShared(&mCrOglLock);
AssertRCReturn(rc, rc);
- if (mCrOglCallbacks.pfnHasDataForScreen && mCrOglCallbacks.pfnHasDataForScreen(u32ScreenID))
+ if ( mCrOglCallbacks.pfnHasDataForScreen
+ && mCrOglCallbacks.pfnHasDataForScreen(u32ScreenID))
rc = crCtlSubmitSync(pCmd, cbCmd);
else
rc = crCtlSubmitAsyncCmdCopy(pCmd, cbCmd);
@@ -4997,6 +5125,11 @@ DECLCALLBACK(int) Display::displayVBVAResize(PPDMIDISPLAYCONNECTOR pInterface, c
pFBInfo->flags = pScreen->u16Flags;
+ pThis->xInputMappingOrigin = 0;
+ pThis->yInputMappingOrigin = 0;
+ pThis->cxInputMapping = 0;
+ pThis->cyInputMapping = 0;
+
if (fNewOrigin)
{
fireGuestMonitorChangedEvent(pThis->mParent->getEventSource(),
@@ -5058,6 +5191,28 @@ DECLCALLBACK(int) Display::displayVBVAMousePointerShape(PPDMIDISPLAYCONNECTOR pI
return VINF_SUCCESS;
}
+
+DECLCALLBACK(void) Display::i_displayVBVAGuestCapabilityUpdate(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities)
+{
+ LogFlowFunc(("\n"));
+
+ PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
+ Display *pThis = pDrv->pDisplay;
+
+ pThis->i_handleUpdateGuestVBVACapabilities(fCapabilities);
+}
+
+DECLCALLBACK(void) Display::i_displayVBVAInputMappingUpdate(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin,
+ uint32_t cx, uint32_t cy)
+{
+ LogFlowFunc(("\n"));
+
+ PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
+ Display *pThis = pDrv->pDisplay;
+
+ pThis->i_handleUpdateVBVAInputMapping(xOrigin, yOrigin, cx, cy);
+}
+
#endif /* VBOX_WITH_HGSMI */
/**
@@ -5155,6 +5310,8 @@ DECLCALLBACK(int) Display::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint
pThis->IConnector.pfnVBVAUpdateEnd = Display::displayVBVAUpdateEnd;
pThis->IConnector.pfnVBVAResize = Display::displayVBVAResize;
pThis->IConnector.pfnVBVAMousePointerShape = Display::displayVBVAMousePointerShape;
+ pThis->IConnector.pfnVBVAGuestCapabilityUpdate = Display::i_displayVBVAGuestCapabilityUpdate;
+ pThis->IConnector.pfnVBVAInputMappingUpdate = Display::i_displayVBVAInputMappingUpdate;
#endif
/*
diff --git a/src/VBox/Main/src-client/GuestImpl.cpp b/src/VBox/Main/src-client/GuestImpl.cpp
index b438f9d..fcc9b26 100644
--- a/src/VBox/Main/src-client/GuestImpl.cpp
+++ b/src/VBox/Main/src-client/GuestImpl.cpp
@@ -1251,8 +1251,5 @@ void Guest::setSupportedFeatures(uint32_t aCaps)
aCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
0 /*fFlags*/, &TimeSpecTS);
/** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */
- facilityUpdate(VBoxGuestFacilityType_Graphics,
- aCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
- 0 /*fFlags*/, &TimeSpecTS);
}
diff --git a/src/VBox/Main/src-client/MouseImpl.cpp b/src/VBox/Main/src-client/MouseImpl.cpp
index 652f2df..7648331 100644
--- a/src/VBox/Main/src-client/MouseImpl.cpp
+++ b/src/VBox/Main/src-client/MouseImpl.cpp
@@ -162,13 +162,18 @@ HRESULT Mouse::updateVMMDevMouseCaps(uint32_t fCapsAdded,
if (!pVMMDev)
return E_FAIL; /* No assertion, as the front-ends can send events
* at all sorts of inconvenient times. */
+ DisplayMouseInterface *pDisplay = mParent->getDisplayMouseInterface();
+ if (pDisplay == NULL)
+ return E_FAIL;
PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
if (!pVMMDevPort)
return E_FAIL; /* same here */
int rc = pVMMDevPort->pfnUpdateMouseCapabilities(pVMMDevPort, fCapsAdded,
fCapsRemoved);
- return RT_SUCCESS(rc) ? S_OK : E_FAIL;
+ if (RT_FAILURE(rc))
+ return E_FAIL;
+ return pDisplay->i_reportHostCursorCapabilities(fCapsAdded, fCapsRemoved);
}
/**
@@ -432,9 +437,8 @@ HRESULT Mouse::reportAbsEventToVMMDev(int32_t x, int32_t y)
*
* @returns COM status code
*/
-HRESULT Mouse::reportAbsEvent(int32_t x, int32_t y,
- int32_t dz, int32_t dw, uint32_t fButtons,
- bool fUsesVMMDevEvent)
+HRESULT Mouse::i_reportAbsEventToInputDevices(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons,
+ bool fUsesVMMDevEvent)
{
HRESULT rc;
/** If we are using the VMMDev to report absolute position but without
@@ -462,6 +466,28 @@ HRESULT Mouse::reportAbsEvent(int32_t x, int32_t y,
return rc;
}
+
+/**
+ * Send an absolute position event to the display device.
+ * @note all calls out of this object are made with no locks held!
+ * @param x Cursor X position in pixels relative to the first screen, where
+ * (1, 1) is the upper left corner.
+ * @param y Cursor Y position in pixels relative to the first screen, where
+ * (1, 1) is the upper left corner.
+ */
+HRESULT Mouse::i_reportAbsEventToDisplayDevice(int32_t x, int32_t y)
+{
+ DisplayMouseInterface *pDisplay = mParent->getDisplayMouseInterface();
+ ComAssertRet(pDisplay, E_FAIL);
+
+ if (x != mcLastX || y != mcLastY)
+ {
+ pDisplay->i_reportHostCursorPosition(x - 1, y - 1);
+ }
+ return S_OK;
+}
+
+
void Mouse::fireMouseEvent(bool fAbsolute, LONG x, LONG y, LONG dz, LONG dw,
LONG fButtons)
{
@@ -654,12 +680,13 @@ STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
updateVMMDevMouseCaps(VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE, 0);
if (fValid)
{
- rc = reportAbsEvent(xAdj, yAdj, dz, dw, fButtonsAdj,
- RT_BOOL( mfVMMDevGuestCaps
- & VMMDEV_MOUSE_NEW_PROTOCOL));
+ rc = i_reportAbsEventToInputDevices(xAdj, yAdj, dz, dw, fButtonsAdj,
+ RT_BOOL(mfVMMDevGuestCaps & VMMDEV_MOUSE_NEW_PROTOCOL));
+ if (FAILED(rc)) return rc;
fireMouseEvent(true, x, y, dz, dw, fButtons);
}
+ rc = i_reportAbsEventToDisplayDevice(x, y);
return rc;
}
@@ -923,22 +950,15 @@ bool Mouse::supportsMT(void)
*/
void Mouse::sendMouseCapsNotifications(void)
{
- bool fAbsDev, fRelDev, fMTDev, fCanAbs, fNeedsHostCursor;
+ bool fRelDev, fMTDev, fCanAbs, fNeedsHostCursor;
{
AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS);
- getDeviceCaps(&fAbsDev, &fRelDev, &fMTDev);
+ getDeviceCaps(NULL, &fRelDev, &fMTDev);
fCanAbs = supportsAbs();
fNeedsHostCursor = guestNeedsHostCursor();
}
- if (fAbsDev)
- updateVMMDevMouseCaps(VMMDEV_MOUSE_HOST_HAS_ABS_DEV, 0);
- else
- updateVMMDevMouseCaps(0, VMMDEV_MOUSE_HOST_HAS_ABS_DEV);
- /** @todo this call takes the Console lock in order to update the cached
- * callback data atomically. However I can't see any sign that the cached
- * data is ever used again. */
mParent->onMouseCapabilityChange(fCanAbs, fRelDev, fMTDev, fNeedsHostCursor);
}
diff --git a/src/VBox/Main/src-client/README.testing b/src/VBox/Main/src-client/README.testing
new file mode 100644
index 0000000..6edd108
--- /dev/null
+++ b/src/VBox/Main/src-client/README.testing
@@ -0,0 +1,16 @@
+This file contains some notes about things to try out to give the client-side
+code in Main a reasonably thorough test. We will add cases of things which
+have been known to fail in the past to this file as we discover them.
+
+*Linux guests*: changes should be tested against the following guests, or
+equivalent vintages, preferably in 32-bit and 64-bit versions, with no
+Additions and with 4.2 and 4.3 Additions and with single and dual screens:
+CentOS 3, CentOS 5, CentOS 6, Current Ubuntu.
+
+Mouse interface changes:
+ * Test that mouse integration works.
+ * Test that disabling mouse integration on the fly works.
+
+Display interface changed:
+ * Test that dynamic resizing works.
+ * Test that switching to seamless mode and back works.
diff --git a/src/VBox/Main/src-client/VMMDevInterface.cpp b/src/VBox/Main/src-client/VMMDevInterface.cpp
index b4f4da4..42be327 100644
--- a/src/VBox/Main/src-client/VMMDevInterface.cpp
+++ b/src/VBox/Main/src-client/VMMDevInterface.cpp
@@ -312,6 +312,15 @@ DECLCALLBACK(void) vmmdevUpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface
pGuest->setSupportedFeatures(newCapabilities);
/*
+ * Tell the Display, so that it can update the "supports graphics"
+ * capability if the graphics card has not asserted it.
+ */
+ Display* pDisplay = pConsole->getDisplay();
+ AssertPtrReturnVoid(pDisplay);
+ pDisplay->i_handleUpdateVMMDevSupportsGraphics(newCapabilities
+ & VMMDEV_GUEST_SUPPORTS_GRAPHICS);
+
+ /*
* Tell the console interface about the event
* so that it can notify its consumers.
*/
diff --git a/src/VBox/Main/src-client/win/VBoxC.rc b/src/VBox/Main/src-client/win/VBoxC.rc
index 2adf754..a3593fd 100644
--- a/src/VBox/Main/src-client/win/VBoxC.rc
+++ b/src/VBox/Main/src-client/win/VBoxC.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -20,7 +20,7 @@
#include "win/resource.h"
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -29,7 +29,7 @@ VS_VERSION_INFO VERSIONINFO
#else
FILEFLAGS 0 // final version
#endif
- FILEOS VOS__WINDOWS32
+ FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0 // not used
BEGIN
@@ -37,17 +37,16 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox Interface\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxC.dll\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename","VBoxC.dll\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
-
- VALUE "OLESelfRegister", ""
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Interface\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxC\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxC.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "OLESelfRegister", "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/VBox/Main/src-client/win/VBoxClient-x86.rc b/src/VBox/Main/src-client/win/VBoxClient-x86.rc
index d5c4ae0..262b1ea 100644
--- a/src/VBox/Main/src-client/win/VBoxClient-x86.rc
+++ b/src/VBox/Main/src-client/win/VBoxClient-x86.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -20,7 +20,7 @@
#include "win/resource.h"
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -29,7 +29,7 @@ VS_VERSION_INFO VERSIONINFO
#else
FILEFLAGS 0 // final version
#endif
- FILEOS VOS__WINDOWS32
+ FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0 // not used
BEGIN
@@ -37,17 +37,16 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox Interface (32-bit)\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxClient-x86.dll\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename","VBoxClient-x86.dll\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
-
- VALUE "OLESelfRegister", ""
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Interface (32-bit)\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxClient-x86\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxClient-x86.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "OLESelfRegister", "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.rc b/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.rc
new file mode 100644
index 0000000..dfaadcf
--- /dev/null
+++ b/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxExtPackHelperApp.rc $ */
+/** @file
+ * VBoxExtPackHelperApp - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox ExtPack Helper\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxExtPackHelperApp\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxExtPackHelperApp.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Main/src-server/HostDnsService.cpp b/src/VBox/Main/src-server/HostDnsService.cpp
index 011528f..cd56461 100644
--- a/src/VBox/Main/src-server/HostDnsService.cpp
+++ b/src/VBox/Main/src-server/HostDnsService.cpp
@@ -1,6 +1,6 @@
/* $Id: HostDnsService.cpp $ */
/** @file
- * Base class fo Host DNS & Co services.
+ * Base class for Host DNS & Co services.
*/
/*
diff --git a/src/VBox/Main/src-server/HostDnsService.h b/src/VBox/Main/src-server/HostDnsService.h
index 56da78d..d7e1978 100644
--- a/src/VBox/Main/src-server/HostDnsService.h
+++ b/src/VBox/Main/src-server/HostDnsService.h
@@ -157,7 +157,6 @@ class HostDnsServiceWin : public HostDnsMonitor
virtual int monitorWorker();
private:
- void strList2List(std::vector<std::string>& lst, char *strLst);
HRESULT updateInfo();
private:
diff --git a/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp b/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
index 3b2ceeb..e580051 100644
--- a/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
+++ b/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
@@ -1,3 +1,20 @@
+/* $Id: HostDnsServiceResolvConf.cpp $ */
+/** @file
+ * Base class for Host DNS & Co services.
+ */
+
+/*
+ * Copyright (C) 2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
/* -*- indent-tabs-mode: nil; -*- */
#include <VBox/com/string.h>
#include <VBox/com/ptr.h>
@@ -64,8 +81,8 @@ HRESULT HostDnsServiceResolvConf::init(const char *aResolvConfFileName)
HRESULT HostDnsServiceResolvConf::readResolvConf()
{
struct rcp_state st;
-
- st.rcps_flags = RCPSF_NO_STR2IPCONV;
+
+ st.rcps_flags = RCPSF_NO_STR2IPCONV;
int rc = rcp_parse(&st, m->resolvConfFilename.c_str());
if (rc == -1)
return S_OK;
@@ -76,7 +93,7 @@ HRESULT HostDnsServiceResolvConf::readResolvConf()
AssertBreak(st.rcps_str_nameserver[i]);
info.servers.push_back(st.rcps_str_nameserver[i]);
}
-
+
if (st.rcps_domain)
info.domain = st.rcps_domain;
diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index 2eb2947..ca8a3ea 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -5710,19 +5710,22 @@ HRESULT Machine::deleteTaskWorker(DeleteTask &task)
if (FAILED(rc)) throw rc;
LogFunc(("Deleting file %s\n", strLocation.c_str()));
}
- ComPtr<IProgress> pProgress2;
- rc = pMedium->DeleteStorage(pProgress2.asOutParam());
- if (FAILED(rc)) throw rc;
- rc = task.pProgress->WaitForAsyncProgressCompletion(pProgress2);
- if (FAILED(rc)) throw rc;
- /* Check the result of the asynchronous process. */
- LONG iRc;
- rc = pProgress2->COMGETTER(ResultCode)(&iRc);
- if (FAILED(rc)) throw rc;
- /* If the thread of the progress object has an error, then
- * retrieve the error info from there, or it'll be lost. */
- if (FAILED(iRc))
- throw setError(ProgressErrorInfo(pProgress2));
+ if (pMedium->isMediumFormatFile())
+ {
+ ComPtr<IProgress> pProgress2;
+ rc = pMedium->DeleteStorage(pProgress2.asOutParam());
+ if (FAILED(rc)) throw rc;
+ rc = task.pProgress->WaitForAsyncProgressCompletion(pProgress2);
+ if (FAILED(rc)) throw rc;
+ /* Check the result of the asynchronous process. */
+ LONG iRc;
+ rc = pProgress2->COMGETTER(ResultCode)(&iRc);
+ if (FAILED(rc)) throw rc;
+ /* If the thread of the progress object has an error, then
+ * retrieve the error info from there, or it'll be lost. */
+ if (FAILED(iRc))
+ throw setError(ProgressErrorInfo(pProgress2));
+ }
/* Close the medium, deliberately without checking the return
* code, and without leaving any trace in the error info, as
@@ -11785,6 +11788,9 @@ HRESULT Machine::detachAllMedia(AutoWriteLock &writeLock,
{
llMedia.push_back(pMedium);
ComObjPtr<Medium> pParent = pMedium->getParent();
+ /* Not allowed to keep this lock as below we need the parent
+ * medium lock, and the lock order is parent to child. */
+ lock.release();
/*
* Search for medias which are not attached to any machine, but
* in the chain to an attached disk. Mediums are only consided
@@ -11882,9 +11888,6 @@ void Machine::commitMedia(bool aOnline /*= false*/)
&& pAttach->getType() == DeviceType_HardDisk
)
{
- ComObjPtr<Medium> parent = pMedium->getParent();
- AutoWriteLock parentLock(parent COMMA_LOCKVAL_SRC_POS);
-
/* update the appropriate lock list */
MediumLockList *pMediumLockList;
rc = mData->mSession.mLockedMedia.Get(pAttach, pMediumLockList);
@@ -11898,7 +11901,7 @@ void Machine::commitMedia(bool aOnline /*= false*/)
AssertComRC(rc);
fMediaNeedsLocking = true;
}
- rc = pMediumLockList->Update(parent, false);
+ rc = pMediumLockList->Update(pMedium->getParent(), false);
AssertComRC(rc);
rc = pMediumLockList->Append(pMedium, true);
AssertComRC(rc);
diff --git a/src/VBox/Main/src-server/MediumImpl.cpp b/src/VBox/Main/src-server/MediumImpl.cpp
index 3a935b5..d5b4f7b 100644
--- a/src/VBox/Main/src-server/MediumImpl.cpp
+++ b/src/VBox/Main/src-server/MediumImpl.cpp
@@ -100,6 +100,7 @@ struct Medium::Data
autoReset(false),
hostDrive(false),
implicit(false),
+ fClosing(false),
uOpenFlagsDef(VD_OPEN_FLAGS_IGNORE_FLUSH),
numCreateDiffTasks(0),
vdDiskIfaces(NULL),
@@ -157,6 +158,8 @@ struct Medium::Data
settings::StringsMap mapProperties;
bool implicit : 1;
+ /** Flag whether the medium is in the process of being closed. */
+ bool fClosing: 1;
/** Default flags passed to VDOpen(). */
unsigned uOpenFlagsDef;
@@ -4282,6 +4285,8 @@ HRESULT Medium::close(AutoCaller &autoCaller)
HRESULT rc = canClose();
if (FAILED(rc)) return rc;
+ m->fClosing = true;
+
if (wasCreated)
{
// remove from the list of known media before performing actual
@@ -5648,9 +5653,10 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId, AutoCaller &autoC
Assert(!isWriteLockOnCurrentThread());
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- if ( m->state != MediumState_Created
- && m->state != MediumState_Inaccessible
- && m->state != MediumState_LockedRead)
+ if ( ( m->state != MediumState_Created
+ && m->state != MediumState_Inaccessible
+ && m->state != MediumState_LockedRead)
+ || m->fClosing)
return E_FAIL;
HRESULT rc = S_OK;
@@ -6765,11 +6771,12 @@ DECLCALLBACK(int) Medium::vdTcpSocketDestroy(VDSOCKET Sock)
return VINF_SUCCESS;
}
-DECLCALLBACK(int) Medium::vdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort)
+DECLCALLBACK(int) Medium::vdTcpClientConnect(VDSOCKET Sock, const char *pszAddress, uint32_t uPort,
+ RTMSINTERVAL cMillies)
{
PVDSOCKETINT pSocketInt = (PVDSOCKETINT)Sock;
- return RTTcpClientConnect(pszAddress, uPort, &pSocketInt->hSocket);
+ return RTTcpClientConnectEx(pszAddress, uPort, &pSocketInt->hSocket, cMillies, NULL);
}
DECLCALLBACK(int) Medium::vdTcpClientClose(VDSOCKET Sock)
diff --git a/src/VBox/Main/src-server/SnapshotImpl.cpp b/src/VBox/Main/src-server/SnapshotImpl.cpp
index ddce18b..a6ea216 100644
--- a/src/VBox/Main/src-server/SnapshotImpl.cpp
+++ b/src/VBox/Main/src-server/SnapshotImpl.cpp
@@ -1451,6 +1451,7 @@ STDMETHODIMP SessionMachine::BeginTakingSnapshot(IConsole *aInitiator,
BOOL fTakingSnapshotOnline,
BSTR *aStateFilePath)
{
+ NOREF(aInitiator);
LogFlowThisFuncEnter();
AssertReturn(aInitiator && aName, E_INVALIDARG);
diff --git a/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp b/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
index 6e91e7e..dc384da 100644
--- a/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
+++ b/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
@@ -60,7 +60,7 @@ HostDnsServiceDarwin::~HostDnsServiceDarwin()
monitorThreadShutdown();
CFRelease(m->m_RunLoopRef);
-
+
CFRelease(m->m_DnsWatcher);
CFRelease(m->m_store);
@@ -121,7 +121,7 @@ void HostDnsServiceDarwin::monitorThreadShutdown()
{
CFRunLoopSourceSignal(m->m_Stopper);
CFRunLoopWakeUp(m->m_RunLoopRef);
-
+
RTSemEventWait(m->m_evtStop, RT_INDEFINITE_WAIT);
}
}
diff --git a/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp b/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
index 89de18d..77e8dd9 100644
--- a/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
+++ b/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -145,6 +145,7 @@ int HostDnsServiceLinux::monitorWorker()
{
RT_ZERO(combo);
ssize_t r = read(polls[0].fd, static_cast<void *>(&combo), sizeof(combo));
+ NOREF(r);
if (combo.e.wd == wd[0])
{
diff --git a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
index 1bd7223..b6599ec 100644
--- a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
+++ b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
@@ -1,85 +1,112 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: HostDnsServiceWin.cpp $ */
+/** @file
+ * Host DNS listener for Windows.
+ */
+
+/*
+ * Copyright (C) 2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+#include "../HostDnsService.h"
+
#include <VBox/com/string.h>
#include <VBox/com/ptr.h>
-
#include <iprt/assert.h>
#include <iprt/err.h>
+#include <VBox/log.h>
#include <Windows.h>
+#include <windns.h>
+#include <algorithm>
+#include <sstream>
#include <string>
#include <vector>
-#include "../HostDnsService.h"
struct HostDnsServiceWin::Data
{
- HostDnsServiceWin::Data(){}
HKEY hKeyTcpipParameters;
-#define DATA_DNS_UPDATE_EVENT 0
-#define DATA_SHUTDOWN_EVENT 1
+
+#define DATA_SHUTDOWN_EVENT 0
+#define DATA_DNS_UPDATE_EVENT 1
#define DATA_MAX_EVENT 2
HANDLE haDataEvent[DATA_MAX_EVENT];
+
+ Data()
+ {
+ hKeyTcpipParameters = NULL;
+
+ for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
+ haDataEvent[i] = NULL;
+ }
+
+ ~Data()
+ {
+ if (hKeyTcpipParameters != NULL)
+ RegCloseKey(hKeyTcpipParameters);
+
+ for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
+ if (haDataEvent[i] != NULL)
+ CloseHandle(haDataEvent[i]);
+ }
};
-static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent)
+
+HostDnsServiceWin::HostDnsServiceWin()
+ : HostDnsMonitor(true),
+ m(NULL)
{
- LONG lrc = RegNotifyChangeKeyValue(hKey,
- TRUE,
- REG_NOTIFY_CHANGE_LAST_SET,
- hEvent,
- TRUE);
- AssertMsgReturn(lrc == ERROR_SUCCESS,
- ("Failed to register event on the key. Please debug me!"),
- VERR_INTERNAL_ERROR);
+ std::auto_ptr<Data> data(new Data());
+ LONG lrc;
+
+ lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+ 0,
+ KEY_READ|KEY_NOTIFY,
+ &data->hKeyTcpipParameters);
+ if (lrc != ERROR_SUCCESS)
+ {
+ LogRel(("HostDnsServiceWin: failed to open key Tcpip\\Parameters (error %d)\n", lrc));
+ return;
+ }
- return VINF_SUCCESS;
-}
+ for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
+ {
+ data->haDataEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (data->haDataEvent[i] == NULL)
+ {
+ LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError()));
+ return;
+ }
+ }
-HostDnsServiceWin::HostDnsServiceWin():HostDnsMonitor(true), m(NULL)
-{
- m = new Data();
-
- m->haDataEvent[DATA_DNS_UPDATE_EVENT] = CreateEvent(NULL,
- TRUE, FALSE, NULL);
- AssertReleaseMsg(m->haDataEvent[DATA_DNS_UPDATE_EVENT],
- ("Failed to create event for DNS event (%d)\n", GetLastError()));
-
- m->haDataEvent[DATA_SHUTDOWN_EVENT] = CreateEvent(NULL,
- TRUE, FALSE, NULL);
- AssertReleaseMsg(m->haDataEvent[DATA_SHUTDOWN_EVENT],
- ("Failed to create event for Shutdown signal (%d)\n", GetLastError()));
-
- LONG lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
- 0, KEY_READ|KEY_NOTIFY, &m->hKeyTcpipParameters);
- AssertReleaseMsg(lrc == ERROR_SUCCESS,
- ("Failed to open Registry Key for read and update notifications (%d)\n",
- GetLastError()));
+ m = data.release();
}
HostDnsServiceWin::~HostDnsServiceWin()
{
- if (m && !m->hKeyTcpipParameters)
- {
- RegCloseKey(m->hKeyTcpipParameters);
- m->hKeyTcpipParameters = 0;
-
- CloseHandle(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
- CloseHandle(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
-
+ if (m != NULL)
delete m;
-
- m = NULL;
- }
}
HRESULT HostDnsServiceWin::init()
{
+ if (m == NULL)
+ return E_FAIL;
+
HRESULT hrc = HostDnsMonitor::init();
- AssertComRCReturn(hrc, hrc);
+ if (FAILED(hrc))
+ return hrc;
return updateInfo();
}
@@ -87,147 +114,196 @@ HRESULT HostDnsServiceWin::init()
void HostDnsServiceWin::monitorThreadShutdown()
{
+ Assert(m != NULL);
SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
}
+static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent)
+{
+ LONG lrc = RegNotifyChangeKeyValue(hKey,
+ TRUE,
+ REG_NOTIFY_CHANGE_LAST_SET,
+ hEvent,
+ TRUE);
+ AssertMsgReturn(lrc == ERROR_SUCCESS,
+ ("Failed to register event on the key. Please debug me!"),
+ VERR_INTERNAL_ERROR);
+
+ return VINF_SUCCESS;
+}
+
+
int HostDnsServiceWin::monitorWorker()
{
+ Assert(m != NULL);
+
registerNotification(m->hKeyTcpipParameters,
m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
monitorThreadInitializationDone();
- DWORD dwRc;
- while (true)
+ for (;;)
{
- dwRc = WaitForMultipleObjects(DATA_MAX_EVENT,
- m->haDataEvent,
- FALSE,
- INFINITE);
- AssertMsgReturn(dwRc != WAIT_FAILED,
- ("WaitForMultipleObjects failed (%d) to wait! Please debug",
- GetLastError()), VERR_INTERNAL_ERROR);
-
- if ((dwRc - WAIT_OBJECT_0) == DATA_DNS_UPDATE_EVENT)
+ DWORD dwReady;
+
+ dwReady = WaitForMultipleObjects(DATA_MAX_EVENT, m->haDataEvent,
+ FALSE, INFINITE);
+
+ if (dwReady == WAIT_OBJECT_0 + DATA_SHUTDOWN_EVENT)
+ break;
+
+ if (dwReady == WAIT_OBJECT_0 + DATA_DNS_UPDATE_EVENT)
{
updateInfo();
notifyAll();
+
ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
registerNotification(m->hKeyTcpipParameters,
m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
}
- else if ((dwRc - WAIT_OBJECT_0) == DATA_SHUTDOWN_EVENT)
- {
- break;
- }
else
{
- AssertMsgFailedReturn(
- ("WaitForMultipleObjects returns out of bound index %d. Please debug!",
- dwRc),
- VERR_INTERNAL_ERROR);
+ if (dwReady == WAIT_FAILED)
+ LogRel(("HostDnsServiceWin: WaitForMultipleObjects failed: error %d\n", GetLastError()));
+ else
+ LogRel(("HostDnsServiceWin: WaitForMultipleObjects unexpected return value %d\n", dwReady));
+ return VERR_INTERNAL_ERROR;
}
}
+
return VINF_SUCCESS;
}
+void vappend(std::vector<std::string> &v, const std::string &s, char sep = ' ')
+{
+ if (s.empty())
+ return;
+
+ std::istringstream stream(s);
+ std::string substr;
+
+ while (std::getline(stream, substr, sep))
+ {
+ if (substr.empty())
+ continue;
+
+ if (std::find(v.cbegin(), v.cend(), substr) != v.cend())
+ continue;
+
+ v.push_back(substr);
+ }
+}
+
+
HRESULT HostDnsServiceWin::updateInfo()
{
- HRESULT hrc;
- DWORD regIndex;
- BYTE abDomain[256];
- BYTE abNameServers[256];
- BYTE abSearchList[256];
-
- RT_ZERO(abDomain);
- RT_ZERO(abNameServers);
- RT_ZERO(abSearchList);
-
- regIndex = 0;
- do {
- CHAR keyName[256];
+ LONG lrc;
+
+ std::string strDomain;
+ std::string strDhcpDomain;
+ std::string strSearchList; /* NB: comma separated, no spaces */
+
+ for (DWORD regIndex = 0; /**/; ++regIndex) {
+ char keyName[256];
DWORD cbKeyName = sizeof(keyName);
DWORD keyType = 0;
- BYTE keyData[1024];
+ char keyData[1024];
DWORD cbKeyData = sizeof(keyData);
- hrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex, keyName, &cbKeyName, 0,
- &keyType, keyData, &cbKeyData);
- if ( hrc == ERROR_SUCCESS
- || hrc == ERROR_MORE_DATA)
+ lrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex,
+ keyName, &cbKeyName, 0,
+ &keyType, (LPBYTE)keyData, &cbKeyData);
+
+ if (lrc == ERROR_NO_MORE_ITEMS)
+ break;
+
+ if (lrc == ERROR_MORE_DATA) /* buffer too small; handle? */
+ continue;
+
+ if (lrc != ERROR_SUCCESS)
{
- if ( RTStrICmp("Domain", keyName) == 0
- && cbKeyData > 1
- && cbKeyData < sizeof(abDomain))
- memcpy(abDomain, keyData, cbKeyData);
-
- else if ( RTStrICmp("DhcpDomain", keyName) == 0
- && cbKeyData > 1
- && abDomain[0] == 0
- && cbKeyData < sizeof(abDomain))
- memcpy(abDomain, keyData, cbKeyData);
-
- else if ( RTStrICmp("NameServer", keyName) == 0
- && cbKeyData > 1
- && cbKeyData < sizeof(abNameServers))
- memcpy(abNameServers, keyData, cbKeyData);
-
- else if ( RTStrICmp("DhcpNameServer", keyName) == 0
- && cbKeyData > 1
- && abNameServers[0] == 0
- && cbKeyData < sizeof(abNameServers))
- memcpy(abNameServers, keyData, cbKeyData);
-
- else if ( RTStrICmp("SearchList", keyName) == 0
- && cbKeyData > 1
- && cbKeyData < sizeof(abSearchList))
- memcpy(abSearchList, keyData, cbKeyData);
+ LogRel(("HostDnsServiceWin: RegEnumValue error %d\n", (int)lrc));
+ return E_FAIL;
}
- regIndex++;
- } while (hrc != ERROR_NO_MORE_ITEMS);
- /* OK, now parse and update DNS structures. */
- /* domain name */
- HostDnsInformation info;
- info.domain = (char*)abDomain;
+ if (keyType != REG_SZ)
+ continue;
- /* server list */
- strList2List(info.servers, (char *)abNameServers);
- /* search list */
- strList2List(info.searchList, (char *)abSearchList);
+ if (cbKeyData > 0 && keyData[cbKeyData - 1] == '\0')
+ --cbKeyData; /* don't count trailing NUL if present */
- HostDnsMonitor::setInfo(info);
+ if (RTStrICmp("Domain", keyName) == 0)
+ {
+ strDomain.assign(keyData, cbKeyData);
+ Log2(("... Domain=\"%s\"\n", strDomain.c_str()));
+ }
+ else if (RTStrICmp("DhcpDomain", keyName) == 0)
+ {
+ strDhcpDomain.assign(keyData, cbKeyData);
+ Log2(("... DhcpDomain=\"%s\"\n", strDhcpDomain.c_str()));
+ }
+ else if (RTStrICmp("SearchList", keyName) == 0)
+ {
+ strSearchList.assign(keyData, cbKeyData);
+ Log2(("... SearchList=\"%s\"\n", strSearchList.c_str()));
+ }
+ }
- return S_OK;
-}
+ HostDnsInformation info;
+ /*
+ * When name servers are configured statically it seems that the
+ * value of Tcpip\Parameters\NameServer is NOT set, inly interface
+ * specific NameServer value is (which triggers notification for
+ * us to pick up the change). Fortunately, DnsApi seems to do the
+ * right thing there.
+ */
+ DNS_STATUS status;
+ PIP4_ARRAY pIp4Array = NULL;
-void HostDnsServiceWin::strList2List(std::vector<std::string>& lst, char *strLst)
-{
- char *next, *current;
- char address[512];
+ // NB: must be set on input it seems, despite docs' claim to the contrary.
+ DWORD cbBuffer = sizeof(&pIp4Array);
- AssertPtrReturnVoid(strLst);
+ status = DnsQueryConfig(DnsConfigDnsServerList,
+ DNS_CONFIG_FLAG_ALLOC, NULL, NULL,
+ &pIp4Array, &cbBuffer);
- if (strlen(strLst) == 0)
- return;
+ if (status == NO_ERROR && pIp4Array != NULL)
+ {
+ for (DWORD i = 0; i < pIp4Array->AddrCount; ++i)
+ {
+ char szAddrStr[16] = "";
+ RTStrPrintf(szAddrStr, sizeof(szAddrStr), "%RTnaipv4", pIp4Array->AddrArray[i]);
- current = strLst;
- do {
- RT_ZERO(address);
- next = RTStrStr(current, " ");
+ Log2((" server %d: %s\n", i+1, szAddrStr));
+ info.servers.push_back(szAddrStr);
+ }
- if (next)
- strncpy(address, current, RT_MIN(sizeof(address)-1, next - current));
- else
- strcpy(address, current);
+ LocalFree(pIp4Array);
+ }
- lst.push_back(std::string(address));
+ if (!strDomain.empty())
+ {
+ info.domain = strDomain;
- current = next + 1;
- } while(next);
+ info.searchList.push_back(strDomain);
+ if (!strDhcpDomain.empty() && strDhcpDomain != strDomain)
+ info.searchList.push_back(strDhcpDomain);
+ }
+ else if (!strDhcpDomain.empty())
+ {
+ info.domain = strDhcpDomain;
+ info.searchList.push_back(strDomain);
+ }
+
+ vappend(info.searchList, strSearchList, ',');
+ if (info.searchList.size() == 1)
+ info.searchList.clear();
+ HostDnsMonitor::setInfo(info);
+
+ return S_OK;
}
diff --git a/src/VBox/Main/src-server/win/VBoxSVC.rc b/src/VBox/Main/src-server/win/VBoxSVC.rc
index b7ac5fd..cb70760 100644
--- a/src/VBox/Main/src-server/win/VBoxSVC.rc
+++ b/src/VBox/Main/src-server/win/VBoxSVC.rc
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -20,7 +20,7 @@
#include "win/resource.h"
-VS_VERSION_INFO VERSIONINFO
+VS_VERSION_INFO VERSIONINFO
FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
@@ -29,7 +29,7 @@ VS_VERSION_INFO VERSIONINFO
#else
FILEFLAGS 0 // final version
#endif
- FILEOS VOS__WINDOWS32
+ FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0 // not used
BEGIN
@@ -37,17 +37,16 @@ BEGIN
BEGIN
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
BEGIN
- VALUE "CompanyName", VBOX_RC_COMPANY_NAME
- VALUE "FileDescription", "VirtualBox Interface\0"
- VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
- VALUE "InternalName", "VBoxSVC.exe\0"
- VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
- VALUE "OriginalFilename","VBoxSVC.exe\0"
- VALUE "ProductName", VBOX_PRODUCT "\0"
- VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
-
- VALUE "OLESelfRegister", ""
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Interface\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxSVC\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxSVC.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ VALUE "OLESelfRegister", "\0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/VBox/Main/testcase/tstMouseImpl.cpp b/src/VBox/Main/testcase/tstMouseImpl.cpp
index 361daf1..cd03f02 100644
--- a/src/VBox/Main/testcase/tstMouseImpl.cpp
+++ b/src/VBox/Main/testcase/tstMouseImpl.cpp
@@ -47,6 +47,9 @@ class TestDisplay : public DisplayMouseInterface
int32_t *px2, int32_t *py2);
int getScreenResolution(uint32_t cScreen, ULONG *pcx, ULONG *pcy,
ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin);
+ virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved)
+ { return S_OK; }
+ virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y) { return S_OK; }
};
class TestConsole : public ConsoleMouseInterface
diff --git a/src/VBox/Main/webservice/Makefile.kmk b/src/VBox/Main/webservice/Makefile.kmk
index 09feabe..0e377bb 100644
--- a/src/VBox/Main/webservice/Makefile.kmk
+++ b/src/VBox/Main/webservice/Makefile.kmk
@@ -314,6 +314,8 @@ endif
$(VBOXWEB_OUT_DIR)/methodmaps.cpp \
$(VBOXWEB_OUT_DIR)/soapServer.cpp \
$(VBOXWEB_OUT_DIR)/vboxweb-wsdl.c
+ vboxwebsrv_SOURCES.win = \
+ VBoxWebSrv.rc
vboxwebsrv_CLEAN = \
$(VBOXWEB_OUT_DIR)/methodmaps.cpp \
$(VBOXWEB_OUT_DIR)/soapServer.cpp \
diff --git a/src/VBox/Main/webservice/VBoxWebSrv.rc b/src/VBox/Main/webservice/VBoxWebSrv.rc
new file mode 100644
index 0000000..5123f4a
--- /dev/null
+++ b/src/VBox/Main/webservice/VBoxWebSrv.rc
@@ -0,0 +1,50 @@
+/* $Id: VBoxWebSrv.rc $ */
+/** @file
+ * VBoxWebSrv - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Web Service\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxWebSrv\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxWebSrv.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/NetworkServices/DHCP/Makefile.kmk b/src/VBox/NetworkServices/DHCP/Makefile.kmk
index 045e3a5..c9cf388 100644
--- a/src/VBox/NetworkServices/DHCP/Makefile.kmk
+++ b/src/VBox/NetworkServices/DHCP/Makefile.kmk
@@ -18,6 +18,8 @@
SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
+VBOX_PATH_NET_DHCP_SRC := $(PATH_SUB_CURRENT)
+
#
# Targets.
#
@@ -47,22 +49,24 @@ VBoxNetDHCP_SOURCES = \
VBoxNetDHCP.cpp \
Config.cpp \
NetworkManagerDhcp.cpp \
- ../NetLib/VBoxNetIntIf.cpp \
- ../NetLib/VBoxNetUDP.cpp \
- ../NetLib/VBoxNetARP.cpp \
- ../NetLib/VBoxNetBaseService.cpp \
- ../NetLib/ComHostUtils.cpp
+ $(VBOX_PATH_NET_DHCP_SRC)/../NetLib/VBoxNetIntIf.cpp \
+ $(VBOX_PATH_NET_DHCP_SRC)/../NetLib/VBoxNetUDP.cpp \
+ $(VBOX_PATH_NET_DHCP_SRC)/../NetLib/VBoxNetARP.cpp \
+ $(VBOX_PATH_NET_DHCP_SRC)/../NetLib/VBoxNetBaseService.cpp \
+ $(VBOX_PATH_NET_DHCP_SRC)/../NetLib/ComHostUtils.cpp
VBoxNetDHCP_LIBS = \
$(LIB_RUNTIME)
VBoxNetDHCP_LDFLAGS.win = /SUBSYSTEM:windows
+ifeq ($(KBUILD_TARGET),win)
# Icon include file.
-VBoxNetDHCP_SOURCES.win += $(VBoxNetDHCP_0_OUTDIR)/VBoxNetDHCP-icon.rc
-VBoxNetDHCP_CLEAN.win += $(VBoxNetDHCP_0_OUTDIR)/VBoxNetDHCP-icon.rc
+VBoxNetDHCP_SOURCES += VBoxNetDHCP.rc
+VBoxNetDHCP.rc_INCS = $(VBoxNetDHCP_0_OUTDIR)
+VBoxNetDHCP.rc_DEPS = $(VBoxNetDHCP_0_OUTDIR)/VBoxNetDHCP-icon.rc
+VBoxNetDHCP.rc_CLEAN = $(VBoxNetDHCP_0_OUTDIR)/VBoxNetDHCP-icon.rc
$$(VBoxNetDHCP_0_OUTDIR)/VBoxNetDHCP-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $$(VBoxNetDHCP_DEFPATH)/Makefile.kmk | $$(dir $$@)
$(RM) -f $@
$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
-
-
+endif # win
include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.rc b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.rc
new file mode 100644
index 0000000..c7bf1b7
--- /dev/null
+++ b/src/VBox/NetworkServices/DHCP/VBoxNetDHCP.rc
@@ -0,0 +1,54 @@
+/* $Id: VBoxNetDHCP.rc $ */
+/** @file
+ * VBoxNetDHCP - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox DHCP Server\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxNetDHCP\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxNetDHCP.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+/* Creates the application icon. */
+#include "VBoxNetDHCP-icon.rc"
+
diff --git a/src/VBox/NetworkServices/NAT/Makefile.kmk b/src/VBox/NetworkServices/NAT/Makefile.kmk
index 8ac7b4b..36106a9 100644
--- a/src/VBox/NetworkServices/NAT/Makefile.kmk
+++ b/src/VBox/NetworkServices/NAT/Makefile.kmk
@@ -17,10 +17,12 @@
SUB_DEPTH = ../../../..
include $(KBUILD_PATH)/subheader.kmk
+VBOX_PATH_NAT_SRC := $(PATH_SUB_CURRENT)
+
ifdef VBOX_WITH_LWIP_NAT
# XXX: do not depend on order
ifndef LWIP_SOURCES
- include ../../Devices/Network/lwip-new/Makefile.kmk
+ include $(PATH_SUB_CURRENT)/../../Devices/Network/lwip-new/Makefile.kmk
endif
ifdef VBOX_WITH_HARDENING
@@ -46,12 +48,12 @@ VBoxNetLwipNAT_DEFS += ${LWIP_DEFS} IPv6
# VBoxNetLwipNAT_DEFS.linux += WITH_VALGRIND # instrument lwip memp.c
VBoxNetLwipNAT_DEFS.win += VBOX_COM_OUTOFPROC_MODULE _WIN32_WINNT=0x501 # Windows XP
VBoxNetLwipNAT_SOURCES += VBoxNetLwipNAT.cpp \
- ../NetLib/VBoxNetBaseService.cpp \
- ../NetLib/VBoxNetPortForwardString.cpp \
- ../NetLib/VBoxNetIntIf.cpp \
- ../NetLib/VBoxNetUDP.cpp \
- ../NetLib/VBoxNetARP.cpp \
- ../NetLib/ComHostUtils.cpp
+ $(VBOX_PATH_NAT_SRC)/../NetLib/VBoxNetBaseService.cpp \
+ $(VBOX_PATH_NAT_SRC)/../NetLib/VBoxNetPortForwardString.cpp \
+ $(VBOX_PATH_NAT_SRC)/../NetLib/VBoxNetIntIf.cpp \
+ $(VBOX_PATH_NAT_SRC)/../NetLib/VBoxNetUDP.cpp \
+ $(VBOX_PATH_NAT_SRC)/../NetLib/VBoxNetARP.cpp \
+ $(VBOX_PATH_NAT_SRC)/../NetLib/ComHostUtils.cpp
VBoxNetLwipNAT_LIBS = \
$(LIB_RUNTIME)
@@ -127,15 +129,18 @@ VBoxNetLwipNAT_SOURCES.win += \
VBoxNetLwipNAT_INCS += . # for lwipopts.h
$(eval $(call def_vbox_lwip_public, \
- VBoxNetLwipNAT, ../../Devices/Network/lwip-new))
+ VBoxNetLwipNAT, $(PATH_SUB_CURRENT)/../../Devices/Network/lwip-new))
endif
+ifeq ($(KBUILD_TARGET),win)
# Icon include file.
-VBoxNetLwipNAT_SOURCES.win += $(VBoxNetLwipNAT_0_OUTDIR)/VBoxNetLwipNAT-icon.rc
-VBoxNetLwipNAT_CLEAN.win += $(VBoxNetLwipNAT_0_OUTDIR)/VBoxNetLwipNAT-icon.rc
+VBoxNetLwipNAT_SOURCES += VBoxNetNAT.rc
+VBoxNetNAT.rc_INCS = $(VBoxNetLwipNAT_0_OUTDIR)
+VBoxNetNAT.rc_DEPS = $(VBoxNetLwipNAT_0_OUTDIR)/VBoxNetLwipNAT-icon.rc
+VBoxNetNAT.rc_CLEAN = $(VBoxNetLwipNAT_0_OUTDIR)/VBoxNetLwipNAT-icon.rc
$$(VBoxNetLwipNAT_0_OUTDIR)/VBoxNetLwipNAT-icon.rc: $(VBOX_WINDOWS_ICON_FILE) $$(VBoxNetLwipNAT_DEFPATH)/Makefile.kmk | $$(dir $$@)
$(RM) -f $@
$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ICON_FILE))"'
-
+endif # win
include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/VBox/NetworkServices/NAT/RTWinPoll.cpp b/src/VBox/NetworkServices/NAT/RTWinPoll.cpp
index bf92fc9..b23fee4 100644
--- a/src/VBox/NetworkServices/NAT/RTWinPoll.cpp
+++ b/src/VBox/NetworkServices/NAT/RTWinPoll.cpp
@@ -1,4 +1,19 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: RTWinPoll.cpp $ */
+/** @file
+ * NAT Network - poll(2) implementation for winsock.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include <iprt/asm.h>
diff --git a/src/VBox/NetworkServices/NAT/RTWinSocketPair.cpp b/src/VBox/NetworkServices/NAT/RTWinSocketPair.cpp
index d5eb0ae..8a9a458 100644
--- a/src/VBox/NetworkServices/NAT/RTWinSocketPair.cpp
+++ b/src/VBox/NetworkServices/NAT/RTWinSocketPair.cpp
@@ -1,3 +1,20 @@
+/* $Id: RTWinSocketPair.cpp $ */
+/** @file
+ * NAT Network - socketpair(2) emulation for winsock.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#include <iprt/asm.h>
#include <iprt/assert.h>
#include <iprt/cdefs.h>
diff --git a/src/VBox/NetworkServices/NAT/VBoxNetNAT.rc b/src/VBox/NetworkServices/NAT/VBoxNetNAT.rc
new file mode 100644
index 0000000..6f11618
--- /dev/null
+++ b/src/VBox/NetworkServices/NAT/VBoxNetNAT.rc
@@ -0,0 +1,54 @@
+/* $Id: VBoxNetNAT.rc $ */
+/** @file
+ * VBoxNetNAT - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox NAT Engine\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxNetNAT\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxNetNAT.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+/* Creates the application icon. */
+#include "VBoxNetLwipNAT-icon.rc"
+
diff --git a/src/VBox/NetworkServices/NAT/dhcp6.h b/src/VBox/NetworkServices/NAT/dhcp6.h
index 358911c..8b972d3 100644
--- a/src/VBox/NetworkServices/NAT/dhcp6.h
+++ b/src/VBox/NetworkServices/NAT/dhcp6.h
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id$ */
+/** @file
+ * NAT Network - DHCPv6 protocol definitions.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _DHCP6_H_
#define _DHCP6_H_
diff --git a/src/VBox/NetworkServices/NAT/fwtcp.c b/src/VBox/NetworkServices/NAT/fwtcp.c
index 4ecae66..f20d32a 100644
--- a/src/VBox/NetworkServices/NAT/fwtcp.c
+++ b/src/VBox/NetworkServices/NAT/fwtcp.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: fwtcp.c $ */
+/** @file
+ * NAT Network - TCP port-forwarding.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/fwudp.c b/src/VBox/NetworkServices/NAT/fwudp.c
index ded9330..508894f 100644
--- a/src/VBox/NetworkServices/NAT/fwudp.c
+++ b/src/VBox/NetworkServices/NAT/fwudp.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: fwudp.c $ */
+/** @file
+ * NAT Network - UDP port-forwarding.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/lwipopts.h b/src/VBox/NetworkServices/NAT/lwipopts.h
index eb1d927..37375cc 100644
--- a/src/VBox/NetworkServices/NAT/lwipopts.h
+++ b/src/VBox/NetworkServices/NAT/lwipopts.h
@@ -1,3 +1,20 @@
+/* $Id$ */
+/** @file
+ * NAT Network - lwIP configuration options.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _VBOX_NETNAT_LWIP_OPTS_H_
#define _VBOX_NETNAT_LWIP_OPTS_H_
diff --git a/src/VBox/NetworkServices/NAT/portfwd.c b/src/VBox/NetworkServices/NAT/portfwd.c
index e916a72..e465fab 100644
--- a/src/VBox/NetworkServices/NAT/portfwd.c
+++ b/src/VBox/NetworkServices/NAT/portfwd.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: portfwd.c $ */
+/** @file
+ * NAT Network - port-forwarding rules.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/portfwd.h b/src/VBox/NetworkServices/NAT/portfwd.h
index 2eb2d6d..1178b5c 100644
--- a/src/VBox/NetworkServices/NAT/portfwd.h
+++ b/src/VBox/NetworkServices/NAT/portfwd.h
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id$ */
+/** @file
+ * NAT Network - port-forwarding rules, definitions and declarations.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _portfwd_h_
#define _portfwd_h_
diff --git a/src/VBox/NetworkServices/NAT/proxy.c b/src/VBox/NetworkServices/NAT/proxy.c
index ade529f..da671f6 100644
--- a/src/VBox/NetworkServices/NAT/proxy.c
+++ b/src/VBox/NetworkServices/NAT/proxy.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: proxy.c $ */
+/** @file
+ * NAT Network - proxy setup and utilities.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/proxy.h b/src/VBox/NetworkServices/NAT/proxy.h
index 9a7b02d..fd4cc07 100644
--- a/src/VBox/NetworkServices/NAT/proxy.h
+++ b/src/VBox/NetworkServices/NAT/proxy.h
@@ -1,3 +1,20 @@
+/* $Id$ */
+/** @file
+ * NAT Network - common definitions and declarations.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _nat_proxy_h_
#define _nat_proxy_h_
diff --git a/src/VBox/NetworkServices/NAT/proxy_dhcp6ds.c b/src/VBox/NetworkServices/NAT/proxy_dhcp6ds.c
index 5764b56..d834feb 100644
--- a/src/VBox/NetworkServices/NAT/proxy_dhcp6ds.c
+++ b/src/VBox/NetworkServices/NAT/proxy_dhcp6ds.c
@@ -1,7 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
-/**
- * Simple stateless DHCPv6 (RFC 3736) server.
+/* $Id: proxy_dhcp6ds.c $ */
+/** @file
+ * NAT Network - Simple stateless DHCPv6 (RFC 3736) server.
*/
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/proxy_pollmgr.c b/src/VBox/NetworkServices/NAT/proxy_pollmgr.c
index 1469b17..48df1c3 100644
--- a/src/VBox/NetworkServices/NAT/proxy_pollmgr.c
+++ b/src/VBox/NetworkServices/NAT/proxy_pollmgr.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: proxy_pollmgr.c $ */
+/** @file
+ * NAT Network - poll manager.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/proxy_pollmgr.h b/src/VBox/NetworkServices/NAT/proxy_pollmgr.h
index 68761b9..677d104 100644
--- a/src/VBox/NetworkServices/NAT/proxy_pollmgr.h
+++ b/src/VBox/NetworkServices/NAT/proxy_pollmgr.h
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id$ */
+/** @file
+ * NAT Network - poll manager, definitions and declarations.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _PROXY_POLLMGR_H_
#define _PROXY_POLLMGR_H_
diff --git a/src/VBox/NetworkServices/NAT/proxy_rtadvd.c b/src/VBox/NetworkServices/NAT/proxy_rtadvd.c
index 6120866..4107188 100644
--- a/src/VBox/NetworkServices/NAT/proxy_rtadvd.c
+++ b/src/VBox/NetworkServices/NAT/proxy_rtadvd.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: proxy_rtadvd.c $ */
+/** @file
+ * NAT Network - IPv6 router advertisement daemon.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/proxy_tftpd.c b/src/VBox/NetworkServices/NAT/proxy_tftpd.c
index e24cd39..9f06a9f 100644
--- a/src/VBox/NetworkServices/NAT/proxy_tftpd.c
+++ b/src/VBox/NetworkServices/NAT/proxy_tftpd.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: proxy_tftpd.c $ */
+/** @file
+ * NAT Network - TFTP server.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/pxdns.c b/src/VBox/NetworkServices/NAT/pxdns.c
index c5b3d4d..e6c7619 100644
--- a/src/VBox/NetworkServices/NAT/pxdns.c
+++ b/src/VBox/NetworkServices/NAT/pxdns.c
@@ -1,7 +1,10 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: pxdns.c $ */
+/** @file
+ * NAT Network - DNS proxy.
+ */
/*
- * Copyright (C) 2009-2013 Oracle Corporation
+ * Copyright (C) 2009-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/NetworkServices/NAT/pxping.c b/src/VBox/NetworkServices/NAT/pxping.c
index b55f677..97f082a 100644
--- a/src/VBox/NetworkServices/NAT/pxping.c
+++ b/src/VBox/NetworkServices/NAT/pxping.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: pxping.c $ */
+/** @file
+ * NAT Network - ping proxy, raw sockets version.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/pxping_win.c b/src/VBox/NetworkServices/NAT/pxping_win.c
index 21254b5..f5427ec 100644
--- a/src/VBox/NetworkServices/NAT/pxping_win.c
+++ b/src/VBox/NetworkServices/NAT/pxping_win.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: pxping_win.c $ */
+/** @file
+ * NAT Network - ping proxy, Windows ICMP API version.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/pxremap.c b/src/VBox/NetworkServices/NAT/pxremap.c
index d108051..28058ee 100644
--- a/src/VBox/NetworkServices/NAT/pxremap.c
+++ b/src/VBox/NetworkServices/NAT/pxremap.c
@@ -1,5 +1,21 @@
-/** -*- indent-tabs-mode: nil; -*-
+/* $Id: pxremap.c $ */
+/** @file
+ * NAT Network - Loopback remapping.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
*
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
* This file contains functions pertinent to magic address remapping.
*
* We want to expose host's loopback interfaces to the guest by
diff --git a/src/VBox/NetworkServices/NAT/pxremap.h b/src/VBox/NetworkServices/NAT/pxremap.h
index 6c9b61e..c5cba0b 100644
--- a/src/VBox/NetworkServices/NAT/pxremap.h
+++ b/src/VBox/NetworkServices/NAT/pxremap.h
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id$ */
+/** @file
+ * NAT Network - Loopback remapping, declarations and definitions.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _pxremap_h_
#define _pxremap_h_
diff --git a/src/VBox/NetworkServices/NAT/pxtcp.c b/src/VBox/NetworkServices/NAT/pxtcp.c
index 58da19d..065b654 100644
--- a/src/VBox/NetworkServices/NAT/pxtcp.c
+++ b/src/VBox/NetworkServices/NAT/pxtcp.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: pxtcp.c $ */
+/** @file
+ * NAT Network - TCP proxy.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/pxtcp.h b/src/VBox/NetworkServices/NAT/pxtcp.h
index 26a7c23..a1043e8 100644
--- a/src/VBox/NetworkServices/NAT/pxtcp.h
+++ b/src/VBox/NetworkServices/NAT/pxtcp.h
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id$ */
+/** @file
+ * NAT Network - TCP proxy, internal interface declarations.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _pxtcp_h_
#define _pxtcp_h_
diff --git a/src/VBox/NetworkServices/NAT/pxudp.c b/src/VBox/NetworkServices/NAT/pxudp.c
index c41a656..5476e3b 100644
--- a/src/VBox/NetworkServices/NAT/pxudp.c
+++ b/src/VBox/NetworkServices/NAT/pxudp.c
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: pxudp.c $ */
+/** @file
+ * NAT Network - UDP proxy.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "winutils.h"
diff --git a/src/VBox/NetworkServices/NAT/rtmon_bsd.c b/src/VBox/NetworkServices/NAT/rtmon_bsd.c
index 529cca1..8596880 100644
--- a/src/VBox/NetworkServices/NAT/rtmon_bsd.c
+++ b/src/VBox/NetworkServices/NAT/rtmon_bsd.c
@@ -1,4 +1,21 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: rtmon_bsd.c $ */
+/** @file
+ * NAT Network - IPv6 default route monitor for BSD routing sockets.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "proxy.h"
diff --git a/src/VBox/NetworkServices/NAT/rtmon_linux.c b/src/VBox/NetworkServices/NAT/rtmon_linux.c
index c225316..3e8716b 100644
--- a/src/VBox/NetworkServices/NAT/rtmon_linux.c
+++ b/src/VBox/NetworkServices/NAT/rtmon_linux.c
@@ -1,4 +1,21 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id: rtmon_linux.c $ */
+/** @file
+ * NAT Network - IPv6 default route monitor for Linux netlink.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
#define LOG_GROUP LOG_GROUP_NAT_SERVICE
#include "proxy.h"
diff --git a/src/VBox/NetworkServices/NAT/rtmon_win.c b/src/VBox/NetworkServices/NAT/rtmon_win.c
index 496032f..a1bf1cd 100644
--- a/src/VBox/NetworkServices/NAT/rtmon_win.c
+++ b/src/VBox/NetworkServices/NAT/rtmon_win.c
@@ -1,3 +1,20 @@
+/* $Id: rtmon_win.c $ */
+/** @file
+ * NAT Network - IPv6 default route monitor for Windows.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
int
rtmon_get_defaults(void) {
return 0;
diff --git a/src/VBox/NetworkServices/NAT/tftp.h b/src/VBox/NetworkServices/NAT/tftp.h
index a9d9a7e..eb5e698 100644
--- a/src/VBox/NetworkServices/NAT/tftp.h
+++ b/src/VBox/NetworkServices/NAT/tftp.h
@@ -1,4 +1,20 @@
-/* -*- indent-tabs-mode: nil; -*- */
+/* $Id$ */
+/** @file
+ * NAT Network - Definitions for TFTP protocol.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _TFTP_H_
#define _TFTP_H_
diff --git a/src/VBox/NetworkServices/NAT/winpoll.h b/src/VBox/NetworkServices/NAT/winpoll.h
index 2c509ed..3e59a6d 100644
--- a/src/VBox/NetworkServices/NAT/winpoll.h
+++ b/src/VBox/NetworkServices/NAT/winpoll.h
@@ -1,3 +1,20 @@
+/* $Id$ */
+/** @file
+ * NAT Network - poll(2) for winsock, definitions and declarations.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef _WINPOLL_H_
#define _WINPOLL_H_
# include <iprt/cdefs.h>
diff --git a/src/VBox/NetworkServices/NAT/winutils.h b/src/VBox/NetworkServices/NAT/winutils.h
index 5c68a3b..2d14ed6 100644
--- a/src/VBox/NetworkServices/NAT/winutils.h
+++ b/src/VBox/NetworkServices/NAT/winutils.h
@@ -1,3 +1,20 @@
+/* $Id$ */
+/** @file
+ * NAT Network - winsock compatibility shim.
+ */
+
+/*
+ * Copyright (C) 2013-2014 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef __WINUTILS_H_
# define __WINUTILS_H_
diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
index 8e0cfd2..917547c 100644
--- a/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
+++ b/src/VBox/NetworkServices/NetLib/VBoxNetBaseService.cpp
@@ -456,6 +456,21 @@ void VBoxNetBaseService::shutdown(void)
{
syncEnter();
m->fShutdown = true;
+ if (m->m_hThrRecv != NIL_RTTHREAD)
+ {
+ int rc = m->m_EventQ->interruptEventQueueProcessing();
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTThreadWait(m->m_hThrRecv, 60000, NULL);
+ if (RT_FAILURE(rc))
+ LogWarningFunc(("RTThreadWait(%RTthrd) -> %Rrc\n", m->m_hThrRecv, rc));
+ }
+ else
+ {
+ AssertMsgFailed(("interruptEventQueueProcessing() failed\n"));
+ RTThreadWait(m->m_hThrRecv , 0, NULL);
+ }
+ }
syncLeave();
}
@@ -733,19 +748,19 @@ int VBoxNetBaseService::startReceiveThreadAndEnterEventLoop()
RTTHREADTYPE_IO, /* type */
0, /* flags, @todo: waitable ?*/
"RECV");
- AssertRCReturn(rc,rc);
+ AssertRCReturn(rc, rc);
m->m_EventQ = com::NativeEventQueue::getMainEventQueue();
AssertPtrReturn(m->m_EventQ, VERR_INTERNAL_ERROR);
- while(true)
+ while (!m->fShutdown)
{
- m->m_EventQ->processEventQueue(0);
-
- if (m->fShutdown)
+ rc = m->m_EventQ->processEventQueue(RT_INDEFINITE_WAIT);
+ if (rc == VERR_INTERRUPTED)
+ {
+ LogFlow(("Event queue processing ended with rc=%Rrc\n", rc));
break;
-
- m->m_EventQ->processEventQueue(500);
+ }
}
return VINF_SUCCESS;
diff --git a/src/VBox/NetworkServices/NetLib/shared_ptr.h b/src/VBox/NetworkServices/NetLib/shared_ptr.h
index ad892de..d1c3a4e 100644
--- a/src/VBox/NetworkServices/NetLib/shared_ptr.h
+++ b/src/VBox/NetworkServices/NetLib/shared_ptr.h
@@ -1,3 +1,20 @@
+/* $Id: shared_ptr.h $ */
+/** @file
+ * Simplified shared pointer.
+ */
+
+/*
+ * Copyright (C) 2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
#ifndef __SHARED_PTR_H__
#define __SHARED_PTR_H__
diff --git a/src/VBox/Runtime/Makefile.kmk b/src/VBox/Runtime/Makefile.kmk
index f6e234c..607c00b 100644
--- a/src/VBox/Runtime/Makefile.kmk
+++ b/src/VBox/Runtime/Makefile.kmk
@@ -1323,6 +1323,7 @@ VBoxRT_SOURCES.amd64 := $(RuntimeR3_SOURCES.amd64)
VBoxRT_SOURCES.win += \
r3/win/dllmain-win.cpp \
r3/win/fileaio-win.cpp \
+ r3/win/VBoxRT.rc \
$(VBoxRT_0_OUTDIR)/VBoxRT.def
VBoxRT_SOURCES.linux += \
r3/linux/fileaio-linux.cpp
diff --git a/src/VBox/Runtime/common/crypto/x509-template.h b/src/VBox/Runtime/common/crypto/x509-template.h
index ff1c6b7..d7170d5 100644
--- a/src/VBox/Runtime/common/crypto/x509-template.h
+++ b/src/VBox/Runtime/common/crypto/x509-template.h
@@ -111,6 +111,23 @@ RTASN1TMPL_SEQ_OF(RTCRX509RELATIVEDISTINGUISHEDNAME, RTCrX509RelativeDistinguish
#undef RTASN1TMPL_INT_NAME
/*
+ * One X.509 OtherName.
+ * Note! This is simplified and might not work correctly for all types with
+ * non-DER compatible encodings.
+ */
+#define RTASN1TMPL_TYPE RTCRX509OTHERNAME
+#define RTASN1TMPL_EXT_NAME RTCrX509OtherName
+#define RTASN1TMPL_INT_NAME rtCrX509OtherName
+RTASN1TMPL_BEGIN_SEQCORE();
+RTASN1TMPL_MEMBER( TypeId, RTASN1OBJID, RTAsn1ObjId);
+RTASN1TMPL_MEMBER( Value, RTASN1DYNTYPE, RTAsn1DynType);
+RTASN1TMPL_END_SEQCORE();
+#undef RTASN1TMPL_TYPE
+#undef RTASN1TMPL_EXT_NAME
+#undef RTASN1TMPL_INT_NAME
+
+
+/*
* One X.509 GeneralName.
* Note! This is simplified and might not work correctly for all types with
* non-DER compatible encodings.
@@ -119,7 +136,7 @@ RTASN1TMPL_SEQ_OF(RTCRX509RELATIVEDISTINGUISHEDNAME, RTCrX509RelativeDistinguish
#define RTASN1TMPL_EXT_NAME RTCrX509GeneralName
#define RTASN1TMPL_INT_NAME rtCrX509GeneralName
RTASN1TMPL_BEGIN_PCHOICE();
-RTASN1TMPL_PCHOICE_XTAG( 0, RTCRX509GENERALNAMECHOICE_OTHER_NAME, u.pT0, CtxTag0, Other, RTASN1DYNTYPE, RTAsn1DynType); /** @todo */
+RTASN1TMPL_PCHOICE_ITAG( 0, RTCRX509GENERALNAMECHOICE_OTHER_NAME, u.pT0_OtherName, OtherName, RTCRX509OTHERNAME, RTCrX509OtherName);
RTASN1TMPL_PCHOICE_ITAG_CP( 1, RTCRX509GENERALNAMECHOICE_RFC822_NAME, u.pT1_Rfc822, Rfc822, RTASN1STRING, RTAsn1Ia5String);
RTASN1TMPL_PCHOICE_ITAG_CP( 2, RTCRX509GENERALNAMECHOICE_DNS_NAME, u.pT2_DnsName, DnsType, RTASN1STRING, RTAsn1Ia5String);
RTASN1TMPL_PCHOICE_XTAG( 3, RTCRX509GENERALNAMECHOICE_X400_ADDRESS, u.pT3, CtxTag3, X400Address, RTASN1DYNTYPE, RTAsn1DynType); /** @todo */
diff --git a/src/VBox/Runtime/common/ldr/ldrPE.cpp b/src/VBox/Runtime/common/ldr/ldrPE.cpp
index c460d15..5583958 100644
--- a/src/VBox/Runtime/common/ldr/ldrPE.cpp
+++ b/src/VBox/Runtime/common/ldr/ldrPE.cpp
@@ -2930,9 +2930,13 @@ static void rtldrPEConvert32BitLoadConfigTo64Bit(PIMAGE_LOAD_CONFIG_DIRECTORY64
/*
* volatile everywhere! Trying to prevent the compiler being a smarta$$ and reorder stuff.
*/
- IMAGE_LOAD_CONFIG_DIRECTORY32_V3 volatile *pLoadCfg32 = (IMAGE_LOAD_CONFIG_DIRECTORY32_V3 volatile *)pLoadCfg;
- IMAGE_LOAD_CONFIG_DIRECTORY64_V3 volatile *pLoadCfg64 = pLoadCfg;
+ IMAGE_LOAD_CONFIG_DIRECTORY32_V4 volatile *pLoadCfg32 = (IMAGE_LOAD_CONFIG_DIRECTORY32_V4 volatile *)pLoadCfg;
+ IMAGE_LOAD_CONFIG_DIRECTORY64_V4 volatile *pLoadCfg64 = pLoadCfg;
+ pLoadCfg64->CodeIntegrity.Reserved = pLoadCfg32->CodeIntegrity.Reserved;
+ pLoadCfg64->CodeIntegrity.CatalogOffset = pLoadCfg32->CodeIntegrity.CatalogOffset;
+ pLoadCfg64->CodeIntegrity.Catalog = pLoadCfg32->CodeIntegrity.Catalog;
+ pLoadCfg64->CodeIntegrity.Flags = pLoadCfg32->CodeIntegrity.Flags;
pLoadCfg64->GuardFlags = pLoadCfg32->GuardFlags;
pLoadCfg64->GuardCFFunctionCount = pLoadCfg32->GuardCFFunctionCount;
pLoadCfg64->GuardCFFunctionTable = pLoadCfg32->GuardCFFunctionTable;
@@ -3216,9 +3220,10 @@ static int rtldrPEValidateOptionalHeader(const IMAGE_OPTIONAL_HEADER64 *pOptHdr,
* @param pOptHdr Pointer to the optional header (valid).
* @param cbRawImage The raw image size.
* @param fFlags Loader flags, RTLDR_O_XXX.
+ * @param fNoCode Verify that the image contains no code.
*/
static int rtldrPEValidateSectionHeaders(const IMAGE_SECTION_HEADER *paSections, unsigned cSections, const char *pszLogName,
- const IMAGE_OPTIONAL_HEADER64 *pOptHdr, RTFOFF cbRawImage, uint32_t fFlags)
+ const IMAGE_OPTIONAL_HEADER64 *pOptHdr, RTFOFF cbRawImage, uint32_t fFlags, bool fNoCode)
{
const uint32_t cbImage = pOptHdr->SizeOfImage;
const IMAGE_SECTION_HEADER *pSH = &paSections[0];
@@ -3305,6 +3310,19 @@ static int rtldrPEValidateSectionHeaders(const IMAGE_SECTION_HEADER *paSections,
uRvaPrev = pSH->VirtualAddress + pSH->Misc.VirtualSize;
}
+ /*
+ * Do a separate run if we need to validate the no-code claim from the
+ * optional header.
+ */
+ if (fNoCode)
+ {
+ pSH = &paSections[0];
+ for (unsigned cSHdrsLeft = cSections; cSHdrsLeft > 0; cSHdrsLeft--, pSH++)
+ if (pSH->Characteristics & (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE))
+ return VERR_LDR_ARCH_MISMATCH;
+ }
+
+
/** @todo r=bird: more sanity checks! */
return VINF_SUCCESS;
}
@@ -3418,6 +3436,9 @@ static int rtldrPEValidateDirectoriesAndRememberStuff(PRTLDRMODPE pModPe, const
IMAGE_DATA_DIRECTORY Dir = pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
if (Dir.Size)
{
+ const size_t cbExpectV4 = !pModPe->f64Bit
+ ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_V4)
+ : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64_V4);
const size_t cbExpectV3 = !pModPe->f64Bit
? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_V3)
: sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64_V3);
@@ -3428,19 +3449,20 @@ static int rtldrPEValidateDirectoriesAndRememberStuff(PRTLDRMODPE pModPe, const
? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_V1)
: sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64_V2) /*No V1*/;
- if ( Dir.Size != cbExpectV3
+ if ( Dir.Size != cbExpectV4
+ && Dir.Size != cbExpectV3
&& Dir.Size != cbExpectV2
&& Dir.Size != cbExpectV1)
{
- Log(("rtldrPEOpen: %s: load cfg dir: unexpected dir size of %d bytes, expected %d, %d, or %d.\n",
- pszLogName, Dir.Size, cbExpectV3, cbExpectV2, cbExpectV1));
+ Log(("rtldrPEOpen: %s: load cfg dir: unexpected dir size of %d bytes, expected %d, %d, %d, or %d.\n",
+ pszLogName, Dir.Size, cbExpectV4, cbExpectV3, cbExpectV2, cbExpectV1));
return VERR_LDRPE_LOAD_CONFIG_SIZE;
}
/*
* Read and convert to 64-bit.
*/
- memset(&u.Cfg64, 0, sizeof(u.Cfg64));
+ RT_ZERO(u.Cfg64);
int rc = rtldrPEReadRVA(pModPe, &u.Cfg64, Dir.Size, Dir.VirtualAddress);
if (RT_FAILURE(rc))
return rc;
@@ -3617,9 +3639,15 @@ int rtldrPEOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF
/*
* Match the CPU architecture.
*/
- if ( enmArch != RTLDRARCH_WHATEVER
- && enmArch != enmArchImage)
- return VERR_LDR_ARCH_MISMATCH;
+ bool fArchNoCodeCheckPending = false;
+ if ( enmArch != enmArchImage
+ && ( enmArch != RTLDRARCH_WHATEVER
+ && !(fFlags & RTLDR_O_WHATEVER_ARCH)) )
+ {
+ if (!(fFlags & RTLDR_O_IGNORE_ARCH_IF_NO_CODE))
+ return VERR_LDR_ARCH_MISMATCH;
+ fArchNoCodeCheckPending = true;
+ }
/*
* Read and validate the "optional" header. Convert 32->64 if necessary.
@@ -3633,6 +3661,8 @@ int rtldrPEOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF
rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader), fFlags);
if (RT_FAILURE(rc))
return rc;
+ if (fArchNoCodeCheckPending && OptHdr.SizeOfCode != 0)
+ return VERR_LDR_ARCH_MISMATCH;
/*
* Read and validate section headers.
@@ -3646,7 +3676,7 @@ int rtldrPEOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, RTFOFF
if (RT_SUCCESS(rc))
{
rc = rtldrPEValidateSectionHeaders(paSections, FileHdr.NumberOfSections, pszLogName,
- &OptHdr, pReader->pfnSize(pReader), fFlags);
+ &OptHdr, pReader->pfnSize(pReader), fFlags, fArchNoCodeCheckPending);
if (RT_SUCCESS(rc))
{
/*
diff --git a/src/VBox/Runtime/include/internal/ldrPE.h b/src/VBox/Runtime/include/internal/ldrPE.h
index d1de685..5cb4579 100644
--- a/src/VBox/Runtime/include/internal/ldrPE.h
+++ b/src/VBox/Runtime/include/internal/ldrPE.h
@@ -539,6 +539,17 @@ typedef IMAGE_THUNK_DATA32 const *PCIMAGE_THUNK_DATA32;
#pragma pack()
+/** @since Windows 10 (preview 9879) */
+typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY
+{
+ uint16_t Flags;
+ uint16_t Catalog;
+ uint32_t CatalogOffset;
+ uint32_t Reserved;
+} IMAGE_LOAD_CONFIG_CODE_INTEGRITY;
+AssertCompileSize(IMAGE_LOAD_CONFIG_CODE_INTEGRITY, 12);
+typedef IMAGE_LOAD_CONFIG_CODE_INTEGRITY *PIMAGE_LOAD_CONFIG_CODE_INTEGRITY;
+typedef IMAGE_LOAD_CONFIG_CODE_INTEGRITY const *PCIMAGE_LOAD_CONFIG_CODE_INTEGRITY;
typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V1
{
@@ -624,9 +635,43 @@ AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V3, 0x5c);
typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V3 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V3;
typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V3 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V3;
-typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V3 IMAGE_LOAD_CONFIG_DIRECTORY32;
-typedef PIMAGE_LOAD_CONFIG_DIRECTORY32_V3 PIMAGE_LOAD_CONFIG_DIRECTORY32;
-typedef PCIMAGE_LOAD_CONFIG_DIRECTORY32_V3 PCIMAGE_LOAD_CONFIG_DIRECTORY32;
+/** @since Windows 10 (preview 9879) */
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32_V4
+{
+ uint32_t Size;
+ uint32_t TimeDateStamp;
+ uint16_t MajorVersion;
+ uint16_t MinorVersion;
+ uint32_t GlobalFlagsClear;
+ uint32_t GlobalFlagsSet;
+ uint32_t CriticalSectionDefaultTimeout;
+ uint32_t DeCommitFreeBlockThreshold;
+ uint32_t DeCommitTotalFreeThreshold;
+ uint32_t LockPrefixTable;
+ uint32_t MaximumAllocationSize;
+ uint32_t VirtualMemoryThreshold;
+ uint32_t ProcessHeapFlags;
+ uint32_t ProcessAffinityMask;
+ uint16_t CSDVersion;
+ uint16_t Reserved1;
+ uint32_t EditList;
+ uint32_t SecurityCookie;
+ uint32_t SEHandlerTable;
+ uint32_t SEHandlerCount;
+ uint32_t GuardCFCCheckFunctionPointer;
+ uint32_t Reserved2;
+ uint32_t GuardCFFunctionTable;
+ uint32_t GuardCFFunctionCount;
+ uint32_t GuardFlags;
+ IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
+} IMAGE_LOAD_CONFIG_DIRECTORY32_V4;
+AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY32_V4, 0x68);
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V4 *PIMAGE_LOAD_CONFIG_DIRECTORY32_V4;
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V4 const *PCIMAGE_LOAD_CONFIG_DIRECTORY32_V4;
+
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32_V4 IMAGE_LOAD_CONFIG_DIRECTORY32;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY32_V4 PIMAGE_LOAD_CONFIG_DIRECTORY32;
+typedef PCIMAGE_LOAD_CONFIG_DIRECTORY32_V4 PCIMAGE_LOAD_CONFIG_DIRECTORY32;
/* No _IMAGE_LOAD_CONFIG_DIRECTORY64_V1 exists. */
@@ -691,9 +736,44 @@ AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V3, 0x94);
typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V3 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V3;
typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V3 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V3;
-typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V3 IMAGE_LOAD_CONFIG_DIRECTORY64;
-typedef PIMAGE_LOAD_CONFIG_DIRECTORY64_V3 PIMAGE_LOAD_CONFIG_DIRECTORY64;
-typedef PCIMAGE_LOAD_CONFIG_DIRECTORY64_V3 PCIMAGE_LOAD_CONFIG_DIRECTORY64;
+/** @since Windows 10 (Preview (9879). */
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64_V4
+{
+ uint32_t Size;
+ uint32_t TimeDateStamp;
+ uint16_t MajorVersion;
+ uint16_t MinorVersion;
+ uint32_t GlobalFlagsClear;
+ uint32_t GlobalFlagsSet;
+ uint32_t CriticalSectionDefaultTimeout;
+ uint64_t DeCommitFreeBlockThreshold;
+ uint64_t DeCommitTotalFreeThreshold;
+ uint64_t LockPrefixTable;
+ uint64_t MaximumAllocationSize;
+ uint64_t VirtualMemoryThreshold;
+ uint64_t ProcessAffinityMask;
+ uint32_t ProcessHeapFlags;
+ uint16_t CSDVersion;
+ uint16_t Reserved1;
+ uint64_t EditList;
+ uint64_t SecurityCookie;
+ uint64_t SEHandlerTable;
+ uint64_t SEHandlerCount;
+ uint64_t GuardCFCCheckFunctionPointer;
+ uint64_t Reserved2;
+ uint64_t GuardCFFunctionTable;
+ uint64_t GuardCFFunctionCount;
+ uint32_t GuardFlags;
+ IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
+} IMAGE_LOAD_CONFIG_DIRECTORY64_V4;
+AssertCompileSize(IMAGE_LOAD_CONFIG_DIRECTORY64_V4, 0xa0);
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V4 *PIMAGE_LOAD_CONFIG_DIRECTORY64_V4;
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V4 const *PCIMAGE_LOAD_CONFIG_DIRECTORY64_V4;
+
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64_V4 IMAGE_LOAD_CONFIG_DIRECTORY64;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY64_V4 PIMAGE_LOAD_CONFIG_DIRECTORY64;
+typedef PCIMAGE_LOAD_CONFIG_DIRECTORY64_V4 PCIMAGE_LOAD_CONFIG_DIRECTORY64;
+
typedef struct _IMAGE_DEBUG_DIRECTORY
{
diff --git a/src/VBox/Runtime/include/internal/socket.h b/src/VBox/Runtime/include/internal/socket.h
index e3ff4eb..a8ab307 100644
--- a/src/VBox/Runtime/include/internal/socket.h
+++ b/src/VBox/Runtime/include/internal/socket.h
@@ -57,7 +57,7 @@ int rtSocketCreate(PRTSOCKET phSocket, int iDomain, int iType, int iProtocol);
int rtSocketBind(RTSOCKET hSocket, PCRTNETADDR pAddr);
int rtSocketListen(RTSOCKET hSocket, int cMaxPending);
int rtSocketAccept(RTSOCKET hSocket, PRTSOCKET phClient, struct sockaddr *pAddr, size_t *pcbAddr);
-int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr);
+int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr, RTMSINTERVAL cMillies);
int rtSocketSetOpt(RTSOCKET hSocket, int iLevel, int iOption, void const *pvValue, int cbValue);
#endif /* IPRT_INTERNAL_SOCKET_POLLING_ONLY */
diff --git a/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
index 211fc36..2b78d7d 100644
--- a/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/memuserkernel-r0drv-linux.c
@@ -63,25 +63,10 @@ RT_EXPORT_SYMBOL(RTR0MemUserIsValidAddr);
RTR0DECL(bool) RTR0MemKernelIsValidAddr(void *pv)
{
/* Couldn't find a straight forward way of doing this... */
-#ifdef RT_ARCH_X86
-# ifdef CONFIG_X86_HIGH_ENTRY
+#if defined(RT_ARCH_X86) && defined(CONFIG_X86_HIGH_ENTRY)
return true; /* ?? */
-# else
+#elif defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
return (uintptr_t)pv >= PAGE_OFFSET;
-# endif
-
-#elif defined(RT_ARCH_AMD64)
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
- /* Linux 2.6.0 ... 2.6.10 set PAGE_OFFSET to 0x0000010000000000.
- * Linux 2.6.11 sets PAGE_OFFSET to 0xffff810000000000.
- * Linux 2.6.33 sets PAGE_OFFSET to 0xffff880000000000. */
- return (uintptr_t)pv >= PAGE_OFFSET;
-# else
- /* Not correct (KERNEL_TEXT_START=0xffffffff80000000),
- * VMALLOC_START (0xffffff0000000000) would be better */
- return (uintptr_t)pv >= KERNEL_TEXT_START;
-# endif
-
#else
# error "PORT ME"
return !access_ok(VERIFY_READ, pv, 1);
diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
index a199e13..7838bc0 100644
--- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
@@ -49,29 +49,39 @@
* Once we start caring about this, we'll simply let the native MP event callback
* and update this variable as CPUs comes online. (The code is done already.)
*/
-RTCPUSET g_rtMpNtCpuSet;
+RTCPUSET g_rtMpNtCpuSet;
/** ExSetTimerResolution, introduced in W2K. */
-PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
+PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
/** KeFlushQueuedDpcs, introduced in XP. */
-PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
/** HalRequestIpi, introduced in ??. */
-PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
+PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
/** HalSendSoftwareInterrupt */
-PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
+PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
/** SendIpi handler based on Windows version */
-PFNRTSENDIPI g_pfnrtSendIpi;
+PFNRTSENDIPI g_pfnrtSendIpi;
/** KeIpiGenericCall - Windows Server 2003+ only */
-PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
+PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
/** RtlGetVersion, introduced in ??. */
-PFNRTRTLGETVERSION g_pfnrtRtlGetVersion;
+PFNRTRTLGETVERSION g_pfnrtRtlGetVersion;
+#ifndef RT_ARCH_AMD64
+/** KeQueryInterruptTime - exported/new in Windows 2000. */
+PFNRTKEQUERYINTERRUPTTIME g_pfnrtKeQueryInterruptTime;
+/** KeQuerySystemTime - exported/new in Windows 2000. */
+PFNRTKEQUERYSYSTEMTIME g_pfnrtKeQuerySystemTime;
+#endif
+/** KeQueryInterruptTimePrecise - new in Windows 8. */
+PFNRTKEQUERYINTERRUPTTIMEPRECISE g_pfnrtKeQueryInterruptTimePrecise;
+/** KeQuerySystemTimePrecise - new in Windows 8. */
+PFNRTKEQUERYSYSTEMTIMEPRECISE g_pfnrtKeQuerySystemTimePrecise;
/** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */
-uint32_t g_offrtNtPbQuantumEnd;
+uint32_t g_offrtNtPbQuantumEnd;
/** Size of the _KPRCB::QuantumEnd field. 0 if not found. */
-uint32_t g_cbrtNtPbQuantumEnd;
+uint32_t g_cbrtNtPbQuantumEnd;
/** Offset of the _KPRCB::DpcQueueDepth field. 0 if not found. */
-uint32_t g_offrtNtPbDpcQueueDepth;
+uint32_t g_offrtNtPbDpcQueueDepth;
/**
@@ -199,6 +209,9 @@ DECLHIDDEN(int) rtR0InitNative(void)
RTCpuSetFromU64(&g_rtMpNtCpuSet, ActiveProcessors);
/** @todo Port to W2K8 with > 64 cpus/threads. */
+ /*
+ * Initialize the function pointers.
+ */
#ifdef IPRT_TARGET_NT4
g_pfnrtNtExSetTimerResolution = NULL;
g_pfnrtNtKeFlushQueuedDpcs = NULL;
@@ -206,10 +219,11 @@ DECLHIDDEN(int) rtR0InitNative(void)
g_pfnrtNtHalSendSoftwareInterrupt = NULL;
g_pfnrtKeIpiGenericCall = NULL;
g_pfnrtRtlGetVersion = NULL;
+ g_pfnrtKeQueryInterruptTime = NULL;
+ g_pfnrtKeQueryInterruptTimePrecise = NULL;
+ g_pfnrtKeQuerySystemTime = NULL;
+ g_pfnrtKeQuerySystemTimePrecise = NULL;
#else
- /*
- * Initialize the function pointers.
- */
UNICODE_STRING RoutineName;
RtlInitUnicodeString(&RoutineName, L"ExSetTimerResolution");
g_pfnrtNtExSetTimerResolution = (PFNMYEXSETTIMERRESOLUTION)MmGetSystemRoutineAddress(&RoutineName);
@@ -228,6 +242,18 @@ DECLHIDDEN(int) rtR0InitNative(void)
RtlInitUnicodeString(&RoutineName, L"RtlGetVersion");
g_pfnrtRtlGetVersion = (PFNRTRTLGETVERSION)MmGetSystemRoutineAddress(&RoutineName);
+# ifndef RT_ARCH_AMD64
+ RtlInitUnicodeString(&RoutineName, L"KeQueryInterruptTime");
+ g_pfnrtKeQueryInterruptTime = (PFNRTKEQUERYINTERRUPTTIME)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"KeQuerySystemTime");
+ g_pfnrtKeQuerySystemTime = (PFNRTKEQUERYSYSTEMTIME)MmGetSystemRoutineAddress(&RoutineName);
+# endif
+ RtlInitUnicodeString(&RoutineName, L"KeQueryInterruptTimePrecise");
+ g_pfnrtKeQueryInterruptTimePrecise = (PFNRTKEQUERYINTERRUPTTIMEPRECISE)MmGetSystemRoutineAddress(&RoutineName);
+
+ RtlInitUnicodeString(&RoutineName, L"KeQuerySystemTimePrecise");
+ g_pfnrtKeQuerySystemTimePrecise = (PFNRTKEQUERYSYSTEMTIMEPRECISE)MmGetSystemRoutineAddress(&RoutineName);
#endif
/*
diff --git a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
index a82c01f..fe8aa8c 100644
--- a/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
+++ b/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
@@ -41,21 +41,34 @@ typedef VOID (__stdcall *PFNHALSENDSOFTWAREINTERRUPT)(ULONG ProcessorNumber, KIR
typedef int (__stdcall *PFNRTSENDIPI)(RTCPUID idCpu);
typedef ULONG_PTR (__stdcall *PFNRTKEIPIGENERICCALL)(PKIPI_BROADCAST_WORKER BroadcastFunction, ULONG_PTR Context);
typedef ULONG (__stdcall *PFNRTRTLGETVERSION)(PRTL_OSVERSIONINFOEXW pVerInfo);
+#ifndef RT_ARCH_AMD64
+typedef ULONGLONG (__stdcall *PFNRTKEQUERYINTERRUPTTIME)(VOID);
+typedef VOID (__stdcall *PFNRTKEQUERYSYSTEMTIME)(PLARGE_INTEGER pTime);
+#endif
+typedef ULONG64 (__stdcall *PFNRTKEQUERYINTERRUPTTIMEPRECISE)(PULONG64 pQpcTS);
+typedef VOID (__stdcall *PFNRTKEQUERYSYSTEMTIMEPRECISE)(PLARGE_INTEGER pTime);
+
/*******************************************************************************
* Global Variables *
*******************************************************************************/
-extern RTCPUSET g_rtMpNtCpuSet;
-extern PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
-extern PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
-extern PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
-extern PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
-extern PFNRTSENDIPI g_pfnrtSendIpi;
-extern PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
-extern PFNRTRTLGETVERSION g_pfnrtRtlGetVersion;
-extern uint32_t g_offrtNtPbQuantumEnd;
-extern uint32_t g_cbrtNtPbQuantumEnd;
-extern uint32_t g_offrtNtPbDpcQueueDepth;
+extern RTCPUSET g_rtMpNtCpuSet;
+extern PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
+extern PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+extern PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi;
+extern PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt;
+extern PFNRTSENDIPI g_pfnrtSendIpi;
+extern PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall;
+extern PFNRTRTLGETVERSION g_pfnrtRtlGetVersion;
+#ifndef RT_ARCH_AMD64
+extern PFNRTKEQUERYINTERRUPTTIME g_pfnrtKeQueryInterruptTime;
+extern PFNRTKEQUERYSYSTEMTIME g_pfnrtKeQuerySystemTime;
+#endif
+extern PFNRTKEQUERYINTERRUPTTIMEPRECISE g_pfnrtKeQueryInterruptTimePrecise;
+extern PFNRTKEQUERYSYSTEMTIMEPRECISE g_pfnrtKeQuerySystemTimePrecise;
+extern uint32_t g_offrtNtPbQuantumEnd;
+extern uint32_t g_cbrtNtPbQuantumEnd;
+extern uint32_t g_offrtNtPbDpcQueueDepth;
int rtMpSendIpiVista(RTCPUID idCpu);
diff --git a/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
index 938cc7c..ce4e1b2 100644
--- a/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/time-r0drv-nt.cpp
@@ -30,6 +30,7 @@
*******************************************************************************/
#define LOG_GROUP RTLOGGROUP_TIME
#include "the-nt-kernel.h"
+#include "internal-r0drv-nt.h"
#include <iprt/time.h>
@@ -48,20 +49,30 @@ DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
* later.
*/
#if 1
- /* Interrupt time. (NT4 doesn't have an API for it.) */
-# ifndef IPRT_TARGET_NT4
- ULONGLONG InterruptTime = KeQueryInterruptTime();
- return (uint64_t)InterruptTime * 100; /* The value is in 100ns, convert to ns units. */
-# else
+ /* Interrupt time. */
LARGE_INTEGER InterruptTime;
- do
+ if (g_pfnrtKeQueryInterruptTimePrecise)
{
- InterruptTime.HighPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High1Time;
- InterruptTime.LowPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.LowPart;
- } while (((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High2Time != InterruptTime.HighPart);
-
- return (uint64_t)InterruptTime.QuadPart * 100;
+ ULONG64 QpcTsIgnored;
+ InterruptTime.QuadPart = g_pfnrtKeQueryInterruptTimePrecise(&QpcTsIgnored);
+ }
+# ifdef RT_ARCH_AMD64
+ else
+ InterruptTime.QuadPart = KeQueryInterruptTime(); /* macro */
+# else
+ else if (g_pfnrtKeQueryInterruptTime)
+ InterruptTime.QuadPart = g_pfnrtKeQueryInterruptTime();
+ else
+ {
+ /* NT4 (no API) and pre-init fallback. */
+ do
+ {
+ InterruptTime.HighPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High1Time;
+ InterruptTime.LowPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.LowPart;
+ } while (((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High2Time != InterruptTime.HighPart);
+ }
# endif
+ return (uint64_t)InterruptTime.QuadPart * 100;
#else
/* Tick Count (NT4 SP1 has these APIs, haven't got SP0 to check). */
LARGE_INTEGER Tick;
@@ -98,14 +109,22 @@ RTDECL(uint64_t) RTTimeSystemMilliTS(void)
RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
{
LARGE_INTEGER SystemTime;
-#ifndef IPRT_TARGET_NT4
- KeQuerySystemTime(&SystemTime);
+ if (g_pfnrtKeQuerySystemTimePrecise)
+ g_pfnrtKeQuerySystemTimePrecise(&SystemTime);
+#ifdef RT_ARCH_AMD64
+ else
+ KeQuerySystemTime(&SystemTime); /* macro */
#else
- do
+ else if (g_pfnrtKeQuerySystemTime)
+ g_pfnrtKeQuerySystemTime(&SystemTime);
+ else
{
- SystemTime.HighPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->SystemTime.High1Time;
- SystemTime.LowPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->SystemTime.LowPart;
- } while (((KUSER_SHARED_DATA volatile *)SharedUserData)->SystemTime.High2Time != SystemTime.HighPart);
+ do
+ {
+ SystemTime.HighPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->SystemTime.High1Time;
+ SystemTime.LowPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->SystemTime.LowPart;
+ } while (((KUSER_SHARED_DATA volatile *)SharedUserData)->SystemTime.High2Time != SystemTime.HighPart);
+ }
#endif
return RTTimeSpecSetNtTime(pTime, SystemTime.QuadPart);
}
diff --git a/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
index 67764b6..5903cfe 100644
--- a/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
+++ b/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
@@ -40,6 +40,9 @@
#include "internal-r0drv-nt.h"
#include "internal/magics.h"
+/** This seems to provide better accuracy. */
+#define RTR0TIMER_NT_MANUAL_RE_ARM 1
+
/*******************************************************************************
* Structures and Typedefs *
@@ -70,6 +73,8 @@ typedef struct RTTIMER
* This is RTTIMER_MAGIC, but changes to something else before the timer
* is destroyed to indicate clearly that thread should exit. */
uint32_t volatile u32Magic;
+ /** Suspend count down for single shot omnit timers. */
+ int32_t volatile cOmniSuspendCountDown;
/** Flag indicating the timer is suspended. */
bool volatile fSuspended;
/** Whether the timer must run on one specific CPU or not. */
@@ -85,6 +90,10 @@ typedef struct RTTIMER
void *pvUser;
/** The timer interval. 0 if one-shot. */
uint64_t u64NanoInterval;
+#ifdef RTR0TIMER_NT_MANUAL_RE_ARM
+ /** The NT start time . */
+ uint64_t uNtStartTime;
+#endif
/** The Nt timer object. */
KTIMER NtTimer;
/** The number of sub-timers. */
@@ -97,6 +106,61 @@ typedef struct RTTIMER
} RTTIMER;
+#ifdef RTR0TIMER_NT_MANUAL_RE_ARM
+/**
+ * Get current NT interrupt time.
+ * @return NT interrupt time
+ */
+static uint64_t rtTimerNtQueryInterruptTime(void)
+{
+# ifdef RT_ARCH_AMD64
+ return KeQueryInterruptTime(); /* macro */
+# else
+ if (g_pfnrtKeQueryInterruptTime)
+ return g_pfnrtKeQueryInterruptTime();
+
+ /* NT4 */
+ ULARGE_INTEGER InterruptTime;
+ do
+ {
+ InterruptTime.HighPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High1Time;
+ InterruptTime.LowPart = ((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.LowPart;
+ } while (((KUSER_SHARED_DATA volatile *)SharedUserData)->InterruptTime.High2Time != InterruptTime.HighPart);
+ return InterruptTime.QuadPart;
+# endif
+}
+#endif /* RTR0TIMER_NT_MANUAL_RE_ARM */
+
+
+/**
+ * Manually re-arms an internval timer.
+ *
+ * Turns out NT doesn't necessarily do a very good job at re-arming timers
+ * accurately.
+ *
+ * @param pTimer The timer.
+ * @param iTick The current timer tick.
+ * @param pMasterDpc The master DPC.
+ */
+DECLINLINE(void) rtTimerNtRearmInternval(PRTTIMER pTimer, uint64_t iTick, PKDPC pMasterDpc)
+{
+#ifdef RTR0TIMER_NT_MANUAL_RE_ARM
+ Assert(pTimer->u64NanoInterval);
+
+ uint64_t uNtNext = (iTick * pTimer->u64NanoInterval) / 100 - 10; /* 1us fudge */
+ LARGE_INTEGER DueTime;
+ DueTime.QuadPart = rtTimerNtQueryInterruptTime() - pTimer->uNtStartTime;
+ if (DueTime.QuadPart < 0)
+ DueTime.QuadPart = 0;
+ if ((uint64_t)DueTime.QuadPart < uNtNext)
+ DueTime.QuadPart -= uNtNext;
+ else
+ DueTime.QuadPart = -2500; /* 0.25ms */
+
+ KeSetTimerEx(&pTimer->NtTimer, DueTime, 0, &pTimer->aSubTimers[0].NtDpc);
+#endif
+}
+
/**
* Timer callback function for the non-omni timers.
@@ -124,7 +188,10 @@ static void _stdcall rtTimerNtSimpleCallback(IN PKDPC pDpc, IN PVOID pvUser, IN
{
if (!pTimer->u64NanoInterval)
ASMAtomicWriteBool(&pTimer->fSuspended, true);
- pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pTimer->aSubTimers[0].iTick);
+ uint64_t iTick = ++pTimer->aSubTimers[0].iTick;
+ if (pTimer->u64NanoInterval)
+ rtTimerNtRearmInternval(pTimer, iTick, &pTimer->aSubTimers[0].NtDpc);
+ pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
}
NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2);
@@ -160,7 +227,9 @@ static void _stdcall rtTimerNtOmniSlaveCallback(IN PKDPC pDpc, IN PVOID pvUser,
&& pTimer->u32Magic == RTTIMER_MAGIC)
{
if (!pTimer->u64NanoInterval)
- ASMAtomicWriteBool(&pTimer->fSuspended, true);
+ if (ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown) <= 0)
+ ASMAtomicWriteBool(&pTimer->fSuspended, true);
+
pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
}
@@ -202,14 +271,43 @@ static void _stdcall rtTimerNtOmniMasterCallback(IN PKDPC pDpc, IN PVOID pvUser,
{
RTCPUSET OnlineSet;
RTMpGetOnlineSet(&OnlineSet);
- for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
- if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)
- && iCpuSelf != iCpu)
- KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0);
- if (!pTimer->u64NanoInterval)
- ASMAtomicWriteBool(&pTimer->fSuspended, true);
- pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
+ if (pTimer->u64NanoInterval)
+ {
+ /*
+ * Recurring timer.
+ */
+ for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
+ if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)
+ && iCpuSelf != iCpu)
+ KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0);
+
+ uint64_t iTick = ++pSubTimer->iTick;
+ rtTimerNtRearmInternval(pTimer, iTick, &pTimer->aSubTimers[RTMpCpuIdToSetIndex(pTimer->idCpu)].NtDpc);
+ pTimer->pfnTimer(pTimer, pTimer->pvUser, iTick);
+ }
+ else
+ {
+ /*
+ * Single shot timers gets complicated wrt to fSuspended maintance.
+ */
+ uint32_t cCpus = 0;
+ for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
+ if (RTCpuSetIsMemberByIndex(&OnlineSet, iCpu))
+ cCpus++;
+ ASMAtomicAddS32(&pTimer->cOmniSuspendCountDown, cCpus);
+
+ for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++)
+ if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)
+ && iCpuSelf != iCpu)
+ if (!KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0))
+ ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown); /* already queued and counted. */
+
+ if (ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown) <= 0)
+ ASMAtomicWriteBool(&pTimer->fSuspended, true);
+
+ pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick);
+ }
}
NOREF(pDpc); NOREF(SystemArgument1); NOREF(SystemArgument2);
@@ -238,12 +336,14 @@ RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
? &pTimer->aSubTimers[RTMpCpuIdToSetIndex(pTimer->idCpu)].NtDpc
: &pTimer->aSubTimers[0].NtDpc;
+#ifndef RTR0TIMER_NT_MANUAL_RE_ARM
uint64_t u64Interval = pTimer->u64NanoInterval / 1000000; /* This is ms, believe it or not. */
ULONG ulInterval = (ULONG)u64Interval;
if (ulInterval != u64Interval)
ulInterval = MAXLONG;
else if (!ulInterval && pTimer->u64NanoInterval)
ulInterval = 1;
+#endif
LARGE_INTEGER DueTime;
DueTime.QuadPart = -(int64_t)(u64First / 100); /* Relative, NT time. */
@@ -253,8 +353,14 @@ RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
unsigned cSubTimers = pTimer->fOmniTimer ? pTimer->cSubTimers : 1;
for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++)
pTimer->aSubTimers[iCpu].iTick = 0;
+ ASMAtomicWriteS32(&pTimer->cOmniSuspendCountDown, 0);
ASMAtomicWriteBool(&pTimer->fSuspended, false);
+#ifdef RTR0TIMER_NT_MANUAL_RE_ARM
+ pTimer->uNtStartTime = rtTimerNtQueryInterruptTime();
+ KeSetTimerEx(&pTimer->NtTimer, DueTime, 0, pMasterDpc);
+#else
KeSetTimerEx(&pTimer->NtTimer, DueTime, ulInterval, pMasterDpc);
+#endif
return VINF_SUCCESS;
}
@@ -368,6 +474,7 @@ RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_
* Initialize it.
*/
pTimer->u32Magic = RTTIMER_MAGIC;
+ pTimer->cOmniSuspendCountDown = 0;
pTimer->fSuspended = true;
pTimer->fSpecificCpu = (fFlags & RTTIMER_FLAGS_CPU_SPECIFIC) && (fFlags & RTTIMER_FLAGS_CPU_ALL) != RTTIMER_FLAGS_CPU_ALL;
pTimer->fOmniTimer = (fFlags & RTTIMER_FLAGS_CPU_ALL) == RTTIMER_FLAGS_CPU_ALL;
diff --git a/src/VBox/Runtime/r3/init.cpp b/src/VBox/Runtime/r3/init.cpp
index 1f680bf..42265da 100644
--- a/src/VBox/Runtime/r3/init.cpp
+++ b/src/VBox/Runtime/r3/init.cpp
@@ -640,11 +640,19 @@ RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char ***
return rtR3Init(fFlags, cArgs, papszArgs, pszProgramPath);
}
+
+RTR3DECL(bool) RTR3InitIsInitialized(void)
+{
+ return g_cUsers >= 1 && !g_fInitializing;
+}
+
+
RTR3DECL(bool) RTR3InitIsUnobtrusive(void)
{
return RT_BOOL(g_fInitFlags & RTR3INIT_FLAGS_UNOBTRUSIVE);
}
+
#if 0 /** @todo implement RTR3Term. */
RTR3DECL(void) RTR3Term(void)
{
diff --git a/src/VBox/Runtime/r3/socket.cpp b/src/VBox/Runtime/r3/socket.cpp
index 8678c37..250d2bb 100644
--- a/src/VBox/Runtime/r3/socket.cpp
+++ b/src/VBox/Runtime/r3/socket.cpp
@@ -678,7 +678,7 @@ RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRT
if (!pHostEnt)
{
rc = rtSocketResolverError();
- AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
+ //AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
return rc;
}
@@ -1720,8 +1720,12 @@ int rtSocketAccept(RTSOCKET hSocket, PRTSOCKET phClient, struct sockaddr *pAddr,
* @returns IPRT status code.
* @param hSocket The socket handle.
* @param pAddr The socket address to connect to.
+ * @param cMillies Number of milliseconds to wait for the connect attempt to complete.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ * Use RT_TCPCLIENTCONNECT_DEFAULT_WAIT to wait for the default time
+ * configured on the running system.
*/
-int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr)
+int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr, RTMSINTERVAL cMillies)
{
/*
* Validate input.
@@ -1736,8 +1740,73 @@ int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr)
int rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), &cbAddr);
if (RT_SUCCESS(rc))
{
- if (connect(pThis->hNative, &u.Addr, cbAddr) != 0)
- rc = rtSocketError();
+ if (cMillies == RT_SOCKETCONNECT_DEFAULT_WAIT)
+ {
+ if (connect(pThis->hNative, &u.Addr, cbAddr) != 0)
+ rc = rtSocketError();
+ }
+ else
+ {
+ /*
+ * Switch the socket to nonblocking mode, initiate the connect
+ * and wait for the socket to become writable or until the timeout
+ * expires.
+ */
+ rc = rtSocketSwitchBlockingMode(pThis, false /* fBlocking */);
+ if (RT_SUCCESS(rc))
+ {
+ if (connect(pThis->hNative, &u.Addr, cbAddr) != 0)
+ {
+ rc = rtSocketError();
+ if (rc == VERR_TRY_AGAIN || rc == VERR_NET_IN_PROGRESS)
+ {
+ int rcSock = 0;
+ fd_set FdSetWriteable;
+ struct timeval TvTimeout;
+
+ TvTimeout.tv_sec = cMillies / RT_MS_1SEC;
+ TvTimeout.tv_usec = (cMillies % RT_MS_1SEC) * RT_US_1MS;
+
+ FD_ZERO(&FdSetWriteable);
+ FD_SET(pThis->hNative, &FdSetWriteable);
+ do
+ {
+ rcSock = select(pThis->hNative + 1, NULL, &FdSetWriteable, NULL,
+ cMillies == RT_INDEFINITE_WAIT || cMillies >= INT_MAX
+ ? NULL
+ : &TvTimeout);
+ if (rcSock > 0)
+ {
+ int iSockError = 0;
+ socklen_t cbSockOpt = sizeof(iSockError);
+ rcSock = getsockopt(pThis->hNative, SOL_SOCKET, SO_ERROR, (char *)&iSockError, &cbSockOpt);
+ if (rcSock == 0)
+ {
+ if (iSockError == 0)
+ rc = VINF_SUCCESS;
+ else
+ {
+#ifdef RT_OS_WINDOWS
+ rc = RTErrConvertFromWin32(iSockError);
+#else
+ rc = RTErrConvertFromErrno(iSockError);
+#endif
+ }
+ }
+ else
+ rc = rtSocketError();
+ }
+ else if (rcSock == 0)
+ rc = VERR_TIMEOUT;
+ else
+ rc = rtSocketError();
+ } while (rc == VERR_INTERRUPTED);
+ }
+ }
+
+ rtSocketSwitchBlockingMode(pThis, true /* fBlocking */);
+ }
+ }
}
rtSocketUnlock(pThis);
diff --git a/src/VBox/Runtime/r3/tcp.cpp b/src/VBox/Runtime/r3/tcp.cpp
index 7c6b2ef..ec4e5ae 100644
--- a/src/VBox/Runtime/r3/tcp.cpp
+++ b/src/VBox/Runtime/r3/tcp.cpp
@@ -805,12 +805,12 @@ RTR3DECL(int) RTTcpServerDestroy(PRTTCPSERVER pServer)
RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock)
{
- return RTTcpClientConnectEx(pszAddress, uPort, pSock, NULL);
+ return RTTcpClientConnectEx(pszAddress, uPort, pSock, RT_SOCKETCONNECT_DEFAULT_WAIT, NULL);
}
RTR3DECL(int) RTTcpClientConnectEx(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock,
- PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie)
+ RTMSINTERVAL cMillies, PRTTCPCLIENTCONNECTCANCEL volatile *ppCancelCookie)
{
/*
* Validate input.
@@ -837,13 +837,13 @@ RTR3DECL(int) RTTcpClientConnectEx(const char *pszAddress, uint32_t uPort, PRTSO
RTSocketSetInheritance(Sock, false /*fInheritable*/);
if (!ppCancelCookie)
- rc = rtSocketConnect(Sock, &Addr);
+ rc = rtSocketConnect(Sock, &Addr, cMillies);
else
{
RTSocketRetain(Sock);
if (ASMAtomicCmpXchgPtr(ppCancelCookie, (PRTTCPCLIENTCONNECTCANCEL)Sock, NULL))
{
- rc = rtSocketConnect(Sock, &Addr);
+ rc = rtSocketConnect(Sock, &Addr, cMillies);
if (ASMAtomicCmpXchgPtr(ppCancelCookie, NULL, (PRTTCPCLIENTCONNECTCANCEL)Sock))
RTSocketRelease(Sock);
else
diff --git a/src/VBox/Runtime/r3/win/VBoxRT-openssl.def b/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
index 967069b..6f59ff8 100644
--- a/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
+++ b/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
@@ -3165,7 +3165,6 @@
ssl3_change_cipher_state
ssl3_check_cert_and_algorithm
ssl3_check_client_hello
- ssl3_check_finished
ssl3_choose_cipher
ssl3_cleanup_key_block
ssl3_clear
diff --git a/src/VBox/Runtime/r3/win/VBoxRT.rc b/src/VBox/Runtime/r3/win/VBoxRT.rc
new file mode 100644
index 0000000..1b34d15
--- /dev/null
+++ b/src/VBox/Runtime/r3/win/VBoxRT.rc
@@ -0,0 +1,59 @@
+/* $Id: VBoxRT.rc $ */
+/** @file
+ * VBoxRT - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Runtime\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxRT\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxRT.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/Runtime/r3/win/ntdll-mini-implib.def b/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
index dc78228..590b5b3 100644
--- a/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
+++ b/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
@@ -91,8 +91,19 @@ EXPORTS
NtWriteVirtualMemory ;;= _NtWriteVirtualMemory at 20
NtYieldExecution ;;= _NtYieldExecution at 0
- LdrInitializeThunk ;;= _LdrInitializeThunk at 12
- LdrRegisterDllNotification ;;= _LdrRegisterDllNotification at 16
+ LdrInitializeThunk ;;= _LdrInitializeThunk at 12
+ LdrRegisterDllNotification ;;= _LdrRegisterDllNotification at 16
+ LdrLoadDll ;;= _LdrLoadDll at 16
+ LdrUnloadDll ;;= _LdrUnloadDll at 4
+ LdrGetDllHandle ;;= _LdrGetDllHandle at 16
+ LdrGetDllHandleEx ;;= _LdrGetDllHandleEx at 20
+ LdrGetDllHandleByMapping ;;= _LdrGetDllHandleByMapping at 8
+ LdrGetDllHandleByName ;;= _LdrGetDllHandleByName at 12
+ LdrAddRefDll ;;= _LdrAddRefDll at 8
+ LdrGetProcedureAddress ;;= _LdrGetProcedureAddress at 12
+ LdrGetProcedureAddressEx ;;= _LdrGetProcedureAddressEx at 16
+ LdrLockLoaderLock ;;= _LdrLockLoaderLock at 12
+ LdrUnlockLoaderLock ;;= _LdrUnlockLoaderLock at 8
RtlAddAccessAllowedAce ;;= _RtlAddAccessAllowedAce at 16
RtlAddAccessDeniedAce ;;= _RtlAddAccessDeniedAce at 16
diff --git a/src/VBox/Runtime/r3/win/path-win.cpp b/src/VBox/Runtime/r3/win/path-win.cpp
index 7d5b055..00910ff 100644
--- a/src/VBox/Runtime/r3/win/path-win.cpp
+++ b/src/VBox/Runtime/r3/win/path-win.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -45,7 +45,7 @@
#include "internal/fs.h"
/* Needed for lazy loading SHGetFolderPathW in RTPathUserDocuments(). */
-typedef HRESULT FNSHGETFOLDERPATHW(HWND, int, HANDLE, DWORD, LPWSTR);
+typedef HRESULT WINAPI FNSHGETFOLDERPATHW(HWND, int, HANDLE, DWORD, LPWSTR);
typedef FNSHGETFOLDERPATHW *PFNSHGETFOLDERPATHW;
/**
@@ -157,16 +157,40 @@ RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath)
*/
RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath)
{
+ /*
+ * Validate input
+ */
+ AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+ AssertReturn(cchPath, VERR_INVALID_PARAMETER);
+
RTUTF16 wszPath[RTPATH_MAX];
- DWORD dwAttr;
+ bool fValidFolderPath = false;
/*
- * There are multiple definitions for what WE think of as user home...
+ * Try with Windows XP+ functionality first.
*/
- if ( !GetEnvironmentVariableW(L"HOME", &wszPath[0], RTPATH_MAX)
+ RTLDRMOD hShell32;
+ int rc = RTLdrLoadSystem("Shell32.dll", true /*fNoUnload*/, &hShell32);
+ if (RT_SUCCESS(rc))
+ {
+ PFNSHGETFOLDERPATHW pfnSHGetFolderPathW;
+ rc = RTLdrGetSymbol(hShell32, "SHGetFolderPathW", (void**)&pfnSHGetFolderPathW);
+ if (RT_SUCCESS(rc))
+ {
+ HRESULT hrc = pfnSHGetFolderPathW(0, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, wszPath);
+ fValidFolderPath = (hrc == S_OK);
+ }
+ RTLdrClose(hShell32);
+ }
+
+ DWORD dwAttr;
+ if ( !fValidFolderPath
|| (dwAttr = GetFileAttributesW(&wszPath[0])) == INVALID_FILE_ATTRIBUTES
|| !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
{
+ /*
+ * Fall back to Windows specific environment variables. HOME is not used.
+ */
if ( !GetEnvironmentVariableW(L"USERPROFILE", &wszPath[0], RTPATH_MAX)
|| (dwAttr = GetFileAttributesW(&wszPath[0])) == INVALID_FILE_ATTRIBUTES
|| !(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
diff --git a/src/VBox/Storage/ISCSI.cpp b/src/VBox/Storage/ISCSI.cpp
index 4fc4dff..96468ed 100644
--- a/src/VBox/Storage/ISCSI.cpp
+++ b/src/VBox/Storage/ISCSI.cpp
@@ -809,7 +809,7 @@ static int iscsiTransportConnect(PISCSIIMAGE pImage)
if (!pImage->pszHostname)
return VERR_NET_DEST_ADDRESS_REQUIRED;
- rc = pImage->pIfNet->pfnClientConnect(pImage->Socket, pImage->pszHostname, pImage->uPort);
+ rc = pImage->pIfNet->pfnClientConnect(pImage->Socket, pImage->pszHostname, pImage->uPort, pImage->uReadTimeout);
if (RT_FAILURE(rc))
{
if ( rc == VERR_NET_CONNECTION_REFUSED
diff --git a/src/VBox/Storage/Makefile.kmk b/src/VBox/Storage/Makefile.kmk
index 56ea233..2054243 100644
--- a/src/VBox/Storage/Makefile.kmk
+++ b/src/VBox/Storage/Makefile.kmk
@@ -60,6 +60,7 @@ if defined(VBOX_WITH_EXTPACK_PUEL) && defined(VBOX_WITH_EXTPACK_PUEL_BUILD)
VDPluginCrypt_LDFLAGS.linux = -Wl,--no-undefined
VDPluginCrypt_SOURCES = VDFilterCrypt.cpp
+ VDPluginCrypt_SOURCES.win = VDPluginCrypt.rc
endif
endif # VBOX_WITH_EXTPACK_PUEL
diff --git a/src/VBox/Storage/testcase/Makefile.kmk b/src/VBox/Storage/testcase/Makefile.kmk
index 5098ee5..01c21b7 100644
--- a/src/VBox/Storage/testcase/Makefile.kmk
+++ b/src/VBox/Storage/testcase/Makefile.kmk
@@ -150,7 +150,9 @@ if defined(VBOX_WITH_TESTCASES) || defined(VBOX_WITH_VBOX_IMG)
../QCOW.cpp \
../VHDX.cpp \
../VCICache.cpp \
- ../VDIfVfs.cpp
+ ../VDIfVfs.cpp
+ vbox-img_SOURCES.win = \
+ vbox-img.rc
vbox-img_LIBS = \
$(VBOX_LIB_RUNTIME_STATIC)
if1of ($(KBUILD_TARGET),os2 win)
diff --git a/src/VBox/Storage/testcase/vbox-img.rc b/src/VBox/Storage/testcase/vbox-img.rc
new file mode 100644
index 0000000..5d55366
--- /dev/null
+++ b/src/VBox/Storage/testcase/vbox-img.rc
@@ -0,0 +1,50 @@
+/* $Id: vbox-img.rc $ */
+/** @file
+ * vbox-img - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Virtual Disk Utility\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "vbox-img\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "vbox-img.exe\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/VMM/Makefile.kmk b/src/VBox/VMM/Makefile.kmk
index 15d348f..056b9d6 100644
--- a/src/VBox/VMM/Makefile.kmk
+++ b/src/VBox/VMM/Makefile.kmk
@@ -265,6 +265,8 @@ VBoxVMM_SOURCES.x86 += \
VMMSwitcher/X86Stub.asm
VBoxVMM_SOURCES.amd64 += \
VMMSwitcher/AMD64Stub.asm
+VBoxVMM_SOURCES.win += \
+ VMMR3/VMMR3.rc
VBoxVMM_LIBS = \
$(PATH_STAGE_LIB)/DisasmR3$(VBOX_SUFF_LIB)
diff --git a/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp b/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
index 7a0b4c5..8b59596 100644
--- a/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
+++ b/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/VMM/VMMAll/TMAllVirtual.cpp b/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
index 2390176..89d94c2 100644
--- a/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
+++ b/src/VBox/VMM/VMMAll/TMAllVirtual.cpp
@@ -925,7 +925,7 @@ VMM_INT_DECL(uint64_t) TMVirtualSyncGetWithDeadlineNoCheck(PVM pVM, uint64_t *pc
* @thread EMT.
* @remarks May set the timer and virtual sync FFs.
*/
-VMM_INT_DECL(uint64_t) TMVirtualSyncGetNsToDeadline(PVM pVM)
+VMMDECL(uint64_t) TMVirtualSyncGetNsToDeadline(PVM pVM)
{
uint64_t cNsToDeadline;
tmVirtualSyncGetEx(pVM, false /*fCheckTimers*/, &cNsToDeadline);
diff --git a/src/VBox/VMM/VMMR0/HMVMXR0.cpp b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
index 26d847b..26e6107 100644
--- a/src/VBox/VMM/VMMR0/HMVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
@@ -144,16 +144,18 @@ typedef RTHCUINTREG HMVMXHCUINTREG;
/**
* Exception bitmap mask for real-mode guests (real-on-v86).
*
- * We need to intercept all exceptions manually (except #PF). #NM is also
- * handled separately, see hmR0VmxLoadSharedCR0(). #PF need not be intercepted
- * even in real-mode if we have Nested Paging support.
+ * We need to intercept all exceptions manually except:
+ * - #NM, #MF handled in hmR0VmxLoadSharedCR0().
+ * - #DB handled in hmR0VmxLoadSharedDebugState().
+ * - #PF need not be intercepted even in real-mode if we have Nested Paging
+ * support.
*/
-#define HMVMX_REAL_MODE_XCPT_MASK ( RT_BIT(X86_XCPT_DE) | RT_BIT(X86_XCPT_DB) | RT_BIT(X86_XCPT_NMI) \
+#define HMVMX_REAL_MODE_XCPT_MASK ( RT_BIT(X86_XCPT_DE) /* RT_BIT(X86_XCPT_DB) */ | RT_BIT(X86_XCPT_NMI) \
| RT_BIT(X86_XCPT_BP) | RT_BIT(X86_XCPT_OF) | RT_BIT(X86_XCPT_BR) \
| RT_BIT(X86_XCPT_UD) /* RT_BIT(X86_XCPT_NM) */ | RT_BIT(X86_XCPT_DF) \
| RT_BIT(X86_XCPT_CO_SEG_OVERRUN) | RT_BIT(X86_XCPT_TS) | RT_BIT(X86_XCPT_NP) \
| RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_GP) /* RT_BIT(X86_XCPT_PF) */ \
- | RT_BIT(X86_XCPT_MF) | RT_BIT(X86_XCPT_AC) | RT_BIT(X86_XCPT_MC) \
+ /* RT_BIT(X86_XCPT_MF) */ | RT_BIT(X86_XCPT_AC) | RT_BIT(X86_XCPT_MC) \
| RT_BIT(X86_XCPT_XF))
/**
@@ -2996,7 +2998,8 @@ DECLINLINE(int) hmR0VmxLoadGuestExitCtls(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
* VMX_VMCS_CTRL_EXIT_SAVE_GUEST_PAT_MSR,
* VMX_VMCS_CTRL_EXIT_LOAD_HOST_PAT_MSR. */
- if (pVM->hm.s.vmx.Msrs.VmxExit.n.allowed1 & VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER)
+ if ( pVM->hm.s.vmx.fUsePreemptTimer
+ && (pVM->hm.s.vmx.Msrs.VmxExit.n.allowed1 & VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER))
val |= VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER;
if ((val & zap) != val)
@@ -3785,9 +3788,10 @@ static int hmR0VmxLoadSharedDebugState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
/*
* Update the exception bitmap regarding intercepting #DB generated by the guest.
*/
- if (fInterceptDB)
+ if ( fInterceptDB
+ || pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_DB);
- else if (!pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
+ else
{
#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
diff --git a/src/VBox/VMM/VMMR0/VMMR0.def b/src/VBox/VMM/VMMR0/VMMR0.def
index fc11689..6c8453e 100644
--- a/src/VBox/VMM/VMMR0/VMMR0.def
+++ b/src/VBox/VMM/VMMR0/VMMR0.def
@@ -96,6 +96,7 @@ EXPORTS
ASMMultU64ByU32DivByU32 ; not-os2
ASMAtomicXchgU8 ; not-x86
ASMBitFirstSet ; not-x86
+ ASMNopPause ; not-x86
nocrt_memchr
nocrt_memcmp
nocrt_memcpy
diff --git a/src/VBox/VMM/VMMR3/VMEmt.cpp b/src/VBox/VMM/VMMR3/VMEmt.cpp
index f52b3c7..e03688c 100644
--- a/src/VBox/VMM/VMMR3/VMEmt.cpp
+++ b/src/VBox/VMM/VMMR3/VMEmt.cpp
@@ -1022,7 +1022,7 @@ VMMR3_INT_DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags)
* This function is called by thread other than EMT to make
* sure EMT wakes up and promptly service an FF request.
*
- * @param pUVM Pointer to the user mode VM structure.
+ * @param pUVCpu Pointer to the user mode per CPU VM structure.
* @param fFlags Notification flags, VMNOTIFYFF_FLAGS_*.
* @internal
*/
@@ -1045,6 +1045,7 @@ VMMR3_INT_DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVCpu, uint32_t fFlags)
* @param pVCpu Pointer to the VMCPU.
* @param fIgnoreInterrupts If set the VM_FF_INTERRUPT flags is ignored.
* @thread The emulation thread.
+ * @remarks Made visible for implementing vmsvga sync register.
* @internal
*/
VMMR3_INT_DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts)
@@ -1295,3 +1296,60 @@ int vmR3SetHaltMethodU(PUVM pUVM, VMHALTMETHOD enmHaltMethod)
return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, vmR3SetHaltMethodCallback, (void *)(uintptr_t)i);
}
+
+/**
+ * Special interface for implementing a HLT-like port on a device.
+ *
+ * This can be called directly from device code, provide the device is trusted
+ * to access the VMM directly. Since we may not have an accurate register set
+ * and the caller certainly shouldn't (device code does not access CPU
+ * registers), this function will return when interrupts are pending regardless
+ * of the actual EFLAGS.IF state.
+ *
+ * @returns VBox error status (never informational statuses).
+ * @param pVM The VM handle.
+ * @param idCpu The id of the calling EMT.
+ */
+VMMR3DECL(int) VMR3WaitForDeviceReady(PVM pVM, VMCPUID idCpu)
+{
+ /*
+ * Validate caller and resolve the CPU ID.
+ */
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
+ PVMCPU pVCpu = &pVM->aCpus[idCpu];
+ VMCPU_ASSERT_EMT_RETURN(pVCpu, VERR_VM_THREAD_NOT_EMT);
+
+ /*
+ * Tag along with the HLT mechanics for now.
+ */
+ int rc = VMR3WaitHalted(pVM, pVCpu, false /*fIgnoreInterrupts*/);
+ if (RT_SUCCESS(rc))
+ return VINF_SUCCESS;
+ return rc;
+}
+
+
+/**
+ * Wakes up a CPU that has called VMR3WaitForDeviceReady.
+ *
+ * @returns VBox error status (never informational statuses).
+ * @param pVM The VM handle.
+ * @param idCpu The id of the calling EMT.
+ */
+VMMR3DECL(int) VMR3NotifyCpuDeviceReady(PVM pVM, VMCPUID idCpu)
+{
+ /*
+ * Validate caller and resolve the CPU ID.
+ */
+ VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
+ AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
+ PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+ /*
+ * Pretend it was an FF that got set since we've got logic for that already.
+ */
+ VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM);
+ return VINF_SUCCESS;
+}
+
diff --git a/src/VBox/VMM/VMMR3/VMMR3.rc b/src/VBox/VMM/VMMR3/VMMR3.rc
new file mode 100644
index 0000000..dd9e188
--- /dev/null
+++ b/src/VBox/VMM/VMMR3/VMMR3.rc
@@ -0,0 +1,50 @@
+/* $Id: VMMR3.rc $ */
+/** @file
+ * VBoxVMM - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox VMM\0"
+ VALUE "FileVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD "." VBOX_SVN_REV "\0"
+ VALUE "InternalName", "VBoxVMM\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxVMM.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", VBOX_VERSION_MAJOR "." VBOX_VERSION_MINOR "." VBOX_VERSION_BUILD ".r" VBOX_SVN_REV "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac b/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
index b51f360..a5c7da2 100644
--- a/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
+++ b/src/VBox/VMM/VMMSwitcher/AMD64andLegacy.mac
@@ -126,6 +126,10 @@ gth64_nopc:
jnc gth64_notherm
and dword [r8 + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
gth64_notherm:
+ shr ecx, 1
+ jnc gth64_nocmci
+ and dword [r8 + APIC_REG_LVT_CMCI], ~APIC_REG_LVT_MASKED
+gth64_nocmci:
jmp gth64_apic_done
; X2 APIC mode:
@@ -160,6 +164,13 @@ gth64_x2_nopc:
and eax, ~APIC_REG_LVT_MASKED
wrmsr
gth64_x2_notherm:
+ shr r10d, 1
+ jnc gth64_x2_nocmci
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth64_x2_nocmci:
mov rax, r8 ; restore rax
gth64_apic_done:
@@ -364,6 +375,17 @@ htg_nopc:
shr eax, 16
cmp al, 5
jb htg_notherm
+ je htg_nocmci
+ mov eax, [rbx + APIC_REG_LVT_CMCI]
+ mov ecx, eax
+ and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ecx, APIC_REG_LVT_MODE_NMI
+ jne htg_nocmci
+ or edi, 0x10
+ or eax, APIC_REG_LVT_MASKED
+ mov [rbx + APIC_REG_LVT_CMCI], eax
+ mov eax, [rbx + APIC_REG_LVT_CMCI] ; write completion
+htg_nocmci:
mov eax, [rbx + APIC_REG_LVT_THMR]
mov ecx, eax
and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
@@ -417,6 +439,17 @@ htg_x2_nopc:
shr eax, 16
cmp al, 5
jb htg_x2_notherm
+ je htg_x2_nocmci
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_nocmci
+ or edi, 0x10
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_nocmci:
mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
rdmsr
mov ebx, eax
diff --git a/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac b/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
index 44765d6..5e6ed8a 100644
--- a/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
+++ b/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
@@ -194,6 +194,10 @@ gth_nopc:
jnc gth_notherm
and dword [edx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
gth_notherm:
+ shr ecx, 1
+ jnc gth_nocmci
+ and dword [edx + APIC_REG_LVT_CMCI], ~APIC_REG_LVT_MASKED
+gth_nocmci:
jmp gth_apic_done
gth_x2apic:
@@ -230,6 +234,13 @@ gth_x2_nopc:
and eax, ~APIC_REG_LVT_MASKED
wrmsr
gth_x2_notherm:
+ shr ebx, 1
+ jnc gth_x2_nocmci
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth_x2_nocmci:
pop edx
pop ebx
pop eax
@@ -354,6 +365,17 @@ htg_nopc:
shr eax, 16
cmp al, 5
jb htg_notherm
+ je htg_nocmci
+ mov eax, [ebx + APIC_REG_LVT_CMCI]
+ mov ecx, eax
+ and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ecx, APIC_REG_LVT_MODE_NMI
+ jne htg_nocmci
+ or edi, 0x10
+ or eax, APIC_REG_LVT_MASKED
+ mov [ebx + APIC_REG_LVT_CMCI], eax
+ mov eax, [ebx + APIC_REG_LVT_CMCI] ; write completion
+htg_nocmci:
mov eax, [ebx + APIC_REG_LVT_THMR]
mov ecx, eax
and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
@@ -406,6 +428,17 @@ htg_x2_nopc:
shr eax, 16
cmp al, 5
jb htg_x2_notherm
+ je htg_x2_nocmci
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_nocmci
+ or edi, 0x10
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_nocmci:
mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
rdmsr
mov ebx, eax
diff --git a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
index 70fde1c..fdb63f2 100644
--- a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
+++ b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
@@ -107,6 +107,10 @@ gth_nopc:
jnc gth_notherm
and dword [edx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
gth_notherm:
+ shr ecx, 1
+ jnc gth_nocmci
+ and dword [edx + APIC_REG_LVT_CMCI], ~APIC_REG_LVT_MASKED
+gth_nocmci:
jmp gth_apic_done
gth_x2apic:
@@ -142,6 +146,13 @@ gth_x2_nopc:
and eax, ~APIC_REG_LVT_MASKED
wrmsr
gth_x2_notherm:
+ shr ebx, 1
+ jnc gth_x2_nocmci
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth_x2_nocmci:
pop edx
pop ebx
pop eax
@@ -250,6 +261,17 @@ htg_nopc:
shr eax, 16
cmp al, 5
jb htg_notherm
+ je htg_nocmci
+ mov eax, [ebx + APIC_REG_LVT_CMCI]
+ mov ecx, eax
+ and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ecx, APIC_REG_LVT_MODE_NMI
+ jne htg_nocmci
+ or edi, 0x10
+ or eax, APIC_REG_LVT_MASKED
+ mov [ebx + APIC_REG_LVT_CMCI], eax
+ mov eax, [ebx + APIC_REG_LVT_CMCI] ; write completion
+htg_nocmci:
mov eax, [ebx + APIC_REG_LVT_THMR]
mov ecx, eax
and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
@@ -302,6 +324,17 @@ htg_x2_nopc:
shr eax, 16
cmp al, 5
jb htg_x2_notherm
+ je htg_x2_nocmci
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_nocmci
+ or edi, 0x10
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_nocmci:
mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
rdmsr
mov ebx, eax
diff --git a/src/VBox/VMM/tools/VBoxVMMPreload.cpp b/src/VBox/VMM/tools/VBoxVMMPreload.cpp
index f58a1e1..e204e03 100644
--- a/src/VBox/VMM/tools/VBoxVMMPreload.cpp
+++ b/src/VBox/VMM/tools/VBoxVMMPreload.cpp
@@ -51,6 +51,7 @@ static struct
};
static uint32_t g_cVerbose = 1;
+static bool g_fLockDown = false;
/**
@@ -70,6 +71,7 @@ static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit)
{
{ "--only", 'o', RTGETOPT_REQ_STRING },
{ "--quiet", 'q', RTGETOPT_REQ_NOTHING },
+ { "--lock" , 'l', RTGETOPT_REQ_NOTHING },
{ "--verbose", 'v', RTGETOPT_REQ_NOTHING },
};
@@ -114,12 +116,16 @@ static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit)
g_cVerbose = 0;
break;
+ case 'l':
+ g_fLockDown = true;
+ break;
+
case 'h':
RTPrintf(VBOX_PRODUCT " VMM ring-0 Module Preloader Version " VBOX_VERSION_STRING
"(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
"All rights reserved.\n"
"\n"
- "Usage: VBoxVMMPreload [-hqvV] [-o|--only <mod>]\n"
+ "Usage: VBoxVMMPreload [-hlqvV] [-o|--only <mod>]\n"
"\n");
*pfExit = true;
return RTEXITCODE_SUCCESS;
@@ -144,6 +150,8 @@ static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit)
*/
static RTEXITCODE LoadModules(void)
{
+ RTERRINFOSTATIC ErrInfo;
+
for (uint32_t i = 0; i < RT_ELEMENTS(g_aModules); i++)
{
if (g_aModules[i].fPreload)
@@ -155,7 +163,6 @@ static RTEXITCODE LoadModules(void)
if (RT_FAILURE(rc))
return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAppPrivateArch or RTPathAppend returned %Rrc", rc);
- RTERRINFOSTATIC ErrInfo;
RTErrInfoInitStatic(&ErrInfo);
rc = SUPR3LoadModule(szPath, g_aModules[i].pszName, &g_aModules[i].pvImageBase, &ErrInfo.Core);
if (RT_FAILURE(rc))
@@ -166,6 +173,17 @@ static RTEXITCODE LoadModules(void)
}
}
+ if (g_fLockDown)
+ {
+ RTErrInfoInitStatic(&ErrInfo);
+ int rc = SUPR3LockDownLoader(&ErrInfo.Core);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LockDownLoader failed: %s (rc=%Rrc)",
+ ErrInfo.Core.pszMsg, rc);
+ if (g_cVerbose >= 1)
+ RTMsgInfo("Locked down module loader interface!\n");
+ }
+
RTStrmFlush(g_pStdOut);
return RTEXITCODE_SUCCESS;
}
diff --git a/src/bldprogs/VBoxDef2LazyLoad.cpp b/src/bldprogs/VBoxDef2LazyLoad.cpp
index fe0006a..4f6870a 100644
--- a/src/bldprogs/VBoxDef2LazyLoad.cpp
+++ b/src/bldprogs/VBoxDef2LazyLoad.cpp
@@ -2,11 +2,11 @@
/** @file
* VBoxDef2LazyLoad - Lazy Library Loader Generator.
*
- * @note Only tested on win.amd64.
+ * @note Only tested on win.amd64 & darwin.amd64.
*/
/*
- * Copyright (C) 2013 Oracle Corporation
+ * Copyright (C) 2013-2015 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -47,9 +47,11 @@ typedef MYEXPORT *PMYEXPORT;
/** @name Options
* @{ */
static const char *g_pszOutput = NULL;
-static const char *g_pszInput = NULL;
static const char *g_pszLibrary = NULL;
+static const char *g_apszInputs[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+static unsigned g_cInputs = 0;
static bool g_fIgnoreData = true;
+static bool g_fWithExplictLoadFunction = false;
/** @} */
/** Pointer to the export name list head. */
@@ -96,7 +98,7 @@ static unsigned wordLength(const char *pszWord)
* details has been displayed.
* @param pInput The input stream.
*/
-static RTEXITCODE parseInputInner(FILE *pInput)
+static RTEXITCODE parseInputInner(FILE *pInput, const char *pszInput)
{
/*
* Process the file line-by-line.
@@ -179,7 +181,7 @@ static RTEXITCODE parseInputInner(FILE *pInput)
psz++;
if (!isdigit(*psz))
{
- fprintf(stderr, "%s:%u: error: Invalid ordinal spec.\n", g_pszInput, iLine);
+ fprintf(stderr, "%s:%u: error: Invalid ordinal spec.\n", pszInput, iLine);
return RTEXITCODE_FAILURE;
}
uOrdinal = *psz++ - '0';
@@ -196,7 +198,7 @@ static RTEXITCODE parseInputInner(FILE *pInput)
fNoName = true;
psz = leftStrip(psz + cch);
#else
- fprintf(stderr, "%s:%u: error: NONAME export not implemented.\n", g_pszInput, iLine);
+ fprintf(stderr, "%s:%u: error: NONAME export not implemented.\n", pszInput, iLine);
return RTEXITCODE_FAILURE;
#endif
}
@@ -210,14 +212,14 @@ static RTEXITCODE parseInputInner(FILE *pInput)
if (!g_fIgnoreData)
{
fprintf(stderr, "%s:%u: error: Cannot wrap up DATA export '%.*s'.\n",
- g_pszInput, iLine, cchName, pchName);
+ pszInput, iLine, cchName, pchName);
return RTEXITCODE_SUCCESS;
}
}
else if (!WORD_CMP(psz, cch, "PRIVATE"))
{
fprintf(stderr, "%s:%u: error: Cannot wrap up DATA export '%.*s'.\n",
- g_pszInput, iLine, cchName, pchName);
+ pszInput, iLine, cchName, pchName);
return RTEXITCODE_SUCCESS;
}
psz = leftStrip(psz + cch);
@@ -229,7 +231,7 @@ static RTEXITCODE parseInputInner(FILE *pInput)
PMYEXPORT pExp = (PMYEXPORT)malloc(sizeof(*pExp) + cchName);
if (!pExp)
{
- fprintf(stderr, "%s:%u: error: Out of memory.\n", g_pszInput, iLine);
+ fprintf(stderr, "%s:%u: error: Out of memory.\n", pszInput, iLine);
return RTEXITCODE_SUCCESS;
}
memcpy(pExp->szName, pchName, cchName);
@@ -247,33 +249,41 @@ static RTEXITCODE parseInputInner(FILE *pInput)
*/
if (feof(pInput))
return RTEXITCODE_SUCCESS;
- fprintf(stderr, "error: Read while reading '%s' (iLine=%u).\n", g_pszInput, iLine);
+ fprintf(stderr, "error: Read while reading '%s' (iLine=%u).\n", pszInput, iLine);
return RTEXITCODE_FAILURE;
}
/**
- * Parses g_pszInput, populating the list pointed to by g_pExpHead.
+ * Parses a_apszInputs, populating the list pointed to by g_pExpHead.
*
* @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE, in the latter case full
* details has been displayed.
*/
-static RTEXITCODE parseInput(void)
+static RTEXITCODE parseInputs(void)
{
- RTEXITCODE rcExit = RTEXITCODE_FAILURE;
- FILE *pInput = fopen(g_pszInput, "r");
- if (pInput)
+ RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
+ for (unsigned i = 0; i < g_cInputs; i++)
{
- rcExit = parseInputInner(pInput);
- fclose(pInput);
- if (rcExit == RTEXITCODE_SUCCESS && !g_pExpHead)
+ FILE *pInput = fopen(g_apszInputs[i], "r");
+ if (pInput)
+ {
+ RTEXITCODE rcExit2 = parseInputInner(pInput, g_apszInputs[i]);
+ fclose(pInput);
+ if (rcExit2 == RTEXITCODE_SUCCESS && !g_pExpHead)
+ {
+ fprintf(stderr, "error: Found no exports in '%s'.\n", g_apszInputs[i]);
+ rcExit2 = RTEXITCODE_FAILURE;
+ }
+ if (rcExit2 != RTEXITCODE_SUCCESS)
+ rcExit = rcExit2;
+ }
+ else
{
- fprintf(stderr, "error: Found no exports in '%s'.\n", g_pszInput);
+ fprintf(stderr, "error: Failed to open '%s' for reading.\n", g_apszInputs[i]);
rcExit = RTEXITCODE_FAILURE;
}
}
- else
- fprintf(stderr, "error: Failed to open '%s' for reading.\n", g_pszInput);
return rcExit;
}
@@ -288,67 +298,136 @@ static RTEXITCODE parseInput(void)
*/
static RTEXITCODE generateOutputInner(FILE *pOutput)
{
+ fprintf(pOutput, ";;\n");
+ for (unsigned i = 0; i < g_cInputs; i++)
+ fprintf(pOutput, ";; Autogenerated from '%s'.\n", g_apszInputs[i]);
+
fprintf(pOutput,
- ";; Autogenerated from '%s'. DO NOT EDIT!\n"
+ ";; DO NOT EDIT!\n"
+ ";;\n"
+ "\n"
"\n"
"%%include \"iprt/asmdefs.mac\"\n"
"\n"
- "BEGINCODE\n",
- g_pszInput);
+ "\n");
+ /*
+ * Put the thunks first for alignment and other reasons. It's the hot part of the code.
+ */
+ fprintf(pOutput,
+ ";\n"
+ "; Thunks.\n"
+ ";\n"
+ "BEGINCODE\n");
+ for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
+ fprintf(pOutput,
+ "BEGINPROC %s\n"
+ " jmp RTCCPTR_PRE [g_pfn%s xWrtRIP]\n"
+ "ENDPROC %s\n",
+ pExp->szName,
+ pExp->szName,
+ pExp->szName);
+ fprintf(pOutput,
+ "\n"
+ "\n");
+
+ /*
+ * Import pointers
+ */
+ fprintf(pOutput,
+ ";\n"
+ "; Import pointers. Initialized to point a lazy loading stubs.\n"
+ ";\n"
+ "BEGINDATA\n"
+ "g_apfnImports:\n");
for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
- {
fprintf(pOutput,
- "BEGINDATA\n"
"%%ifdef ASM_FORMAT_PE\n"
"global __imp_%s\n"
"__imp_%s:\n"
"%%endif\n"
- "g_pfn%s RTCCPTR_DEF ___LazyLoad___%s\n"
- "BEGINCODE\n"
- "BEGINPROC %s\n"
- " jmp RTCCPTR_PRE [g_pfn%s xWrtRIP]\n"
- "ENDPROC %s\n"
+ "g_pfn%s RTCCPTR_DEF ___LazyLoad___%s\n",
+ pExp->szName,
+ pExp->szName,
+ pExp->szName,
+ pExp->szName);
+ fprintf(pOutput,
+ "RTCCPTR_DEF 0 ; Terminator entry for traversal.\n"
+ "\n"
+ "\n");
+
+ /*
+ * Now for the less important stuff, starting with the names.
+ *
+ * We keep the names separate so we can traverse them in parallel to
+ * g_apfnImports in the load-everything routine further down.
+ */
+ fprintf(pOutput,
+ ";\n"
+ "; Imported names.\n"
+ ";\n"
+ "BEGINCODE\n"
+ "g_szLibrary db '%s',0\n"
+ "g_szzNames:\n",
+ g_pszLibrary);
+ for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
+ fprintf(pOutput, "g_sz%s: db '%s',0\n", pExp->szName, pExp->szName);
+ fprintf(pOutput,
+ "g_EndOfNames: db 0\n"
+ "\n"
+ "\n");
+
+ /*
+ * The per import lazy load code.
+ */
+ fprintf(pOutput,
+ ";\n"
+ "; Lazy load+resolve stubs.\n"
+ ";\n"
+ "BEGINCODE\n");
+ for (PMYEXPORT pExp = g_pExpHead; pExp; pExp = pExp->pNext)
+ fprintf(pOutput,
"___LazyLoad___%s:\n"
/* "int3\n" */
"%%ifdef RT_ARCH_AMD64\n"
- " lea rax, [.szName wrt rip]\n"
+ " lea rax, [g_sz%s wrt rip]\n"
" lea r10, [g_pfn%s wrt rip]\n"
"%%elifdef RT_ARCH_X86\n"
- " push .szName\n"
+ " push g_sz%s\n"
" push g_pfn%s\n"
"%%else\n"
" %%error \"Unsupported architecture\"\n"
"%%endif\n"
- " call NAME(LazyLoadResolver)\n"
+ " call LazyLoadResolver\n"
"%%ifdef RT_ARCH_X86\n"
" add esp, 8h\n"
"%%endif\n"
" jmp NAME(%s)\n"
- ".szName db '%s',0\n"
"\n"
,
pExp->szName,
pExp->szName,
- pExp->szName, pExp->szName,
- pExp->szName,
- pExp->szName,
- pExp->szName,
- pExp->szName,
pExp->szName,
pExp->szName,
pExp->szName,
pExp->szName);
- }
+ fprintf(pOutput,
+ "\n"
+ "\n"
+ "\n");
/*
* The code that does the loading and resolving.
*/
fprintf(pOutput,
+ ";\n"
+ "; The module handle.\n"
+ ";\n"
"BEGINDATA\n"
"g_hMod RTCCPTR_DEF 0\n"
"\n"
- "BEGINCODE\n");
+ "\n"
+ "\n");
/*
* How we load the module needs to be selectable later on.
@@ -358,40 +437,41 @@ static RTEXITCODE generateOutputInner(FILE *pOutput)
*/
fprintf(pOutput,
";\n"
- ";SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, \n"
+ ";SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod,\n"
"; uint32_t fFlags, PRTERRINFO pErrInfo);\n"
";\n"
- "extern IMPNAME(SUPR3HardenedLdrLoadAppPriv)\n"
+ "EXTERN_IMP2 SUPR3HardenedLdrLoadAppPriv\n"
+ "BEGINCODE\n"
"\n"
- "BEGINPROC LazyLoading\n"
+ "LazyLoading:\n"
" mov xCX, [g_hMod xWrtRIP]\n"
" or xCX, xCX\n"
" jnz .return\n"
"\n"
"%%ifdef ASM_CALL64_GCC\n"
- " xor rcx, rcx ; pErrInfo (local load)\n"
+ " xor rcx, rcx ; pErrInfo\n"
" xor rdx, rdx ; fFlags (local load)\n"
" lea rsi, [g_hMod wrt rip] ; phLdrMod\n"
- " lea rdi, [.szLib wrt rip] ; pszFilename\n"
+ " lea rdi, [g_szLibrary wrt rip] ; pszFilename\n"
" sub rsp, 08h\n"
" call IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
" add rsp, 08h\n"
"\n"
"%%elifdef ASM_CALL64_MSC\n"
- " xor r9, r9 ; pErrInfo (local load)\n"
+ " xor r9, r9 ; pErrInfo\n"
" xor r8, r8 ; fFlags (local load)\n"
" lea rdx, [g_hMod wrt rip] ; phLdrMod\n"
- " lea rcx, [.szLib wrt rip] ; pszFilename\n"
+ " lea rcx, [g_szLibrary wrt rip] ; pszFilename\n"
" sub rsp, 28h\n"
" call IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
" add rsp, 28h\n"
"\n"
"%%elifdef RT_ARCH_X86\n"
- " sub rsp, 0ch\n"
+ " sub xSP, 0ch\n"
" push 0 ; pErrInfo\n"
" push 0 ; fFlags (local load)\n"
" push g_hMod ; phLdrMod\n"
- " push .szLib ; pszFilename\n"
+ " push g_szLibrary ; pszFilename\n"
" call IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
" add esp, 1ch\n"
"%%else\n"
@@ -406,18 +486,18 @@ static RTEXITCODE generateOutputInner(FILE *pOutput)
" mov xCX, [g_hMod xWrtRIP]\n"
".return:\n"
" ret\n"
- ".szLib db '%s',0\n"
- "ENDPROC LazyLoading\n"
- , g_pszLibrary);
+ "LazyLoading_End:\n"
+ "\n"
+ "\n");
fprintf(pOutput,
- "\n"
";\n"
";RTDECL(int) RTLdrGetSymbol(RTLDRMOD hLdrMod, const char *pszSymbol, void **ppvValue);\n"
";\n"
- "extern IMPNAME(RTLdrGetSymbol)\n"
- "BEGINPROC LazyLoadResolver\n"
+ "EXTERN_IMP2 RTLdrGetSymbol\n"
+ "BEGINCODE\n"
+ "LazyLoadResolver:\n"
"%%ifdef RT_ARCH_AMD64\n"
" push rbp\n"
" mov rbp, rsp\n"
@@ -440,7 +520,7 @@ static RTEXITCODE generateOutputInner(FILE *pOutput)
" %%endif\n"
" and rsp, 0fffffff0h ; Try make sure the stack is aligned\n"
"\n"
- " call NAME(LazyLoading) ; returns handle in rcx\n"
+ " call LazyLoading ; returns handle in rcx\n"
" %%ifdef ASM_CALL64_GCC\n"
" mov rdi, rcx ; hLdrMod\n"
" mov rsi, r15 ; pszSymbol\n"
@@ -451,8 +531,8 @@ static RTEXITCODE generateOutputInner(FILE *pOutput)
" %%endif\n"
" call IMP2(RTLdrGetSymbol)\n"
" or eax, eax\n"
- ".badsym:\n"
" jz .symok\n"
+ ".badsym:\n"
" int3\n"
" jmp .badsym\n"
".symok:\n"
@@ -484,12 +564,12 @@ static RTEXITCODE generateOutputInner(FILE *pOutput)
" push eax\n"
" mov edx, [ebp + 8] ; symbol name\n"
" push edx\n"
- " call NAME(LazyLoading) ; returns handle in ecx\n"
+ " call LazyLoading ; returns handle in ecx\n"
" mov ecx, [g_hMod]\n"
" call IMP2(RTLdrGetSymbol)\n"
" or eax, eax\n"
- ".badsym:\n"
" jz .symok\n"
+ ".badsym:\n"
" int3\n"
" jmp .badsym\n"
".symok:\n"
@@ -502,9 +582,176 @@ static RTEXITCODE generateOutputInner(FILE *pOutput)
" %%error \"Unsupported architecture\"\n"
"%%endif\n"
" ret\n"
- "ENDPROC LazyLoadResolver\n"
+ "LazyLoadResolver_End:\n"
+ "\n"
+ "\n"
);
+
+
+ /*
+ * C callable method for explicitly loading the library and optionally
+ * resolving all the imports.
+ */
+ if (g_fWithExplictLoadFunction)
+ {
+ int cchLibBaseName = (int)(strchr(g_pszLibrary, '.') ? strchr(g_pszLibrary, '.') - g_pszLibrary : strlen(g_pszLibrary));
+ fprintf(pOutput,
+ ";;\n"
+ "; ExplicitlyLoad%.*s(bool fResolveAllImports, pErrInfo);\n"
+ ";\n"
+ "EXTERN_IMP2 RTErrInfoSet\n"
+ "BEGINCODE\n"
+ "BEGINPROC ExplicitlyLoad%.*s\n"
+ " push xBP\n"
+ " mov xBP, xSP\n"
+ " push xBX\n"
+ "%%ifdef ASM_CALL64_GCC\n"
+ " %%define pszCurStr r14\n"
+ " push r14\n"
+ "%%else\n"
+ " %%define pszCurStr xDI\n"
+ " push xDI\n"
+ "%%endif\n"
+ " sub xSP, 40h\n"
+ "\n"
+ " ;\n"
+ " ; Save parameters on stack (64-bit only).\n"
+ " ;\n"
+ "%%ifdef ASM_CALL64_GCC\n"
+ " mov [xBP - xCB * 3], rdi ; fResolveAllImports\n"
+ " mov [xBP - xCB * 4], rsi ; pErrInfo\n"
+ "%%elifdef ASM_CALL64_MSC\n"
+ " mov [xBP - xCB * 3], rcx ; fResolveAllImports\n"
+ " mov [xBP - xCB * 4], rdx ; pErrInfo\n"
+ "%%endif\n"
+ "\n"
+ " ;\n"
+ " ; Is the module already loaded?\n"
+ " ;\n"
+ " cmp RTCCPTR_PRE [g_hMod xWrtRIP], 0\n"
+ " jnz .loaded\n"
+ "\n"
+ " ;\n"
+ " ; Load the module.\n"
+ " ;\n"
+ "%%ifdef ASM_CALL64_GCC\n"
+ " mov rcx, [xBP - xCB * 4] ; pErrInfo\n"
+ " xor rdx, rdx ; fFlags (local load)\n"
+ " lea rsi, [g_hMod wrt rip] ; phLdrMod\n"
+ " lea rdi, [g_szLibrary wrt rip] ; pszFilename\n"
+ " call IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
+ "\n"
+ "%%elifdef ASM_CALL64_MSC\n"
+ " mov r9, [xBP - xCB * 4] ; pErrInfo\n"
+ " xor r8, r8 ; fFlags (local load)\n"
+ " lea rdx, [g_hMod wrt rip] ; phLdrMod\n"
+ " lea rcx, [g_szLibrary wrt rip] ; pszFilename\n"
+ " call IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
+ "\n"
+ "%%elifdef RT_ARCH_X86\n"
+ " sub xSP, 0ch\n"
+ " push dword [xBP + 12] ; pErrInfo\n"
+ " push 0 ; fFlags (local load)\n"
+ " push g_hMod ; phLdrMod\n"
+ " push g_szLibrary ; pszFilename\n"
+ " call IMP2(SUPR3HardenedLdrLoadAppPriv)\n"
+ " add esp, 1ch\n"
+ "%%else\n"
+ " %%error \"Unsupported architecture\"\n"
+ "%%endif\n"
+ " or eax, eax\n"
+ " jnz .return\n"
+ "\n"
+ " ;\n"
+ " ; Resolve the imports too if requested to do so.\n"
+ " ;\n"
+ ".loaded:\n"
+ "%%ifdef ASM_ARCH_X86\n"
+ " cmp byte [xBP + 8], 0\n"
+ "%%else\n"
+ " cmp byte [xBP - xCB * 3], 0\n"
+ "%%endif\n"
+ " je .return\n"
+ "\n"
+ " lea pszCurStr, [g_szzNames xWrtRIP]\n"
+ " lea xBX, [g_apfnImports xWrtRIP]\n"
+ ".next_import:\n"
+ " cmp RTCCPTR_PRE [xBX], 0\n"
+ " je .return\n"
+ "%%ifdef ASM_CALL64_GCC\n"
+ " mov rdx, xBX ; ppvValue\n"
+ " mov rsi, pszCurStr ; pszSymbol\n"
+ " mov rdi, [g_hMod wrt rip] ; hLdrMod\n"
+ " call IMP2(RTLdrGetSymbol)\n"
+ "%%elifdef ASM_CALL64_MSC\n"
+ " mov r8, xBX ; ppvValue\n"
+ " mov rdx, pszCurStr ; pszSymbol\n"
+ " mov rcx, [g_hMod wrt rip] ; pszSymbol\n"
+ " call IMP2(RTLdrGetSymbol)\n"
+ "%%else\n"
+ " push xBX ; ppvValue\n"
+ " push pszCurStr ; pszSymbol\n"
+ " push RTCCPTR_PRE [g_hMod] ; hLdrMod\n"
+ " call IMP2(RTLdrGetSymbol)\n"
+ " add xSP, 0ch\n"
+ "%%endif\n"
+ " or eax, eax\n"
+ " jnz .symbol_error\n"
+ "\n"
+ " ; Advance.\n"
+ " add xBX, RTCCPTR_CB\n"
+ " xor eax, eax\n"
+ " mov xCX, 0ffffffffh\n"
+ "%%ifdef ASM_CALL64_GCC\n"
+ " mov xDI, pszCurStr\n"
+ " repne scasb\n"
+ " mov pszCurStr, xDI\n"
+ "%%else\n"
+ " repne scasb\n"
+ "%%endif\n"
+ " jmp .next_import\n"
+ "\n"
+ " ;\n"
+ " ; Error loading a symbol. Call RTErrInfoSet on pErrInfo (preserves eax).\n"
+ " ;\n"
+ ".symbol_error:\n"
+ "%%ifdef ASM_CALL64_GCC\n"
+ " mov rdx, pszCurStr ; pszMsg\n"
+ " mov esi, eax ; rc\n"
+ " mov rdi, [xBP - xCB * 4] ; pErrInfo\n"
+ " call IMP2(RTErrInfoSet)\n"
+ "%%elifdef ASM_CALL64_MSC\n"
+ " mov r8, pszCurStr ; pszMsg\n"
+ " mov edx, eax ; rc\n"
+ " mov rcx, [xBP - xCB * 4] ; pErrInfo\n"
+ " call IMP2(RTErrInfoSet)\n"
+ "%%else\n"
+ " push pszCurStr ; pszMsg\n"
+ " push eax ; pszSymbol\n"
+ " push dword [xBP + 0ch] ; pErrInfo\n"
+ " call IMP2(RTErrInfoSet)\n"
+ " add xSP, 0ch\n"
+ "%%endif\n"
+ " "
+ "\n"
+ ".return:\n"
+ " lea xSP, [xBP - xCB * 3]\n"
+ " pop pszCurStr\n"
+ " pop xBX\n"
+ " leave\n"
+ " ret\n"
+ "ENDPROC ExplicitlyLoad%.*s\n"
+ "\n"
+ "\n"
+ ,
+ cchLibBaseName, g_pszLibrary,
+ cchLibBaseName, g_pszLibrary,
+ cchLibBaseName, g_pszLibrary
+ );
+ }
+
+
return RTEXITCODE_SUCCESS;
}
@@ -542,9 +789,13 @@ static RTEXITCODE generateOutput(void)
*/
static int usage(const char *pszArgv0)
{
- printf("usage: %s --libary <loadname> --output <lazyload.asm> <input.def>\n"
+ printf("usage: %s [options] --libary <loadname> --output <lazyload.asm> <input.def>\n"
+ "\n"
+ "Options:\n"
+ " --explicit-load-function, --no-explicit-load-function\n"
+ " Whether to include the explicit load function, default is not to.\n"
"\n"
- "Copyright (C) 2013 Oracle Corporation\n"
+ "Copyright (C) 2013-2015 Oracle Corporation\n"
, pszArgv0);
return RTEXITCODE_SUCCESS;
@@ -579,6 +830,10 @@ int main(int argc, char **argv)
}
g_pszLibrary = argv[i];
}
+ else if (!strcmp(psz, "--explicit-load-function"))
+ g_fWithExplictLoadFunction = true;
+ else if (!strcmp(psz, "--no-explicit-load-function"))
+ g_fWithExplictLoadFunction = false;
/** @todo Support different load methods so this can be used on system libs and
* such if we like. */
else if ( !strcmp(psz, "--help")
@@ -589,7 +844,7 @@ int main(int argc, char **argv)
else if ( !strcmp(psz, "--version")
|| !strcmp(psz, "-V"))
{
- printf("$Revision: 87893 $\n");
+ printf("$Revision: 98182 $\n");
return RTEXITCODE_SUCCESS;
}
else
@@ -600,15 +855,15 @@ int main(int argc, char **argv)
}
else
{
- if (g_pszInput)
+ if (g_cInputs >= RT_ELEMENTS(g_apszInputs))
{
- fprintf(stderr, "syntax error: Already specified '%s' as the input file.\n", g_pszInput);
+ fprintf(stderr, "syntax error: Too many input files, max is %d.\n", (int)RT_ELEMENTS(g_apszInputs));
return RTEXITCODE_SYNTAX;
}
- g_pszInput = argv[i];
+ g_apszInputs[g_cInputs++] = argv[i];
}
}
- if (!g_pszInput)
+ if (g_cInputs == 0)
{
fprintf(stderr, "syntax error: No input file specified.\n");
return RTEXITCODE_SYNTAX;
@@ -627,7 +882,7 @@ int main(int argc, char **argv)
/*
* Do the job.
*/
- RTEXITCODE rcExit = parseInput();
+ RTEXITCODE rcExit = parseInputs();
if (rcExit == RTEXITCODE_SUCCESS)
rcExit = generateOutput();
return rcExit;
diff --git a/src/libs/Makefile.kmk b/src/libs/Makefile.kmk
index 316d7f7..a048ced 100644
--- a/src/libs/Makefile.kmk
+++ b/src/libs/Makefile.kmk
@@ -52,7 +52,7 @@ endif
if !defined(VBOX_ONLY_SDK) \
&& ( "$(SDK_VBOX_OPENSSL_INCS)" == "$(SDK_VBOX_OPENSSL_VBOX_DEFAULT_INCS)" \
|| defined(VBOX_WITH_EXTPACK_PUEL_BUILD))
- include $(PATH_SUB_CURRENT)/openssl-1.0.1j/Makefile.kmk
+ include $(PATH_SUB_CURRENT)/openssl-1.0.1k/Makefile.kmk
endif
# libjpeg for VRDP video redirection
diff --git a/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp b/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
index 9212273..051f9c7 100644
--- a/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
+++ b/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
@@ -1143,10 +1143,6 @@ IPC_WaitMessage(PRUint32 aSenderID,
if (NS_FAILED(rv))
return rv;
- // if the requested sender has died while waiting, return an error
- if (data.senderDead)
- return NS_ERROR_ABORT; // XXX better error code?
-
// if the selector has accepted some message, then we pass it to aConsumer
// for safe processing. The IPC susbsystem is quite stable here (i.e. we're
// not inside any of the monitors, and the message has been already removed
@@ -1161,6 +1157,10 @@ IPC_WaitMessage(PRUint32 aSenderID,
delete msg;
+ // if the requested sender has died while waiting, return an error
+ if (data.senderDead)
+ return NS_ERROR_ABORT; // XXX better error code?
+
return NS_OK;
}
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
index d654047..db36313 100644
--- a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp
@@ -3553,7 +3553,7 @@ ipcDConnectService::OnMessageAvailable(PRUint32 aSenderID,
PR_Sleep(PR_INTERVAL_NO_WAIT);
mon.Enter();
// examine the queue
- if (!mPendingQ.IsEmpty() && !mWaitingWorkers)
+ if (mPendingQ.Count() > mWaitingWorkers)
{
// wait a little while to let the workers empty the queue.
mon.Exit();
@@ -3564,7 +3564,7 @@ ipcDConnectService::OnMessageAvailable(PRUint32 aSenderID,
}
mon.Enter();
// examine the queue again
- if (!mPendingQ.IsEmpty() && !mWaitingWorkers)
+ if (mPendingQ.Count() > mWaitingWorkers)
{
// we need one more worker
nsresult rv = CreateWorker();
diff --git a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h
index ebf3d09..a9b9c95 100644
--- a/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h
+++ b/src/libs/xpcom18a4/ipc/ipcd/shared/src/ipcList.h
@@ -174,6 +174,19 @@ public:
mTail = NULL;
}
+ // gets count of list elements
+ PRUint32 Count()
+ {
+ T *obj = mHead;
+ PRUint32 count = 0;
+ while (obj) {
+ count++;
+ obj = obj->mNext;
+ }
+
+ return count;
+ }
+
protected:
void AdvanceHead()
{
diff --git a/src/libs/xpcom18a4/nsprpub/Makefile.in b/src/libs/xpcom18a4/nsprpub/Makefile.in
old mode 100755
new mode 100644
diff --git a/src/libs/xpcom18a4/nsprpub/config/config.mk b/src/libs/xpcom18a4/nsprpub/config/config.mk
old mode 100755
new mode 100644
diff --git a/src/libs/xpcom18a4/nsprpub/config/rules.mk b/src/libs/xpcom18a4/nsprpub/config/rules.mk
old mode 100755
new mode 100644
diff --git a/src/libs/xpcom18a4/python/client/__init__.py b/src/libs/xpcom18a4/python/client/__init__.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/file.py b/src/libs/xpcom18a4/python/file.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/primitives.py b/src/libs/xpcom18a4/python/primitives.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/__init__.py b/src/libs/xpcom18a4/python/server/__init__.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/enumerator.py b/src/libs/xpcom18a4/python/server/enumerator.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/factory.py b/src/libs/xpcom18a4/python/server/factory.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/loader.py b/src/libs/xpcom18a4/python/server/loader.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/module.py b/src/libs/xpcom18a4/python/server/module.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/server/policy.py b/src/libs/xpcom18a4/python/server/policy.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py b/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_com_exceptions.py b/src/libs/xpcom18a4/python/test/test_com_exceptions.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_comfile.py b/src/libs/xpcom18a4/python/test/test_comfile.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_component/py_test_component.py b/src/libs/xpcom18a4/python/test/test_component/py_test_component.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_components.py b/src/libs/xpcom18a4/python/test/test_components.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_isupports_primitives.py b/src/libs/xpcom18a4/python/test/test_isupports_primitives.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_misc.py b/src/libs/xpcom18a4/python/test/test_misc.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_streams.py b/src/libs/xpcom18a4/python/test/test_streams.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_test_component.py b/src/libs/xpcom18a4/python/test/test_test_component.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/test/test_weakreferences.py b/src/libs/xpcom18a4/python/test/test_weakreferences.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/tools/regxpcom.py b/src/libs/xpcom18a4/python/tools/regxpcom.py
old mode 100644
new mode 100755
diff --git a/src/libs/xpcom18a4/python/xpt.py b/src/libs/xpcom18a4/python/xpt.py
old mode 100644
new mode 100755
diff --git a/src/recompiler/Makefile.kmk b/src/recompiler/Makefile.kmk
index fa6ec1a..b5c809a 100644
--- a/src/recompiler/Makefile.kmk
+++ b/src/recompiler/Makefile.kmk
@@ -117,6 +117,7 @@ VBoxRemPrimary_SOURCES = \
target-i386/translate.c
VBoxRemPrimary_SOURCES.debug += \
Sun/testmath.c
+VBoxRemPrimary_SOURCES.win = $(VBoxREMImp_0_OUTDIR)/VBoxREMRes.o
VBoxRemPrimary_SOURCES.win.x86 = $(VBoxREMImp_0_OUTDIR)/VBoxREMWin.def
ifdef VBOX_USE_MINGWW64
if 0 # exporting all helps when windbg pops up on crashes
@@ -248,6 +249,7 @@ ifdef VBOX_REM_WRAPPER
endif
VBoxREMWrapper_SOURCES = \
VBoxREMWrapper.cpp
+ VBoxREMWrapper_SOURCES.win = VBoxREM.rc
if "$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)" == "win.amd64" && !defined(VBOX_USE_MINGWW64)
VBoxREMWrapper_SOURCES += \
VBoxREMWrapperA.asm
@@ -316,6 +318,14 @@ $$(VBoxREMImp_0_OUTDIR)/VBoxREMOS2.def: $(VBOX_PATH_RECOMPILER_SRC)/VBoxREM.def
$$(VBoxREMImp_0_OUTDIR)/VBoxREMWin.def: $(VBOX_PATH_RECOMPILER_SRC)/VBoxREM.def $(MAKEFILE_CURRENT) | $$(dir $$@)
$(CP) -f $< $@
+$$(VBoxREMImp_0_OUTDIR)/VBoxREMRes.o: $(VBOX_PATH_RECOMPILER_SRC)/VBoxREM.rc $(MAKEFILE_CURRENT) | $$(dir $$@)
+ $(call MSG_GENERATE,,$@)
+ $(QUIET)$(REDIRECT) -E 'COMSPEC=$(VBOX_GOOD_COMSPEC_BS)' -- $(TOOL_MINGWW64_PREFIX)windres \
+ $(addprefix -I,$(INCS) $(PATH_SDK_$(VBOX_WINPSDK)_INC) $(PATH_TOOL_$(VBOX_VCC_TOOL)_INC)) \
+ -DVBOX_VERSION_MAJOR_NR=$(VBOX_VERSION_MAJOR) \
+ -DVBOX_VERSION_MINOR_NR=$(VBOX_VERSION_MINOR) \
+ -DVBOX_VERSION_BUILD_NR=$(VBOX_VERSION_BUILD) \
+ -DVBOX_SVN_REV_NR=$(VBOX_SVN_REV) $< $@
#
# The math testcase as a standalone program for testing and debugging purposes.
diff --git a/src/recompiler/VBoxREM.rc b/src/recompiler/VBoxREM.rc
new file mode 100644
index 0000000..f91aa68
--- /dev/null
+++ b/src/recompiler/VBoxREM.rc
@@ -0,0 +1,54 @@
+/* $Id: VBoxREM.rc $ */
+/** @file
+ * VBoxREM - Resource file containing version info.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+/* stupid windres! */
+#define RT_STR(x) #x
+#define RT_XSTR(x) RT_STR(x)
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ PRODUCTVERSION VBOX_VERSION_MAJOR_NR,VBOX_VERSION_MINOR_NR,VBOX_VERSION_BUILD_NR,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0x0L
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileDescription", "VirtualBox Recompiler\0"
+ VALUE "FileVersion", RT_XSTR(VBOX_VERSION_MAJOR_NR) "." RT_XSTR(VBOX_VERSION_MINOR_NR) "." RT_XSTR(VBOX_VERSION_BUILD_NR) "." RT_XSTR(VBOX_SVN_REV_NR) "\0"
+ VALUE "InternalName", "VBoxREM\0"
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "OriginalFilename", "VBoxREM.dll\0"
+ VALUE "ProductName", VBOX_PRODUCT "\0"
+ VALUE "ProductVersion", RT_XSTR(VBOX_VERSION_MAJOR_NR) "." RT_XSTR(VBOX_VERSION_MINOR_NR) "." RT_XSTR(VBOX_VERSION_BUILD_NR) ".r" RT_XSTR(VBOX_SVN_REV_NR) "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-virtualbox/virtualbox.git
More information about the Pkg-virtualbox-commits
mailing list