summaryrefslogtreecommitdiff
path: root/src/VBox
diff options
context:
space:
mode:
authorFelix Geyer <debfx-pkg@fobos.de>2012-03-14 12:03:25 +0100
committerFelix Geyer <debfx-pkg@fobos.de>2012-03-14 12:03:25 +0100
commit6718f4631b859139b072de5a0406d781d60f9084 (patch)
tree4cb1b24186b5a02cbb0737a710a784e8ae2d04d2 /src/VBox
parentfe1df57ef1efe45f85243a527a295b5fd2e4e778 (diff)
downloadvirtualbox-6718f4631b859139b072de5a0406d781d60f9084.tar.gz
Imported Upstream version 4.1.10-dfsgupstream/4.1.10-dfsg
Diffstat (limited to 'src/VBox')
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp48
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp168
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h3
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp14
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk3
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/SysHlp.h4
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c4
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h2
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAutoLogon.cpp149
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp82
-rw-r--r--src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp61
-rw-r--r--src/VBox/Additions/common/VBoxService/Makefile.kmk8
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxService-win.cpp85
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxService.cpp342
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp3
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp3
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp5
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp861
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp1444
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp601
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h39
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp1709
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp3
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h267
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp27
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp542
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h42
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp3
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp30
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp469
-rw-r--r--src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp68
-rw-r--r--src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp42
-rw-r--r--src/VBox/Additions/common/crOpenGL/icd_drv.c22
-rw-r--r--src/VBox/Additions/common/crOpenGL/load.c8
-rw-r--r--src/VBox/Additions/common/crOpenGL/wgl.c129
-rw-r--r--src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py15
-rw-r--r--src/VBox/Additions/linux/Makefile.kmk5
-rw-r--r--src/VBox/Additions/linux/drm/vboxvideo_drm.c25
-rwxr-xr-xsrc/VBox/Additions/linux/installer/vboxadd-x11.sh7
-rwxr-xr-xsrc/VBox/Additions/linux/installer/vboxadd.sh11
-rw-r--r--src/VBox/Additions/linux/sharedfolders/dirops.c16
-rw-r--r--src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c4
-rw-r--r--src/VBox/Additions/linux/sharedfolders/regops.c10
-rw-r--r--src/VBox/Additions/linux/sharedfolders/vfsmod.c2
-rwxr-xr-xsrc/VBox/Additions/solaris/Installer/postinstall.sh5
-rwxr-xr-xsrc/VBox/Additions/solaris/Installer/preremove.sh7
-rwxr-xr-xsrc/VBox/Additions/solaris/Installer/vboxguest.sh23
-rw-r--r--src/VBox/Additions/solaris/Makefile.kmk3
-rw-r--r--src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c4
-rw-r--r--src/VBox/Additions/x11/vboxmouse/undefined_152
-rw-r--r--src/VBox/Additions/x11/vboxmouse/undefined_702
-rw-r--r--src/VBox/Additions/x11/vboxmouse/undefined_712
-rw-r--r--src/VBox/Additions/x11/vboxvideo/Makefile.kmk35
-rw-r--r--src/VBox/Additions/x11/vboxvideo/undefined3
-rw-r--r--src/VBox/Additions/x11/vboxvideo/vboxvideo.c2
-rw-r--r--src/VBox/Debugger/DBGCCommands.cpp12
-rw-r--r--src/VBox/Debugger/DBGCEmulateCodeView.cpp58
-rw-r--r--src/VBox/Debugger/VBoxDbgStatsQt4.cpp39
-rw-r--r--src/VBox/Devices/Audio/noaudio.c9
-rw-r--r--src/VBox/Devices/Bus/DevPCI.cpp2
-rw-r--r--src/VBox/Devices/Bus/DevPciIch9.cpp2
-rw-r--r--src/VBox/Devices/Graphics/DevVGA_VBVA.cpp33
-rw-r--r--src/VBox/Devices/Input/DrvKeyboardQueue.cpp2
-rw-r--r--src/VBox/Devices/Input/DrvMouseQueue.cpp2
-rw-r--r--src/VBox/Devices/Input/UsbKbd.cpp17
-rw-r--r--src/VBox/Devices/Input/UsbMouse.cpp2
-rw-r--r--src/VBox/Devices/Makefile.kmk7
-rw-r--r--src/VBox/Devices/Network/DevE1000.cpp2
-rw-r--r--src/VBox/Devices/Network/DrvDedicatedNic.cpp2
-rw-r--r--src/VBox/Devices/Network/DrvIntNet.cpp2
-rw-r--r--src/VBox/Devices/Network/DrvNAT.cpp64
-rw-r--r--src/VBox/Devices/Network/DrvTAP.cpp2
-rw-r--r--src/VBox/Devices/Network/DrvUDPTunnel.cpp2
-rw-r--r--src/VBox/Devices/Network/DrvVDE.cpp2
-rw-r--r--src/VBox/Devices/Network/slirp/libalias/alias_dns.c181
-rw-r--r--src/VBox/Devices/Network/slirp/libslirp.h4
-rw-r--r--src/VBox/Devices/Network/slirp/slirp.c48
-rw-r--r--src/VBox/Devices/Network/slirp/slirp_state.h19
-rw-r--r--src/VBox/Devices/PC/DevACPI.cpp2
-rw-r--r--src/VBox/Devices/PC/DevPIC.cpp8
-rw-r--r--src/VBox/Devices/PC/DrvACPI.cpp2
-rw-r--r--src/VBox/Devices/PC/DrvAcpiCpu.cpp2
-rw-r--r--src/VBox/Devices/Parallel/DrvHostParallel.cpp2
-rw-r--r--src/VBox/Devices/Serial/DrvChar.cpp2
-rw-r--r--src/VBox/Devices/Serial/DrvHostSerial.cpp12
-rw-r--r--src/VBox/Devices/Serial/DrvNamedPipe.cpp2
-rw-r--r--src/VBox/Devices/Serial/DrvRawFile.cpp2
-rw-r--r--src/VBox/Devices/Storage/DevAHCI.cpp2
-rw-r--r--src/VBox/Devices/Storage/DevBusLogic.cpp2
-rw-r--r--src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp4
-rw-r--r--src/VBox/Devices/Storage/DrvBlock.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvDiskIntegrity.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvHostDVD.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvHostFloppy.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvMediaISO.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvRawImage.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvSCSI.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvSCSIHost.cpp2
-rw-r--r--src/VBox/Devices/Storage/DrvVD.cpp2
-rw-r--r--src/VBox/Devices/Storage/UsbMsd.cpp2
-rw-r--r--src/VBox/Devices/USB/DevOHCI.cpp2
-rw-r--r--src/VBox/Devices/USB/DrvVUSBRootHub.cpp2
-rw-r--r--src/VBox/Devices/USB/USBProxyDevice.cpp2
-rw-r--r--src/VBox/Devices/VMMDev/VMMDev.cpp681
-rw-r--r--src/VBox/Devices/VMMDev/VMMDevState.h38
-rw-r--r--src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h64
-rw-r--r--src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp2
-rw-r--r--src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp2
-rw-r--r--src/VBox/Frontends/VBoxBFE/StatusImpl.cpp2
-rw-r--r--src/VBox/Frontends/VBoxBFE/VMMDev.h3
-rw-r--r--src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp49
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp485
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp12
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp2
-rw-r--r--src/VBox/Frontends/VBoxSDL/Framebuffer.cpp6
-rw-r--r--src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp14
-rwxr-xr-xsrc/VBox/Frontends/VBoxShell/vboxshell.py17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts4
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_en.ts14
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts436
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts373
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts17
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts15
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxFBOverlayCommon.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp16
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h16
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp19
-rw-r--r--src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp30
-rw-r--r--src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp5
-rw-r--r--src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp8
-rw-r--r--src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp16
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.h2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp8
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp10
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp6
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp10
-rw-r--r--src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp4
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp2
-rw-r--r--src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp12
-rw-r--r--src/VBox/GuestHost/OpenGL/include/GL/glext.h9
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_error.h17
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_extstring.h5
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_glstate.h3
-rw-r--r--src/VBox/GuestHost/OpenGL/include/cr_version.h1
-rw-r--r--src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h4
-rw-r--r--src/VBox/GuestHost/OpenGL/include/state/cr_limits.h1
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c23
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c64
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_limits.c3
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c84
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c38
-rw-r--r--src/VBox/GuestHost/OpenGL/util/error.c24
-rw-r--r--src/VBox/GuestHost/OpenGL/util/net.c1
-rw-r--r--src/VBox/GuestHost/OpenGL/util/threads.c7
-rw-r--r--src/VBox/HostDrivers/Support/Makefile.kmk8
-rw-r--r--src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp2
-rw-r--r--src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c2
-rw-r--r--src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp6
-rw-r--r--src/VBox/HostServices/GuestControl/service.cpp246
-rw-r--r--src/VBox/HostServices/GuestProperties/service.cpp2
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c11
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c4
-rw-r--r--src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c42
-rw-r--r--src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py8
-rw-r--r--src/VBox/Installer/darwin/Makefile.kmk4
-rw-r--r--src/VBox/Installer/linux/Makefile.include.footer2
-rw-r--r--src/VBox/Installer/linux/Makefile.include.header3
-rw-r--r--src/VBox/Installer/linux/Makefile.kmk10
-rw-r--r--src/VBox/Installer/linux/distributions_deb2
-rw-r--r--src/VBox/Installer/linux/distributions_rpm2
-rwxr-xr-xsrc/VBox/Installer/linux/install.sh4
-rw-r--r--src/VBox/Installer/linux/rpm/LocalConfig.kmk3
-rw-r--r--src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec1
-rwxr-xr-xsrc/VBox/Installer/linux/rpm/rules10
-rwxr-xr-xsrc/VBox/Installer/linux/run-inst.sh27
-rwxr-xr-xsrc/VBox/Installer/linux/vboxweb-service.sh.in9
-rwxr-xr-xsrc/VBox/Installer/solaris/checkinstall.sh7
-rwxr-xr-xsrc/VBox/Installer/solaris/smf-vboxwebsrv.sh35
-rwxr-xr-xsrc/VBox/Installer/solaris/vboxconfig.sh14
-rw-r--r--src/VBox/Installer/solaris/virtualbox-webservice.xml3
-rw-r--r--src/VBox/Installer/win/Languages/de_DE.wxl12
-rw-r--r--src/VBox/Installer/win/Languages/en_US.wxl12
-rw-r--r--src/VBox/Installer/win/Languages/fr_FR.wxl12
-rw-r--r--src/VBox/Main/cbinding/Makefile.kmk22
-rw-r--r--src/VBox/Main/cbinding/VBoxCAPI_v2_2.h4
-rw-r--r--src/VBox/Main/cbinding/VBoxCAPI_v3_0.h4
-rw-r--r--src/VBox/Main/cbinding/VBoxCAPI_v3_1.h4
-rw-r--r--src/VBox/Main/cbinding/VBoxCAPI_v3_2.h5613
-rw-r--r--src/VBox/Main/cbinding/VBoxCAPI_v4_0.h7445
-rw-r--r--src/VBox/Main/cbinding/VBoxXPCOMC.cpp2
-rw-r--r--src/VBox/Main/cbinding/VBoxXPCOMCGlue.h6
-rw-r--r--src/VBox/Main/cbinding/xpcidl.xsl6
-rw-r--r--src/VBox/Main/glue/com.cpp2
-rw-r--r--src/VBox/Main/glue/glue-java.xsl32
-rw-r--r--src/VBox/Main/idl/VirtualBox.xidl113
-rw-r--r--src/VBox/Main/include/AdditionsFacilityImpl.h35
-rw-r--r--src/VBox/Main/include/ConsoleImpl.h14
-rw-r--r--src/VBox/Main/include/ExtPackManagerImpl.h2
-rw-r--r--src/VBox/Main/include/ExtPackUtil.h8
-rw-r--r--src/VBox/Main/include/GuestCtrlImplPrivate.h30
-rw-r--r--src/VBox/Main/include/GuestImpl.h47
-rw-r--r--src/VBox/Main/include/MachineImpl.h7
-rw-r--r--src/VBox/Main/include/Performance.h170
-rw-r--r--src/VBox/Main/include/PerformanceImpl.h3
-rw-r--r--src/VBox/Main/include/SessionImpl.h1
-rw-r--r--src/VBox/Main/src-all/ExtPackManagerImpl.cpp44
-rw-r--r--src/VBox/Main/src-all/ExtPackUtil.cpp161
-rw-r--r--src/VBox/Main/src-all/Global.cpp18
-rw-r--r--src/VBox/Main/src-client/AdditionsFacilityImpl.cpp59
-rw-r--r--src/VBox/Main/src-client/AudioSnifferInterface.cpp2
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl.cpp17
-rw-r--r--src/VBox/Main/src-client/ConsoleImpl2.cpp40
-rw-r--r--src/VBox/Main/src-client/DisplayImpl.cpp2
-rw-r--r--src/VBox/Main/src-client/GuestCtrlIO.cpp52
-rw-r--r--src/VBox/Main/src-client/GuestCtrlImpl.cpp914
-rw-r--r--src/VBox/Main/src-client/GuestCtrlImplDir.cpp105
-rw-r--r--src/VBox/Main/src-client/GuestCtrlImplFile.cpp56
-rw-r--r--src/VBox/Main/src-client/GuestCtrlImplTasks.cpp294
-rw-r--r--src/VBox/Main/src-client/GuestDirEntryImpl.cpp12
-rw-r--r--src/VBox/Main/src-client/GuestImpl.cpp483
-rw-r--r--src/VBox/Main/src-client/KeyboardImpl.cpp2
-rw-r--r--src/VBox/Main/src-client/MouseImpl.cpp2
-rw-r--r--src/VBox/Main/src-client/PciRawDevImpl.cpp2
-rw-r--r--src/VBox/Main/src-client/SessionImpl.cpp9
-rw-r--r--src/VBox/Main/src-client/VMMDevInterface.cpp79
-rw-r--r--src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp52
-rw-r--r--src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp12
-rw-r--r--src/VBox/Main/src-server/MachineImpl.cpp30
-rw-r--r--src/VBox/Main/src-server/MachineImplCloneVM.cpp2
-rw-r--r--src/VBox/Main/src-server/MediumImpl.cpp46
-rw-r--r--src/VBox/Main/src-server/Performance.cpp465
-rw-r--r--src/VBox/Main/src-server/PerformanceImpl.cpp44
-rw-r--r--src/VBox/Main/src-server/VirtualBoxImpl.cpp12
-rw-r--r--src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp100
-rw-r--r--src/VBox/Main/webservice/Makefile.kmk33
-rw-r--r--src/VBox/Main/webservice/samples/php/clienttest.php32
-rwxr-xr-xsrc/VBox/Main/webservice/samples/python/clienttest.py101
-rw-r--r--src/VBox/Main/webservice/vboxweb.cpp302
-rw-r--r--src/VBox/Main/webservice/vboxweb.h2
-rw-r--r--src/VBox/Main/webservice/webtest.cpp204
-rw-r--r--src/VBox/RDP/client/Makefile.kmk4
-rw-r--r--src/VBox/Runtime/Makefile.kmk9
-rw-r--r--src/VBox/Runtime/VBox/VBoxRTDeps.cpp11
-rw-r--r--src/VBox/Runtime/VBox/VBoxRTImp.def1
-rw-r--r--src/VBox/Runtime/common/checksum/manifest2.cpp138
-rw-r--r--src/VBox/Runtime/common/checksum/manifest3.cpp1
-rw-r--r--src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h2
-rw-r--r--src/VBox/Runtime/common/misc/s3.cpp2
-rw-r--r--src/VBox/Runtime/common/string/base64.cpp6
-rw-r--r--src/VBox/Runtime/common/string/ministring.cpp33
-rw-r--r--src/VBox/Runtime/common/string/strhash1.cpp (renamed from src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp)46
-rw-r--r--src/VBox/Runtime/common/string/strtonum.cpp38
-rw-r--r--src/VBox/Runtime/common/table/avl_RemoveNode.cpp.h144
-rw-r--r--src/VBox/Runtime/common/table/avllu32.cpp1
-rw-r--r--src/VBox/Runtime/generic/timerlr-generic.cpp18
-rw-r--r--src/VBox/Runtime/include/internal/strhash.h15
-rw-r--r--src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c142
-rw-r--r--src/VBox/Runtime/r0drv/linux/the-linux-kernel.h3
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files235
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files.patch19
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared316
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared.patch20
-rw-r--r--src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c5
-rw-r--r--src/VBox/Runtime/r3/os2/pipe-os2.cpp6
-rw-r--r--src/VBox/Runtime/r3/posix/pipe-posix.cpp30
-rw-r--r--src/VBox/Runtime/r3/win/VBoxRT-openssl.def6
-rw-r--r--src/VBox/Runtime/r3/win/pipe-win.cpp23
-rw-r--r--src/VBox/Runtime/r3/win/process-win.cpp17
-rw-r--r--src/VBox/Runtime/r3/xml.cpp4
-rw-r--r--src/VBox/Runtime/testcase/tstLdr.cpp46
-rw-r--r--src/VBox/Runtime/testcase/tstRTBase64.cpp34
-rw-r--r--src/VBox/Runtime/testcase/tstRTPipe.cpp20
-rw-r--r--src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp2
-rw-r--r--src/VBox/Runtime/testcase/tstTimerLR.cpp82
-rw-r--r--src/VBox/Storage/ISCSI.cpp14
-rw-r--r--src/VBox/Storage/VD.cpp22
-rw-r--r--src/VBox/Storage/VDI.cpp4
-rw-r--r--src/VBox/Storage/VHD.cpp2
-rw-r--r--src/VBox/VMM/VMMAll/IOMAllMMIO.cpp10
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllBth.h2
-rw-r--r--src/VBox/VMM/VMMAll/PGMAllPhys.cpp4
-rw-r--r--src/VBox/VMM/VMMR0/CPUMR0.cpp2
-rw-r--r--src/VBox/VMM/VMMR0/GMMR0.cpp1381
-rw-r--r--src/VBox/VMM/VMMR0/GMMR0Internal.h80
-rw-r--r--src/VBox/VMM/VMMR0/HWVMXR0.cpp12
-rw-r--r--src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp141
-rw-r--r--src/VBox/VMM/VMMR0/VMMR0.cpp14
-rw-r--r--src/VBox/VMM/VMMR3/CFGM.cpp275
-rw-r--r--src/VBox/VMM/VMMR3/CPUM.cpp2
-rw-r--r--src/VBox/VMM/VMMR3/PATMA.asm68
-rw-r--r--src/VBox/VMM/VMMR3/PDM.cpp23
-rw-r--r--src/VBox/VMM/VMMR3/PDMDevice.cpp5
-rw-r--r--src/VBox/VMM/VMMR3/PDMDriver.cpp263
-rw-r--r--src/VBox/VMM/VMMR3/PDMUsb.cpp5
-rw-r--r--src/VBox/VMM/VMMR3/PGM.cpp4
-rw-r--r--src/VBox/VMM/VMMR3/PGMPhys.cpp8
-rw-r--r--src/VBox/VMM/VMMR3/PGMPool.cpp19
-rw-r--r--src/VBox/VMM/VMMR3/PGMSharedPage.cpp272
-rw-r--r--src/VBox/VMM/VMMR3/STAM.cpp135
-rw-r--r--src/VBox/VMM/VMMR3/VM.cpp5
-rw-r--r--src/VBox/VMM/include/PATMA.h2
-rw-r--r--src/VBox/VMM/include/PDMInternal.h3
-rw-r--r--src/VBox/VMM/include/PGMInternal.h38
-rw-r--r--src/VBox/VMM/include/STAMInternal.h10
-rw-r--r--src/VBox/VMM/include/VMInternal.h19
-rw-r--r--src/VBox/VMM/testcase/tstAnimate.cpp6
-rw-r--r--src/VBox/VMM/testcase/tstCompressionBenchmark.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp1
-rw-r--r--src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp1
-rw-r--r--src/VBox/VMM/testcase/tstVMM-HwAccm.cpp4
-rw-r--r--src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp2
-rw-r--r--src/VBox/VMM/testcase/tstVMREQ.cpp6
-rw-r--r--src/VBox/VMM/testcase/tstX86-1.cpp1
351 files changed, 26145 insertions, 7281 deletions
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
index 9e811cae1..6c2616805 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
@@ -44,6 +44,7 @@ static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vboxguestwinRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue);
static NTSTATUS vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp);
static NTSTATUS vboxguestwinNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
@@ -490,6 +491,16 @@ NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICO
if (RT_SUCCESS(rc))
{
+ ULONG ulValue = 0;
+ NTSTATUS s = vboxguestwinRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled",
+ &ulValue);
+ if (NT_SUCCESS(s))
+ {
+ pDevExt->fLoggingEnabled = ulValue >= 0xFF;
+ if (pDevExt->fLoggingEnabled)
+ Log(("Logging to release log enabled (0x%x)", ulValue));
+ }
+
/* Ready to rumble! */
Log(("VBoxGuest::vboxguestwinInit: Device is ready!\n"));
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, WORKING);
@@ -1026,6 +1037,43 @@ void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
/**
+ * Queries (gets) a DWORD value from the registry.
+ *
+ * @return NTSTATUS
+ * @param ulRoot Relative path root. See RTL_REGISTRY_SERVICES or RTL_REGISTRY_ABSOLUTE.
+ * @param pwszPath Path inside path root.
+ * @param pwszName Actual value name to look up.
+ * @param puValue On input this can specify the default value (if RTL_REGISTRY_OPTIONAL is
+ * not specified in ulRoot), on output this will retrieve the looked up
+ * registry value if found.
+ */
+NTSTATUS vboxguestwinRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName,
+ PULONG puValue)
+{
+ if (!pwszPath || !pwszName || !puValue)
+ return STATUS_INVALID_PARAMETER;
+
+ ULONG ulDefault = *puValue;
+
+ RTL_QUERY_REGISTRY_TABLE tblQuery[2];
+ RtlZeroMemory(tblQuery, sizeof(tblQuery));
+ /** @todo Add RTL_QUERY_REGISTRY_TYPECHECK! */
+ tblQuery[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ tblQuery[0].Name = pwszName;
+ tblQuery[0].EntryContext = puValue;
+ tblQuery[0].DefaultType = REG_DWORD;
+ tblQuery[0].DefaultData = &ulDefault;
+ tblQuery[0].DefaultLength = sizeof(ULONG);
+
+ return RtlQueryRegistryValues(ulRoot,
+ pwszPath,
+ &tblQuery[0],
+ NULL /* Context */,
+ NULL /* Environment */);
+}
+
+
+/**
* Helper to scan the PCI resource list and remember stuff.
*
* @param pResList Resource list
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
index a5de085ae..32f89802d 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
@@ -709,6 +709,7 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
#endif
RTListInit(&pDevExt->WokenUpList);
RTListInit(&pDevExt->FreeList);
+ pDevExt->fLoggingEnabled = false;
pDevExt->f32PendingEvents = 0;
pDevExt->u32MousePosChangedSeq = 0;
pDevExt->SessionSpinlock = NIL_RTSPINLOCK;
@@ -1412,6 +1413,156 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
return VINF_SUCCESS;
}
+/**
+ * Checks if the VMM request is allowed in the context of the given session.
+ *
+ * @returns VINF_SUCCESS or VERR_PERMISSION_DENIED.
+ * @param pSession The calling session.
+ * @param enmType The request type.
+ * @param pReqHdr The request.
+ */
+static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
+ VMMDevRequestHeader const *pReqHdr)
+{
+ /*
+ * Categorize the request being made.
+ */
+ /** @todo This need quite some more work! */
+ enum
+ {
+ kLevel_Invalid, kLevel_NoOne, kLevel_OnlyVBoxGuest, kLevel_OnlyKernel, kLevel_TrustedUsers, kLevel_AllUsers
+ } enmRequired;
+ switch (enmType)
+ {
+ /*
+ * Deny access to anything we don't know or provide specialized I/O controls for.
+ */
+#ifdef VBOX_WITH_HGCM
+ case VMMDevReq_HGCMConnect:
+ case VMMDevReq_HGCMDisconnect:
+# ifdef VBOX_WITH_64_BITS_GUESTS
+ case VMMDevReq_HGCMCall32:
+ case VMMDevReq_HGCMCall64:
+# else
+ case VMMDevReq_HGCMCall:
+# endif /* VBOX_WITH_64_BITS_GUESTS */
+ case VMMDevReq_HGCMCancel:
+ case VMMDevReq_HGCMCancel2:
+#endif /* VBOX_WITH_HGCM */
+ default:
+ enmRequired = kLevel_NoOne;
+ break;
+
+ /*
+ * There are a few things only this driver can do (and it doesn't use
+ * the VMMRequst I/O control route anyway, but whatever).
+ */
+ case VMMDevReq_ReportGuestInfo:
+ case VMMDevReq_ReportGuestInfo2:
+ case VMMDevReq_GetHypervisorInfo:
+ case VMMDevReq_SetHypervisorInfo:
+ case VMMDevReq_RegisterPatchMemory:
+ case VMMDevReq_DeregisterPatchMemory:
+ case VMMDevReq_GetMemBalloonChangeRequest:
+ enmRequired = kLevel_OnlyVBoxGuest;
+ break;
+
+ /*
+ * Trusted users apps only.
+ */
+ case VMMDevReq_QueryCredentials:
+ case VMMDevReq_ReportCredentialsJudgement:
+ case VMMDevReq_RegisterSharedModule:
+ case VMMDevReq_UnregisterSharedModule:
+ case VMMDevReq_WriteCoreDump:
+ case VMMDevReq_GetCpuHotPlugRequest:
+ case VMMDevReq_SetCpuHotPlugStatus:
+ case VMMDevReq_CheckSharedModules:
+ case VMMDevReq_GetPageSharingStatus:
+ case VMMDevReq_DebugIsPageShared:
+ case VMMDevReq_ReportGuestStats:
+ case VMMDevReq_GetStatisticsChangeRequest:
+ case VMMDevReq_ChangeMemBalloon:
+ enmRequired = kLevel_TrustedUsers;
+ break;
+
+ /*
+ * Anyone.
+ */
+ case VMMDevReq_GetMouseStatus:
+ case VMMDevReq_SetMouseStatus:
+ case VMMDevReq_SetPointerShape:
+ case VMMDevReq_GetHostVersion:
+ case VMMDevReq_Idle:
+ case VMMDevReq_GetHostTime:
+ case VMMDevReq_SetPowerStatus:
+ case VMMDevReq_AcknowledgeEvents:
+ case VMMDevReq_CtlGuestFilterMask:
+ case VMMDevReq_ReportGuestStatus:
+ case VMMDevReq_GetDisplayChangeRequest:
+ case VMMDevReq_VideoModeSupported:
+ case VMMDevReq_GetHeightReduction:
+ case VMMDevReq_GetDisplayChangeRequest2:
+ case VMMDevReq_SetGuestCapabilities:
+ case VMMDevReq_VideoModeSupported2:
+ case VMMDevReq_VideoAccelEnable:
+ case VMMDevReq_VideoAccelFlush:
+ case VMMDevReq_VideoSetVisibleRegion:
+ case VMMDevReq_GetSeamlessChangeRequest:
+ case VMMDevReq_GetVRDPChangeRequest:
+ case VMMDevReq_LogString:
+ case VMMDevReq_GetSessionId:
+ enmRequired = kLevel_AllUsers;
+ break;
+
+ /*
+ * Depends on the request parameters...
+ */
+ /** @todo this have to be changed into an I/O control and the facilities
+ * tracked in the session so they can automatically be failed when the
+ * session terminates without reporting the new status.
+ *
+ * The information presented by IGuest is not reliable without this! */
+ case VMMDevReq_ReportGuestCapabilities:
+ switch (((VMMDevReportGuestStatus const *)pReqHdr)->guestStatus.facility)
+ {
+ case VBoxGuestFacilityType_All:
+ case VBoxGuestFacilityType_VBoxGuestDriver:
+ enmRequired = kLevel_OnlyVBoxGuest;
+ break;
+ case VBoxGuestFacilityType_VBoxService:
+ enmRequired = kLevel_TrustedUsers;
+ break;
+ case VBoxGuestFacilityType_VBoxTrayClient:
+ case VBoxGuestFacilityType_Seamless:
+ case VBoxGuestFacilityType_Graphics:
+ default:
+ enmRequired = kLevel_AllUsers;
+ break;
+ }
+ break;
+ }
+
+ /*
+ * Check against the session.
+ */
+ switch (enmRequired)
+ {
+ default:
+ case kLevel_NoOne:
+ break;
+ case kLevel_OnlyVBoxGuest:
+ case kLevel_OnlyKernel:
+ if (pSession->R0Process == NIL_RTR0PROCESS)
+ return VINF_SUCCESS;
+ break;
+ case kLevel_TrustedUsers:
+ case kLevel_AllUsers:
+ return VINF_SUCCESS;
+ }
+
+ return VERR_PERMISSION_DENIED;
+}
static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
VMMDevRequestHeader *pReqHdr, size_t cbData, size_t *pcbDataReturned)
@@ -1448,6 +1599,13 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
return rc;
}
+ rc = VBoxGuestCheckIfVMMReqAllowed(pSession, enmType, pReqHdr);
+ if (RT_FAILURE(rc))
+ {
+ Log(("VBoxGuestCommonIOCtl: VMMREQUEST: Operation not allowed! type=%#x rc=%Rrc\n", enmType, rc));
+ return rc;
+ }
+
/*
* Make a copy of the request in the physical memory heap so
* the VBoxGuestLibrary can more easily deal with the request.
@@ -2180,15 +2338,19 @@ static void testSetMouseStatus(void)
*
* @returns VBox status code.
*
+ * @param pDevExt The device extension.
* @param pch The log message (need not be NULL terminated).
* @param cbData Size of the buffer.
* @param pcbDataReturned Where to store the amount of returned data. Can be NULL.
*/
-static int VBoxGuestCommonIOCtl_Log(const char *pch, size_t cbData, size_t *pcbDataReturned)
+static int VBoxGuestCommonIOCtl_Log(PVBOXGUESTDEVEXT pDevExt, const char *pch, size_t cbData, size_t *pcbDataReturned)
{
NOREF(pch);
NOREF(cbData);
- Log(("%.*s", cbData, pch));
+ if (pDevExt->fLoggingEnabled)
+ RTLogBackdoorPrintf("%.*s", cbData, pch);
+ else
+ Log(("%.*s", cbData, pch));
if (pcbDataReturned)
*pcbDataReturned = 0;
return VINF_SUCCESS;
@@ -2318,7 +2480,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((char *)pvData, cbData, pcbDataReturned);
+ rc = VBoxGuestCommonIOCtl_Log(pDevExt, (char *)pvData, cbData, pcbDataReturned);
}
else
{
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
index b974c2b49..614130bb8 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
@@ -147,6 +147,9 @@ typedef struct VBOXGUESTDEVEXT
#ifdef VBOX_WITH_VRDP_SESSION_HANDLING
BOOL fVRDPEnabled;
#endif
+ /** 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
diff --git a/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp b/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
index 5cde531d0..116d9ce11 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
@@ -1,4 +1,4 @@
-/* $Revision: 70720 $ */
+/* $Revision: 76652 $ */
/** @file
* VBoxGuestLib - Host-Guest Communication Manager internal functions, implemented by VBoxGuest
*/
@@ -258,7 +258,9 @@ static int vbglR0HGCMInternalPreprocessCall(VBoxGuestHGCMCallInfo const *pCallIn
case VMMDevHGCMParmType_LinAddr_Locked:
if (fIsUser)
return VERR_INVALID_PARAMETER;
- if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
+ /* always perform it as !VBGLR0_CAN_USE_PHYS_PAGE_LIST() since otherwise
+ * we end up creating a RTR0MEMOBJ and doing page lock again, which leads to undefined behavior and possible BSOD on Win */
+ //if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
{
cb = pSrcParm->u.Pointer.size;
AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM),
@@ -535,7 +537,9 @@ static void vbglR0HGCMInternalInitCall(VMMDevHGCMCall *pHGCMCall, VBoxGuestHGCMC
case VMMDevHGCMParmType_LinAddr_Locked_In:
case VMMDevHGCMParmType_LinAddr_Locked_Out:
case VMMDevHGCMParmType_LinAddr_Locked:
- if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
+ /* always perform it as !VBGLR0_CAN_USE_PHYS_PAGE_LIST() since otherwise
+ * we end up creating a RTR0MEMOBJ and doing page lock again, which leads to undefined behavior and possible BSOD on Win */
+// if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
{
*pDstParm = *pSrcParm;
pDstParm->type = vbglR0HGCMInternalConvertLinAddrType(pSrcParm->type);
@@ -799,7 +803,9 @@ static int vbglR0HGCMInternalCopyBackResult(VBoxGuestHGCMCallInfo *pCallInfo, VM
case VMMDevHGCMParmType_LinAddr_Locked_Out:
case VMMDevHGCMParmType_LinAddr_Locked:
- if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
+ /* always perform it as !VBGLR0_CAN_USE_PHYS_PAGE_LIST() since otherwise
+ * we end up creating a RTR0MEMOBJ and doing page lock again, which leads to undefined behavior and possible BSOD on Win */
+// if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
{
pDstParm->u.Pointer.size = pSrcParm->u.Pointer.size;
break;
diff --git a/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk b/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
index 242aeb5b9..2c2a27c9c 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
@@ -4,7 +4,7 @@
#
#
-# Copyright (C) 2006-2010 Oracle Corporation
+# 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;
@@ -92,6 +92,7 @@ VBoxGuestR3Lib_DEFS = \
VBoxGuestR3Lib_SOURCES = \
VBoxGuestR3Lib.cpp \
VBoxGuestR3LibAdditions.cpp \
+ VBoxGuestR3LibAutoLogon.cpp \
VBoxGuestR3LibBalloon.cpp \
VBoxGuestR3LibClipboard.cpp \
VBoxGuestR3LibCoreDump.cpp \
diff --git a/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h b/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
index 8b68df513..97547fdf4 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
+++ b/src/VBox/Additions/common/VBoxGuestLib/SysHlp.h
@@ -1,4 +1,4 @@
-/* $Revision: 60692 $ */
+/* $Revision: 76576 $ */
/** @file
* VBoxGuestLibR0 - System dependent helpers internal header.
*/
@@ -28,6 +28,8 @@
#define __VBoxGuestLib_SysHlp_h
#ifdef RT_OS_WINDOWS
+# undef PAGE_SIZE
+# undef PAGE_SHIFT
# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
# include <iprt/asm.h>
# define _InterlockedExchange _InterlockedExchange_StupidDDKVsCompilerCrap
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
index 55fd41230..d8e8212a5 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
@@ -1,4 +1,4 @@
-/* $Revision: 72532 $ */
+/* $Revision: 76576 $ */
/** @file
* VBoxGuestR0LibSharedFolders - Ring 0 Shared Folders calls.
*/
@@ -500,7 +500,7 @@ DECLVBGL(int) VbglR0SfWritePhysCont(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHAND
pData->buffer.u.PageList.offset = sizeof(VBoxSFWrite);
pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
- pPgLst->offFirstPage = PhysBuffer & PAGE_OFFSET_MASK;
+ pPgLst->offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
pPgLst->cPages = cPages;
PhysBuffer &= ~(RTCCPHYS)PAGE_OFFSET_MASK;
for (iPage = 0; iPage < cPages; iPage++, PhysBuffer += PAGE_SIZE)
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
index 0274c753d..43c2cbbf0 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
@@ -29,6 +29,8 @@
#include <VBox/VBoxGuestLib.h>
#ifndef _NTIFS_
# ifdef RT_OS_WINDOWS
+# undef PAGE_SIZE
+# undef PAGE_SHIFT
# if (_MSC_VER >= 1400) && !defined(VBOX_WITH_PATCHED_DDK)
# include <iprt/asm.h>
# define _InterlockedExchange _InterlockedExchange_StupidDDKvsCompilerCrap
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAutoLogon.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAutoLogon.cpp
new file mode 100644
index 000000000..eb528c98d
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAutoLogon.cpp
@@ -0,0 +1,149 @@
+/* $Id */
+/** @file
+ * VBoxGuestR3LibAutoLogon - Ring-3 utility functions for auto-logon modules
+ * (VBoxGINA / VBoxCredProv / pam_vbox).
+ */
+
+/*
+ * Copyright (C) 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.
+ *
+ * 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.
+ */
+
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <iprt/asm.h>
+#include <iprt/mem.h>
+#include <iprt/rand.h>
+#include <iprt/string.h>
+#include <VBox/log.h>
+
+#include "VBGLR3Internal.h"
+
+
+/**
+ * Reports the current auto-logon status to the host.
+ *
+ * This makes sure that the Failed state is sticky.
+ *
+ * @return IPRT status code.
+ * @param enmStatus Status to report to the host.
+ */
+VBGLR3DECL(int) VbglR3AutoLogonReportStatus(VBoxGuestFacilityStatus enmStatus)
+{
+ /*
+ * VBoxGuestFacilityStatus_Failed is sticky.
+ */
+ static VBoxGuestFacilityStatus s_enmLastStatus = VBoxGuestFacilityStatus_Inactive;
+ if (s_enmLastStatus != VBoxGuestFacilityStatus_Failed)
+ {
+ int rc = VbglR3ReportAdditionsStatus(VBoxGuestFacilityType_AutoLogon,
+ enmStatus, 0 /* Flags */);
+ if (rc == VERR_NOT_SUPPORTED)
+ {
+ /*
+ * To maintain backwards compatibility to older hosts which don't have
+ * VMMDevReportGuestStatus implemented we set the appropriate status via
+ * guest property to have at least something.
+ */
+ uint32_t u32ClientId = 0;
+ rc = VbglR3GuestPropConnect(&u32ClientId);
+ if (RT_SUCCESS(rc))
+ {
+ /** @todo Move VBoxGuestStatusCurrent -> const char* to an own function. */
+ char szStatus[RTPATH_MAX];
+ size_t cbRet = 0;
+ switch (enmStatus)
+ {
+ case VBoxGuestFacilityStatus_Inactive:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Inactive");
+ break;
+ case VBoxGuestFacilityStatus_Paused:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Disabled");
+ break;
+ case VBoxGuestFacilityStatus_PreInit:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "PreInit");
+ break;
+ case VBoxGuestFacilityStatus_Init:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Init");
+ break;
+ case VBoxGuestFacilityStatus_Active:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Active");
+ break;
+ case VBoxGuestFacilityStatus_Terminating:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Terminating");
+ break;
+ case VBoxGuestFacilityStatus_Terminated:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Terminated");
+ break;
+ case VBoxGuestFacilityStatus_Failed:
+ cbRet = RTStrPrintf(szStatus, sizeof(szStatus), "Failed");
+ break;
+ default:
+ /* cbRet will be 0. */
+ break;
+ }
+
+ if (cbRet)
+ {
+ const char szPath[] = "/VirtualBox/GuestInfo/OS/AutoLogonStatus";
+
+ /*
+ * Because a value can be temporary we have to make sure it also
+ * gets deleted when the property cache did not have the chance to
+ * gracefully clean it up (due to a hard VM reset etc), so set this
+ * guest property using the TRANSRESET flag..
+ */
+ rc = VbglR3GuestPropWrite(u32ClientId, szPath, szStatus, "TRANSRESET");
+ if (rc == VERR_PARSE_ERROR)
+ {
+ /* Host does not support the "TRANSRESET" flag, so only
+ * use the "TRANSIENT" flag -- better than nothing :-). */
+ rc = VbglR3GuestPropWrite(u32ClientId, szPath, szStatus, "TRANSIENT");
+ }
+ }
+ else
+ rc = VERR_INVALID_PARAMETER;
+
+ VbglR3GuestPropDisconnect(u32ClientId);
+ }
+ }
+
+ s_enmLastStatus = enmStatus;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Detects whether our process is running in a remote session or not.
+ *
+ * @return bool true if running in a remote session, false if not.
+ */
+VBGLR3DECL(bool) VbglR3AutoLogonIsRemoteSession(void)
+{
+#ifdef RT_OS_WINDOWS
+ return (0 != GetSystemMetrics(SM_REMOTESESSION)) ? true : false;
+#else
+ return false; /* Not implemented. */
+#endif
+}
+
+
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp
index 678d32ee3..a25515e19 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCredentials.cpp
@@ -73,6 +73,10 @@ VBGLR3DECL(int) VbglR3CredentialsQueryAvailability(void)
*/
VBGLR3DECL(int) VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword, char **ppszDomain)
{
+ AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);
+ AssertPtrReturn(ppszPassword, VERR_INVALID_POINTER);
+ AssertPtrReturn(ppszDomain, VERR_INVALID_POINTER);
+
VMMDevCredentials Req;
RT_ZERO(Req);
vmmdevInitRequest((VMMDevRequestHeader*)&Req, VMMDevReq_QueryCredentials);
@@ -101,6 +105,55 @@ VBGLR3DECL(int) VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword,
/**
+ * Retrieves and clears the user credentials for logging into the guest OS.
+ * UTF-16 version.
+ *
+ * @returns IPRT status value
+ * @param ppwszUser Receives pointer of allocated user name string.
+ * The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
+ * @param ppswzPassword Receives pointer of allocated user password string.
+ * The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
+ * @param ppwszDomain Receives pointer of allocated domain name string.
+ * The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
+ */
+VBGLR3DECL(int) VbglR3CredentialsRetrieveUtf16(PRTUTF16 *ppwszUser, PRTUTF16 *ppwszPassword, PRTUTF16 *ppwszDomain)
+{
+ AssertPtrReturn(ppwszUser, VERR_INVALID_POINTER);
+ AssertPtrReturn(ppwszPassword, VERR_INVALID_POINTER);
+ AssertPtrReturn(ppwszDomain, VERR_INVALID_POINTER);
+
+ char *pszUser, *pszPassword, *pszDomain;
+ int rc = VbglR3CredentialsRetrieve(&pszUser, &pszPassword, &pszDomain);
+ if (RT_SUCCESS(rc))
+ {
+ PRTUTF16 pwszUser = NULL;
+ PRTUTF16 pwszPassword = NULL;
+ PRTUTF16 pwszDomain = NULL;
+
+ rc = RTStrToUtf16(pszUser, &pwszUser);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTStrToUtf16(pszPassword, &pwszPassword);
+ if (RT_SUCCESS(rc))
+ rc = RTStrToUtf16(pszDomain, &pwszDomain);
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ *ppwszUser = pwszUser;
+ *ppwszPassword = pwszPassword;
+ *ppwszDomain = pwszDomain;
+ }
+ else
+ VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain, 3 /* Passes */);
+ VbglR3CredentialsDestroy(pszUser, pszPassword, pszDomain, 3 /* Passes */);
+ }
+
+ return rc;
+}
+
+
+/**
* Clears and frees the three strings.
*
* @param pszUser Receives pointer of the user name string to destroy.
@@ -127,3 +180,32 @@ VBGLR3DECL(void) VbglR3CredentialsDestroy(char *pszUser, char *pszPassword, char
RTStrFree(pszDomain);
}
+
+/**
+ * Clears and frees the three strings. UTF-16 version.
+ *
+ * @param pwszUser Receives pointer of the user name string to destroy.
+ * Optional.
+ * @param pwszPassword Receives pointer of the password string to destroy.
+ * Optional.
+ * @param pwszDomain Receives pointer of allocated domain name string.
+ * Optional.
+ * @param cPasses Number of wipe passes. The more the better + slower.
+ */
+VBGLR3DECL(void) VbglR3CredentialsDestroyUtf16(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain,
+ uint32_t cPasses)
+{
+ /* wipe first */
+ if (pwszUser)
+ RTMemWipeThoroughly(pwszUser, (RTUtf16Len(pwszUser) + 1) * sizeof(RTUTF16), cPasses);
+ if (pwszPassword)
+ RTMemWipeThoroughly(pwszPassword, (RTUtf16Len(pwszPassword) + 1) * sizeof(RTUTF16), cPasses);
+ if (pwszDomain)
+ RTMemWipeThoroughly(pwszDomain, (RTUtf16Len(pwszDomain) + 1) * sizeof(RTUTF16), cPasses);
+
+ /* then free. */
+ RTUtf16Free(pwszUser);
+ RTUtf16Free(pwszPassword);
+ RTUtf16Free(pwszDomain);
+}
+
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
index dd9729515..09555c9f1 100644
--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
+++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-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;
@@ -108,10 +108,10 @@ VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *pu
VBoxGuestCtrlHGCMMsgType Msg;
- Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.result = VERR_WRONG_ORDER;
Msg.hdr.u32ClientID = u32ClientId;
Msg.hdr.u32Function = GUEST_GET_HOST_MSG; /* Tell the host we want our next command. */
- Msg.hdr.cParms = 2; /* Just peek for the next message! */
+ Msg.hdr.cParms = 2; /* Just peek for the next message! */
VbglHGCMParmUInt32Set(&Msg.msg, 0);
VbglHGCMParmUInt32Set(&Msg.num_parms, 0);
@@ -140,10 +140,10 @@ VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId)
{
VBoxGuestCtrlHGCMMsgCancelPendingWaits Msg;
- Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.result = VERR_WRONG_ORDER;
Msg.hdr.u32ClientID = u32ClientId;
Msg.hdr.u32Function = GUEST_CANCEL_PENDING_WAITS;
- Msg.hdr.cParms = 0;
+ Msg.hdr.cParms = 0;
int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
if (RT_SUCCESS(rc))
@@ -166,34 +166,35 @@ VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId)
* @param uNumParms
** @todo Docs!
*/
-VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t uNumParms,
- uint32_t *puContext,
- char *pszCmd, uint32_t cbCmd,
- uint32_t *puFlags,
- char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs,
- char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars,
- char *pszUser, uint32_t cbUser,
- char *pszPassword, uint32_t cbPassword,
- uint32_t *puTimeLimit)
+VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdExec(uint32_t u32ClientId, uint32_t cParms,
+ uint32_t *puContext,
+ char *pszCmd, uint32_t cbCmd,
+ uint32_t *puFlags,
+ char *pszArgs, uint32_t cbArgs, uint32_t *pcArgs,
+ char *pszEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars,
+ char *pszUser, uint32_t cbUser,
+ char *pszPassword, uint32_t cbPassword,
+ uint32_t *pcMsTimeLimit)
{
AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszCmd, VERR_INVALID_PARAMETER);
AssertPtrReturn(puFlags, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszArgs, VERR_INVALID_PARAMETER);
- AssertPtrReturn(puNumArgs, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pcArgs, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszEnv, VERR_INVALID_PARAMETER);
AssertPtrReturn(pcbEnv, VERR_INVALID_PARAMETER);
- AssertPtrReturn(puNumEnvVars, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pcEnvVars, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszUser, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER);
- AssertPtrReturn(puTimeLimit, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pcMsTimeLimit, VERR_INVALID_PARAMETER);
VBoxGuestCtrlHGCMMsgExecCmd Msg;
- Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.result = VERR_WRONG_ORDER;
Msg.hdr.u32ClientID = u32ClientId;
Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
- Msg.hdr.cParms = uNumParms;
+ Msg.hdr.cParms = cParms; /** @todo r=bird: This isn't safe/right. The parameter count of this HGCM call
+ * is fixed from our point of view. */
VbglHGCMParmUInt32Set(&Msg.context, 0);
VbglHGCMParmPtrSet(&Msg.cmd, pszCmd, cbCmd);
@@ -219,10 +220,10 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t
{
Msg.context.GetUInt32(puContext);
Msg.flags.GetUInt32(puFlags);
- Msg.num_args.GetUInt32(puNumArgs);
- Msg.num_env.GetUInt32(puNumEnvVars);
+ Msg.num_args.GetUInt32(pcArgs);
+ Msg.num_env.GetUInt32(pcEnvVars);
Msg.cb_env.GetUInt32(pcbEnv);
- Msg.timeout.GetUInt32(puTimeLimit);
+ Msg.timeout.GetUInt32(pcMsTimeLimit);
}
}
return rc;
@@ -236,10 +237,10 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmd(uint32_t u32ClientId, uint32_t
*
* @returns VBox status code.
* @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
- * @param uNumParms
+ * @param cParms
** @todo Docs!
*/
-VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t uNumParms,
+VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t cParms,
uint32_t *puContext, uint32_t *puPID,
uint32_t *puHandle, uint32_t *puFlags)
{
@@ -253,7 +254,7 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, ui
Msg.hdr.result = VERR_WRONG_ORDER;
Msg.hdr.u32ClientID = u32ClientId;
Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
- Msg.hdr.cParms = uNumParms;
+ Msg.hdr.cParms = cParms;
VbglHGCMParmUInt32Set(&Msg.context, 0);
VbglHGCMParmUInt32Set(&Msg.pid, 0);
@@ -288,13 +289,13 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, ui
*
* @returns VBox status code.
* @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().
- * @param uNumParms
+ * @param cParms
** @todo Docs!
*/
-VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t uNumParms,
+VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t cParms,
uint32_t *puContext, uint32_t *puPID,
uint32_t *puFlags,
- void *pvData, uint32_t cbData,
+ void *pvData, uint32_t cbData,
uint32_t *pcbSize)
{
AssertPtrReturn(puContext, VERR_INVALID_PARAMETER);
@@ -305,10 +306,10 @@ VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uin
VBoxGuestCtrlHGCMMsgExecIn Msg;
- Msg.hdr.result = VERR_WRONG_ORDER;
+ Msg.hdr.result = VERR_WRONG_ORDER;
Msg.hdr.u32ClientID = u32ClientId;
Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
- Msg.hdr.cParms = uNumParms;
+ Msg.hdr.cParms = cParms;
VbglHGCMParmUInt32Set(&Msg.context, 0);
VbglHGCMParmUInt32Set(&Msg.pid, 0);
diff --git a/src/VBox/Additions/common/VBoxService/Makefile.kmk b/src/VBox/Additions/common/VBoxService/Makefile.kmk
index ee88c6ba8..abc1c41f4 100644
--- a/src/VBox/Additions/common/VBoxService/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxService/Makefile.kmk
@@ -33,7 +33,9 @@ PROGRAMS.win.x86 += VBoxServiceNT
# VBoxService
#
VBoxService_TEMPLATE = VBOXGUESTR3EXE
-VBoxService_DEFS = LOG_TO_BACKDOOR VBOX_WITH_HGCM VBOXSERVICE_TIMESYNC VBOXSERVICE_MANAGEMENT VBOXSERVICE_TOOLBOX
+VBoxService_DEFS = VBOX_WITH_HGCM VBOXSERVICE_TIMESYNC VBOXSERVICE_MANAGEMENT VBOXSERVICE_TOOLBOX
+VBoxService_DEFS += \
+ VBOX_BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\"
VBoxService_DEFS.win += _WIN32_WINNT=0x0501
VBoxService_DEFS.os2 = VBOX_WITH_HGCM VBOXSERVICE_CLIPBOARD
ifdef VBOX_WITH_GUEST_PROPS
@@ -68,9 +70,7 @@ VBoxService_SOURCES = \
ifdef VBOX_WITH_GUEST_CONTROL
VBoxService_SOURCES += \
VBoxServiceControl.cpp \
- VBoxServiceControlExec.cpp \
- VBoxServiceControlExecThread.cpp \
- VBoxServicePipeBuf.cpp
+ VBoxServiceControlThread.cpp
endif
ifdef VBOX_WITH_MEMBALLOON
diff --git a/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp b/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
index ca54b67a0..e09173c1f 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
@@ -135,6 +135,9 @@ static BOOL vboxServiceWinSetStatus(DWORD dwStatus, DWORD dwCheckPoint)
ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ss.dwCurrentState = dwStatus;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+#ifndef TARGET_NT4
+ ss.dwControlsAccepted |= SERVICE_ACCEPT_SESSIONCHANGE;
+#endif
ss.dwWin32ExitCode = NO_ERROR;
ss.dwServiceSpecificExitCode = 0; /* Not used */
ss.dwCheckPoint = dwCheckPoint;
@@ -378,6 +381,53 @@ RTEXITCODE VBoxServiceWinEnterCtrlDispatcher(void)
}
+#ifndef TARGET_NT4
+static const char* vboxServiceWTSStateToString(DWORD dwEvent)
+{
+ switch (dwEvent)
+ {
+ case WTS_CONSOLE_CONNECT:
+ return "A session was connected to the console terminal";
+
+ case WTS_CONSOLE_DISCONNECT:
+ return "A session was disconnected from the console terminal";
+
+ case WTS_REMOTE_CONNECT:
+ return "A session connected to the remote terminal";
+
+ case WTS_REMOTE_DISCONNECT:
+ return "A session was disconnected from the remote terminal";
+
+ case WTS_SESSION_LOGON:
+ return "A user has logged on to a session";
+
+ case WTS_SESSION_LOGOFF:
+ return "A user has logged off the session";
+
+ case WTS_SESSION_LOCK:
+ return "A session has been locked";
+
+ case WTS_SESSION_UNLOCK:
+ return "A session has been unlocked";
+
+ case WTS_SESSION_REMOTE_CONTROL:
+ return "A session has changed its remote controlled status";
+#if 0
+ case WTS_SESSION_CREATE:
+ return "A session has been created";
+
+ case WTS_SESSION_TERMINATE:
+ return "The session has been terminated";
+#endif
+ default:
+ break;
+ }
+
+ return "Uknonwn state";
+}
+#endif /* !TARGET_NT4 */
+
+
#ifdef TARGET_NT4
static VOID WINAPI vboxServiceWinCtrlHandler(DWORD dwControl)
#else
@@ -416,27 +466,26 @@ static DWORD WINAPI vboxServiceWinCtrlHandler(DWORD dwControl, DWORD dwEventType
break;
}
- case SERVICE_CONTROL_SESSIONCHANGE: /* Only Win XP and up. */
-#ifndef TARGET_NT4
-# if 0
- switch (dwEventType)
- {
- case WTS_SESSION_LOGON:
- VBoxServiceVerbose(2, "A user has logged on to the session.\n");
- break;
-
- case WTS_SESSION_LOGOFF:
- VBoxServiceVerbose(2, "A user has logged off from the session.\n");
- break;
- default:
- break;
- }
-# endif
-#endif /* !TARGET_NT4 */
+# ifndef TARGET_NT4
+ case SERVICE_CONTROL_SESSIONCHANGE: /* Only Windows 2000 and up. */
+ {
+ AssertPtr(lpEventData);
+ PWTSSESSION_NOTIFICATION pNotify = (PWTSSESSION_NOTIFICATION)lpEventData;
+ Assert(pNotify->cbSize == sizeof(WTSSESSION_NOTIFICATION));
+
+ VBoxServiceVerbose(1, "Control handler: %s (Session=%ld, Event=%#x)\n",
+ vboxServiceWTSStateToString(dwEventType),
+ pNotify->dwSessionId, dwEventType);
+
+ /* Handle all events, regardless of dwEventType. */
+ int rc2 = VBoxServiceVMInfoSignal();
+ AssertRC(rc2);
break;
+ }
+# endif /* !TARGET_NT4 */
default:
- VBoxServiceVerbose(1, "Service control function not implemented: %#x\n", dwControl);
+ VBoxServiceVerbose(1, "Control handler: Function not implemented: %#x\n", dwControl);
rcRet = ERROR_CALL_NOT_IMPLEMENTED;
break;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxService.cpp b/src/VBox/Additions/common/VBoxService/VBoxService.cpp
index d093d23ea..ba92420f9 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxService.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxService.cpp
@@ -35,15 +35,22 @@
# include <pthread.h>
#endif
+#include <package-generated.h>
#include "product-generated.h"
+
#include <iprt/asm.h>
#include <iprt/buildconfig.h>
#include <iprt/initterm.h>
+#ifdef DEBUG
+# include <iprt/memtracker.h>
+#endif
#include <iprt/message.h>
#include <iprt/path.h>
+#include <iprt/process.h>
#include <iprt/semaphore.h>
#include <iprt/string.h>
#include <iprt/stream.h>
+#include <iprt/system.h>
#include <iprt/thread.h>
#include <VBox/log.h>
@@ -55,20 +62,26 @@
* Global Variables *
*******************************************************************************/
/** The program name (derived from argv[0]). */
-char *g_pszProgName = (char *)"";
+char *g_pszProgName = (char *)"";
/** The current verbosity level. */
-int g_cVerbosity = 0;
+int g_cVerbosity = 0;
+/** Logging parameters. */
+/** @todo Make this configurable later. */
+static PRTLOGGER g_pLoggerRelease = NULL;
+static uint32_t g_cHistory = 10; /* Enable log rotation, 10 files. */
+static uint32_t g_uHistoryFileTime = RT_SEC_1DAY; /* Max 1 day per file. */
+static uint64_t g_uHistoryFileSize = 100 * _1M; /* Max 100MB per file. */
/** Critical section for (debug) logging. */
#ifdef DEBUG
- RTCRITSECT g_csLog;
+ RTCRITSECT g_csLog;
#endif
/** The default service interval (the -i | --interval) option). */
-uint32_t g_DefaultInterval = 0;
+uint32_t g_DefaultInterval = 0;
#ifdef RT_OS_WINDOWS
/** Signal shutdown to the Windows service thread. */
static bool volatile g_fWindowsServiceShutdown;
/** Event the Windows service thread waits for shutdown. */
-static RTSEMEVENT g_hEvtWindowsService;
+static RTSEMEVENT g_hEvtWindowsService;
#endif
/**
@@ -123,6 +136,118 @@ static struct
/**
+ * Release logger callback.
+ *
+ * @return IPRT status code.
+ * @param pLoggerRelease
+ * @param enmPhase
+ * @param pfnLog
+ */
+static void VBoxServiceLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
+{
+ /* Some introductory information. */
+ static RTTIMESPEC s_TimeSpec;
+ char szTmp[256];
+ if (enmPhase == RTLOGPHASE_BEGIN)
+ RTTimeNow(&s_TimeSpec);
+ RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));
+
+ switch (enmPhase)
+ {
+ case RTLOGPHASE_BEGIN:
+ {
+ pfnLog(pLoggerRelease,
+ "VBoxService %s r%s (verbosity: %d) %s (%s %s) release log\n"
+ "Log opened %s\n",
+ RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity, VBOX_BUILD_TARGET,
+ __DATE__, __TIME__, szTmp);
+
+ int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
+ if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
+ pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp);
+ vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
+ if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
+ pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp);
+ vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
+ if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
+ pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp);
+ if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
+ pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp);
+
+ /* the package type is interesting for Linux distributions */
+ char szExecName[RTPATH_MAX];
+ char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
+ pfnLog(pLoggerRelease,
+ "Executable: %s\n"
+ "Process ID: %u\n"
+ "Package type: %s"
+#ifdef VBOX_OSE
+ " (OSE)"
+#endif
+ "\n",
+ pszExecName ? pszExecName : "unknown",
+ RTProcSelf(),
+ VBOX_PACKAGE_STRING);
+ break;
+ }
+
+ case RTLOGPHASE_PREROTATE:
+ pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp);
+ break;
+
+ case RTLOGPHASE_POSTROTATE:
+ pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp);
+ break;
+
+ case RTLOGPHASE_END:
+ pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp);
+ break;
+
+ default:
+ /* nothing */;
+ }
+}
+
+
+/**
+ * Creates the default release logger outputting to the specified file.
+ *
+ * @return IPRT status code.
+ * @param pszLogFile Filename for log output. Optional.
+ */
+static int VBoxServiceLogCreate(const char *pszLogFile)
+{
+ /* Create release logger (stdout + file). */
+ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+ RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG;
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+ fFlags |= RTLOGFLAGS_USECRLF;
+#endif
+ char szError[RTPATH_MAX + 128] = "";
+ int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags, "all",
+ "VBOXSERVICE_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
+ RTLOGDEST_STDOUT,
+ VBoxServiceLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
+ szError, sizeof(szError), pszLogFile);
+ if (RT_SUCCESS(rc))
+ {
+ /* register this logger as the release logger */
+ RTLogRelSetDefaultInstance(g_pLoggerRelease);
+
+ /* Explicitly flush the log in case of VBOXSERVICE_RELEASE_LOG=buffered. */
+ RTLogFlush(g_pLoggerRelease);
+ }
+
+ return rc;
+}
+
+static void VBoxServiceLogDestroy(void)
+{
+ RTLogDestroy(g_pLoggerRelease);
+}
+
+
+/**
* Displays the program usage message.
*
* @returns 1.
@@ -130,7 +255,8 @@ static struct
static int vboxServiceUsage(void)
{
RTPrintf("Usage:\n"
- " %-12s [-f|--foreground] [-v|--verbose] [-i|--interval <seconds>]\n"
+ " %-12s [-f|--foreground] [-v|--verbose] [-l|--logfile <file>]\n"
+ " [-i|--interval <seconds>]\n"
" [--disable-<service>] [--enable-<service>]\n"
" [--only-<service>] [-h|-?|--help]\n", g_pszProgName);
#ifdef RT_OS_WINDOWS
@@ -143,6 +269,7 @@ static int vboxServiceUsage(void)
"Options:\n"
" -i | --interval The default interval.\n"
" -f | --foreground Don't daemonize the program. For debugging.\n"
+ " -l | --logfile <file> Enables logging to a file.\n"
" -v | --verbose Increment the verbosity level. For debugging.\n"
" -V | --version Show version information.\n"
" -h | -? | --help Show this message and exit with status 1.\n"
@@ -170,26 +297,6 @@ static int vboxServiceUsage(void)
/**
- * Displays a syntax error message.
- *
- * @returns RTEXITCODE_SYNTAX.
- * @param pszFormat The message text.
- * @param ... Format arguments.
- */
-RTEXITCODE VBoxServiceSyntax(const char *pszFormat, ...)
-{
- RTStrmPrintf(g_pStdErr, "%s: syntax error: ", g_pszProgName);
-
- va_list va;
- va_start(va, pszFormat);
- RTStrmPrintfV(g_pStdErr, pszFormat, va);
- va_end(va);
-
- return RTEXITCODE_SYNTAX;
-}
-
-
-/**
* Displays an error message.
*
* @returns RTEXITCODE_FAILURE.
@@ -198,16 +305,16 @@ RTEXITCODE VBoxServiceSyntax(const char *pszFormat, ...)
*/
RTEXITCODE VBoxServiceError(const char *pszFormat, ...)
{
- RTStrmPrintf(g_pStdErr, "%s: error: ", g_pszProgName);
+ va_list args;
+ va_start(args, pszFormat);
+ char *psz = NULL;
+ RTStrAPrintfV(&psz, pszFormat, args);
+ va_end(args);
- va_list va;
- va_start(va, pszFormat);
- RTStrmPrintfV(g_pStdErr, pszFormat, va);
- va_end(va);
+ AssertPtr(psz);
+ LogRel(("Error: %s", psz));
- va_start(va, pszFormat);
- LogRel(("%s: Error: %N", g_pszProgName, pszFormat, &va));
- va_end(va);
+ RTStrFree(psz);
return RTEXITCODE_FAILURE;
}
@@ -216,7 +323,6 @@ RTEXITCODE VBoxServiceError(const char *pszFormat, ...)
/**
* Displays a verbose message.
*
- * @returns 1
* @param iLevel Minimum log level required to display this message.
* @param pszFormat The message text.
* @param ... Format arguments.
@@ -229,20 +335,17 @@ void VBoxServiceVerbose(int iLevel, const char *pszFormat, ...)
int rc = RTCritSectEnter(&g_csLog);
if (RT_SUCCESS(rc))
{
- const char *pszThreadName = RTThreadSelfName();
- AssertPtr(pszThreadName);
- RTStrmPrintf(g_pStdOut, "%s [%s]: ",
- g_pszProgName, pszThreadName);
-#else
- RTStrmPrintf(g_pStdOut, "%s: ", g_pszProgName);
-#endif
- va_list va;
- va_start(va, pszFormat);
- RTStrmPrintfV(g_pStdOut, pszFormat, va);
- va_end(va);
- va_start(va, pszFormat);
- LogRel(("%s: %N", g_pszProgName, pszFormat, &va));
- va_end(va);
+#endif
+ va_list args;
+ va_start(args, pszFormat);
+ char *psz = NULL;
+ RTStrAPrintfV(&psz, pszFormat, args);
+ va_end(args);
+
+ AssertPtr(psz);
+ LogRel(("%s", psz));
+
+ RTStrFree(psz);
#ifdef DEBUG
RTCritSectLeave(&g_csLog);
}
@@ -283,6 +386,7 @@ int VBoxServiceReportStatus(VBoxGuestFacilityStatus enmStatus)
/**
* Gets a 32-bit value argument.
+ * @todo Get rid of this and VBoxServiceArgString() as soon as we have RTOpt handling.
*
* @returns 0 on success, non-zero exit code on error.
* @param argc The argument count.
@@ -300,20 +404,41 @@ int VBoxServiceArgUInt32(int argc, char **argv, const char *psz, int *pi, uint32
if (!*psz)
{
if (*pi + 1 >= argc)
- return VBoxServiceSyntax("Missing value for the '%s' argument\n", argv[*pi]);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing value for the '%s' argument\n", argv[*pi]);
psz = argv[++*pi];
}
char *pszNext;
int rc = RTStrToUInt32Ex(psz, &pszNext, 0, pu32);
if (RT_FAILURE(rc) || *pszNext)
- return VBoxServiceSyntax("Failed to convert interval '%s' to a number.\n", psz);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Failed to convert interval '%s' to a number\n", psz);
if (*pu32 < u32Min || *pu32 > u32Max)
- return VBoxServiceSyntax("The timesync interval of %RU32 seconds is out of range [%RU32..%RU32].\n",
- *pu32, u32Min, u32Max);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The timesync interval of %RU32 seconds is out of range [%RU32..%RU32]\n",
+ *pu32, u32Min, u32Max);
return 0;
}
+/** @todo Get rid of this and VBoxServiceArgUInt32() as soon as we have RTOpt handling. */
+int VBoxServiceArgString(int argc, char **argv, const char *psz, int *pi, char *pszBuf, size_t cbBuf)
+{
+ AssertPtrReturn(pszBuf, VERR_INVALID_POINTER);
+ AssertPtrReturn(cbBuf, VERR_INVALID_PARAMETER);
+
+ if (*psz == ':' || *psz == '=')
+ psz++;
+ if (!*psz)
+ {
+ if (*pi + 1 >= argc)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing string for the '%s' argument\n", argv[*pi]);
+ psz = argv[++*pi];
+ }
+
+ if (!RTStrPrintf(pszBuf, cbBuf, "%s", psz))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "String for '%s' argument too big\n", argv[*pi]);
+ return 0;
+}
+
+
/**
* The service thread.
@@ -373,6 +498,35 @@ static unsigned vboxServiceCountEnabledServices(void)
}
+#ifdef RT_OS_WINDOWS
+static BOOL WINAPI VBoxServiceConsoleControlHandler(DWORD dwCtrlType)
+{
+ int rc = VINF_SUCCESS;
+ bool fEventHandled = FALSE;
+ switch (dwCtrlType)
+ {
+ /* User pressed CTRL+C or CTRL+BREAK or an external event was sent
+ * via GenerateConsoleCtrlEvent(). */
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ case CTRL_C_EVENT:
+ VBoxServiceVerbose(2, "ControlHandler: Received break/close event\n");
+ rc = VBoxServiceStopServices();
+ fEventHandled = TRUE;
+ break;
+ default:
+ break;
+ /** @todo Add other events here. */
+ }
+
+ if (RT_FAILURE(rc))
+ VBoxServiceError("ControlHandler: Event %ld handled with error rc=%Rrc\n",
+ dwCtrlType, rc);
+ return fEventHandled;
+}
+#endif /* RT_OS_WINDOWS */
+
+
/**
* Starts the service.
*
@@ -554,7 +708,6 @@ void VBoxServiceMainWait(void)
}
RTSemEventDestroy(g_hEvtWindowsService);
g_hEvtWindowsService = NIL_RTSEMEVENT;
-
#else
/*
* Wait explicitly for a HUP, INT, QUIT, ABRT or TERM signal, blocking
@@ -627,9 +780,9 @@ int main(int argc, char **argv)
if (RT_FAILURE(rc))
{
if (rc == VERR_ACCESS_DENIED)
- return VBoxServiceError("Insufficient privileges to start %s! Please start with Administrator/root privileges!\n",
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Insufficient privileges to start %s! Please start with Administrator/root privileges!\n",
g_pszProgName);
- return VBoxServiceError("VbglR3Init failed with rc=%Rrc.\n", rc);
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "VbglR3Init failed with rc=%Rrc\n", rc);
}
#ifdef RT_OS_WINDOWS
@@ -642,6 +795,8 @@ int main(int argc, char **argv)
return VBoxServicePageSharingInitFork();
#endif
+ char szLogFile[RTPATH_MAX + 128] = "";
+
/*
* Parse the arguments.
*
@@ -653,7 +808,7 @@ int main(int argc, char **argv)
{
const char *psz = argv[i];
if (*psz != '-')
- return VBoxServiceSyntax("Unknown argument '%s'\n", psz);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown argument '%s'\n", psz);
psz++;
/* translate long argument to short */
@@ -679,6 +834,8 @@ int main(int argc, char **argv)
else if (MATCHES("unregister"))
psz = "u";
#endif
+ else if (MATCHES("logfile"))
+ psz = "l";
else if (MATCHES("daemonized"))
{
fDaemonized = true;
@@ -700,18 +857,21 @@ int main(int argc, char **argv)
if (cch > sizeof("only-") && !memcmp(psz, "only-", sizeof("only-") - 1))
for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
+ {
g_aServices[j].fEnabled = !RTStrICmp(psz + sizeof("only-") - 1, g_aServices[j].pDesc->pszName);
+ if (g_aServices[j].fEnabled)
+ fFound = true;
+ }
if (!fFound)
{
rcExit = vboxServiceLazyPreInit();
if (rcExit != RTEXITCODE_SUCCESS)
return rcExit;
-
for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++)
{
rc = g_aServices[j].pDesc->pfnOption(NULL, argc, argv, &i);
- fFound = rc == 0;
+ fFound = rc == VINF_SUCCESS;
if (fFound)
break;
if (rc != -1)
@@ -719,7 +879,7 @@ int main(int argc, char **argv)
}
}
if (!fFound)
- return VBoxServiceSyntax("Unknown option '%s'\n", argv[i]);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%s'\n", argv[i]);
continue;
}
#undef MATCHES
@@ -762,6 +922,16 @@ int main(int argc, char **argv)
return VBoxServiceWinUninstall();
#endif
+ case 'l':
+ {
+ rc = VBoxServiceArgString(argc, argv, psz + 1, &i,
+ szLogFile, sizeof(szLogFile));
+ if (rc)
+ return rc;
+ psz = NULL;
+ break;
+ }
+
default:
{
rcExit = vboxServiceLazyPreInit();
@@ -779,7 +949,7 @@ int main(int argc, char **argv)
return rc;
}
if (!fFound)
- return VBoxServiceSyntax("Unknown option '%c' (%s)\n", *psz, argv[i]);
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%c' (%s)\n", *psz, argv[i]);
break;
}
}
@@ -788,7 +958,12 @@ int main(int argc, char **argv)
/* Check that at least one service is enabled. */
if (vboxServiceCountEnabledServices() == 0)
- return VBoxServiceSyntax("At least one service must be enabled.\n");
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "At least one service must be enabled\n");
+
+ rc = VBoxServiceLogCreate(strlen(szLogFile) ? szLogFile : NULL);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log (%s, %Rrc)",
+ strlen(szLogFile) ? szLogFile : "<None>", rc);
/* Call pre-init if we didn't do it already. */
rcExit = vboxServiceLazyPreInit();
@@ -819,15 +994,18 @@ int main(int argc, char **argv)
hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME);
if (hMutexAppRunning == NULL)
{
+ DWORD dwErr = GetLastError();
+ if ( dwErr == ERROR_ALREADY_EXISTS
+ || dwErr == ERROR_ACCESS_DENIED)
+ {
+ VBoxServiceError("%s is already running! Terminating.", g_pszProgName);
+ return RTEXITCODE_FAILURE;
+ }
+
VBoxServiceError("CreateMutex failed with last error %u! Terminating", GetLastError());
return RTEXITCODE_FAILURE;
}
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- VBoxServiceError("%s is already running! Terminating.", g_pszProgName);
- CloseHandle(hMutexAppRunning);
- return RTEXITCODE_FAILURE;
- }
+
#else /* !RT_OS_WINDOWS */
/** @todo Add PID file creation here? */
#endif /* !RT_OS_WINDOWS */
@@ -863,11 +1041,35 @@ int main(int argc, char **argv)
* POSIX: This is used for both daemons and console runs. Start all services
* and return immediately.
*/
+#ifdef RT_OS_WINDOWS
+# ifndef RT_OS_NT4
+ /* Install console control handler. */
+ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)VBoxServiceConsoleControlHandler, TRUE /* Add handler */))
+ {
+ VBoxServiceError("Unable to add console control handler, error=%ld\n", GetLastError());
+ /* Just skip this error, not critical. */
+ }
+# endif /* !RT_OS_NT4 */
+#endif /* RT_OS_WINDOWS */
rc = VBoxServiceStartServices();
rcExit = RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
if (RT_SUCCESS(rc))
VBoxServiceMainWait();
+#ifdef RT_OS_WINDOWS
+# ifndef RT_OS_NT4
+ /* Uninstall console control handler. */
+ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */))
+ {
+ VBoxServiceError("Unable to remove console control handler, error=%ld\n", GetLastError());
+ /* Just skip this error, not critical. */
+ }
+# endif /* !RT_OS_NT4 */
+#else /* !RT_OS_WINDOWS */
+ /* On Windows - since we're running as a console application - we already stopped all services
+ * through the console control handler. So only do the stopping of services here on other platforms
+ * where the break/shutdown/whatever signal was just received. */
VBoxServiceStopServices();
+#endif /* RT_OS_WINDOWS */
}
VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated);
@@ -882,7 +1084,11 @@ int main(int argc, char **argv)
#ifdef DEBUG
RTCritSectDelete(&g_csLog);
+ //RTMemTrackerDumpAllToStdOut();
#endif
+
+ VBoxServiceLogDestroy();
+
return rcExit;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
index 498cee8df..3ef15dda5 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
@@ -82,7 +82,8 @@ static DECLCALLBACK(int) VBoxServiceAutoMountOption(const char **ppszShort, int
NOREF(argc);
NOREF(argv);
NOREF(pi);
- return VINF_SUCCESS;
+
+ return -1;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
index 8b609d432..ecfd743c3 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceBalloon.cpp
@@ -240,7 +240,8 @@ static DECLCALLBACK(int) VBoxServiceBalloonOption(const char **ppszShort, int ar
NOREF(argc);
NOREF(argv);
NOREF(pi);
- return VINF_SUCCESS;
+
+ return -1;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
index ea32683cf..3f20b7f1a 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
@@ -133,6 +133,11 @@ static DECLCALLBACK(int) VBoxServiceClipboardOS2PreInit(void)
/** @copydoc VBOXSERVICE::pfnOption */
static DECLCALLBACK(int) VBoxServiceClipboardOS2Option(const char **ppszShort, int argc, char **argv, int *pi)
{
+ NOREF(ppszShort);
+ NOREF(argc);
+ NOREF(argv);
+ NOREF(pi);
+
return -1;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
index 8de4144e4..95a9abebd 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
@@ -21,15 +21,16 @@
*******************************************************************************/
#include <iprt/asm.h>
#include <iprt/assert.h>
+#include <iprt/file.h>
#include <iprt/getopt.h>
#include <iprt/mem.h>
+#include <iprt/path.h>
#include <iprt/semaphore.h>
#include <iprt/thread.h>
#include <VBox/VBoxGuestLib.h>
#include <VBox/HostServices/GuestControlSvc.h>
#include "VBoxServiceInternal.h"
#include "VBoxServiceUtils.h"
-#include "VBoxServiceControlExecThread.h"
using namespace guestControl;
@@ -37,19 +38,70 @@ using namespace guestControl;
* Global Variables *
*******************************************************************************/
/** The control interval (milliseconds). */
-uint32_t g_ControlInterval = 0;
-/** The semaphore we're blocking on. */
+static uint32_t g_uControlIntervalMS = 0;
+/** The semaphore we're blocking our main control thread on. */
static RTSEMEVENTMULTI g_hControlEvent = NIL_RTSEMEVENTMULTI;
/** The guest control service client ID. */
-static uint32_t g_GuestControlSvcClientID = 0;
+static uint32_t g_uControlSvcClientID = 0;
/** How many started guest processes are kept into memory for supplying
- * information to the host. Default is 5 processes. If 0 is specified,
+ * information to the host. Default is 25 processes. If 0 is specified,
* the maximum number of processes is unlimited. */
-uint32_t g_GuestControlProcsMaxKept = 5;
-/** List of guest control threads. */
-RTLISTNODE g_GuestControlThreads;
+static uint32_t g_uControlProcsMaxKept = 25;
+#ifdef DEBUG
+static bool g_fControlDumpStdErr = false;
+static bool g_fControlDumpStdOut = false;
+#endif
+/** List of active guest control threads (VBOXSERVICECTRLTHREAD). */
+static RTLISTNODE g_lstControlThreadsActive;
+/** List of inactive guest control threads (VBOXSERVICECTRLTHREAD). */
+static RTLISTNODE g_lstControlThreadsInactive;
/** Critical section protecting g_GuestControlExecThreads. */
-RTCRITSECT g_GuestControlThreadsCritSect;
+static RTCRITSECT g_csControlThreads;
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+/** @todo Shorten "VBoxServiceControl" to "gstsvcCntl". */
+static int VBoxServiceControlReapThreads(void);
+static int VBoxServiceControlStartAllowed(bool *pbAllowed);
+static int VBoxServiceControlHandleCmdStartProc(uint32_t u32ClientId, uint32_t uNumParms);
+static int VBoxServiceControlHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, size_t cbMaxBufSize);
+static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms);
+
+
+#ifdef DEBUG
+static int vboxServiceControlDump(const char *pszFileName, void *pvBuf, size_t cbBuf)
+{
+ AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
+ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+
+ if (!cbBuf)
+ return VINF_SUCCESS;
+
+ char szFile[RTPATH_MAX];
+
+ int rc = RTPathTemp(szFile, sizeof(szFile));
+ if (RT_SUCCESS(rc))
+ rc = RTPathAppend(szFile, sizeof(szFile), pszFileName);
+
+ if (RT_SUCCESS(rc))
+ {
+ VBoxServiceVerbose(4, "Dumping %ld bytes to \"%s\"\n", cbBuf, szFile);
+
+ RTFILE fh;
+ rc = RTFileOpen(&fh, szFile, RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTFileWrite(fh, pvBuf, cbBuf, NULL /* pcbWritten */);
+ RTFileClose(fh);
+ }
+ }
+
+ return rc;
+}
+#endif
+
/** @copydoc VBOXSERVICE::pfnPreInit */
static DECLCALLBACK(int) VBoxServiceControlPreInit(void)
@@ -74,7 +126,7 @@ static DECLCALLBACK(int) VBoxServiceControlPreInit(void)
else
{
rc = VBoxServiceReadPropUInt32(uGuestPropSvcClientID, "/VirtualBox/GuestAdd/VBoxService/--control-procs-max-kept",
- &g_GuestControlProcsMaxKept, 0, UINT32_MAX - 1);
+ &g_uControlProcsMaxKept, 0, UINT32_MAX - 1);
VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
}
@@ -97,10 +149,22 @@ static DECLCALLBACK(int) VBoxServiceControlOption(const char **ppszShort, int ar
/* no short options */;
else if (!strcmp(argv[*pi], "--control-interval"))
rc = VBoxServiceArgUInt32(argc, argv, "", pi,
- &g_ControlInterval, 1, UINT32_MAX - 1);
+ &g_uControlIntervalMS, 1, UINT32_MAX - 1);
else if (!strcmp(argv[*pi], "--control-procs-max-kept"))
rc = VBoxServiceArgUInt32(argc, argv, "", pi,
- &g_GuestControlProcsMaxKept, 0, UINT32_MAX - 1);
+ &g_uControlProcsMaxKept, 0, UINT32_MAX - 1);
+#ifdef DEBUG
+ else if (!strcmp(argv[*pi], "--control-dump-stderr"))
+ {
+ g_fControlDumpStdErr = true;
+ rc = 0; /* Flag this command as parsed. */
+ }
+ else if (!strcmp(argv[*pi], "--control-dump-stdout"))
+ {
+ g_fControlDumpStdOut = true;
+ rc = 0; /* Flag this command as parsed. */
+ }
+#endif
return rc;
}
@@ -112,20 +176,23 @@ static DECLCALLBACK(int) VBoxServiceControlInit(void)
* If not specified, find the right interval default.
* Then create the event sem to block on.
*/
- if (!g_ControlInterval)
- g_ControlInterval = 1000;
+ if (!g_uControlIntervalMS)
+ g_uControlIntervalMS = 1000;
int rc = RTSemEventMultiCreate(&g_hControlEvent);
AssertRCReturn(rc, rc);
- rc = VbglR3GuestCtrlConnect(&g_GuestControlSvcClientID);
+ rc = VbglR3GuestCtrlConnect(&g_uControlSvcClientID);
if (RT_SUCCESS(rc))
{
- VBoxServiceVerbose(3, "Control: Service client ID: %#x\n", g_GuestControlSvcClientID);
+ VBoxServiceVerbose(3, "Control: Service client ID: %#x\n", g_uControlSvcClientID);
- /* Init thread list. */
- RTListInit(&g_GuestControlThreads);
- rc = RTCritSectInit(&g_GuestControlThreadsCritSect);
+ /* Init thread lists. */
+ RTListInit(&g_lstControlThreadsActive);
+ RTListInit(&g_lstControlThreadsInactive);
+
+ /* Init critical section for protecting the thread lists. */
+ rc = RTCritSectInit(&g_csControlThreads);
AssertRC(rc);
}
else
@@ -154,7 +221,7 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown)
* spawning services.
*/
RTThreadUserSignal(RTThreadSelf());
- Assert(g_GuestControlSvcClientID > 0);
+ Assert(g_uControlSvcClientID > 0);
int rc = VINF_SUCCESS;
@@ -165,41 +232,37 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown)
*/
for (;;)
{
- uint32_t uMsg;
- uint32_t uNumParms;
VBoxServiceVerbose(3, "Control: Waiting for host msg ...\n");
- rc = VbglR3GuestCtrlWaitForHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms);
- if (RT_FAILURE(rc))
+ uint32_t uMsg;
+ uint32_t cParms;
+ rc = VbglR3GuestCtrlWaitForHostMsg(g_uControlSvcClientID, &uMsg, &cParms);
+ if (rc == VERR_TOO_MUCH_DATA)
{
- if (rc == VERR_TOO_MUCH_DATA)
- {
- VBoxServiceVerbose(4, "Control: Message requires %ld parameters, but only 2 supplied -- retrying request (no error!)...\n", uNumParms);
- rc = VINF_SUCCESS; /* Try to get "real" message in next block below. */
- }
- else
- VBoxServiceVerbose(3, "Control: Getting host message failed with %Rrc\n", rc); /* VERR_GEN_IO_FAILURE seems to be normal if ran into timeout. */
+ VBoxServiceVerbose(4, "Control: Message requires %ld parameters, but only 2 supplied -- retrying request (no error!)...\n", cParms);
+ rc = VINF_SUCCESS; /* Try to get "real" message in next block below. */
}
-
+ else if (RT_FAILURE(rc))
+ VBoxServiceVerbose(3, "Control: Getting host message failed with %Rrc\n", rc); /* VERR_GEN_IO_FAILURE seems to be normal if ran into timeout. */
if (RT_SUCCESS(rc))
{
- VBoxServiceVerbose(3, "Control: Msg=%u (%u parms) retrieved\n", uMsg, uNumParms);
- switch(uMsg)
+ VBoxServiceVerbose(3, "Control: Msg=%u (%u parms) retrieved\n", uMsg, cParms);
+ switch (uMsg)
{
case HOST_CANCEL_PENDING_WAITS:
VBoxServiceVerbose(3, "Control: Host asked us to quit ...\n");
break;
case HOST_EXEC_CMD:
- rc = VBoxServiceControlExecHandleCmdStartProcess(g_GuestControlSvcClientID, uNumParms);
+ rc = VBoxServiceControlHandleCmdStartProc(g_uControlSvcClientID, cParms);
break;
case HOST_EXEC_SET_INPUT:
/** @todo Make buffer size configurable via guest properties/argv! */
- rc = VBoxServiceControlExecHandleCmdSetInput(g_GuestControlSvcClientID, uNumParms, _1M /* Buffer size */);
+ rc = VBoxServiceControlHandleCmdSetInput(g_uControlSvcClientID, cParms, _1M /* Buffer size */);
break;
case HOST_EXEC_GET_OUTPUT:
- rc = VBoxServiceControlExecHandleCmdGetOutput(g_GuestControlSvcClientID, uNumParms);
+ rc = VBoxServiceControlHandleCmdGetOutput(g_uControlSvcClientID, cParms);
break;
default:
@@ -207,9 +270,6 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown)
/* Don't terminate here; just wait for the next message. */
break;
}
-
- if (RT_FAILURE(rc))
- VBoxServiceVerbose(3, "Control: Message was processed with rc=%Rrc\n", rc);
}
/* Do we need to shutdown? */
@@ -224,107 +284,550 @@ DECLCALLBACK(int) VBoxServiceControlWorker(bool volatile *pfShutdown)
RTThreadYield();
}
- RTSemEventMultiDestroy(g_hControlEvent);
- g_hControlEvent = NIL_RTSEMEVENTMULTI;
return rc;
}
-/** @copydoc VBOXSERVICE::pfnStop */
-static DECLCALLBACK(void) VBoxServiceControlStop(void)
+/**
+ * Handles starting processes on the guest.
+ *
+ * @returns IPRT status code.
+ * @param uClientID The HGCM client session ID.
+ * @param cParms The number of parameters the host is offering.
+ */
+static int VBoxServiceControlHandleCmdStartProc(uint32_t uClientID, uint32_t cParms)
{
- VBoxServiceVerbose(3, "Control: Stopping ...\n");
+ uint32_t uContextID = 0;
- /** @todo Later, figure what to do if we're in RTProcWait(). it's a very
- * annoying call since doesn't support timeouts in the posix world. */
- RTSemEventMultiSignal(g_hControlEvent);
+ int rc;
+ bool fStartAllowed = false; /* Flag indicating whether starting a process is allowed or not. */
+ if (cParms == 11)
+ {
+ VBOXSERVICECTRLPROCESS proc;
+ RT_ZERO(proc);
- /*
- * Ask the host service to cancel all pending requests so that we can
- * shutdown properly here.
- */
- if (g_GuestControlSvcClientID)
+ rc = VbglR3GuestCtrlExecGetHostCmdExec(uClientID,
+ cParms,
+ &uContextID,
+ /* Command */
+ proc.szCmd, sizeof(proc.szCmd),
+ /* Flags */
+ &proc.uFlags,
+ /* Arguments */
+ proc.szArgs, sizeof(proc.szArgs), &proc.uNumArgs,
+ /* Environment */
+ proc.szEnv, &proc.cbEnv, &proc.uNumEnvVars,
+ /* Credentials */
+ proc.szUser, sizeof(proc.szUser),
+ proc.szPassword, sizeof(proc.szPassword),
+ /* Timelimit */
+ &proc.uTimeLimitMS);
+ if (RT_SUCCESS(rc))
+ {
+ VBoxServiceVerbose(3, "Control: Request to start process szCmd=%s, uFlags=0x%x, szArgs=%s, szEnv=%s, szUser=%s, uTimeout=%u\n",
+ proc.szCmd, proc.uFlags,
+ proc.uNumArgs ? proc.szArgs : "<None>",
+ proc.uNumEnvVars ? proc.szEnv : "<None>",
+ proc.szUser, proc.uTimeLimitMS);
+
+ rc = VBoxServiceControlReapThreads();
+ if (RT_FAILURE(rc))
+ VBoxServiceError("Control: Reaping stopped processes failed with rc=%Rrc\n", rc);
+ /* Keep going. */
+
+ rc = VBoxServiceControlStartAllowed(&fStartAllowed);
+ if (RT_SUCCESS(rc))
+ {
+ if (fStartAllowed)
+ {
+ rc = VBoxServiceControlThreadStart(uContextID, &proc);
+ }
+ else
+ rc = VERR_MAX_PROCS_REACHED; /* Maximum number of processes reached. */
+ }
+ }
+ }
+ else
+ rc = VERR_INVALID_PARAMETER; /* Incorrect number of parameters. */
+
+ /* In case of an error we need to notify the host to not wait forever for our response. */
+ if (RT_FAILURE(rc))
{
- int rc = VbglR3GuestCtrlCancelPendingWaits(g_GuestControlSvcClientID);
- if (RT_FAILURE(rc))
- VBoxServiceError("Control: Cancelling pending waits failed; rc=%Rrc\n", rc);
+ VBoxServiceError("Control: Starting process failed with rc=%Rrc\n", rc);
+
+ int rc2 = VbglR3GuestCtrlExecReportStatus(uClientID, uContextID, 0 /* PID, invalid. */,
+ PROC_STS_ERROR, rc,
+ NULL /* pvData */, 0 /* cbData */);
+ if (RT_FAILURE(rc2))
+ {
+ VBoxServiceError("Control: Error sending start process status to host, rc=%Rrc\n", rc2);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ }
}
+
+ return rc;
}
-void VBoxServiceControlThreadSignalShutdown(const PVBOXSERVICECTRLTHREAD pThread)
+/**
+ * Gets output from stdout/stderr of a specified guest process.
+ *
+ * @return IPRT status code.
+ * @param uPID PID of process to retrieve the output from.
+ * @param uHandleId Stream ID (stdout = 0, stderr = 2) to get the output from.
+ * @param uTimeout Timeout (in ms) to wait for output becoming available.
+ * @param pvBuf Pointer to a pre-allocated buffer to store the output.
+ * @param cbBuf Size (in bytes) of the pre-allocated buffer.
+ * @param pcbRead Pointer to number of bytes read. Optional.
+ */
+int VBoxServiceControlExecGetOutput(uint32_t uPID, uint32_t uCID,
+ uint32_t uHandleId, uint32_t uTimeout,
+ void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
{
- AssertPtrReturnVoid(pThread);
- ASMAtomicXchgBool(&pThread->fShutdown, true);
+ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
+ /* pcbRead is optional. */
+
+ int rc = VINF_SUCCESS;
+ VBOXSERVICECTRLREQUESTTYPE reqType;
+ switch (uHandleId)
+ {
+ case OUTPUT_HANDLE_ID_STDERR:
+ reqType = VBOXSERVICECTRLREQUEST_STDERR_READ;
+ break;
+
+ case OUTPUT_HANDLE_ID_STDOUT:
+ case OUTPUT_HANDLE_ID_STDOUT_DEPRECATED:
+ reqType = VBOXSERVICECTRLREQUEST_STDOUT_READ;
+ break;
+
+ default:
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+
+ PVBOXSERVICECTRLREQUEST pRequest;
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxServiceControlThreadRequestAllocEx(&pRequest, reqType,
+ pvBuf, cbBuf, uCID);
+ if (RT_SUCCESS(rc))
+ rc = VBoxServiceControlThreadPerform(uPID, pRequest);
+
+ if (RT_SUCCESS(rc))
+ {
+ if (pcbRead)
+ *pcbRead = pRequest->cbData;
+ }
+
+ VBoxServiceControlThreadRequestFree(pRequest);
+ }
+
+ return rc;
}
-int VBoxServiceControlThreadWaitForShutdown(const PVBOXSERVICECTRLTHREAD pThread)
+/**
+ * Sets the specified guest thread to a certain list.
+ *
+ * @return IPRT status code.
+ * @param enmList List to move thread to.
+ * @param pThread Thread to set inactive.
+ */
+int VBoxServiceControlListSet(VBOXSERVICECTRLTHREADLISTTYPE enmList,
+ PVBOXSERVICECTRLTHREAD pThread)
{
+ AssertReturn(enmList > VBOXSERVICECTRLTHREADLIST_UNKNOWN, VERR_INVALID_PARAMETER);
AssertPtrReturn(pThread, VERR_INVALID_POINTER);
- int rc = VINF_SUCCESS;
- if ( pThread->Thread != NIL_RTTHREAD
- && !pThread->fShutdown) /* Only shutdown threads which aren't yet. */
+
+ int rc = RTCritSectEnter(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
{
- /* Wait a bit ... */
- rc = RTThreadWait(pThread->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL);
+ VBoxServiceVerbose(3, "Control: Setting thread (PID %u) inactive\n",
+ pThread->uPID);
+
+ PRTLISTNODE pAnchor = NULL;
+ switch (enmList)
+ {
+ case VBOXSERVICECTRLTHREADLIST_STOPPED:
+ pAnchor = &g_lstControlThreadsInactive;
+ break;
+
+ case VBOXSERVICECTRLTHREADLIST_RUNNING:
+ pAnchor = &g_lstControlThreadsActive;
+ break;
+
+ default:
+ AssertMsgFailed(("Unknown list type: %u", enmList));
+ break;
+ }
+
+ if (!pAnchor)
+ rc = VERR_INVALID_PARAMETER;
+
+ if (RT_SUCCESS(rc))
+ {
+ if (pThread->pAnchor != NULL)
+ {
+ /* If thread was assigned to a list before,
+ * remove the thread from the old list first. */
+ /* rc = */ RTListNodeRemove(&pThread->Node);
+ }
+
+ /* Add thread to desired list. */
+ /* rc = */ RTListAppend(pAnchor, &pThread->Node);
+ pThread->pAnchor = pAnchor;
+ }
+
+ int rc2 = RTCritSectLeave(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
}
- return rc;
+
+ return VINF_SUCCESS;
}
-static void VBoxServiceControlDestroyThreads(void)
+/**
+ * Injects input to a specified running process.
+ *
+ * @return IPRT status code.
+ * @param uPID PID of process to set the input for.
+ * @param fPendingClose Flag indicating whether this is the last input block sent to the process.
+ * @param pvBuf Pointer to a buffer containing the actual input data.
+ * @param cbBuf Size (in bytes) of the input buffer data.
+ * @param pcbWritten Pointer to number of bytes written to the process. Optional.
+ */
+int VBoxServiceControlSetInput(uint32_t uPID, uint32_t uCID,
+ bool fPendingClose,
+ void *pvBuf, uint32_t cbBuf,
+ uint32_t *pcbWritten)
{
- VBoxServiceVerbose(3, "Control: Destroying threads ...\n");
+ /* pvBuf is optional. */
+ /* cbBuf is optional. */
+ /* pcbWritten is optional. */
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
+ PVBOXSERVICECTRLREQUEST pRequest;
+ int rc = VBoxServiceControlThreadRequestAllocEx(&pRequest,
+ fPendingClose
+ ? VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF
+ : VBOXSERVICECTRLREQUEST_STDIN_WRITE,
+ pvBuf, cbBuf, uCID);
if (RT_SUCCESS(rc))
{
- /* Signal all threads that we want to shutdown. */
- PVBOXSERVICECTRLTHREAD pNode;
- RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
- VBoxServiceControlThreadSignalShutdown(pNode);
+ rc = VBoxServiceControlThreadPerform(uPID, pRequest);
+ if (RT_SUCCESS(rc))
+ {
+ if (pcbWritten)
+ *pcbWritten = pRequest->cbData;
+ }
+
+ VBoxServiceControlThreadRequestFree(pRequest);
+ }
+
+ return rc;
+}
+
+
+/**
+ * Handles input for a started process by copying the received data into its
+ * stdin pipe.
+ *
+ * @returns IPRT status code.
+ * @param idClient The HGCM client session ID.
+ * @param cParms The number of parameters the host is
+ * offering.
+ * @param cMaxBufSize The maximum buffer size for retrieving the input data.
+ */
+static int VBoxServiceControlHandleCmdSetInput(uint32_t idClient, uint32_t cParms, size_t cbMaxBufSize)
+{
+ uint32_t uContextID;
+ uint32_t uPID;
+ uint32_t uFlags;
+ uint32_t cbSize;
- /* Wait for threads to shutdown. */
- RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
+ AssertReturn(RT_IS_POWER_OF_TWO(cbMaxBufSize), VERR_INVALID_PARAMETER);
+ uint8_t *pabBuffer = (uint8_t*)RTMemAlloc(cbMaxBufSize);
+ AssertPtrReturn(pabBuffer, VERR_NO_MEMORY);
+
+ uint32_t uStatus = INPUT_STS_UNDEFINED; /* Status sent back to the host. */
+ uint32_t cbWritten = 0; /* Number of bytes written to the guest. */
+
+ /*
+ * Ask the host for the input data.
+ */
+ int rc = VbglR3GuestCtrlExecGetHostCmdInput(idClient, cParms,
+ &uContextID, &uPID, &uFlags,
+ pabBuffer, cbMaxBufSize, &cbSize);
+ if (RT_FAILURE(rc))
+ {
+ VBoxServiceError("Control: [PID %u]: Failed to retrieve exec input command! Error: %Rrc\n",
+ uPID, rc);
+ }
+ else if (cbSize > cbMaxBufSize)
+ {
+ VBoxServiceError("Control: [PID %u]: Too much input received! cbSize=%u, cbMaxBufSize=%u\n",
+ uPID, cbSize, cbMaxBufSize);
+ rc = VERR_INVALID_PARAMETER;
+ }
+ else
+ {
+ /*
+ * Is this the last input block we need to deliver? Then let the pipe know ...
+ */
+ bool fPendingClose = false;
+ if (uFlags & INPUT_FLAG_EOF)
{
- int rc2 = VBoxServiceControlThreadWaitForShutdown(pNode);
- if (RT_FAILURE(rc2))
- VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2);
+ fPendingClose = true;
+ VBoxServiceVerbose(4, "Control: [PID %u]: Got last input block of size %u ...\n",
+ uPID, cbSize);
+ }
- /* Destroy thread specific data. */
- switch (pNode->enmType)
+ rc = VBoxServiceControlSetInput(uPID, uContextID, fPendingClose, pabBuffer,
+ cbSize, &cbWritten);
+ VBoxServiceVerbose(4, "Control: [PID %u]: Written input, CID=%u, rc=%Rrc, uFlags=0x%x, fPendingClose=%d, cbSize=%u, cbWritten=%u\n",
+ uPID, uContextID, rc, uFlags, fPendingClose, cbSize, cbWritten);
+ if (RT_SUCCESS(rc))
+ {
+ if (cbWritten || !cbSize) /* Did we write something or was there anything to write at all? */
{
- case kVBoxServiceCtrlThreadDataExec:
- VBoxServiceControlExecThreadDataDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData);
- break;
+ uStatus = INPUT_STS_WRITTEN;
+ uFlags = 0;
+ }
+ }
+ else
+ {
+ if (rc == VERR_BAD_PIPE)
+ uStatus = INPUT_STS_TERMINATED;
+ else if (rc == VERR_BUFFER_OVERFLOW)
+ uStatus = INPUT_STS_OVERFLOW;
+ }
+ }
+ RTMemFree(pabBuffer);
- default:
- break;
+ /*
+ * If there was an error and we did not set the host status
+ * yet, then do it now.
+ */
+ if ( RT_FAILURE(rc)
+ && uStatus == INPUT_STS_UNDEFINED)
+ {
+ uStatus = INPUT_STS_ERROR;
+ uFlags = rc;
+ }
+ Assert(uStatus > INPUT_STS_UNDEFINED);
+
+ VBoxServiceVerbose(3, "Control: [PID %u]: Input processed, CID=%u, uStatus=%u, uFlags=0x%x, cbWritten=%u\n",
+ uPID, uContextID, uStatus, uFlags, cbWritten);
+
+ /* Note: Since the context ID is unique the request *has* to be completed here,
+ * regardless whether we got data or not! Otherwise the progress object
+ * on the host never will get completed! */
+ rc = VbglR3GuestCtrlExecReportStatusIn(idClient, uContextID, uPID,
+ uStatus, uFlags, (uint32_t)cbWritten);
+
+ if (RT_FAILURE(rc))
+ VBoxServiceError("Control: [PID %u]: Failed to report input status! Error: %Rrc\n",
+ uPID, rc);
+ return rc;
+}
+
+
+/**
+ * Handles the guest control output command.
+ *
+ * @return IPRT status code.
+ * @param idClient The HGCM client session ID.
+ * @param cParms The number of parameters the host is offering.
+ */
+static int VBoxServiceControlHandleCmdGetOutput(uint32_t idClient, uint32_t cParms)
+{
+ uint32_t uContextID;
+ uint32_t uPID;
+ uint32_t uHandleID;
+ uint32_t uFlags;
+
+ int rc = VbglR3GuestCtrlExecGetHostCmdOutput(idClient, cParms,
+ &uContextID, &uPID, &uHandleID, &uFlags);
+ if (RT_SUCCESS(rc))
+ {
+ uint8_t *pBuf = (uint8_t*)RTMemAlloc(_64K);
+ if (pBuf)
+ {
+ uint32_t cbRead = 0;
+ rc = VBoxServiceControlExecGetOutput(uPID, uContextID, uHandleID, RT_INDEFINITE_WAIT /* Timeout */,
+ pBuf, _64K /* cbSize */, &cbRead);
+ VBoxServiceVerbose(3, "Control: [PID %u]: Got output, rc=%Rrc, CID=%u, cbRead=%u, uHandle=%u, uFlags=%u\n",
+ uPID, rc, uContextID, cbRead, uHandleID, uFlags);
+
+#ifdef DEBUG
+ if ( g_fControlDumpStdErr
+ && uHandleID == OUTPUT_HANDLE_ID_STDERR)
+ {
+ char szPID[RTPATH_MAX];
+ if (!RTStrPrintf(szPID, sizeof(szPID), "VBoxService_PID%u_StdOut.txt", uPID))
+ rc = VERR_BUFFER_UNDERFLOW;
+ if (RT_SUCCESS(rc))
+ rc = vboxServiceControlDump(szPID, pBuf, cbRead);
}
+ else if ( g_fControlDumpStdOut
+ && ( uHandleID == OUTPUT_HANDLE_ID_STDOUT
+ || uHandleID == OUTPUT_HANDLE_ID_STDOUT_DEPRECATED))
+ {
+ char szPID[RTPATH_MAX];
+ if (!RTStrPrintf(szPID, sizeof(szPID), "VBoxService_PID%u_StdOut.txt", uPID))
+ rc = VERR_BUFFER_UNDERFLOW;
+ if (RT_SUCCESS(rc))
+ rc = vboxServiceControlDump(szPID, pBuf, cbRead);
+ AssertRC(rc);
+ }
+#endif
+ /** Note: Don't convert/touch/modify/whatever the output data here! This might be binary
+ * data which the host needs to work with -- so just pass through all data unfiltered! */
+
+ /* Note: Since the context ID is unique the request *has* to be completed here,
+ * regardless whether we got data or not! Otherwise the progress object
+ * on the host never will get completed! */
+ int rc2 = VbglR3GuestCtrlExecSendOut(idClient, uContextID, uPID, uHandleID, uFlags,
+ pBuf, cbRead);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ else if (rc == VERR_NOT_FOUND) /* It's not critical if guest process (PID) is not found. */
+ rc = VINF_SUCCESS;
+
+ RTMemFree(pBuf);
}
+ else
+ rc = VERR_NO_MEMORY;
+ }
+
+ if (RT_FAILURE(rc))
+ VBoxServiceError("Control: [PID %u]: Error handling output command! Error: %Rrc\n",
+ uPID, rc);
+ return rc;
+}
+
+
+/** @copydoc VBOXSERVICE::pfnStop */
+static DECLCALLBACK(void) VBoxServiceControlStop(void)
+{
+ VBoxServiceVerbose(3, "Control: Stopping ...\n");
+
+ /** @todo Later, figure what to do if we're in RTProcWait(). It's a very
+ * annoying call since doesn't support timeouts in the posix world. */
+ if (g_hControlEvent != NIL_RTSEMEVENTMULTI)
+ RTSemEventMultiSignal(g_hControlEvent);
+
+ /*
+ * Ask the host service to cancel all pending requests so that we can
+ * shutdown properly here.
+ */
+ if (g_uControlSvcClientID)
+ {
+ VBoxServiceVerbose(3, "Control: Cancelling pending waits (client ID=%u) ...\n",
+ g_uControlSvcClientID);
+
+ int rc = VbglR3GuestCtrlCancelPendingWaits(g_uControlSvcClientID);
+ if (RT_FAILURE(rc))
+ VBoxServiceError("Control: Cancelling pending waits failed; rc=%Rrc\n", rc);
+ }
+}
+
- /* Finally destroy thread list. */
- pNode = RTListGetFirst(&g_GuestControlThreads, VBOXSERVICECTRLTHREAD, Node);
- while (pNode)
+/**
+ * Reaps all inactive guest process threads.
+ *
+ * @return IPRT status code.
+ */
+static int VBoxServiceControlReapThreads(void)
+{
+ int rc = RTCritSectEnter(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ {
+ PVBOXSERVICECTRLTHREAD pThread =
+ RTListGetFirst(&g_lstControlThreadsInactive, VBOXSERVICECTRLTHREAD, Node);
+ while (pThread)
{
- PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node);
- bool fLast = RTListNodeIsLast(&g_GuestControlThreads, &pNode->Node);
+ PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pThread->Node, VBOXSERVICECTRLTHREAD, Node);
+ bool fLast = RTListNodeIsLast(&g_lstControlThreadsInactive, &pThread->Node);
+
+ int rc2 = VBoxServiceControlThreadWait(pThread, 30 * 1000 /* 30 seconds max. */);
+ if (RT_SUCCESS(rc2))
+ {
+ RTListNodeRemove(&pThread->Node);
- RTListNodeRemove(&pNode->Node);
- RTMemFree(pNode);
+ rc2 = VBoxServiceControlThreadFree(pThread);
+ if (RT_FAILURE(rc2))
+ {
+ VBoxServiceError("Control: Stopping guest process thread failed with rc=%Rrc\n", rc2);
+ if (RT_SUCCESS(rc)) /* Keep original failure. */
+ rc = rc2;
+ }
+ }
+ else
+ VBoxServiceError("Control: Waiting on guest process thread failed with rc=%Rrc\n", rc2);
+ /* Keep going. */
if (fLast)
break;
- pNode = pNext;
+ pThread = pNext;
}
- int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
+ int rc2 = RTCritSectLeave(&g_csControlThreads);
if (RT_SUCCESS(rc))
rc = rc2;
}
- RTCritSectDelete(&g_GuestControlThreadsCritSect);
+
+ VBoxServiceVerbose(4, "Control: Reaping threads returned with rc=%Rrc\n", rc);
+ return rc;
+}
+
+
+/**
+ * Destroys all guest process threads which are still active.
+ */
+static void VBoxServiceControlShutdown(void)
+{
+ VBoxServiceVerbose(2, "Control: Shutting down ...\n");
+
+ /* Signal all threads in the active list that we want to shutdown. */
+ PVBOXSERVICECTRLTHREAD pThread;
+ RTListForEach(&g_lstControlThreadsActive, pThread, VBOXSERVICECTRLTHREAD, Node)
+ VBoxServiceControlThreadStop(pThread);
+
+ /* Wait for all active threads to shutdown and destroy the active thread list. */
+ pThread = RTListGetFirst(&g_lstControlThreadsActive, VBOXSERVICECTRLTHREAD, Node);
+ while (pThread)
+ {
+ PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pThread->Node, VBOXSERVICECTRLTHREAD, Node);
+ bool fLast = RTListNodeIsLast(&g_lstControlThreadsActive, &pThread->Node);
+
+ int rc2 = VBoxServiceControlThreadWait(pThread,
+ 30 * 1000 /* Wait 30 seconds max. */);
+ if (RT_FAILURE(rc2))
+ VBoxServiceError("Control: Guest process thread failed to stop; rc=%Rrc\n", rc2);
+
+ if (fLast)
+ break;
+
+ pThread = pNext;
+ }
+
+ int rc2 = VBoxServiceControlReapThreads();
+ if (RT_FAILURE(rc2))
+ VBoxServiceError("Control: Reaping inactive threads failed with rc=%Rrc\n", rc2);
+
+ AssertMsg(RTListIsEmpty(&g_lstControlThreadsActive),
+ ("Guest process active thread list still contains entries when it should not\n"));
+ AssertMsg(RTListIsEmpty(&g_lstControlThreadsInactive),
+ ("Guest process inactive thread list still contains entries when it should not\n"));
+
+ /* Destroy critical section. */
+ RTCritSectDelete(&g_csControlThreads);
+
+ VBoxServiceVerbose(2, "Control: Shutting down complete\n");
}
@@ -333,10 +836,12 @@ static DECLCALLBACK(void) VBoxServiceControlTerm(void)
{
VBoxServiceVerbose(3, "Control: Terminating ...\n");
- VBoxServiceControlDestroyThreads();
+ VBoxServiceControlShutdown();
- VbglR3GuestCtrlDisconnect(g_GuestControlSvcClientID);
- g_GuestControlSvcClientID = 0;
+ VBoxServiceVerbose(3, "Control: Disconnecting client ID=%u ...\n",
+ g_uControlSvcClientID);
+ VbglR3GuestCtrlDisconnect(g_uControlSvcClientID);
+ g_uControlSvcClientID = 0;
if (g_hControlEvent != NIL_RTSEMEVENTMULTI)
{
@@ -347,6 +852,152 @@ static DECLCALLBACK(void) VBoxServiceControlTerm(void)
/**
+ * Determines whether starting a new guest process according to the
+ * maximum number of concurrent guest processes defined is allowed or not.
+ *
+ * @return IPRT status code.
+ * @param pbAllowed True if starting (another) guest process
+ * is allowed, false if not.
+ */
+static int VBoxServiceControlStartAllowed(bool *pbAllowed)
+{
+ AssertPtrReturn(pbAllowed, VERR_INVALID_POINTER);
+
+ int rc = RTCritSectEnter(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Check if we're respecting our memory policy by checking
+ * how many guest processes are started and served already.
+ */
+ bool fLimitReached = false;
+ if (g_uControlProcsMaxKept) /* If we allow unlimited processes (=0), take a shortcut. */
+ {
+ uint32_t uProcsRunning = 0;
+ PVBOXSERVICECTRLTHREAD pThread;
+ RTListForEach(&g_lstControlThreadsActive, pThread, VBOXSERVICECTRLTHREAD, Node)
+ uProcsRunning++;
+
+ VBoxServiceVerbose(3, "Control: Maximum served guest processes set to %u, running=%u\n",
+ g_uControlProcsMaxKept, uProcsRunning);
+
+ int32_t iProcsLeft = (g_uControlProcsMaxKept - uProcsRunning - 1);
+ if (iProcsLeft < 0)
+ {
+ VBoxServiceVerbose(3, "Control: Maximum running guest processes reached (%u)\n",
+ g_uControlProcsMaxKept);
+ fLimitReached = true;
+ }
+ }
+
+ *pbAllowed = !fLimitReached;
+
+ int rc2 = RTCritSectLeave(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Finds a (formerly) started process given by its PID and locks it. Must be unlocked
+ * by the caller with VBoxServiceControlThreadUnlock().
+ *
+ * @return PVBOXSERVICECTRLTHREAD Process structure if found, otherwise NULL.
+ * @param uPID PID to search for.
+ */
+PVBOXSERVICECTRLTHREAD VBoxServiceControlLockThread(uint32_t uPID)
+{
+ PVBOXSERVICECTRLTHREAD pThread = NULL;
+ int rc = RTCritSectEnter(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ {
+ PVBOXSERVICECTRLTHREAD pThreadCur;
+ RTListForEach(&g_lstControlThreadsActive, pThreadCur, VBOXSERVICECTRLTHREAD, Node)
+ {
+ if (pThreadCur->uPID == uPID)
+ {
+ rc = RTCritSectEnter(&pThreadCur->CritSect);
+ if (RT_SUCCESS(rc))
+ pThread = pThreadCur;
+ break;
+ }
+ }
+
+ int rc2 = RTCritSectLeave(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ }
+
+ return pThread;
+}
+
+
+/**
+ * Unlocks a previously locked guest process thread.
+ *
+ * @param pThread Thread to unlock.
+ */
+void VBoxServiceControlUnlockThread(const PVBOXSERVICECTRLTHREAD pThread)
+{
+ AssertPtr(pThread);
+
+ int rc = RTCritSectLeave(&pThread->CritSect);
+ AssertRC(rc);
+}
+
+
+/**
+ * Assigns a valid PID to a guest control thread and also checks if there already was
+ * another (stale) guest process which was using that PID before and destroys it.
+ *
+ * @return IPRT status code.
+ * @param pThread Thread to assign PID to.
+ * @param uPID PID to assign to the specified guest control execution thread.
+ */
+int VBoxServiceControlAssignPID(PVBOXSERVICECTRLTHREAD pThread, uint32_t uPID)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ AssertReturn(uPID, VERR_INVALID_PARAMETER);
+
+ int rc = RTCritSectEnter(&g_csControlThreads);
+ if (RT_SUCCESS(rc))
+ {
+ /* Search old threads using the desired PID and shut them down completely -- it's
+ * not used anymore. */
+ PVBOXSERVICECTRLTHREAD pThreadCur;
+ bool fTryAgain = false;
+ do
+ {
+ RTListForEach(&g_lstControlThreadsActive, pThreadCur, VBOXSERVICECTRLTHREAD, Node)
+ {
+ if (pThreadCur->uPID == uPID)
+ {
+ Assert(pThreadCur != pThread); /* can't happen */
+ uint32_t uTriedPID = uPID;
+ uPID += 391939;
+ VBoxServiceVerbose(2, "ControlThread: PID %u was used before, trying again with %u ...\n",
+ uTriedPID, uPID);
+ fTryAgain = true;
+ break;
+ }
+ }
+ } while (fTryAgain);
+
+ /* Assign PID to current thread. */
+ pThread->uPID = uPID;
+
+ rc = RTCritSectLeave(&g_csControlThreads);
+ AssertRC(rc);
+ }
+
+ return rc;
+}
+
+
+/**
* The 'vminfo' service description.
*/
VBOXSERVICE g_Control =
@@ -356,14 +1007,24 @@ VBOXSERVICE g_Control =
/* pszDescription. */
"Host-driven Guest Control",
/* pszUsage. */
- " [--control-interval <ms>] [--control-procs-max-kept <x>]"
+#ifdef DEBUG
+ " [--control-dump-stderr] [--control-dump-stdout]\n"
+#endif
+ " [--control-interval <ms>] [--control-procs-max-kept <x>]\n"
+ " [--control-procs-mem-std[in|out|err] <KB>]"
,
/* pszOptions. */
+#ifdef DEBUG
+ " --control-dump-stderr Dumps all guest proccesses stderr data to the\n"
+ " temporary directory.\n"
+ " --control-dump-stdout Dumps all guest proccesses stdout data to the\n"
+ " temporary directory.\n"
+#endif
" --control-interval Specifies the interval at which to check for\n"
" new control commands. The default is 1000 ms.\n"
" --control-procs-max-kept\n"
" Specifies how many started guest processes are\n"
- " kept into memory to work with.\n"
+ " kept into memory to work with. Default is 25.\n"
,
/* methods */
VBoxServiceControlPreInit,
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
deleted file mode 100644
index 1c7b7c280..000000000
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
+++ /dev/null
@@ -1,1444 +0,0 @@
-/* $Id: VBoxServiceControlExec.cpp $ */
-/** @file
- * VBoxServiceControlExec - Utility functions for process execution.
- */
-
-/*
- * 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 <iprt/assert.h>
-#include <iprt/crc.h>
-#include <iprt/ctype.h>
-#include <iprt/env.h>
-#include <iprt/file.h>
-#include <iprt/getopt.h>
-#include <iprt/handle.h>
-#include <iprt/mem.h>
-#include <iprt/path.h>
-#include <iprt/param.h>
-#include <iprt/pipe.h>
-#include <iprt/poll.h>
-#include <iprt/process.h>
-#include <iprt/string.h>
-#include <iprt/stream.h>
-#include <iprt/thread.h>
-#include <VBox/version.h>
-#include <VBox/VBoxGuestLib.h>
-#include <VBox/HostServices/GuestControlSvc.h>
-
-#include "VBoxServiceInternal.h"
-#include "VBoxServiceUtils.h"
-#include "VBoxServicePipeBuf.h"
-#include "VBoxServiceControlExecThread.h"
-
-using namespace guestControl;
-
-extern RTLISTNODE g_GuestControlThreads;
-extern RTCRITSECT g_GuestControlThreadsCritSect;
-
-
-/**
- * Handle an error event on standard input.
- *
- * @returns IPRT status code.
- * @param hPollSet The polling set.
- * @param fPollEvt The event mask returned by RTPollNoResume.
- * @param phStdInW The standard input pipe handle.
- * @param pStdInBuf The standard input buffer.
- */
-static int VBoxServiceControlExecProcHandleStdInErrorEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW,
- PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf)
-{
- int rc = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE);
- /* Don't assert if writable handle is not in poll set anymore. */
- if ( RT_FAILURE(rc)
- && rc != VERR_POLL_HANDLE_ID_NOT_FOUND)
- {
- AssertRC(rc);
- }
-
- /* Close writable stdin pipe. */
- rc = RTPipeClose(*phStdInW);
- AssertRC(rc);
- *phStdInW = NIL_RTPIPE;
-
- /* Mark the stdin buffer as dead; we're not using it anymore. */
- rc = VBoxServicePipeBufSetStatus(pStdInBuf, false /* Disabled */);
- AssertRC(rc);
-
- /* Remove stdin error handle from set. */
- rc = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_ERROR);
- /* Don't assert if writable handle is not in poll set anymore. */
- if ( RT_FAILURE(rc)
- && rc != VERR_POLL_HANDLE_ID_NOT_FOUND)
- {
- AssertRC(rc);
- }
- else
- rc = VINF_SUCCESS;
-
- return rc;
-}
-
-
-/**
- * Try write some more data to the standard input of the child.
- *
- * @returns IPRT status code.
- * @retval VINF_TRY_AGAIN if there is still data left in the buffer.
- *
- * @param hPollSet The polling set.
- * @param pStdInBuf The standard input buffer.
- * @param hStdInW The standard input pipe.
- * @param pfClose Pointer to a flag whether the pipe needs to be closed afterwards.
- */
-static int VBoxServiceControlExecProcWriteStdIn(RTPOLLSET hPollSet, PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf, RTPIPE hStdInW,
- size_t *pcbWritten, bool *pfClose)
-{
- AssertPtrReturn(pStdInBuf, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pcbWritten, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pfClose, VERR_INVALID_PARAMETER);
-
- size_t cbLeft;
- int rc = VBoxServicePipeBufWriteToPipe(pStdInBuf, hStdInW, pcbWritten, &cbLeft);
-
- /* If we have written all data which is in the buffer set the close flag. */
- *pfClose = (cbLeft == 0) && VBoxServicePipeBufIsClosing(pStdInBuf);
-
- if ( !*pcbWritten
- && VBoxServicePipeBufIsEnabled(pStdInBuf))
- {
- /*
- * Nothing else left to write now? Remove the writable event from the poll set
- * to not trigger too high CPU loads.
- */
- int rc2 = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE);
- AssertRC(rc2);
- }
-
- VBoxServiceVerbose(3, "VBoxServiceControlExecProcWriteStdIn: Written=%u, Left=%u, rc=%Rrc\n",
- *pcbWritten, cbLeft, rc);
- return rc;
-}
-
-
-/**
- * Handle an event indicating we can write to the standard input pipe of the
- * child process.
- *
- * @returns IPRT status code.
- * @param hPollSet The polling set.
- * @param fPollEvt The event mask returned by RTPollNoResume.
- * @param phStdInW The standard input pipe.
- * @param pStdInBuf The standard input buffer.
- * @param pcbWritten Where to return the number of bytes written.
- */
-static int VBoxServiceControlExecProcHandleStdInWritableEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW,
- PVBOXSERVICECTRLEXECPIPEBUF pStdInBuf, size_t *pcbWritten)
-{
- AssertPtrReturn(pcbWritten, VERR_INVALID_PARAMETER);
- int rc;
- if (!(fPollEvt & RTPOLL_EVT_ERROR))
- {
- bool fClose;
- rc = VBoxServiceControlExecProcWriteStdIn(hPollSet,
- pStdInBuf, *phStdInW,
- pcbWritten, &fClose);
- if ( rc == VINF_TRY_AGAIN
- || rc == VERR_MORE_DATA)
- rc = VINF_SUCCESS;
- if (RT_FAILURE(rc))
- {
- if ( rc == VERR_BAD_PIPE
- || rc == VERR_BROKEN_PIPE)
- {
- rc = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE);
- AssertRC(rc);
- }
- else
- {
- /** @todo Do we need to do something about this error condition? */
- AssertRC(rc);
- }
- }
- else if (fClose)
- {
- /* If the pipe needs to be closed, do so. */
- rc = VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, pStdInBuf);
- }
- }
- else
- {
- *pcbWritten = 0;
- rc = VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, pStdInBuf);
- }
- return rc;
-}
-
-
-/**
- * Handle pending output data/error on stdout or stderr.
- *
- * @return IPRT status code.
- * @param hPollSet The polling set.
- * @param fPollEvt The event mask returned by RTPollNoResume.
- * @param phPipeR The pipe to be read from.
- * @param uHandleId Handle ID of the pipe to be read from.
- * @param pBuf Pointer to pipe buffer to store the read data into.
- */
-static int VBoxServiceControlExecProcHandleOutputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR,
- uint32_t uHandleId, PVBOXSERVICECTRLEXECPIPEBUF pBuf)
-{
- AssertPtrReturn(phPipeR, VERR_INVALID_POINTER);
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
-
- /*
- * Try drain the pipe before acting on any errors.
- */
- int rc = VINF_SUCCESS;
- size_t cbRead;
- uint8_t abBuf[_64K];
-
- int rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead);
- if (RT_SUCCESS(rc2) && cbRead)
- {
- uint32_t cbWritten;
- rc = VBoxServicePipeBufWriteToBuf(pBuf, abBuf,
- cbRead, false /* Pending close */, &cbWritten);
-#ifdef DEBUG_andy
- VBoxServiceVerbose(4, "ControlExec: Written output event [%u %u], cbRead=%u, cbWritten=%u, rc=%Rrc, uHandleId=%u, fPollEvt=%#x\n",
- pBuf->uPID, pBuf->uPipeId, cbRead, cbWritten, rc, uHandleId, fPollEvt);
-#endif
- if (RT_SUCCESS(rc))
- {
- Assert(cbRead == cbWritten);
- /* Make sure we go another poll round in case there was too much data
- for the buffer to hold. */
- fPollEvt &= RTPOLL_EVT_ERROR;
- }
- }
- else if (RT_FAILURE(rc2))
- {
- fPollEvt |= RTPOLL_EVT_ERROR;
- AssertMsg(rc2 == VERR_BROKEN_PIPE, ("%Rrc\n", rc));
- }
-
- /*
- * If an error was signalled, close reading stdout/stderr pipe.
- */
- if (fPollEvt & RTPOLL_EVT_ERROR)
- {
- rc2 = RTPollSetRemove(hPollSet, uHandleId);
- AssertRC(rc2);
-
- rc2 = RTPipeClose(*phPipeR);
- AssertRC(rc2);
- *phPipeR = NIL_RTPIPE;
-
- /* Sinc some error occured (or because the pipe simply broke) we
- * have to set our pipe buffer to disabled so that others don't wait
- * for new data to arrive anymore. */
- VBoxServicePipeBufSetStatus(pBuf, false);
- }
- return rc;
-}
-
-
-int VBoxServiceControlExecProcHandleStdInputNotify(RTPOLLSET hPollSet,
- PRTPIPE phNotificationPipeR, PRTPIPE phInputPipeW)
-{
-#ifdef DEBUG_andy
- VBoxServiceVerbose(4, "ControlExec: HandleStdInputNotify\n");
-#endif
- /* Drain the notification pipe. */
- uint8_t abBuf[8];
- size_t cbIgnore;
- int rc = RTPipeRead(*phNotificationPipeR, abBuf, sizeof(abBuf), &cbIgnore);
- if (RT_SUCCESS(rc))
- {
- /*
- * When the writable handle previously was removed from the poll set we need to add
- * it here again so that writable events from the started procecss get handled correctly.
- */
- RTHANDLE hWritableIgnored;
- rc = RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE, &hWritableIgnored);
- if (rc == VERR_POLL_HANDLE_ID_NOT_FOUND)
- rc = RTPollSetAddPipe(hPollSet, *phInputPipeW, RTPOLL_EVT_WRITE, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE);
- }
- return rc;
-}
-
-
-/**
- * Execution loop which runs in a dedicated per-started-process thread and
- * handles all pipe input/output and signalling stuff.
- *
- * @return IPRT status code.
- * @param pThread The process' thread handle.
- * @param hProcess The actual process handle.
- * @param cMsTimeout Time limit (in ms) of the process' life time.
- * @param hPollSet The poll set to use.
- * @param hStdInW Handle to the process' stdin write end.
- * @param hStdOutR Handle to the process' stdout read end.
- * @param hStdErrR Handle to the process' stderr read end.
- */
-static int VBoxServiceControlExecProcLoop(PVBOXSERVICECTRLTHREAD pThread,
- RTPROCESS hProcess, RTMSINTERVAL cMsTimeout, RTPOLLSET hPollSet,
- PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR)
-{
- AssertPtrReturn(phStdInW, VERR_INVALID_PARAMETER);
- AssertPtrReturn(phStdOutR, VERR_INVALID_PARAMETER);
- AssertPtrReturn(phStdErrR, VERR_INVALID_PARAMETER);
-
- int rc;
- int rc2;
- uint64_t const MsStart = RTTimeMilliTS();
- RTPROCSTATUS ProcessStatus = { 254, RTPROCEXITREASON_ABEND };
- bool fProcessAlive = true;
- bool fProcessTimedOut = false;
- uint64_t MsProcessKilled = UINT64_MAX;
- RTMSINTERVAL const cMsPollBase = *phStdInW != NIL_RTPIPE
- ? 100 /* Need to poll for input. */
- : 1000; /* Need only poll for process exit and aborts. */
- RTMSINTERVAL cMsPollCur = 0;
-
- AssertPtr(pThread);
- Assert(pThread->enmType == kVBoxServiceCtrlThreadDataExec);
- PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
- AssertPtr(pData);
-
- /*
- * Assign PID to thread data.
- * Also check if there already was a thread with the same PID and shut it down -- otherwise
- * the first (stale) entry will be found and we get really weird results!
- */
- rc = VBoxServiceControlExecThreadAssignPID(pData, hProcess);
- if (RT_FAILURE(rc))
- {
- VBoxServiceError("ControlExec: Unable to assign PID to new thread, rc=%Rrc\n", rc);
- return rc;
- }
-
- /*
- * Before entering the loop, tell the host that we've started the guest
- * and that it's now OK to send input to the process.
- */
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Process started, CID=%u, User=%s\n",
- pData->uPID, pThread->uContextID, pData->pszUser);
- rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
- pData->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
- NULL /* pvData */, 0 /* cbData */);
-
- /*
- * Process input, output, the test pipe and client requests.
- */
- while ( RT_SUCCESS(rc)
- && RT_UNLIKELY(!pThread->fShutdown))
- {
- /*
- * Wait/Process all pending events.
- */
- uint32_t idPollHnd;
- uint32_t fPollEvt;
- rc2 = RTPollNoResume(hPollSet, cMsPollCur, &fPollEvt, &idPollHnd);
- if (pThread->fShutdown)
- continue;
-
- cMsPollCur = 0; /* No rest until we've checked everything. */
-
- if (RT_SUCCESS(rc2))
- {
- /*VBoxServiceVerbose(4, "ControlExec: [PID %u}: RTPollNoResume idPollHnd=%u\n",
- pData->uPID, idPollHnd);*/
- switch (idPollHnd)
- {
- case VBOXSERVICECTRLPIPEID_STDIN_ERROR:
- rc = VBoxServiceControlExecProcHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW, &pData->stdIn);
- break;
-
- case VBOXSERVICECTRLPIPEID_STDIN_INPUT_NOTIFY:
- rc = VBoxServiceControlExecProcHandleStdInputNotify(hPollSet,
- &pData->stdIn.hNotificationPipeR, &pData->pipeStdInW);
- AssertRC(rc);
- /* Fall through. */
- case VBOXSERVICECTRLPIPEID_STDIN_WRITABLE:
- {
- size_t cbWritten;
- rc = VBoxServiceControlExecProcHandleStdInWritableEvent(hPollSet, fPollEvt, phStdInW,
- &pData->stdIn, &cbWritten);
- break;
- }
-
- case VBOXSERVICECTRLPIPEID_STDOUT:
-#ifdef DEBUG
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: StdOut fPollEvt=%#x\n",
- pData->uPID, fPollEvt);
-#endif
- rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, phStdOutR,
- VBOXSERVICECTRLPIPEID_STDOUT, &pData->stdOut);
- break;
-
- case VBOXSERVICECTRLPIPEID_STDERR:
-#ifdef DEBUG
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: StdErr: fPollEvt=%#x\n",
- pData->uPID, fPollEvt);
-#endif
- rc = VBoxServiceControlExecProcHandleOutputEvent(hPollSet, fPollEvt, phStdErrR,
- VBOXSERVICECTRLPIPEID_STDERR, &pData->stdErr);
- break;
-
- default:
- AssertMsgFailed(("PID=%u idPollHnd=%u fPollEvt=%#x\n",
- pData->uPID, idPollHnd, fPollEvt));
- break;
- }
- if (RT_FAILURE(rc) || rc == VINF_EOF)
- break; /* Abort command, or client dead or something. */
- continue;
- }
-
- /*
- * Check for process death.
- */
- if (fProcessAlive)
- {
- rc2 = RTProcWaitNoResume(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
- if (RT_SUCCESS_NP(rc2))
- {
- fProcessAlive = false;
- continue;
- }
- if (RT_UNLIKELY(rc2 == VERR_INTERRUPTED))
- continue;
- if (RT_UNLIKELY(rc2 == VERR_PROCESS_NOT_FOUND))
- {
- fProcessAlive = false;
- ProcessStatus.enmReason = RTPROCEXITREASON_ABEND;
- ProcessStatus.iStatus = 255;
- AssertFailed();
- }
- else
- AssertMsg(rc2 == VERR_PROCESS_RUNNING, ("%Rrc\n", rc2));
- }
-
- /*
- * If the process has terminated, we're should head out.
- */
- if (!fProcessAlive)
- break;
-
- /*
- * Check for timed out, killing the process.
- */
- uint32_t cMilliesLeft = RT_INDEFINITE_WAIT;
- if (cMsTimeout != RT_INDEFINITE_WAIT)
- {
- uint64_t u64Now = RTTimeMilliTS();
- uint64_t cMsElapsed = u64Now - MsStart;
- if (cMsElapsed >= cMsTimeout)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
- pData->uPID, cMsElapsed, cMsTimeout);
-
- fProcessTimedOut = true;
- if ( MsProcessKilled == UINT64_MAX
- || u64Now - MsProcessKilled > 1000)
- {
- if (u64Now - MsProcessKilled > 20*60*1000)
- break; /* Give up after 20 mins. */
- RTProcTerminate(hProcess);
- MsProcessKilled = u64Now;
- continue;
- }
- cMilliesLeft = 10000;
- }
- else
- cMilliesLeft = cMsTimeout - (uint32_t)cMsElapsed;
- }
-
- /* Reset the polling interval since we've done all pending work. */
- cMsPollCur = cMilliesLeft >= cMsPollBase ? cMsPollBase : cMilliesLeft;
-
- /*
- * Need to exit?
- */
- if (pThread->fShutdown)
- break;
- }
-
- /*
- * Try kill the process if it's still alive at this point.
- */
- if (fProcessAlive)
- {
- if (MsProcessKilled == UINT64_MAX)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Is still alive and not killed yet\n",
- pData->uPID);
-
- MsProcessKilled = RTTimeMilliTS();
- RTProcTerminate(hProcess);
- RTThreadSleep(500);
- }
-
- for (size_t i = 0; i < 10; i++)
- {
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Kill attempt %d/10: Waiting to exit ...\n",
- pData->uPID, i + 1);
- rc2 = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
- if (RT_SUCCESS(rc2))
- {
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Kill attempt %d/10: Exited\n",
- pData->uPID, i + 1);
- fProcessAlive = false;
- break;
- }
- if (i >= 5)
- {
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Kill attempt %d/10: Trying to terminate ...\n",
- pData->uPID, i + 1);
- RTProcTerminate(hProcess);
- }
- RTThreadSleep(i >= 5 ? 2000 : 500);
- }
-
- if (fProcessAlive)
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Could not be killed\n", pData->uPID);
- }
-
- /*
- * If we don't have a client problem (RT_FAILURE(rc)) we'll reply to the
- * clients exec packet now.
- */
- if (RT_SUCCESS(rc))
- {
- /* Mark this thread as stopped and do some action required for stopping ... */
- VBoxServiceControlExecThreadStop(pThread);
-
- uint32_t uStatus = PROC_STS_UNDEFINED;
- uint32_t uFlags = 0;
-
- if ( fProcessTimedOut && !fProcessAlive && MsProcessKilled != UINT64_MAX)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Timed out and got killed\n",
- pData->uPID);
- uStatus = PROC_STS_TOK;
- }
- else if (fProcessTimedOut && fProcessAlive && MsProcessKilled != UINT64_MAX)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Timed out and did *not* get killed\n",
- pData->uPID);
- uStatus = PROC_STS_TOA;
- }
- else if (pThread->fShutdown && (fProcessAlive || MsProcessKilled != UINT64_MAX))
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Got terminated because system/service is about to shutdown\n",
- pData->uPID);
- uStatus = PROC_STS_DWN; /* Service is stopping, process was killed. */
- uFlags = pData->uFlags; /* Return handed-in execution flags back to the host. */
- }
- else if (fProcessAlive)
- {
- VBoxServiceError("ControlExec: [PID %u]: Is alive when it should not!\n",
- pData->uPID);
- }
- else if (MsProcessKilled != UINT64_MAX)
- {
- VBoxServiceError("ControlExec: [PID %u]: Has been killed when it should not!\n",
- pData->uPID);
- }
- else if (ProcessStatus.enmReason == RTPROCEXITREASON_NORMAL)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Ended with RTPROCEXITREASON_NORMAL (%u)\n",
- pData->uPID, ProcessStatus.iStatus);
-
- uStatus = PROC_STS_TEN;
- uFlags = ProcessStatus.iStatus;
- }
- else if (ProcessStatus.enmReason == RTPROCEXITREASON_SIGNAL)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Ended with RTPROCEXITREASON_SIGNAL (%u)\n",
- pData->uPID, ProcessStatus.iStatus);
-
- uStatus = PROC_STS_TES;
- uFlags = ProcessStatus.iStatus;
- }
- else if (ProcessStatus.enmReason == RTPROCEXITREASON_ABEND)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Ended with RTPROCEXITREASON_ABEND (%u)\n",
- pData->uPID, ProcessStatus.iStatus);
-
- uStatus = PROC_STS_TEA;
- uFlags = ProcessStatus.iStatus;
- }
- else
- VBoxServiceError("ControlExec: [PID %u]: Reached an undefined state!\n",
- pData->uPID);
-
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Ended, CID=%u, Status=%u, Flags=%u\n",
- pData->uPID, pThread->uContextID, uStatus, uFlags);
- rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
- pData->uPID, uStatus, uFlags,
- NULL /* pvData */, 0 /* cbData */);
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Process loop ended with rc=%Rrc\n",
- pData->uPID, rc);
-
- /*
- * Dump stdout for debugging purposes.
- * Only do that on *very* high verbosity (5+).
- */
- if (g_cVerbosity >= 5)
- {
- VBoxServiceVerbose(5, "[PID %u]: StdOut:\n", pData->uPID);
-
- uint8_t szBuf[_64K];
- uint32_t cbOffset = 0;
- uint32_t cbRead, cbLeft;
- while ( RT_SUCCESS(VBoxServicePipeBufPeek(&pData->stdOut, szBuf, sizeof(szBuf),
- cbOffset, &cbRead, &cbLeft))
- && cbRead)
- {
-#ifdef DEBUG
- int rc2 = RTCritSectEnter(&g_csLog);
- if (RT_SUCCESS(rc2))
- {
-#endif
- RTStrmWriteEx(g_pStdOut, szBuf, cbRead, NULL /* No partial write. */);
-#ifdef DEBUG
- rc2 = RTCritSectLeave(&g_csLog);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
-#endif
- cbOffset += cbRead;
- if (!cbLeft)
- break;
- }
-
- VBoxServiceVerbose(5, "\n");
- }
- }
- else
- VBoxServiceError("ControlExec: [PID %u]: Loop failed with rc=%Rrc\n",
- pData->uPID, rc);
- return rc;
-}
-
-
-/**
- * Sets up the redirection / pipe / nothing for one of the standard handles.
- *
- * @returns IPRT status code. No client replies made.
- * @param fd Which standard handle it is (0 == stdin, 1 ==
- * stdout, 2 == stderr).
- * @param ph The generic handle that @a pph may be set
- * pointing to. Always set.
- * @param pph Pointer to the RTProcCreateExec argument.
- * Always set.
- * @param phPipe Where to return the end of the pipe that we
- * should service. Always set.
- */
-static int VBoxServiceControlExecSetupPipe(int fd, PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
-{
- AssertPtrReturn(ph, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pph, VERR_INVALID_PARAMETER);
- AssertPtrReturn(phPipe, VERR_INVALID_PARAMETER);
-
- ph->enmType = RTHANDLETYPE_PIPE;
- ph->u.hPipe = NIL_RTPIPE;
- *pph = NULL;
- *phPipe = NIL_RTPIPE;
-
- int rc;
-
- /*
- * Setup a pipe for forwarding to/from the client.
- * The ph union struct will be filled with a pipe read/write handle
- * to represent the "other" end to phPipe.
- */
- if (fd == 0) /* stdin? */
- {
- /* Connect a wrtie pipe specified by phPipe to stdin. */
- rc = RTPipeCreate(&ph->u.hPipe, phPipe, RTPIPE_C_INHERIT_READ);
- }
- else /* stdout or stderr? */
- {
- /* Connect a read pipe specified by phPipe to stdout or stderr. */
- rc = RTPipeCreate(phPipe, &ph->u.hPipe, RTPIPE_C_INHERIT_WRITE);
- }
- if (RT_FAILURE(rc))
- return rc;
- ph->enmType = RTHANDLETYPE_PIPE;
- *pph = ph;
-
- return rc;
-}
-
-
-/**
- * Expands a file name / path to its real content. This only works on Windows
- * for now (e.g. translating "%TEMP%\foo.exe" to "C:\Windows\Temp" when starting
- * with system / administrative rights).
- *
- * @return IPRT status code.
- * @param pszPath Path to resolve.
- * @param pszExpanded Pointer to string to store the resolved path in.
- * @param cbExpanded Size (in bytes) of string to store the resolved path.
- */
-static int VBoxServiceControlExecMakeFullPath(const char *pszPath, char *pszExpanded, size_t cbExpanded)
-{
- int rc = VINF_SUCCESS;
-#ifdef RT_OS_WINDOWS
- if (!ExpandEnvironmentStrings(pszPath, pszExpanded, cbExpanded))
- rc = RTErrConvertFromWin32(GetLastError());
-#else
- /* No expansion for non-Windows yet. */
- rc = RTStrCopy(pszExpanded, cbExpanded, pszPath);
-#endif
-#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlExec: VBoxServiceControlExecMakeFullPath: %s -> %s\n",
- pszPath, pszExpanded);
-#endif
- return rc;
-}
-
-
-/**
- * Resolves the full path of a specified executable name. This function also
- * resolves internal VBoxService tools to its appropriate executable path + name.
- *
- * @return IPRT status code.
- * @param pszFileName File name to resovle.
- * @param pszResolved Pointer to a string where the resolved file name will be stored.
- * @param cbResolved Size (in bytes) of resolved file name string.
- */
-static int VBoxServiceControlExecResolveExecutable(const char *pszFileName, char *pszResolved, size_t cbResolved)
-{
- int rc = VINF_SUCCESS;
-
- /* Search the path of our executable. */
- char szVBoxService[RTPATH_MAX];
- if (RTProcGetExecutablePath(szVBoxService, sizeof(szVBoxService)))
- {
- char *pszExecResolved = NULL;
- if ( (g_pszProgName && RTStrICmp(pszFileName, g_pszProgName) == 0)
- || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
- {
- /* We just want to execute VBoxService (no toolbox). */
- pszExecResolved = RTStrDup(szVBoxService);
- }
- else /* Nothing to resolve, copy original. */
- pszExecResolved = RTStrDup(pszFileName);
- AssertPtr(pszExecResolved);
-
- rc = VBoxServiceControlExecMakeFullPath(pszExecResolved, pszResolved, cbResolved);
-#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlExec: VBoxServiceControlExecResolveExecutable: %s -> %s\n",
- pszFileName, pszResolved);
-#endif
- RTStrFree(pszExecResolved);
- }
- return rc;
-}
-
-
-/**
- * Constructs the argv command line by resolving environment variables
- * and relative paths.
- *
- * @return IPRT status code.
- * @param pszArgv0 First argument (argv0), either original or modified version.
- * @param papszArgs Original argv command line from the host, starting at argv[1].
- * @param ppapszArgv Pointer to a pointer with the new argv command line.
- * Needs to be freed with RTGetOptArgvFree.
- */
-static int VBoxServiceControlExecPrepareArgv(const char *pszArgv0,
- const char * const *papszArgs, char ***ppapszArgv)
-{
-/** @todo RTGetOptArgvToString converts to MSC quoted string, while
- * RTGetOptArgvFromString takes bourne shell according to the docs...
- * Actually, converting to and from here is a very roundabout way of prepending
- * an entry (pszFilename) to an array (*ppapszArgv). */
- int rc = VINF_SUCCESS;
- char *pszNewArgs = NULL;
- if (pszArgv0)
- rc = RTStrAAppend(&pszNewArgs, pszArgv0);
- if ( RT_SUCCESS(rc)
- && papszArgs)
-
- {
- char *pszArgs;
- rc = RTGetOptArgvToString(&pszArgs, papszArgs,
- RTGETOPTARGV_CNV_QUOTE_MS_CRT); /* RTGETOPTARGV_CNV_QUOTE_BOURNE_SH */
- if (RT_SUCCESS(rc))
- {
- rc = RTStrAAppend(&pszNewArgs, " ");
- if (RT_SUCCESS(rc))
- rc = RTStrAAppend(&pszNewArgs, pszArgs);
- }
- }
-
- if (RT_SUCCESS(rc))
- {
- int iNumArgsIgnored;
- rc = RTGetOptArgvFromString(ppapszArgv, &iNumArgsIgnored,
- pszNewArgs ? pszNewArgs : "", NULL /* Use standard separators. */);
- }
-
- if (pszNewArgs)
- RTStrFree(pszNewArgs);
- return rc;
-}
-
-
-/**
- * Helper function to create/start a process on the guest.
- *
- * @return IPRT status code.
- * @param pszExec Full qualified path of process to start (without arguments).
- * @param papszArgs Pointer to array of command line arguments.
- * @param hEnv Handle to environment block to use.
- * @param fFlags Process execution flags.
- * @param phStdIn Handle for the process' stdin pipe.
- * @param phStdOut Handle for the process' stdout pipe.
- * @param phStdErr Handle for the process' stderr pipe.
- * @param pszAsUser User name (account) to start the process under.
- * @param pszPassword Password of the specified user.
- * @param phProcess Pointer which will receive the process handle after
- * successful process start.
- */
-static int VBoxServiceControlExecCreateProcess(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
- PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
- const char *pszPassword, PRTPROCESS phProcess)
-{
- AssertPtrReturn(pszExec, VERR_INVALID_PARAMETER);
- AssertPtrReturn(papszArgs, VERR_INVALID_PARAMETER);
- AssertPtrReturn(phProcess, VERR_INVALID_PARAMETER);
-
- int rc = VINF_SUCCESS;
- char szExecExp[RTPATH_MAX];
-#ifdef RT_OS_WINDOWS
- /*
- * If sysprep should be executed do this in the context of VBoxService, which
- * (usually, if started by SCM) has administrator rights. Because of that a UI
- * won't be shown (doesn't have a desktop).
- */
- if (RTStrICmp(pszExec, "sysprep") == 0)
- {
- /* Use a predefined sysprep path as default. */
- char szSysprepCmd[RTPATH_MAX] = "C:\\sysprep\\sysprep.exe";
-
- /*
- * On Windows Vista (and up) sysprep is located in "system32\\sysprep\\sysprep.exe",
- * so detect the OS and use a different path.
- */
- OSVERSIONINFOEX OSInfoEx;
- RT_ZERO(OSInfoEx);
- OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- if ( GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
- && OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
- && OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
- {
- rc = RTEnvGetEx(RTENV_DEFAULT, "windir", szSysprepCmd, sizeof(szSysprepCmd), NULL);
- if (RT_SUCCESS(rc))
- rc = RTPathAppend(szSysprepCmd, sizeof(szSysprepCmd), "system32\\sysprep\\sysprep.exe");
- }
-
- if (RT_SUCCESS(rc))
- {
- char **papszArgsExp;
- rc = VBoxServiceControlExecPrepareArgv(szSysprepCmd /* argv0 */, papszArgs, &papszArgsExp);
- if (RT_SUCCESS(rc))
- {
- rc = RTProcCreateEx(szSysprepCmd, papszArgsExp, hEnv, 0 /* fFlags */,
- phStdIn, phStdOut, phStdErr, NULL /* pszAsUser */,
- NULL /* pszPassword */, phProcess);
- }
- RTGetOptArgvFree(papszArgsExp);
- }
- return rc;
- }
-#endif /* RT_OS_WINDOWS */
-
-#ifdef VBOXSERVICE_TOOLBOX
- if (RTStrStr(pszExec, "vbox_") == pszExec)
- {
- /* We want to use the internal toolbox (all internal
- * tools are starting with "vbox_" (e.g. "vbox_cat"). */
- rc = VBoxServiceControlExecResolveExecutable(VBOXSERVICE_NAME, szExecExp, sizeof(szExecExp));
- }
- else
- {
-#endif
- /*
- * Do the environment variables expansion on executable and arguments.
- */
- rc = VBoxServiceControlExecResolveExecutable(pszExec, szExecExp, sizeof(szExecExp));
-#ifdef VBOXSERVICE_TOOLBOX
- }
-#endif
- if (RT_SUCCESS(rc))
- {
- char **papszArgsExp;
- rc = VBoxServiceControlExecPrepareArgv(pszExec /* Always use the unmodified executable name as argv0. */,
- papszArgs /* Append the rest of the argument vector (if any). */, &papszArgsExp);
- if (RT_SUCCESS(rc))
- {
- uint32_t uProcFlags = 0;
- if (fFlags)
- {
- /* Process Main flag "ExecuteProcessFlag_Hidden". */
- if (fFlags & RT_BIT(2))
- uProcFlags |= RTPROC_FLAGS_HIDDEN;
- /* Process Main flag "ExecuteProcessFlag_NoProfile". */
- if (fFlags & RT_BIT(3))
- uProcFlags |= RTPROC_FLAGS_NO_PROFILE;
- }
-
- /* If no user name specified run with current credentials (e.g.
- * full service/system rights). This is prohibited via official Main API!
- *
- * Otherwise use the RTPROC_FLAGS_SERVICE to use some special authentication
- * code (at least on Windows) for running processes as different users
- * started from our system service. */
- if (*pszAsUser)
- uProcFlags |= RTPROC_FLAGS_SERVICE;
-#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlExec: Command: %s\n", szExecExp);
- for (size_t i = 0; papszArgsExp[i]; i++)
- VBoxServiceVerbose(3, "ControlExec:\targv[%ld]: %s\n", i, papszArgsExp[i]);
-#endif
- /* Do normal execution. */
- rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, uProcFlags,
- phStdIn, phStdOut, phStdErr,
- *pszAsUser ? pszAsUser : NULL,
- *pszPassword ? pszPassword : NULL,
- phProcess);
- RTGetOptArgvFree(papszArgsExp);
- }
- }
- return rc;
-}
-
-/**
- * The actual worker routine (lopp) for a started guest process.
- *
- * @return IPRT status code.
- * @param PVBOXSERVICECTRLTHREAD Thread data associated with a started process.
- */
-static DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
-{
- AssertPtr(pThread);
- PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
- AssertPtr(pData);
-
- VBoxServiceVerbose(3, "ControlExec: Thread of process \"%s\" started\n", pData->pszCmd);
-
- int rc = VbglR3GuestCtrlConnect(&pThread->uClientID);
- if (RT_FAILURE(rc))
- {
- VBoxServiceError("ControlExec: Thread failed to connect to the guest control service, aborted! Error: %Rrc\n", rc);
- RTThreadUserSignal(RTThreadSelf());
- return rc;
- }
-
- bool fSignalled = false; /* Indicator whether we signalled the thread user event already. */
-
- /*
- * Create the environment.
- */
- RTENV hEnv;
- rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
- if (RT_SUCCESS(rc))
- {
- size_t i;
- for (i = 0; i < pData->uNumEnvVars && pData->papszEnv; i++)
- {
- rc = RTEnvPutEx(hEnv, pData->papszEnv[i]);
- if (RT_FAILURE(rc))
- break;
- }
- if (RT_SUCCESS(rc))
- {
- /*
- * Setup the redirection of the standard stuff.
- */
- /** @todo consider supporting: gcc stuff.c >file 2>&1. */
- RTHANDLE hStdIn;
- PRTHANDLE phStdIn;
- rc = VBoxServiceControlExecSetupPipe(0 /*STDIN_FILENO*/, &hStdIn, &phStdIn, &pData->pipeStdInW);
- if (RT_SUCCESS(rc))
- {
- RTHANDLE hStdOut;
- PRTHANDLE phStdOut;
- RTPIPE hStdOutR;
- rc = VBoxServiceControlExecSetupPipe(1 /*STDOUT_FILENO*/, &hStdOut, &phStdOut, &hStdOutR);
- if (RT_SUCCESS(rc))
- {
- RTHANDLE hStdErr;
- PRTHANDLE phStdErr;
- RTPIPE hStdErrR;
- rc = VBoxServiceControlExecSetupPipe(2 /*STDERR_FILENO*/, &hStdErr, &phStdErr, &hStdErrR);
- if (RT_SUCCESS(rc))
- {
- /*
- * Create a poll set for the pipes and let the
- * transport layer add stuff to it as well.
- */
- RTPOLLSET hPollSet;
- rc = RTPollSetCreate(&hPollSet);
- if (RT_SUCCESS(rc))
- {
- rc = RTPollSetAddPipe(hPollSet, pData->pipeStdInW, RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDIN_ERROR);
- if (RT_SUCCESS(rc))
- rc = RTPollSetAddPipe(hPollSet, hStdOutR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDOUT);
- if (RT_SUCCESS(rc))
- rc = RTPollSetAddPipe(hPollSet, hStdErrR, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDERR);
- if (RT_SUCCESS(rc))
- rc = RTPollSetAddPipe(hPollSet, pData->pipeStdInW, RTPOLL_EVT_WRITE, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE);
- if (RT_SUCCESS(rc))
- rc = RTPollSetAddPipe(hPollSet, pData->stdIn.hNotificationPipeR, RTPOLL_EVT_READ, VBOXSERVICECTRLPIPEID_STDIN_INPUT_NOTIFY);
- if (RT_SUCCESS(rc))
- {
- RTPROCESS hProcess;
- rc = VBoxServiceControlExecCreateProcess(pData->pszCmd, pData->papszArgs, hEnv, pData->uFlags,
- phStdIn, phStdOut, phStdErr,
- pData->pszUser, pData->pszPassword,
- &hProcess);
- if (RT_FAILURE(rc))
- VBoxServiceError("ControlExec: Error starting process, rc=%Rrc\n", rc);
- /*
- * Tell the control thread that it can continue
- * spawning services. This needs to be done after the new
- * process has been started because otherwise signal handling
- * on (Open) Solaris does not work correctly (see #5068).
- */
- int rc2 = RTThreadUserSignal(RTThreadSelf());
- if (RT_FAILURE(rc2))
- rc = rc2;
- fSignalled = true;
-
- if (RT_SUCCESS(rc))
- {
- /*
- * Close the child ends of any pipes and redirected files.
- */
- rc2 = RTHandleClose(phStdIn); AssertRC(rc2);
- phStdIn = NULL;
- rc2 = RTHandleClose(phStdOut); AssertRC(rc2);
- phStdOut = NULL;
- rc2 = RTHandleClose(phStdErr); AssertRC(rc2);
- phStdErr = NULL;
-
- /* Enter the process loop. */
- rc = VBoxServiceControlExecProcLoop(pThread,
- hProcess, pData->uTimeLimitMS, hPollSet,
- &pData->pipeStdInW, &hStdOutR, &hStdErrR);
-
- /*
- * The handles that are no longer in the set have
- * been closed by the above call in order to prevent
- * the guest from getting stuck accessing them.
- * So, NIL the handles to avoid closing them again.
- */
- if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_WRITABLE, NULL)))
- pData->pipeStdInW = NIL_RTPIPE;
- if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDIN_INPUT_NOTIFY, NULL)))
- pData->stdIn.hNotificationPipeR = NIL_RTPIPE;
- if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDOUT, NULL)))
- hStdOutR = NIL_RTPIPE;
- if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDERR, NULL)))
- hStdErrR = NIL_RTPIPE;
- }
- else /* Something went wrong; report error! */
- {
- VBoxServiceError("ControlExec: Could not start process '%s' (CID: %u)! Error: %Rrc\n",
- pData->pszCmd, pThread->uContextID, rc);
-
- rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pData->uPID,
- PROC_STS_ERROR, rc,
- NULL /* pvData */, 0 /* cbData */);
- if (RT_FAILURE(rc2))
- VBoxServiceError("ControlExec: Could not report process start error! Error: %Rrc (process error %Rrc)\n",
- rc2, rc);
- }
- }
- RTPollSetDestroy(hPollSet);
- RTPipeClose(pData->stdIn.hNotificationPipeR);
- }
- RTPipeClose(hStdErrR);
- RTHandleClose(phStdErr);
- }
- RTPipeClose(hStdOutR);
- RTHandleClose(phStdOut);
- }
- RTPipeClose(pData->pipeStdInW);
- RTHandleClose(phStdIn);
- }
- }
- RTEnvDestroy(hEnv);
- }
-
- VbglR3GuestCtrlDisconnect(pThread->uClientID);
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Thread of process \"%s\" ended with rc=%Rrc\n",
- pData->uPID, pData->pszCmd, rc);
-
- /*
- * If something went wrong signal the user event so that others don't wait
- * forever on this thread.
- */
- if (RT_FAILURE(rc) && !fSignalled)
- RTThreadUserSignal(RTThreadSelf());
- return rc;
-}
-
-
-/**
- * Thread main routine for a started process.
- *
- * @return IPRT status code.
- * @param RTTHREAD Pointer to the thread's data.
- * @param void* User-supplied argument pointer.
- *
- */
-static DECLCALLBACK(int) VBoxServiceControlExecThread(RTTHREAD ThreadSelf, void *pvUser)
-{
- PVBOXSERVICECTRLTHREAD pThread = (VBOXSERVICECTRLTHREAD*)pvUser;
- AssertPtr(pThread);
- return VBoxServiceControlExecProcessWorker(pThread);
-}
-
-
-/**
- * Executes (starts) a process on the guest. This causes a new thread to be created
- * so that this function will not block the overall program execution.
- *
- * @return IPRT status code.
- * @param uClientID Client ID for accessing host service.
- * @param uContextID Context ID to associate the process to start with.
- * @param pszCmd Full qualified path of process to start (without arguments).
- * @param uFlags Process execution flags.
- * @param pszArgs String of arguments to pass to the process to start.
- * @param uNumArgs Number of arguments specified in pszArgs.
- * @param pszEnv String of environment variables ("FOO=BAR") to pass to the process
- * to start.
- * @param cbEnv Size (in bytes) of environment variables.
- * @param uNumEnvVars Number of environment variables specified in pszEnv.
- * @param pszUser User name (account) to start the process under.
- * @param pszPassword Password of specified user name (account).
- * @param uTimeLimitMS Time limit (in ms) of the process' life time.
- */
-int VBoxServiceControlExecProcess(uint32_t uClientID, uint32_t uContextID,
- const char *pszCmd, uint32_t uFlags,
- const char *pszArgs, uint32_t uNumArgs,
- const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars,
- const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS)
-{
- bool fAllowed = false;
- int rc = VBoxServiceControlExecThreadStartAllowed(&fAllowed);
- if (RT_FAILURE(rc))
- VBoxServiceError("ControlExec: Error determining whether process can be started or not, rc=%Rrc\n", rc);
-
- if (fAllowed)
- {
- /*
- * Allocate new thread data and assign it to our thread list.
- */
- PVBOXSERVICECTRLTHREAD pThread = (PVBOXSERVICECTRLTHREAD)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREAD));
- if (pThread)
- {
- rc = VBoxServiceControlExecThreadAlloc(pThread,
- uContextID,
- pszCmd, uFlags,
- pszArgs, uNumArgs,
- pszEnv, cbEnv, uNumEnvVars,
- pszUser, pszPassword,
- uTimeLimitMS);
- if (RT_SUCCESS(rc))
- {
- static uint32_t uCtrlExecThread = 0;
- char szThreadName[32];
- if (!RTStrPrintf(szThreadName, sizeof(szThreadName), "controlexec%ld", uCtrlExecThread++))
- AssertMsgFailed(("Unable to create unique control exec thread name!\n"));
-
- rc = RTThreadCreate(&pThread->Thread, VBoxServiceControlExecThread,
- (void *)(PVBOXSERVICECTRLTHREAD*)pThread, 0,
- RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, szThreadName);
- if (RT_FAILURE(rc))
- {
- VBoxServiceError("ControlExec: RTThreadCreate failed, rc=%Rrc\n, pThread=%p\n",
- rc, pThread);
- }
- else
- {
- VBoxServiceVerbose(4, "ControlExec: Waiting for thread to initialize ...\n");
-
- /* Wait for the thread to initialize. */
- RTThreadUserWait(pThread->Thread, 60 * 1000 /* 60 seconds max. */);
- if (pThread->fShutdown)
- {
- VBoxServiceError("ControlExec: Thread for process \"%s\" failed to start!\n", pszCmd);
- rc = VERR_GENERAL_FAILURE;
- }
- else
- {
- pThread->fStarted = true;
- /*rc =*/ RTListAppend(&g_GuestControlThreads, &pThread->Node);
- }
- }
-
- if (RT_FAILURE(rc))
- VBoxServiceControlExecThreadDataDestroy((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData);
- }
- if (RT_FAILURE(rc))
- RTMemFree(pThread);
- }
- else
- rc = VERR_NO_MEMORY;
- }
- else /* Process start is not allowed due to policy settings. */
- {
- VBoxServiceVerbose(3, "ControlExec: Guest process limit is reached!\n");
-
- /* Tell the host. */
- rc = VbglR3GuestCtrlExecReportStatus(uClientID, uContextID, 0 /* PID */,
- PROC_STS_ERROR, VERR_MAX_PROCS_REACHED,
- NULL /* pvData */, 0 /* cbData */);
- }
- return rc;
-}
-
-
-/**
- * Handles starting processes on the guest.
- *
- * @returns IPRT status code.
- * @param u32ClientId The HGCM client session ID.
- * @param uNumParms The number of parameters the host is offering.
- */
-int VBoxServiceControlExecHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms)
-{
- uint32_t uContextID;
- char szCmd[_1K];
- uint32_t uFlags;
- char szArgs[_1K];
- uint32_t uNumArgs;
- char szEnv[_64K];
- uint32_t cbEnv = sizeof(szEnv);
- uint32_t uNumEnvVars;
- char szUser[128];
- char szPassword[128];
- uint32_t uTimeLimitMS;
-
-#if 0 /* for valgrind */
- RT_ZERO(szCmd);
- RT_ZERO(szArgs);
- RT_ZERO(szEnv);
- RT_ZERO(szUser);
- RT_ZERO(szPassword);
-#endif
-
- if (uNumParms != 11)
- return VERR_INVALID_PARAMETER;
-
- int rc = VbglR3GuestCtrlExecGetHostCmd(u32ClientId,
- uNumParms,
- &uContextID,
- /* Command */
- szCmd, sizeof(szCmd),
- /* Flags */
- &uFlags,
- /* Arguments */
- szArgs, sizeof(szArgs), &uNumArgs,
- /* Environment */
- szEnv, &cbEnv, &uNumEnvVars,
- /* Credentials */
- szUser, sizeof(szUser),
- szPassword, sizeof(szPassword),
- /* Timelimit */
- &uTimeLimitMS);
-#ifdef DEBUG
- VBoxServiceVerbose(3, "ControlExec: Start process szCmd=%s, uFlags=%u, szArgs=%s, szEnv=%s, szUser=%s, szPW=%s, uTimeout=%u\n",
- szCmd, uFlags, uNumArgs ? szArgs : "<None>", uNumEnvVars ? szEnv : "<None>", szUser, szPassword, uTimeLimitMS);
-#endif
- if (RT_SUCCESS(rc))
- {
- /** @todo Put the following params into a struct! */
- rc = VBoxServiceControlExecProcess(u32ClientId, uContextID,
- szCmd, uFlags, szArgs, uNumArgs,
- szEnv, cbEnv, uNumEnvVars,
- szUser, szPassword, uTimeLimitMS);
- }
- else
- VBoxServiceError("ControlExec: Failed to retrieve exec start command! Error: %Rrc\n", rc);
- return rc;
-}
-
-
-/**
- * Handles input for a started process by copying the received data into its
- * stdin pipe.
- *
- * @returns IPRT status code.
- * @param u32ClientId The HGCM client session ID.
- * @param uNumParms The number of parameters the host is offering.
- * @param cMaxBufSize The maximum buffer size for retrieving the input data.
- */
-int VBoxServiceControlExecHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, size_t cbMaxBufSize)
-{
- uint32_t uContextID;
- uint32_t uPID;
- uint32_t uFlags;
- uint32_t cbSize;
-
- AssertReturn(RT_IS_POWER_OF_TWO(cbMaxBufSize), VERR_INVALID_PARAMETER);
- uint8_t *pabBuffer = (uint8_t*)RTMemAlloc(cbMaxBufSize);
- AssertPtrReturn(pabBuffer, VERR_NO_MEMORY);
-
- uint32_t uStatus = INPUT_STS_UNDEFINED; /* Status sent back to the host. */
- uint32_t cbWritten = 0; /* Number of bytes written to the guest. */
-
- /*
- * Ask the host for the input data.
- */
- int rc = VbglR3GuestCtrlExecGetHostCmdInput(u32ClientId, uNumParms,
- &uContextID, &uPID, &uFlags,
- pabBuffer, cbMaxBufSize, &cbSize);
- if (RT_FAILURE(rc))
- {
- VBoxServiceError("ControlExec: [PID %u]: Failed to retrieve exec input command! Error: %Rrc\n",
- uPID, rc);
- }
- else if (cbSize > cbMaxBufSize)
- {
- VBoxServiceError("ControlExec: [PID %u]: Maximum input buffer size is too small! cbSize=%u, cbMaxBufSize=%u\n",
- uPID, cbSize, cbMaxBufSize);
- rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- /*
- * Is this the last input block we need to deliver? Then let the pipe know ...
- */
- bool fPendingClose = false;
- if (uFlags & INPUT_FLAG_EOF)
- {
- fPendingClose = true;
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Got last input block of size %u ...\n",
- uPID, cbSize);
- }
-
- rc = VBoxServiceControlExecThreadSetInput(uPID, fPendingClose, pabBuffer,
- cbSize, &cbWritten);
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Written input, rc=%Rrc, uFlags=0x%x, fPendingClose=%d, cbSize=%u, cbWritten=%u\n",
- uPID, rc, uFlags, fPendingClose, cbSize, cbWritten);
- if (RT_SUCCESS(rc))
- {
- if (cbWritten || !cbSize) /* Did we write something or was there anything to write at all? */
- {
- uStatus = INPUT_STS_WRITTEN;
- uFlags = 0;
- }
- }
- else
- {
- if (rc == VERR_BAD_PIPE)
- uStatus = INPUT_STS_TERMINATED;
- else if (rc == VERR_BUFFER_OVERFLOW)
- uStatus = INPUT_STS_OVERFLOW;
- }
- }
- RTMemFree(pabBuffer);
-
- /*
- * If there was an error and we did not set the host status
- * yet, then do it now.
- */
- if ( RT_FAILURE(rc)
- && uStatus == INPUT_STS_UNDEFINED)
- {
- uStatus = INPUT_STS_ERROR;
- uFlags = rc;
- }
- Assert(uStatus > INPUT_STS_UNDEFINED);
-
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Input processed, CID=%u, uStatus=%u, uFlags=0x%x, cbWritten=%u\n",
- uPID, uContextID, uStatus, uFlags, cbWritten);
-
- /* Note: Since the context ID is unique the request *has* to be completed here,
- * regardless whether we got data or not! Otherwise the progress object
- * on the host never will get completed! */
- rc = VbglR3GuestCtrlExecReportStatusIn(u32ClientId, uContextID, uPID,
- uStatus, uFlags, (uint32_t)cbWritten);
-
- if (RT_FAILURE(rc))
- VBoxServiceError("ControlExec: [PID %u]: Failed to report input status! Error: %Rrc\n",
- uPID, rc);
- return rc;
-}
-
-
-/**
- * Handles the guest control output command.
- *
- * @return IPRT status code.
- * @param u32ClientId idClient The HGCM client session ID.
- * @param uNumParms cParms The number of parameters the host is
- * offering.
- */
-int VBoxServiceControlExecHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms)
-{
- uint32_t uContextID;
- uint32_t uPID;
- uint32_t uHandleID;
- uint32_t uFlags;
-
- int rc = VbglR3GuestCtrlExecGetHostCmdOutput(u32ClientId, uNumParms,
- &uContextID, &uPID, &uHandleID, &uFlags);
- if (RT_SUCCESS(rc))
- {
- uint32_t cbRead = 0;
- uint8_t *pBuf = (uint8_t*)RTMemAlloc(_64K);
- if (pBuf)
- {
- rc = VBoxServiceControlExecThreadGetOutput(uPID, uHandleID, RT_INDEFINITE_WAIT /* Timeout */,
- pBuf, _64K /* cbSize */, &cbRead);
- if (RT_SUCCESS(rc))
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Got output, CID=%u, cbRead=%u, uHandle=%u, uFlags=%u\n",
- uPID, uContextID, cbRead, uHandleID, uFlags);
- else
- VBoxServiceError("ControlExec: [PID %u]: Failed to retrieve output, CID=%u, uHandle=%u, rc=%Rrc\n",
- uPID, uContextID, uHandleID, rc);
- /* Note: Since the context ID is unique the request *has* to be completed here,
- * regardless whether we got data or not! Otherwise the progress object
- * on the host never will get completed! */
- /* cbRead now contains actual size. */
- int rc2 = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, uHandleID, uFlags,
- pBuf, cbRead);
- if (RT_SUCCESS(rc))
- rc = rc2;
- RTMemFree(pBuf);
- }
- else
- rc = VERR_NO_MEMORY;
- }
-
- if (RT_FAILURE(rc))
- VBoxServiceError("ControlExec: [PID %u]: Failed to handle output command! Error: %Rrc\n",
- uPID, rc);
- return rc;
-}
-
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
deleted file mode 100644
index 4692437bc..000000000
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/* $Id: VBoxServiceControlExecThread.cpp $ */
-/** @file
- * VBoxServiceControlExecThread - Thread for an executed guest process.
- */
-
-/*
- * 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 <iprt/asm.h>
-#include <iprt/assert.h>
-#include <iprt/getopt.h>
-#include <iprt/mem.h>
-#include <iprt/pipe.h>
-#include <iprt/semaphore.h>
-#include <iprt/string.h>
-
-#include <VBox/HostServices/GuestControlSvc.h>
-
-#include "VBoxServicePipeBuf.h"
-#include "VBoxServiceControlExecThread.h"
-
-extern uint32_t g_GuestControlProcsMaxKept;
-extern RTLISTNODE g_GuestControlThreads;
-extern RTCRITSECT g_GuestControlThreadsCritSect;
-
-PVBOXSERVICECTRLTHREAD vboxServiceControlExecThreadGetByPID(uint32_t uPID);
-int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread);
-
-/**
- * Allocates and gives back a thread data struct which then can be used by the worker thread.
- * Needs to be freed with VBoxServiceControlExecDestroyThreadData().
- *
- * @return IPRT status code.
- * @param pThread The thread's handle to allocate the data for.
- * @param u32ContextID The context ID bound to this request / command.
- * @param pszCmd Full qualified path of process to start (without arguments).
- * @param uFlags Process execution flags.
- * @param pszArgs String of arguments to pass to the process to start.
- * @param uNumArgs Number of arguments specified in pszArgs.
- * @param pszEnv String of environment variables ("FOO=BAR") to pass to the process
- * to start.
- * @param cbEnv Size (in bytes) of environment variables.
- * @param uNumEnvVars Number of environment variables specified in pszEnv.
- * @param pszUser User name (account) to start the process under.
- * @param pszPassword Password of specified user name (account).
- * @param uTimeLimitMS Time limit (in ms) of the process' life time.
- */
-int VBoxServiceControlExecThreadAlloc(PVBOXSERVICECTRLTHREAD pThread,
- uint32_t u32ContextID,
- const char *pszCmd, uint32_t uFlags,
- const char *pszArgs, uint32_t uNumArgs,
- const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars,
- const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS)
-{
- AssertPtr(pThread);
-
- /* General stuff. */
- pThread->Node.pPrev = NULL;
- pThread->Node.pNext = NULL;
-
- pThread->fShutdown = false;
- pThread->fStarted = false;
- pThread->fStopped = false;
-
- pThread->uContextID = u32ContextID;
- /* ClientID will be assigned when thread is started! */
-
- /* Specific stuff. */
- PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREADDATAEXEC));
- if (pData == NULL)
- return VERR_NO_MEMORY;
-
- pData->uPID = 0; /* Don't have a PID yet. */
- pData->pszCmd = RTStrDup(pszCmd);
- pData->uFlags = uFlags;
- pData->uNumEnvVars = 0;
- pData->uNumArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */
-
- /* Prepare argument list. */
- int rc = RTGetOptArgvFromString(&pData->papszArgs, (int*)&pData->uNumArgs,
- (uNumArgs > 0) ? pszArgs : "", NULL);
- /* Did we get the same result? */
- Assert(uNumArgs == pData->uNumArgs);
-
- if (RT_SUCCESS(rc))
- {
- /* Prepare environment list. */
- if (uNumEnvVars)
- {
- pData->papszEnv = (char **)RTMemAlloc(uNumEnvVars * sizeof(char*));
- AssertPtr(pData->papszEnv);
- pData->uNumEnvVars = uNumEnvVars;
-
- const char *pszCur = pszEnv;
- uint32_t i = 0;
- uint32_t cbLen = 0;
- while (cbLen < cbEnv)
- {
- /* sanity check */
- if (i >= uNumEnvVars)
- {
- rc = VERR_INVALID_PARAMETER;
- break;
- }
- int cbStr = RTStrAPrintf(&pData->papszEnv[i++], "%s", pszCur);
- if (cbStr < 0)
- {
- rc = VERR_NO_STR_MEMORY;
- break;
- }
- pszCur += cbStr + 1; /* Skip terminating '\0' */
- cbLen += cbStr + 1; /* Skip terminating '\0' */
- }
- }
-
- pData->pszUser = RTStrDup(pszUser);
- pData->pszPassword = RTStrDup(pszPassword);
- pData->uTimeLimitMS = uTimeLimitMS;
-
- /* Adjust time limit value. */
- pData->uTimeLimitMS = ( uTimeLimitMS == UINT32_MAX
- || uTimeLimitMS == 0)
- ? RT_INDEFINITE_WAIT : uTimeLimitMS;
-
- /* Init buffers. */
- rc = VBoxServicePipeBufInit(&pData->stdOut, VBOXSERVICECTRLPIPEID_STDOUT,
- false /*fNeedNotificationPipe*/);
- if (RT_SUCCESS(rc))
- {
- rc = VBoxServicePipeBufInit(&pData->stdErr, VBOXSERVICECTRLPIPEID_STDERR,
- false /*fNeedNotificationPipe*/);
- if (RT_SUCCESS(rc))
- rc = VBoxServicePipeBufInit(&pData->stdIn, VBOXSERVICECTRLPIPEID_STDIN,
- true /*fNeedNotificationPipe*/);
- }
-
- if (RT_SUCCESS(rc))
- {
- pThread->enmType = kVBoxServiceCtrlThreadDataExec;
- pThread->pvData = pData;
- }
- }
-
- if (RT_FAILURE(rc))
- VBoxServiceControlExecThreadDataDestroy(pData);
- return rc;
-}
-
-
-/**
- * Assigns a valid PID to a guest control thread and also checks if there already was
- * another (stale) guest process which was using that PID before and destroys it.
- *
- * @return IPRT status code.
- * @param pData Pointer to guest control execution thread data.
- * @param uPID PID to assign to the specified guest control execution thread.
- */
-int VBoxServiceControlExecThreadAssignPID(PVBOXSERVICECTRLTHREADDATAEXEC pData, uint32_t uPID)
-{
- AssertPtrReturn(pData, VERR_INVALID_POINTER);
- AssertReturn(uPID, VERR_INVALID_PARAMETER);
-
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- {
- /* Search an old thread using the desired PID and shut it down completely -- it's
- * not used anymore. */
- PVBOXSERVICECTRLTHREAD pOldNode = vboxServiceControlExecThreadGetByPID(uPID);
- if ( pOldNode
- && pOldNode->pvData != pData)
- {
- PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pOldNode->Node, VBOXSERVICECTRLTHREAD, Node);
-
- VBoxServiceVerbose(3, "ControlExec: PID %u was used before, shutting down stale exec thread ...\n",
- uPID);
- AssertPtr(pOldNode->pvData);
- rc = VBoxServiceControlExecThreadShutdown(pOldNode);
- if (RT_FAILURE(rc))
- {
- VBoxServiceVerbose(3, "ControlExec: Unable to shut down stale exec thread, rc=%Rrc\n", rc);
- /* Keep going. */
- }
-
- RTListNodeRemove(&pOldNode->Node);
- RTMemFree(pOldNode);
- }
-
- /* Assign PID to current thread. */
- pData->uPID = uPID;
- VBoxServicePipeBufSetPID(&pData->stdIn, pData->uPID);
- VBoxServicePipeBufSetPID(&pData->stdOut, pData->uPID);
- VBoxServicePipeBufSetPID(&pData->stdErr, pData->uPID);
-
- int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
-
- return rc;
-}
-
-
-/**
- * Frees an allocated thread data structure along with all its allocated parameters.
- *
- * @param pData Pointer to thread data to free.
- */
-void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData)
-{
- if (pData)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Destroying thread data ...\n",
- pData->uPID);
-
- RTStrFree(pData->pszCmd);
- if (pData->uNumEnvVars)
- {
- for (uint32_t i = 0; i < pData->uNumEnvVars; i++)
- RTStrFree(pData->papszEnv[i]);
- RTMemFree(pData->papszEnv);
- }
- RTGetOptArgvFree(pData->papszArgs);
- RTStrFree(pData->pszUser);
- RTStrFree(pData->pszPassword);
-
- VBoxServicePipeBufDestroy(&pData->stdOut);
- VBoxServicePipeBufDestroy(&pData->stdErr);
- VBoxServicePipeBufDestroy(&pData->stdIn);
-
- RTMemFree(pData);
- pData = NULL;
- }
-}
-
-
-/**
- * Finds a (formerly) started process given by its PID.
- * Internal function, does not do locking -- this must be done from the caller function!
- *
- * @return PVBOXSERVICECTRLTHREAD Process structure if found, otherwise NULL.
- * @param uPID PID to search for.
- */
-PVBOXSERVICECTRLTHREAD vboxServiceControlExecThreadGetByPID(uint32_t uPID)
-{
- PVBOXSERVICECTRLTHREAD pNode = NULL;
- RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
- {
- if (pNode->enmType == kVBoxServiceCtrlThreadDataExec)
- {
- PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData;
- if (pData && pData->uPID == uPID)
- return pNode;
- }
- }
- return NULL;
-}
-
-
-/**
- * Injects input to a specified running process.
- *
- * @return IPRT status code.
- * @param uPID PID of process to set the input for.
- * @param fPendingClose Flag indicating whether this is the last input block sent to the process.
- * @param pBuf Pointer to a buffer containing the actual input data.
- * @param cbSize Size (in bytes) of the input buffer data.
- * @param pcbWritten Pointer to number of bytes written to the process. Optional.
- */
-int VBoxServiceControlExecThreadSetInput(uint32_t uPID, bool fPendingClose, uint8_t *pBuf,
- uint32_t cbSize, uint32_t *pcbWritten)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_PARAMETER);
-
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- {
- PVBOXSERVICECTRLTHREAD pNode = vboxServiceControlExecThreadGetByPID(uPID);
- if (pNode)
- {
- PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData;
- AssertPtr(pData);
-
- if (VBoxServicePipeBufIsEnabled(&pData->stdIn))
- {
- /*
- * Feed the data to the pipe.
- */
- uint32_t cbWritten;
- rc = VBoxServicePipeBufWriteToBuf(&pData->stdIn, pBuf,
- cbSize, fPendingClose, &cbWritten);
- if (pcbWritten)
- *pcbWritten = cbWritten;
- }
- else
- {
- /* If input buffer is not enabled anymore we cannot handle that data ... */
- rc = VERR_BAD_PIPE;
- }
- }
- else
- rc = VERR_NOT_FOUND; /* PID not found! */
- RTCritSectLeave(&g_GuestControlThreadsCritSect);
- }
- return rc;
-}
-
-
-/**
- * Gets output from stdout/stderr of a specified process.
- *
- * @return IPRT status code.
- * @param uPID PID of process to retrieve the output from.
- * @param uHandleId Stream ID (stdout = 0, stderr = 2) to get the output from.
- * @param uTimeout Timeout (in ms) to wait for output becoming available.
- * @param pBuf Pointer to a pre-allocated buffer to store the output.
- * @param cbSize Size (in bytes) of the pre-allocated buffer.
- * @param pcbRead Pointer to number of bytes read. Optional.
- */
-int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uint32_t uTimeout,
- uint8_t *pBuf, uint32_t cbSize, uint32_t *pcbRead)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
- AssertReturn(cbSize, VERR_INVALID_PARAMETER);
-
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- {
- const PVBOXSERVICECTRLTHREAD pThread = vboxServiceControlExecThreadGetByPID(uPID);
- if (pThread)
- {
- const PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
- AssertPtr(pData);
-
- PVBOXSERVICECTRLEXECPIPEBUF pPipeBuf = NULL;
- switch (uHandleId)
- {
- case OUTPUT_HANDLE_ID_STDERR:
- pPipeBuf = &pData->stdErr;
- break;
-
- case OUTPUT_HANDLE_ID_STDOUT:
- case OUTPUT_HANDLE_ID_STDOUT_DEPRECATED:
- pPipeBuf = &pData->stdOut;
- break;
-
- default:
- rc = VERR_NOT_FOUND; /* Handle ID not found! */
- break;
- }
-
- if (RT_SUCCESS(rc))
- {
- AssertPtr(pPipeBuf);
-
- #ifdef DEBUG_andy
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Getting output from pipe buffer %u ...\n",
- uPID, pPipeBuf->uPipeId);
- #endif
- /* If the stdout pipe buffer is enabled (that is, still could be filled by a running
- * process) wait for the signal to arrive so that we don't return without any actual
- * data read. */
- bool fEnabled = VBoxServicePipeBufIsEnabled(pPipeBuf);
- if (fEnabled)
- {
- #ifdef DEBUG_andy
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Waiting for pipe buffer %u (%ums)\n",
- uPID, pPipeBuf->uPipeId, uTimeout);
- #endif
- rc = VBoxServicePipeBufWaitForEvent(pPipeBuf, uTimeout);
- }
- if (RT_SUCCESS(rc))
- {
- uint32_t cbRead = cbSize; /* Read as much as possible. */
- rc = VBoxServicePipeBufRead(pPipeBuf, pBuf, cbSize, &cbRead);
- if (RT_SUCCESS(rc))
- {
- if ( !cbRead
- && fEnabled)
- {
- AssertReleaseMsg(!VBoxServicePipeBufIsEnabled(pPipeBuf),
- ("[PID %u]: Waited (%ums) for active pipe buffer %u (%u size, %u bytes left), but nothing read!\n",
- uPID, uTimeout, pPipeBuf->uPipeId, pPipeBuf->cbSize, pPipeBuf->cbSize - pPipeBuf->cbOffset));
- }
- if (pcbRead)
- *pcbRead = cbRead;
- }
- else
- VBoxServiceError("ControlExec: [PID %u]: Unable to read from pipe buffer %u, rc=%Rrc\n",
- uPID, pPipeBuf->uPipeId, rc);
- }
- }
- }
- else
- rc = VERR_NOT_FOUND; /* PID not found! */
-
- int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
- return rc;
-}
-
-
-int VBoxServiceControlExecThreadRemove(uint32_t uPID)
-{
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- {
- PVBOXSERVICECTRLTHREAD pThread = vboxServiceControlExecThreadGetByPID(uPID);
- if (pThread)
- {
- Assert(pThread->fStarted != pThread->fStopped);
- if (pThread->fStopped) /* Only shut down stopped threads. */
- {
- VBoxServiceVerbose(4, "ControlExec: [PID %u]: Removing thread ... \n",
- uPID);
-
- rc = VBoxServiceControlExecThreadShutdown(pThread);
-
- RTListNodeRemove(&pThread->Node);
- RTMemFree(pThread);
- }
- }
- else
- rc = VERR_NOT_FOUND;
-
- int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
-
- return rc;
-}
-
-/* Does not do locking, must be done by the caller! */
-int VBoxServiceControlExecThreadShutdown(const PVBOXSERVICECTRLTHREAD pThread)
-{
- AssertPtrReturn(pThread, VERR_INVALID_POINTER);
-
- if (pThread->enmType == kVBoxServiceCtrlThreadDataExec)
- {
- PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
- if (!pData) /* Already destroyed execution data. */
- return VINF_SUCCESS;
- if (pThread->fStarted)
- {
- VBoxServiceVerbose(2, "ControlExec: [PID %u]: Shutting down a still running thread without stopping is not possible!\n",
- pData->uPID);
- return VERR_INVALID_PARAMETER;
- }
-
- VBoxServiceVerbose(2, "ControlExec: [PID %u]: Shutting down, will not be served anymore\n",
- pData->uPID);
- VBoxServiceControlExecThreadDataDestroy(pData);
- }
-
- VBoxServiceControlThreadSignalShutdown(pThread);
- return VBoxServiceControlThreadWaitForShutdown(pThread);
-}
-
-
-int VBoxServiceControlExecThreadStartAllowed(bool *pbAllowed)
-{
- AssertPtrReturn(pbAllowed, VERR_INVALID_POINTER);
-
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- {
- /*
- * Check if we're respecting our memory policy by checking
- * how many guest processes are started and served already.
- */
- bool fLimitReached = false;
- if (g_GuestControlProcsMaxKept) /* If we allow unlimited processes (=0), take a shortcut. */
- {
- /** @todo Put running/stopped (+ memory alloc) stats into global struct! */
- uint32_t uProcsRunning = 0;
- uint32_t uProcsStopped = 0;
- PVBOXSERVICECTRLTHREAD pNode;
- RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
- {
- if (pNode->enmType == kVBoxServiceCtrlThreadDataExec)
- {
- Assert(pNode->fStarted != pNode->fStopped);
- if (pNode->fStarted)
- uProcsRunning++;
- else if (pNode->fStopped)
- uProcsStopped++;
- else
- AssertMsgFailed(("Process neither started nor stopped!?\n"));
- }
- }
-
- VBoxServiceVerbose(2, "ControlExec: Maximum served guest processes set to %u, running=%u, stopped=%u\n",
- g_GuestControlProcsMaxKept, uProcsRunning, uProcsStopped);
-
- int32_t iProcsLeft = (g_GuestControlProcsMaxKept - uProcsRunning - 1);
- if (iProcsLeft < 0)
- {
- VBoxServiceVerbose(3, "ControlExec: Maximum running guest processes reached (%u)\n",
- g_GuestControlProcsMaxKept);
- fLimitReached = true;
- }
- else if (uProcsStopped > (uint32_t)iProcsLeft)
- {
- uint32_t uProcsToKill = uProcsStopped - iProcsLeft;
- Assert(uProcsToKill);
- VBoxServiceVerbose(3, "ControlExec: Shutting down %ld stopped guest processes\n", uProcsToKill);
-
- RTListForEach(&g_GuestControlThreads, pNode, VBOXSERVICECTRLTHREAD, Node)
- {
- if ( pNode->enmType == kVBoxServiceCtrlThreadDataExec
- && pNode->fStopped)
- {
- PVBOXSERVICECTRLTHREAD pNext = RTListNodeGetNext(&pNode->Node, VBOXSERVICECTRLTHREAD, Node);
-
- int rc2 = VBoxServiceControlExecThreadShutdown(pNode);
- if (RT_FAILURE(rc2))
- {
- VBoxServiceError("ControlExec: Unable to shut down thread due to policy, rc=%Rrc\n", rc2);
- if (RT_SUCCESS(rc))
- rc = rc2;
- /* Keep going. */
- }
-
- RTListNodeRemove(&pNode->Node);
- RTMemFree(pNode);
- pNode = pNext;
-
- Assert(uProcsToKill);
- uProcsToKill--;
- if (!uProcsToKill)
- break;
- }
- }
- Assert(uProcsToKill == 0);
- }
- }
-
- *pbAllowed = !fLimitReached;
-
- int rc2 = RTCritSectLeave(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
-
- return rc;
-}
-
-
-/**
- * Marks an guest execution thread as stopped and cleans up its internal pipe buffers.
- *
- * @param pThread Pointer to guest execution thread.
- */
-void VBoxServiceControlExecThreadStop(const PVBOXSERVICECTRLTHREAD pThread)
-{
- AssertPtr(pThread);
-
- int rc = RTCritSectEnter(&g_GuestControlThreadsCritSect);
- if (RT_SUCCESS(rc))
- {
- if (pThread->fStarted)
- {
- const PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData;
- if (pData)
- {
- VBoxServiceVerbose(3, "ControlExec: [PID %u]: Marking as stopped\n", pData->uPID);
-
- VBoxServicePipeBufSetStatus(&pData->stdIn, false /* Disabled */);
- VBoxServicePipeBufSetStatus(&pData->stdOut, false /* Disabled */);
- VBoxServicePipeBufSetStatus(&pData->stdErr, false /* Disabled */);
-
- /* Since the process is not alive anymore, destroy its local
- * stdin pipe buffer - it's not used anymore and can eat up quite
- * a bit of memory. */
- VBoxServicePipeBufDestroy(&pData->stdIn);
- }
-
- /* Mark as stopped. */
- ASMAtomicXchgBool(&pThread->fStarted, false);
- ASMAtomicXchgBool(&pThread->fStopped, true);
- }
-
- RTCritSectLeave(&g_GuestControlThreadsCritSect);
- }
-}
-
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
deleted file mode 100644
index b1369a987..000000000
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExecThread.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $Id: VBoxServiceControlExecThread.h $ */
-/** @file
- * VBoxServiceControlExecThread - Thread for an executed guest process.
- */
-
-/*
- * 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.
- */
-
-#ifndef ___VBoxServiceControlExecThread_h
-#define ___VBoxServiceControlExecThread_h
-
-#include "VBoxServiceInternal.h"
-
-int VBoxServiceControlExecThreadAlloc(PVBOXSERVICECTRLTHREAD pThread,
- uint32_t u32ContextID,
- const char *pszCmd, uint32_t uFlags,
- const char *pszArgs, uint32_t uNumArgs,
- const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars,
- const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS);
-int VBoxServiceControlExecThreadAssignPID(PVBOXSERVICECTRLTHREADDATAEXEC pData, uint32_t uPID);
-void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pData);
-int VBoxServiceControlExecThreadGetOutput(uint32_t uPID, uint32_t uHandleId, uint32_t uTimeout,
- uint8_t *pBuf, uint32_t cbSize, uint32_t *pcbRead);
-int VBoxServiceControlExecThreadRemove(uint32_t uPID);
-int VBoxServiceControlExecThreadSetInput(uint32_t uPID, bool fPendingClose, uint8_t *pBuf,
- uint32_t cbSize, uint32_t *pcbWritten);
-int VBoxServiceControlExecThreadStartAllowed(bool *pbAllowed);
-void VBoxServiceControlExecThreadStop(const PVBOXSERVICECTRLTHREAD pThread);
-#endif /* !___VBoxServiceControlExecThread_h */
-
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
new file mode 100644
index 000000000..22a3bf549
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
@@ -0,0 +1,1709 @@
+/* $Id: VBoxServiceControlThread.cpp $ */
+/** @file
+ * VBoxServiceControlExecThread - Thread for every started guest process.
+ */
+
+/*
+ * 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 <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/env.h>
+#include <iprt/file.h>
+#include <iprt/getopt.h>
+#include <iprt/handle.h>
+#include <iprt/mem.h>
+#include <iprt/path.h>
+#include <iprt/pipe.h>
+#include <iprt/poll.h>
+#include <iprt/process.h>
+#include <iprt/semaphore.h>
+#include <iprt/string.h>
+#include <iprt/thread.h>
+
+#include <VBox/VBoxGuestLib.h>
+#include <VBox/HostServices/GuestControlSvc.h>
+
+#include "VBoxServiceInternal.h"
+
+using namespace guestControl;
+
+/* Internal functions. */
+static int vboxServiceControlThreadRequestCancel(PVBOXSERVICECTRLREQUEST pThread);
+
+/**
+ * Initialies the passed in thread data structure with the parameters given.
+ *
+ * @return IPRT status code.
+ * @param pThread The thread's handle to allocate the data for.
+ * @param u32ContextID The context ID bound to this request / command.
+ @ @param pProcess Process information.
+ */
+static int gstsvcCntlExecThreadInit(PVBOXSERVICECTRLTHREAD pThread,
+ PVBOXSERVICECTRLPROCESS pProcess,
+ uint32_t u32ContextID)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
+
+ /* General stuff. */
+ pThread->pAnchor = NULL;
+ pThread->Node.pPrev = NULL;
+ pThread->Node.pNext = NULL;
+
+ pThread->fShutdown = false;
+ pThread->fStarted = false;
+ pThread->fStopped = false;
+
+ pThread->uContextID = u32ContextID;
+ /* ClientID will be assigned when thread is started; every guest
+ * process has its own client ID to detect crashes on a per-guest-process
+ * level. */
+
+ int rc = RTCritSectInit(&pThread->CritSect);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ pThread->uPID = 0; /* Don't have a PID yet. */
+ pThread->pRequest = NULL; /* No request assigned yet. */
+ pThread->uFlags = pProcess->uFlags;
+ pThread->uTimeLimitMS = ( pProcess->uTimeLimitMS == UINT32_MAX
+ || pProcess->uTimeLimitMS == 0)
+ ? RT_INDEFINITE_WAIT : pProcess->uTimeLimitMS;
+
+ /* Prepare argument list. */
+ pThread->uNumArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */
+ rc = RTGetOptArgvFromString(&pThread->papszArgs, (int*)&pThread->uNumArgs,
+ (pProcess->uNumArgs > 0) ? pProcess->szArgs : "", NULL);
+ /* Did we get the same result? */
+ Assert(pProcess->uNumArgs == pThread->uNumArgs);
+
+ if (RT_SUCCESS(rc))
+ {
+ /* Prepare environment list. */
+ pThread->uNumEnvVars = 0;
+ if (pProcess->uNumEnvVars)
+ {
+ pThread->papszEnv = (char **)RTMemAlloc(pProcess->uNumEnvVars * sizeof(char*));
+ AssertPtr(pThread->papszEnv);
+ pThread->uNumEnvVars = pProcess->uNumEnvVars;
+
+ const char *pszCur = pProcess->szEnv;
+ uint32_t i = 0;
+ uint32_t cbLen = 0;
+ while (cbLen < pProcess->cbEnv)
+ {
+ /* sanity check */
+ if (i >= pProcess->uNumEnvVars)
+ {
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+ int cbStr = RTStrAPrintf(&pThread->papszEnv[i++], "%s", pszCur);
+ if (cbStr < 0)
+ {
+ rc = VERR_NO_STR_MEMORY;
+ break;
+ }
+ pszCur += cbStr + 1; /* Skip terminating '\0' */
+ cbLen += cbStr + 1; /* Skip terminating '\0' */
+ }
+ Assert(i == pThread->uNumEnvVars);
+ }
+
+ /* The actual command to execute. */
+ pThread->pszCmd = RTStrDup(pProcess->szCmd);
+ AssertPtr(pThread->pszCmd);
+
+ /* User management. */
+ pThread->pszUser = RTStrDup(pProcess->szUser);
+ AssertPtr(pThread->pszUser);
+ pThread->pszPassword = RTStrDup(pProcess->szPassword);
+ AssertPtr(pThread->pszPassword);
+ }
+
+ if (RT_FAILURE(rc)) /* Clean up on failure. */
+ VBoxServiceControlThreadFree(pThread);
+ return rc;
+}
+
+
+/**
+ * Frees a guest thread.
+ *
+ * @return IPRT status code.
+ * @param pThread Thread to shut down.
+ */
+int VBoxServiceControlThreadFree(PVBOXSERVICECTRLTHREAD pThread)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Freeing ...\n",
+ pThread->uPID);
+
+ int rc = RTCritSectEnter(&pThread->CritSect);
+ if (RT_SUCCESS(rc))
+ {
+ if (pThread->uNumEnvVars)
+ {
+ for (uint32_t i = 0; i < pThread->uNumEnvVars; i++)
+ RTStrFree(pThread->papszEnv[i]);
+ RTMemFree(pThread->papszEnv);
+ }
+ RTGetOptArgvFree(pThread->papszArgs);
+
+ RTStrFree(pThread->pszCmd);
+ RTStrFree(pThread->pszUser);
+ RTStrFree(pThread->pszPassword);
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Setting stopped state\n",
+ pThread->uPID);
+
+ rc = RTCritSectLeave(&pThread->CritSect);
+ AssertRC(rc);
+ }
+
+ /*
+ * Destroy other thread data.
+ */
+ if (RTCritSectIsInitialized(&pThread->CritSect))
+ RTCritSectDelete(&pThread->CritSect);
+
+ /*
+ * Destroy thread structure as final step.
+ */
+ RTMemFree(pThread);
+ pThread = NULL;
+
+ return rc;
+}
+
+
+/**
+ * Signals a guest process thread that we want it to shut down in
+ * a gentle way.
+ *
+ * @return IPRT status code.
+ * @param pThread Thread to shut down.
+ */
+int VBoxServiceControlThreadStop(const PVBOXSERVICECTRLTHREAD pThread)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Stopping ...\n",
+ pThread->uPID);
+
+ int rc = vboxServiceControlThreadRequestCancel(pThread->pRequest);
+ if (RT_FAILURE(rc))
+ VBoxServiceError("ControlThread: [PID %u]: Signalling request event failed, rc=%Rrc\n",
+ pThread->uPID, rc);
+
+ /* Do *not* set pThread->fShutdown or other stuff here!
+ * The guest thread loop will do that as soon as it processes the quit message. */
+
+ PVBOXSERVICECTRLREQUEST pRequest;
+ rc = VBoxServiceControlThreadRequestAlloc(&pRequest, VBOXSERVICECTRLREQUEST_QUIT);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VBoxServiceControlThreadPerform(pThread->uPID, pRequest);
+ if (RT_FAILURE(rc))
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Sending quit request failed with rc=%Rrc\n",
+ pThread->uPID, rc);
+
+ VBoxServiceControlThreadRequestFree(pRequest);
+ }
+ return rc;
+}
+
+
+/**
+ * Wait for a guest process thread to shut down.
+ *
+ * @return IPRT status code.
+ * @param pThread Thread to wait shutting down for.
+ * @param RTMSINTERVAL Timeout in ms to wait for shutdown.
+ */
+int VBoxServiceControlThreadWait(const PVBOXSERVICECTRLTHREAD pThread,
+ RTMSINTERVAL msTimeout)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ int rc = VINF_SUCCESS;
+ if ( pThread->Thread != NIL_RTTHREAD
+ && ASMAtomicReadBool(&pThread->fStarted))
+ {
+ VBoxServiceVerbose(2, "ControlThread: [PID %u]: Waiting for shutdown ...\n",
+ pThread->uPID);
+
+ /* Wait a bit ... */
+ int rcThread;
+ rc = RTThreadWait(pThread->Thread, msTimeout, &rcThread);
+ if (RT_FAILURE(rc))
+ {
+ VBoxServiceError("ControlThread: [PID %u]: Waiting for shutting down thread returned error rc=%Rrc\n",
+ pThread->uPID, rc);
+ }
+ else
+ {
+ if (RT_FAILURE(rcThread))
+ {
+ VBoxServiceError("ControlThread: [PID %u]: Shutdown returned error rc=%Rrc\n",
+ pThread->uPID, rcThread);
+ rc = rcThread;
+ }
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * Closes the stdin pipe of a guest process.
+ *
+ * @return IPRT status code.
+ * @param hPollSet The polling set.
+ * @param phStdInW The standard input pipe handle.
+ */
+static int VBoxServiceControlThreadCloseStdIn(RTPOLLSET hPollSet, PRTPIPE phStdInW)
+{
+ AssertPtrReturn(phStdInW, VERR_INVALID_POINTER);
+
+ int rc = RTPollSetRemove(hPollSet, VBOXSERVICECTRLPIPEID_STDIN);
+ if (rc != VERR_POLL_HANDLE_ID_NOT_FOUND)
+ AssertRC(rc);
+
+ if (*phStdInW != NIL_RTPIPE)
+ {
+ rc = RTPipeClose(*phStdInW);
+ AssertRC(rc);
+ *phStdInW = NIL_RTPIPE;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Handle an error event on standard input.
+ *
+ * @return IPRT status code.
+ * @param hPollSet The polling set.
+ * @param fPollEvt The event mask returned by RTPollNoResume.
+ * @param phStdInW The standard input pipe handle.
+ */
+static int VBoxServiceControlThreadHandleStdInErrorEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phStdInW)
+{
+ NOREF(fPollEvt);
+
+ return VBoxServiceControlThreadCloseStdIn(hPollSet, phStdInW);
+}
+
+
+/**
+ * Handle pending output data or error on standard out or standard error.
+ *
+ * @returns IPRT status code from client send.
+ * @param hPollSet The polling set.
+ * @param fPollEvt The event mask returned by RTPollNoResume.
+ * @param phPipeR The pipe handle.
+ * @param idPollHnd The pipe ID to handle.
+ *
+ */
+static int VBoxServiceControlThreadHandleOutputError(RTPOLLSET hPollSet, uint32_t fPollEvt,
+ PRTPIPE phPipeR, uint32_t idPollHnd)
+{
+ AssertPtrReturn(phPipeR, VERR_INVALID_POINTER);
+
+#ifdef DEBUG
+ VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputError: fPollEvt=0x%x, idPollHnd=%u\n",
+ fPollEvt, idPollHnd);
+#endif
+
+ /* Remove pipe from poll set. */
+ int rc2 = RTPollSetRemove(hPollSet, idPollHnd);
+ AssertMsg(RT_SUCCESS(rc2) || rc2 == VERR_POLL_HANDLE_ID_NOT_FOUND, ("%Rrc\n", rc2));
+
+ bool fClosePipe = true; /* By default close the pipe. */
+
+ /* Check if there's remaining data to read from the pipe. */
+ size_t cbReadable;
+ rc2 = RTPipeQueryReadable(*phPipeR, &cbReadable);
+ if ( RT_SUCCESS(rc2)
+ && cbReadable)
+ {
+ VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlThreadHandleOutputError: idPollHnd=%u has %ld bytes left, vetoing close\n",
+ idPollHnd, cbReadable);
+
+ /* Veto closing the pipe yet because there's still stuff to read
+ * from the pipe. This can happen on UNIX-y systems where on
+ * error/hangup there still can be data to be read out. */
+ fClosePipe = false;
+ }
+ else
+ VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlThreadHandleOutputError: idPollHnd=%u will be closed\n",
+ idPollHnd);
+
+ if ( *phPipeR != NIL_RTPIPE
+ && fClosePipe)
+ {
+ rc2 = RTPipeClose(*phPipeR);
+ AssertRC(rc2);
+ *phPipeR = NIL_RTPIPE;
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Handle pending output data or error on standard out or standard error.
+ *
+ * @returns IPRT status code from client send.
+ * @param hPollSet The polling set.
+ * @param fPollEvt The event mask returned by RTPollNoResume.
+ * @param phPipeR The pipe handle.
+ * @param idPollHnd The pipe ID to handle.
+ *
+ */
+static int VBoxServiceControlThreadHandleOutputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt,
+ PRTPIPE phPipeR, uint32_t idPollHnd)
+{
+#if 0
+ VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%u\n",
+ fPollEvt, idPollHnd);
+#endif
+
+ int rc = VINF_SUCCESS;
+
+#ifdef DEBUG
+ size_t cbReadable;
+ rc = RTPipeQueryReadable(*phPipeR, &cbReadable);
+ if ( RT_SUCCESS(rc)
+ && cbReadable)
+ {
+ VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent: cbReadable=%ld\n",
+ cbReadable);
+ }
+#endif
+
+#if 0
+ //if (fPollEvt & RTPOLL_EVT_READ)
+ {
+ size_t cbRead = 0;
+ uint8_t byData[_64K];
+ rc = RTPipeRead(*phPipeR,
+ byData, sizeof(byData), &cbRead);
+ VBoxServiceVerbose(4, "ControlThread: VBoxServiceControlThreadHandleOutputEvent cbRead=%u, rc=%Rrc\n",
+ cbRead, rc);
+
+ /* Make sure we go another poll round in case there was too much data
+ for the buffer to hold. */
+ fPollEvt &= RTPOLL_EVT_ERROR;
+ }
+#endif
+
+ if (fPollEvt & RTPOLL_EVT_ERROR)
+ rc = VBoxServiceControlThreadHandleOutputError(hPollSet, fPollEvt,
+ phPipeR, idPollHnd);
+ return rc;
+}
+
+
+static int VBoxServiceControlThreadHandleRequest(RTPOLLSET hPollSet, uint32_t fPollEvt,
+ PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR,
+ PVBOXSERVICECTRLTHREAD pThread)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ AssertPtrReturn(phStdInW, VERR_INVALID_POINTER);
+ AssertPtrReturn(phStdOutR, VERR_INVALID_POINTER);
+ AssertPtrReturn(phStdErrR, VERR_INVALID_POINTER);
+
+ /* Drain the notification pipe. */
+ uint8_t abBuf[8];
+ size_t cbIgnore;
+ int rc = RTPipeRead(pThread->hNotificationPipeR, abBuf, sizeof(abBuf), &cbIgnore);
+ if (RT_FAILURE(rc))
+ VBoxServiceError("ControlThread: Draining IPC notification pipe failed with rc=%Rrc\n", rc);
+
+ int rcReq = VINF_SUCCESS; /* Actual request result. */
+
+ PVBOXSERVICECTRLREQUEST pRequest = pThread->pRequest;
+ if (!pRequest)
+ {
+ VBoxServiceError("ControlThread: IPC request is invalid\n");
+ return VERR_INVALID_POINTER;
+ }
+
+ switch (pRequest->enmType)
+ {
+ case VBOXSERVICECTRLREQUEST_QUIT: /* Main control asked us to quit. */
+ {
+ /** @todo Check for some conditions to check to
+ * veto quitting. */
+ ASMAtomicXchgBool(&pThread->fShutdown, true);
+ rcReq = VERR_CANCELLED;
+ break;
+ }
+
+ case VBOXSERVICECTRLREQUEST_STDIN_WRITE:
+ case VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF:
+ {
+ size_t cbWritten = 0;
+ if (pRequest->cbData)
+ {
+ AssertPtrReturn(pRequest->pvData, VERR_INVALID_POINTER);
+ if (*phStdInW != NIL_RTPIPE)
+ {
+ rcReq = RTPipeWrite(*phStdInW,
+ pRequest->pvData, pRequest->cbData, &cbWritten);
+ }
+ else
+ rcReq = VINF_EOF;
+ }
+
+ /*
+ * If this is the last write + we have really have written all data
+ * we need to close the stdin pipe on our end and remove it from
+ * the poll set.
+ */
+ if ( pRequest->enmType == VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF
+ && pRequest->cbData == cbWritten)
+ {
+ rc = VBoxServiceControlThreadCloseStdIn(hPollSet, phStdInW);
+ }
+
+ /* Reqport back actual data written (if any). */
+ pRequest->cbData = cbWritten;
+ break;
+ }
+
+ case VBOXSERVICECTRLREQUEST_STDOUT_READ:
+ case VBOXSERVICECTRLREQUEST_STDERR_READ:
+ {
+ AssertPtrReturn(pRequest->pvData, VERR_INVALID_POINTER);
+ AssertReturn(pRequest->cbData, VERR_INVALID_PARAMETER);
+
+ PRTPIPE pPipeR = pRequest->enmType == VBOXSERVICECTRLREQUEST_STDERR_READ
+ ? phStdErrR : phStdOutR;
+ AssertPtr(pPipeR);
+
+ size_t cbRead = 0;
+ if (*pPipeR != NIL_RTPIPE)
+ {
+ rcReq = RTPipeRead(*pPipeR,
+ pRequest->pvData, pRequest->cbData, &cbRead);
+ if (RT_FAILURE(rcReq))
+ {
+ RTPollSetRemove(hPollSet, pRequest->enmType == VBOXSERVICECTRLREQUEST_STDERR_READ
+ ? VBOXSERVICECTRLPIPEID_STDERR : VBOXSERVICECTRLPIPEID_STDOUT);
+ RTPipeClose(*pPipeR);
+ *pPipeR = NIL_RTPIPE;
+ if (rcReq == VERR_BROKEN_PIPE)
+ rcReq = VINF_EOF;
+ }
+ }
+ else
+ rcReq = VINF_EOF;
+
+ /* Report back actual data read (if any). */
+ pRequest->cbData = cbRead;
+ break;
+ }
+
+ default:
+ rcReq = VERR_NOT_IMPLEMENTED;
+ break;
+ }
+
+ /* Assign overall result. */
+ pRequest->rc = RT_SUCCESS(rc)
+ ? rcReq : rc;
+
+ VBoxServiceVerbose(2, "ControlThread: [PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n",
+ pThread->uPID, pRequest->enmType, pRequest->uCID, pRequest->rc, pRequest->cbData);
+
+ /* In any case, regardless of the result, we notify
+ * the main guest control to unblock it. */
+ int rc2 = RTSemEventMultiSignal(pRequest->Event);
+ AssertRC(rc2);
+
+ /* No access to pRequest here anymore -- could be out of scope
+ * or modified already! */
+ pThread->pRequest = pRequest = NULL;
+
+ return rc;
+}
+
+
+/**
+ * Execution loop which runs in a dedicated per-started-process thread and
+ * handles all pipe input/output and signalling stuff.
+ *
+ * @return IPRT status code.
+ * @param pThread The process' thread handle.
+ * @param hProcess The actual process handle.
+ * @param cMsTimeout Time limit (in ms) of the process' life time.
+ * @param hPollSet The poll set to use.
+ * @param hStdInW Handle to the process' stdin write end.
+ * @param hStdOutR Handle to the process' stdout read end.
+ * @param hStdErrR Handle to the process' stderr read end.
+ */
+static int VBoxServiceControlThreadProcLoop(PVBOXSERVICECTRLTHREAD pThread,
+ RTPROCESS hProcess, RTMSINTERVAL cMsTimeout, RTPOLLSET hPollSet,
+ PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ AssertPtrReturn(phStdInW, VERR_INVALID_PARAMETER);
+ /* Rest is optional. */
+
+ int rc;
+ int rc2;
+ uint64_t const MsStart = RTTimeMilliTS();
+ RTPROCSTATUS ProcessStatus = { 254, RTPROCEXITREASON_ABEND };
+ bool fProcessAlive = true;
+ bool fProcessTimedOut = false;
+ uint64_t MsProcessKilled = UINT64_MAX;
+ RTMSINTERVAL const cMsPollBase = *phStdInW != NIL_RTPIPE
+ ? 100 /* Need to poll for input. */
+ : 1000; /* Need only poll for process exit and aborts. */
+ RTMSINTERVAL cMsPollCur = 0;
+
+ /*
+ * Assign PID to thread data.
+ * Also check if there already was a thread with the same PID and shut it down -- otherwise
+ * the first (stale) entry will be found and we get really weird results!
+ */
+ rc = VBoxServiceControlAssignPID(pThread, hProcess);
+ if (RT_FAILURE(rc))
+ {
+ VBoxServiceError("ControlThread: Unable to assign PID=%u, to new thread, rc=%Rrc\n",
+ hProcess, rc);
+ return rc;
+ }
+
+ /*
+ * Before entering the loop, tell the host that we've started the guest
+ * and that it's now OK to send input to the process.
+ */
+ VBoxServiceVerbose(2, "ControlThread: [PID %u]: Process \"%s\" started, CID=%u, User=%s\n",
+ pThread->uPID, pThread->pszCmd, pThread->uContextID, pThread->pszUser);
+ rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
+ pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
+ NULL /* pvData */, 0 /* cbData */);
+
+ /*
+ * Process input, output, the test pipe and client requests.
+ */
+ while ( RT_SUCCESS(rc)
+ && RT_UNLIKELY(!pThread->fShutdown))
+ {
+ /*
+ * Wait/Process all pending events.
+ */
+ uint32_t idPollHnd;
+ uint32_t fPollEvt;
+ rc2 = RTPollNoResume(hPollSet, cMsPollCur, &fPollEvt, &idPollHnd);
+ if (pThread->fShutdown)
+ continue;
+
+ cMsPollCur = 0; /* No rest until we've checked everything. */
+
+ if (RT_SUCCESS(rc2))
+ {
+ /*VBoxServiceVerbose(4, "ControlThread: [PID %u}: RTPollNoResume idPollHnd=%u\n",
+ pThread->uPID, idPollHnd);*/
+ switch (idPollHnd)
+ {
+ case VBOXSERVICECTRLPIPEID_STDIN:
+ rc = VBoxServiceControlThreadHandleStdInErrorEvent(hPollSet, fPollEvt, phStdInW);
+ break;
+
+ case VBOXSERVICECTRLPIPEID_STDOUT:
+ rc = VBoxServiceControlThreadHandleOutputEvent(hPollSet, fPollEvt,
+ phStdOutR, idPollHnd);
+ break;
+
+ case VBOXSERVICECTRLPIPEID_STDERR:
+ rc = VBoxServiceControlThreadHandleOutputEvent(hPollSet, fPollEvt,
+ phStdErrR, idPollHnd);
+ break;
+
+ case VBOXSERVICECTRLPIPEID_IPC_NOTIFY:
+ rc = VBoxServiceControlThreadHandleRequest(hPollSet, fPollEvt,
+ phStdInW, phStdOutR, phStdErrR, pThread);
+ break;
+ }
+
+ if (RT_FAILURE(rc) || rc == VINF_EOF)
+ break; /* Abort command, or client dead or something. */
+
+ if (RT_UNLIKELY(pThread->fShutdown))
+ break; /* We were asked to shutdown. */
+
+ continue;
+ }
+
+#if 0
+ VBoxServiceVerbose(4, "ControlThread: [PID %u]: Polling done, pollRC=%Rrc, pollCnt=%u, rc=%Rrc, fShutdown=%RTbool\n",
+ pThread->uPID, rc2, RTPollSetGetCount(hPollSet), rc, pThread->fShutdown);
+#endif
+ /*
+ * Check for process death.
+ */
+ if (fProcessAlive)
+ {
+ rc2 = RTProcWaitNoResume(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
+ if (RT_SUCCESS_NP(rc2))
+ {
+ fProcessAlive = false;
+ continue;
+ }
+ if (RT_UNLIKELY(rc2 == VERR_INTERRUPTED))
+ continue;
+ if (RT_UNLIKELY(rc2 == VERR_PROCESS_NOT_FOUND))
+ {
+ fProcessAlive = false;
+ ProcessStatus.enmReason = RTPROCEXITREASON_ABEND;
+ ProcessStatus.iStatus = 255;
+ AssertFailed();
+ }
+ else
+ AssertMsg(rc2 == VERR_PROCESS_RUNNING, ("%Rrc\n", rc2));
+ }
+
+ /*
+ * If the process has terminated and all output has been consumed,
+ * we should be heading out.
+ */
+ if ( !fProcessAlive
+ && *phStdOutR == NIL_RTPIPE
+ && *phStdErrR == NIL_RTPIPE)
+ break;
+
+ /*
+ * Check for timed out, killing the process.
+ */
+ uint32_t cMilliesLeft = RT_INDEFINITE_WAIT;
+ if (cMsTimeout != RT_INDEFINITE_WAIT)
+ {
+ uint64_t u64Now = RTTimeMilliTS();
+ uint64_t cMsElapsed = u64Now - MsStart;
+ if (cMsElapsed >= cMsTimeout)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
+ pThread->uPID, cMsElapsed, cMsTimeout);
+
+ fProcessTimedOut = true;
+ if ( MsProcessKilled == UINT64_MAX
+ || u64Now - MsProcessKilled > 1000)
+ {
+ if (u64Now - MsProcessKilled > 20*60*1000)
+ break; /* Give up after 20 mins. */
+ RTProcTerminate(hProcess);
+ MsProcessKilled = u64Now;
+ continue;
+ }
+ cMilliesLeft = 10000;
+ }
+ else
+ cMilliesLeft = cMsTimeout - (uint32_t)cMsElapsed;
+ }
+
+ /* Reset the polling interval since we've done all pending work. */
+ cMsPollCur = fProcessAlive
+ ? cMsPollBase
+ : RT_MS_1MIN;
+ if (cMilliesLeft < cMsPollCur)
+ cMsPollCur = cMilliesLeft;
+
+ /*
+ * Need to exit?
+ */
+ if (pThread->fShutdown)
+ break;
+ }
+
+ rc2 = RTCritSectEnter(&pThread->CritSect);
+ if (RT_SUCCESS(rc2))
+ {
+ ASMAtomicXchgBool(&pThread->fShutdown, true);
+
+ rc2 = RTCritSectLeave(&pThread->CritSect);
+ AssertRC(rc2);
+ }
+
+ /*
+ * Try kill the process if it's still alive at this point.
+ */
+ if (fProcessAlive)
+ {
+ if (MsProcessKilled == UINT64_MAX)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Is still alive and not killed yet\n",
+ pThread->uPID);
+
+ MsProcessKilled = RTTimeMilliTS();
+ RTProcTerminate(hProcess);
+ RTThreadSleep(500);
+ }
+
+ for (size_t i = 0; i < 10; i++)
+ {
+ VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Waiting to exit ...\n",
+ pThread->uPID, i + 1);
+ rc2 = RTProcWait(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
+ if (RT_SUCCESS(rc2))
+ {
+ VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Exited\n",
+ pThread->uPID, i + 1);
+ fProcessAlive = false;
+ break;
+ }
+ if (i >= 5)
+ {
+ VBoxServiceVerbose(4, "ControlThread: [PID %u]: Kill attempt %d/10: Trying to terminate ...\n",
+ pThread->uPID, i + 1);
+ RTProcTerminate(hProcess);
+ }
+ RTThreadSleep(i >= 5 ? 2000 : 500);
+ }
+
+ if (fProcessAlive)
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Could not be killed\n", pThread->uPID);
+ }
+
+ /*
+ * If we don't have a client problem (RT_FAILURE(rc)) we'll reply to the
+ * clients exec packet now.
+ */
+ if (RT_SUCCESS(rc))
+ {
+ uint32_t uStatus = PROC_STS_UNDEFINED;
+ uint32_t uFlags = 0;
+
+ if ( fProcessTimedOut && !fProcessAlive && MsProcessKilled != UINT64_MAX)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out and got killed\n",
+ pThread->uPID);
+ uStatus = PROC_STS_TOK;
+ }
+ else if (fProcessTimedOut && fProcessAlive && MsProcessKilled != UINT64_MAX)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Timed out and did *not* get killed\n",
+ pThread->uPID);
+ uStatus = PROC_STS_TOA;
+ }
+ else if (pThread->fShutdown && (fProcessAlive || MsProcessKilled != UINT64_MAX))
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Got terminated because system/service is about to shutdown\n",
+ pThread->uPID);
+ uStatus = PROC_STS_DWN; /* Service is stopping, process was killed. */
+ uFlags = pThread->uFlags; /* Return handed-in execution flags back to the host. */
+ }
+ else if (fProcessAlive)
+ {
+ VBoxServiceError("ControlThread: [PID %u]: Is alive when it should not!\n",
+ pThread->uPID);
+ }
+ else if (MsProcessKilled != UINT64_MAX)
+ {
+ VBoxServiceError("ControlThread: [PID %u]: Has been killed when it should not!\n",
+ pThread->uPID);
+ }
+ else if (ProcessStatus.enmReason == RTPROCEXITREASON_NORMAL)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_NORMAL (Exit code: %u)\n",
+ pThread->uPID, ProcessStatus.iStatus);
+
+ uStatus = PROC_STS_TEN;
+ uFlags = ProcessStatus.iStatus;
+ }
+ else if (ProcessStatus.enmReason == RTPROCEXITREASON_SIGNAL)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_SIGNAL (Signal: %u)\n",
+ pThread->uPID, ProcessStatus.iStatus);
+
+ uStatus = PROC_STS_TES;
+ uFlags = ProcessStatus.iStatus;
+ }
+ else if (ProcessStatus.enmReason == RTPROCEXITREASON_ABEND)
+ {
+ /* ProcessStatus.iStatus will be undefined. */
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Ended with RTPROCEXITREASON_ABEND\n",
+ pThread->uPID);
+
+ uStatus = PROC_STS_TEA;
+ uFlags = ProcessStatus.iStatus;
+ }
+ else
+ VBoxServiceVerbose(1, "ControlThread: [PID %u]: Handling process status %u not implemented\n",
+ pThread->uPID, ProcessStatus.enmReason);
+
+ VBoxServiceVerbose(2, "ControlThread: [PID %u]: Ended, ClientID=%u, CID=%u, Status=%u, Flags=0x%x\n",
+ pThread->uPID, pThread->uClientID, pThread->uContextID, uStatus, uFlags);
+ rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
+ pThread->uPID, uStatus, uFlags,
+ NULL /* pvData */, 0 /* cbData */);
+ if (RT_FAILURE(rc))
+ VBoxServiceError("ControlThread: [PID %u]: Error reporting final status to host; rc=%Rrc\n",
+ pThread->uPID, rc);
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Process loop ended with rc=%Rrc\n",
+ pThread->uPID, rc);
+ }
+ else
+ VBoxServiceError("ControlThread: [PID %u]: Loop failed with rc=%Rrc\n",
+ pThread->uPID, rc);
+ return rc;
+}
+
+
+/**
+ * Initializes a pipe's handle and pipe object.
+ *
+ * @return IPRT status code.
+ * @param ph The pipe's handle to initialize.
+ * @param phPipe The pipe's object to initialize.
+ */
+static int vboxServiceControlThreadInitPipe(PRTHANDLE ph, PRTPIPE phPipe)
+{
+ AssertPtrReturn(ph, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(phPipe, VERR_INVALID_PARAMETER);
+
+ ph->enmType = RTHANDLETYPE_PIPE;
+ ph->u.hPipe = NIL_RTPIPE;
+ *phPipe = NIL_RTPIPE;
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Allocates a guest thread request with the specified request data.
+ *
+ * @return IPRT status code.
+ * @param ppReq Pointer that will receive the newly allocated request.
+ * Must be freed later with VBoxServiceControlThreadRequestFree().
+ * @param enmType Request type.
+ * @param pbData Payload data, based on request type.
+ * @param cbData Size of payload data (in bytes).
+ * @param uCID Context ID to which this request belongs to.
+ */
+int VBoxServiceControlThreadRequestAllocEx(PVBOXSERVICECTRLREQUEST *ppReq,
+ VBOXSERVICECTRLREQUESTTYPE enmType,
+ void* pbData,
+ size_t cbData,
+ uint32_t uCID)
+{
+ AssertPtrReturn(ppReq, VERR_INVALID_POINTER);
+
+ PVBOXSERVICECTRLREQUEST pReq = (PVBOXSERVICECTRLREQUEST)
+ RTMemAlloc(sizeof(VBOXSERVICECTRLREQUEST));
+ AssertPtrReturn(pReq, VERR_NO_MEMORY);
+
+ RT_ZERO(*pReq);
+ pReq->enmType = enmType;
+ pReq->uCID = uCID;
+ pReq->cbData = cbData;
+ pReq->pvData = (uint8_t*)pbData;
+
+ /* Set request result to some defined state in case
+ * it got cancelled. */
+ pReq->rc = VERR_CANCELLED;
+
+ int rc = RTSemEventMultiCreate(&pReq->Event);
+ AssertRC(rc);
+
+ if (RT_SUCCESS(rc))
+ {
+ *ppReq = pReq;
+ return VINF_SUCCESS;
+ }
+
+ RTMemFree(pReq);
+ return rc;
+}
+
+
+/**
+ * Allocates a guest thread request with the specified request data.
+ *
+ * @return IPRT status code.
+ * @param ppReq Pointer that will receive the newly allocated request.
+ * Must be freed later with VBoxServiceControlThreadRequestFree().
+ * @param enmType Request type.
+ */
+int VBoxServiceControlThreadRequestAlloc(PVBOXSERVICECTRLREQUEST *ppReq,
+ VBOXSERVICECTRLREQUESTTYPE enmType)
+{
+ return VBoxServiceControlThreadRequestAllocEx(ppReq, enmType,
+ NULL /* pvData */, 0 /* cbData */,
+ 0 /* ContextID */);
+}
+
+
+/**
+ * Cancels a previously fired off guest thread request.
+ *
+ * Note: Does *not* do locking since VBoxServiceControlThreadRequestWait()
+ * holds the lock (critsect); so only trigger the signal; the owner
+ * needs to clean up afterwards.
+ *
+ * @return IPRT status code.
+ * @param pReq Request to cancel.
+ */
+static int vboxServiceControlThreadRequestCancel(PVBOXSERVICECTRLREQUEST pReq)
+{
+ if (!pReq) /* Silently skip non-initialized requests. */
+ return VINF_SUCCESS;
+
+ VBoxServiceVerbose(4, "ControlThread: Cancelling request=0x%p\n", pReq);
+
+ return RTSemEventMultiSignal(pReq->Event);
+}
+
+
+/**
+ * Frees a formerly allocated guest thread request.
+ *
+ * @return IPRT status code.
+ * @param pReq Request to free.
+ */
+void VBoxServiceControlThreadRequestFree(PVBOXSERVICECTRLREQUEST pReq)
+{
+ AssertPtrReturnVoid(pReq);
+
+ VBoxServiceVerbose(4, "ControlThread: Freeing request=0x%p (event=%RTsem)\n",
+ pReq, &pReq->Event);
+
+ int rc = RTSemEventMultiDestroy(pReq->Event);
+ AssertRC(rc);
+
+ RTMemFree(pReq);
+ pReq = NULL;
+}
+
+
+/**
+ * Waits for a guest thread's event to get triggered.
+ *
+ * @return IPRT status code.
+ * @param pReq Request to wait for.
+ */
+int VBoxServiceControlThreadRequestWait(PVBOXSERVICECTRLREQUEST pReq)
+{
+ AssertPtrReturn(pReq, VERR_INVALID_POINTER);
+
+ /* Wait on the request to get completed (or we are asked to abort/shutdown). */
+ int rc = RTSemEventMultiWait(pReq->Event, RT_INDEFINITE_WAIT);
+ if (RT_SUCCESS(rc))
+ {
+ VBoxServiceVerbose(4, "ControlThread: Performed request with rc=%Rrc, cbData=%u\n",
+ pReq->rc, pReq->cbData);
+
+ /* Give back overall request result. */
+ rc = pReq->rc;
+ }
+ else
+ VBoxServiceError("ControlThread: Waiting for request failed, rc=%Rrc\n", rc);
+
+ return rc;
+}
+
+
+/**
+ * Sets up the redirection / pipe / nothing for one of the standard handles.
+ *
+ * @returns IPRT status code. No client replies made.
+ * @param pszHowTo How to set up this standard handle.
+ * @param fd Which standard handle it is (0 == stdin, 1 ==
+ * stdout, 2 == stderr).
+ * @param ph The generic handle that @a pph may be set
+ * pointing to. Always set.
+ * @param pph Pointer to the RTProcCreateExec argument.
+ * Always set.
+ * @param phPipe Where to return the end of the pipe that we
+ * should service.
+ */
+static int VBoxServiceControlThreadSetupPipe(const char *pszHowTo, int fd,
+ PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
+{
+ AssertPtrReturn(ph, VERR_INVALID_POINTER);
+ AssertPtrReturn(pph, VERR_INVALID_POINTER);
+ AssertPtrReturn(phPipe, VERR_INVALID_POINTER);
+
+ int rc;
+
+ ph->enmType = RTHANDLETYPE_PIPE;
+ ph->u.hPipe = NIL_RTPIPE;
+ *pph = NULL;
+ *phPipe = NIL_RTPIPE;
+
+ if (!strcmp(pszHowTo, "|"))
+ {
+ /*
+ * Setup a pipe for forwarding to/from the client.
+ * The ph union struct will be filled with a pipe read/write handle
+ * to represent the "other" end to phPipe.
+ */
+ if (fd == 0) /* stdin? */
+ {
+ /* Connect a wrtie pipe specified by phPipe to stdin. */
+ rc = RTPipeCreate(&ph->u.hPipe, phPipe, RTPIPE_C_INHERIT_READ);
+ }
+ else /* stdout or stderr? */
+ {
+ /* Connect a read pipe specified by phPipe to stdout or stderr. */
+ rc = RTPipeCreate(phPipe, &ph->u.hPipe, RTPIPE_C_INHERIT_WRITE);
+ }
+
+ if (RT_FAILURE(rc))
+ return rc;
+
+ ph->enmType = RTHANDLETYPE_PIPE;
+ *pph = ph;
+ }
+ else if (!strcmp(pszHowTo, "/dev/null"))
+ {
+ /*
+ * Redirect to/from /dev/null.
+ */
+ RTFILE hFile;
+ rc = RTFileOpenBitBucket(&hFile, fd == 0 ? RTFILE_O_READ : RTFILE_O_WRITE);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ ph->enmType = RTHANDLETYPE_FILE;
+ ph->u.hFile = hFile;
+ *pph = ph;
+ }
+ else /* Add other piping stuff here. */
+ rc = VINF_SUCCESS; /* Same as parent (us). */
+
+ return rc;
+}
+
+
+/**
+ * Expands a file name / path to its real content. This only works on Windows
+ * for now (e.g. translating "%TEMP%\foo.exe" to "C:\Windows\Temp" when starting
+ * with system / administrative rights).
+ *
+ * @return IPRT status code.
+ * @param pszPath Path to resolve.
+ * @param pszExpanded Pointer to string to store the resolved path in.
+ * @param cbExpanded Size (in bytes) of string to store the resolved path.
+ */
+static int VBoxServiceControlThreadMakeFullPath(const char *pszPath, char *pszExpanded, size_t cbExpanded)
+{
+ int rc = VINF_SUCCESS;
+#ifdef RT_OS_WINDOWS
+ if (!ExpandEnvironmentStrings(pszPath, pszExpanded, cbExpanded))
+ rc = RTErrConvertFromWin32(GetLastError());
+#else
+ /* No expansion for non-Windows yet. */
+ rc = RTStrCopy(pszExpanded, cbExpanded, pszPath);
+#endif
+#ifdef DEBUG
+ VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlExecMakeFullPath: %s -> %s\n",
+ pszPath, pszExpanded);
+#endif
+ return rc;
+}
+
+
+/**
+ * Resolves the full path of a specified executable name. This function also
+ * resolves internal VBoxService tools to its appropriate executable path + name.
+ *
+ * @return IPRT status code.
+ * @param pszFileName File name to resovle.
+ * @param pszResolved Pointer to a string where the resolved file name will be stored.
+ * @param cbResolved Size (in bytes) of resolved file name string.
+ */
+static int VBoxServiceControlThreadResolveExecutable(const char *pszFileName,
+ char *pszResolved, size_t cbResolved)
+{
+ int rc = VINF_SUCCESS;
+
+ /* Search the path of our executable. */
+ char szVBoxService[RTPATH_MAX];
+ if (RTProcGetExecutablePath(szVBoxService, sizeof(szVBoxService)))
+ {
+ char *pszExecResolved = NULL;
+ if ( (g_pszProgName && RTStrICmp(pszFileName, g_pszProgName) == 0)
+ || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
+ {
+ /* We just want to execute VBoxService (no toolbox). */
+ pszExecResolved = RTStrDup(szVBoxService);
+ }
+ else /* Nothing to resolve, copy original. */
+ pszExecResolved = RTStrDup(pszFileName);
+ AssertPtr(pszExecResolved);
+
+ rc = VBoxServiceControlThreadMakeFullPath(pszExecResolved, pszResolved, cbResolved);
+#ifdef DEBUG
+ VBoxServiceVerbose(3, "ControlThread: VBoxServiceControlExecResolveExecutable: %s -> %s\n",
+ pszFileName, pszResolved);
+#endif
+ RTStrFree(pszExecResolved);
+ }
+ return rc;
+}
+
+
+/**
+ * Constructs the argv command line by resolving environment variables
+ * and relative paths.
+ *
+ * @return IPRT status code.
+ * @param pszArgv0 First argument (argv0), either original or modified version.
+ * @param papszArgs Original argv command line from the host, starting at argv[1].
+ * @param ppapszArgv Pointer to a pointer with the new argv command line.
+ * Needs to be freed with RTGetOptArgvFree.
+ */
+static int VBoxServiceControlThreadPrepareArgv(const char *pszArgv0,
+ const char * const *papszArgs, char ***ppapszArgv)
+{
+/** @todo RTGetOptArgvToString converts to MSC quoted string, while
+ * RTGetOptArgvFromString takes bourne shell according to the docs...
+ * Actually, converting to and from here is a very roundabout way of prepending
+ * an entry (pszFilename) to an array (*ppapszArgv). */
+ int rc = VINF_SUCCESS;
+ char *pszNewArgs = NULL;
+ if (pszArgv0)
+ rc = RTStrAAppend(&pszNewArgs, pszArgv0);
+ if ( RT_SUCCESS(rc)
+ && papszArgs)
+
+ {
+ char *pszArgs;
+ rc = RTGetOptArgvToString(&pszArgs, papszArgs,
+ RTGETOPTARGV_CNV_QUOTE_MS_CRT); /* RTGETOPTARGV_CNV_QUOTE_BOURNE_SH */
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTStrAAppend(&pszNewArgs, " ");
+ if (RT_SUCCESS(rc))
+ rc = RTStrAAppend(&pszNewArgs, pszArgs);
+ RTStrFree(pszArgs);
+ }
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ int iNumArgsIgnored;
+ rc = RTGetOptArgvFromString(ppapszArgv, &iNumArgsIgnored,
+ pszNewArgs ? pszNewArgs : "", NULL /* Use standard separators. */);
+ }
+
+ if (pszNewArgs)
+ RTStrFree(pszNewArgs);
+ return rc;
+}
+
+
+/**
+ * Helper function to create/start a process on the guest.
+ *
+ * @return IPRT status code.
+ * @param pszExec Full qualified path of process to start (without arguments).
+ * @param papszArgs Pointer to array of command line arguments.
+ * @param hEnv Handle to environment block to use.
+ * @param fFlags Process execution flags.
+ * @param phStdIn Handle for the process' stdin pipe.
+ * @param phStdOut Handle for the process' stdout pipe.
+ * @param phStdErr Handle for the process' stderr pipe.
+ * @param pszAsUser User name (account) to start the process under.
+ * @param pszPassword Password of the specified user.
+ * @param phProcess Pointer which will receive the process handle after
+ * successful process start.
+ */
+static int VBoxServiceControlThreadCreateProcess(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
+ PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
+ const char *pszPassword, PRTPROCESS phProcess)
+{
+ AssertPtrReturn(pszExec, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(papszArgs, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(phProcess, VERR_INVALID_PARAMETER);
+
+ int rc = VINF_SUCCESS;
+ char szExecExp[RTPATH_MAX];
+#ifdef RT_OS_WINDOWS
+ /*
+ * If sysprep should be executed do this in the context of VBoxService, which
+ * (usually, if started by SCM) has administrator rights. Because of that a UI
+ * won't be shown (doesn't have a desktop).
+ */
+ if (RTStrICmp(pszExec, "sysprep") == 0)
+ {
+ /* Use a predefined sysprep path as default. */
+ char szSysprepCmd[RTPATH_MAX] = "C:\\sysprep\\sysprep.exe";
+
+ /*
+ * On Windows Vista (and up) sysprep is located in "system32\\sysprep\\sysprep.exe",
+ * so detect the OS and use a different path.
+ */
+ OSVERSIONINFOEX OSInfoEx;
+ RT_ZERO(OSInfoEx);
+ OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if ( GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
+ && OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
+ {
+ rc = RTEnvGetEx(RTENV_DEFAULT, "windir", szSysprepCmd, sizeof(szSysprepCmd), NULL);
+ if (RT_SUCCESS(rc))
+ rc = RTPathAppend(szSysprepCmd, sizeof(szSysprepCmd), "system32\\sysprep\\sysprep.exe");
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ char **papszArgsExp;
+ rc = VBoxServiceControlThreadPrepareArgv(szSysprepCmd /* argv0 */, papszArgs, &papszArgsExp);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTProcCreateEx(szSysprepCmd, papszArgsExp, hEnv, 0 /* fFlags */,
+ phStdIn, phStdOut, phStdErr, NULL /* pszAsUser */,
+ NULL /* pszPassword */, phProcess);
+ RTGetOptArgvFree(papszArgsExp);
+ }
+ }
+ return rc;
+ }
+#endif /* RT_OS_WINDOWS */
+
+#ifdef VBOXSERVICE_TOOLBOX
+ if (RTStrStr(pszExec, "vbox_") == pszExec)
+ {
+ /* We want to use the internal toolbox (all internal
+ * tools are starting with "vbox_" (e.g. "vbox_cat"). */
+ rc = VBoxServiceControlThreadResolveExecutable(VBOXSERVICE_NAME, szExecExp, sizeof(szExecExp));
+ }
+ else
+ {
+#endif
+ /*
+ * Do the environment variables expansion on executable and arguments.
+ */
+ rc = VBoxServiceControlThreadResolveExecutable(pszExec, szExecExp, sizeof(szExecExp));
+#ifdef VBOXSERVICE_TOOLBOX
+ }
+#endif
+ if (RT_SUCCESS(rc))
+ {
+ char **papszArgsExp;
+ rc = VBoxServiceControlThreadPrepareArgv(pszExec /* Always use the unmodified executable name as argv0. */,
+ papszArgs /* Append the rest of the argument vector (if any). */, &papszArgsExp);
+ if (RT_SUCCESS(rc))
+ {
+ uint32_t uProcFlags = 0;
+ if (fFlags)
+ {
+ if (fFlags & EXECUTEPROCESSFLAG_HIDDEN)
+ uProcFlags |= RTPROC_FLAGS_HIDDEN;
+ if (fFlags & EXECUTEPROCESSFLAG_NO_PROFILE)
+ uProcFlags |= RTPROC_FLAGS_NO_PROFILE;
+ }
+
+ /* If no user name specified run with current credentials (e.g.
+ * full service/system rights). This is prohibited via official Main API!
+ *
+ * Otherwise use the RTPROC_FLAGS_SERVICE to use some special authentication
+ * code (at least on Windows) for running processes as different users
+ * started from our system service. */
+ if (*pszAsUser)
+ uProcFlags |= RTPROC_FLAGS_SERVICE;
+#ifdef DEBUG
+ VBoxServiceVerbose(3, "ControlThread: Command: %s\n", szExecExp);
+ for (size_t i = 0; papszArgsExp[i]; i++)
+ VBoxServiceVerbose(3, "ControlThread:\targv[%ld]: %s\n", i, papszArgsExp[i]);
+#endif
+ /* Do normal execution. */
+ rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, uProcFlags,
+ phStdIn, phStdOut, phStdErr,
+ *pszAsUser ? pszAsUser : NULL,
+ *pszPassword ? pszPassword : NULL,
+ phProcess);
+ RTGetOptArgvFree(papszArgsExp);
+ }
+ }
+ return rc;
+}
+
+/**
+ * The actual worker routine (loop) for a started guest process.
+ *
+ * @return IPRT status code.
+ * @param PVBOXSERVICECTRLTHREAD Thread data associated with a started process.
+ */
+static int VBoxServiceControlThreadProcessWorker(PVBOXSERVICECTRLTHREAD pThread)
+{
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ VBoxServiceVerbose(3, "ControlThread: Thread of process \"%s\" started\n", pThread->pszCmd);
+
+ int rc = VBoxServiceControlListSet(VBOXSERVICECTRLTHREADLIST_RUNNING, pThread);
+ AssertRC(rc);
+
+ rc = VbglR3GuestCtrlConnect(&pThread->uClientID);
+ if (RT_FAILURE(rc))
+ {
+ VBoxServiceError("ControlThread: Thread failed to connect to the guest control service, aborted! Error: %Rrc\n", rc);
+ RTThreadUserSignal(RTThreadSelf());
+ return rc;
+ }
+ VBoxServiceVerbose(3, "ControlThread: Guest process \"%s\" got client ID=%u, flags=0x%x\n",
+ pThread->pszCmd, pThread->uClientID, pThread->uFlags);
+
+ bool fSignalled = false; /* Indicator whether we signalled the thread user event already. */
+
+ /*
+ * Create the environment.
+ */
+ RTENV hEnv;
+ rc = RTEnvClone(&hEnv, RTENV_DEFAULT);
+ if (RT_SUCCESS(rc))
+ {
+ size_t i;
+ for (i = 0; i < pThread->uNumEnvVars && pThread->papszEnv; i++)
+ {
+ rc = RTEnvPutEx(hEnv, pThread->papszEnv[i]);
+ if (RT_FAILURE(rc))
+ break;
+ }
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Setup the redirection of the standard stuff.
+ */
+ /** @todo consider supporting: gcc stuff.c >file 2>&1. */
+ RTHANDLE hStdIn;
+ PRTHANDLE phStdIn;
+ rc = VBoxServiceControlThreadSetupPipe("|", 0 /*STDIN_FILENO*/,
+ &hStdIn, &phStdIn, &pThread->pipeStdInW);
+ if (RT_SUCCESS(rc))
+ {
+ RTHANDLE hStdOut;
+ PRTHANDLE phStdOut;
+ RTPIPE pipeStdOutR;
+ rc = VBoxServiceControlThreadSetupPipe( (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)
+ ? "|" : "/dev/null",
+ 1 /*STDOUT_FILENO*/,
+ &hStdOut, &phStdOut, &pipeStdOutR);
+ if (RT_SUCCESS(rc))
+ {
+ RTHANDLE hStdErr;
+ PRTHANDLE phStdErr;
+ RTPIPE pipeStdErrR;
+ rc = VBoxServiceControlThreadSetupPipe( (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)
+ ? "|" : "/dev/null",
+ 2 /*STDERR_FILENO*/,
+ &hStdErr, &phStdErr, &pipeStdErrR);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Create a poll set for the pipes and let the
+ * transport layer add stuff to it as well.
+ */
+ RTPOLLSET hPollSet;
+ rc = RTPollSetCreate(&hPollSet);
+ if (RT_SUCCESS(rc))
+ {
+ uint32_t uFlags = RTPOLL_EVT_ERROR;
+#if 0
+ /* Add reading event to pollset to get some more information. */
+ uFlags |= RTPOLL_EVT_READ;
+#endif
+ /* Stdin. */
+ if (RT_SUCCESS(rc))
+ rc = RTPollSetAddPipe(hPollSet, pThread->pipeStdInW, RTPOLL_EVT_ERROR, VBOXSERVICECTRLPIPEID_STDIN);
+ /* Stdout. */
+ if (RT_SUCCESS(rc))
+ rc = RTPollSetAddPipe(hPollSet, pipeStdOutR, uFlags, VBOXSERVICECTRLPIPEID_STDOUT);
+ /* Stderr. */
+ if (RT_SUCCESS(rc))
+ rc = RTPollSetAddPipe(hPollSet, pipeStdErrR, uFlags, VBOXSERVICECTRLPIPEID_STDERR);
+ /* IPC notification pipe. */
+ if (RT_SUCCESS(rc))
+ rc = RTPipeCreate(&pThread->hNotificationPipeR, &pThread->hNotificationPipeW, 0 /* Flags */);
+ if (RT_SUCCESS(rc))
+ rc = RTPollSetAddPipe(hPollSet, pThread->hNotificationPipeR, RTPOLL_EVT_READ, VBOXSERVICECTRLPIPEID_IPC_NOTIFY);
+
+ if (RT_SUCCESS(rc))
+ {
+ RTPROCESS hProcess;
+ rc = VBoxServiceControlThreadCreateProcess(pThread->pszCmd, pThread->papszArgs, hEnv, pThread->uFlags,
+ phStdIn, phStdOut, phStdErr,
+ pThread->pszUser, pThread->pszPassword,
+ &hProcess);
+ if (RT_FAILURE(rc))
+ VBoxServiceError("ControlThread: Error starting process, rc=%Rrc\n", rc);
+ /*
+ * Tell the control thread that it can continue
+ * spawning services. This needs to be done after the new
+ * process has been started because otherwise signal handling
+ * on (Open) Solaris does not work correctly (see #5068).
+ */
+ int rc2 = RTThreadUserSignal(RTThreadSelf());
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ fSignalled = true;
+
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Close the child ends of any pipes and redirected files.
+ */
+ rc2 = RTHandleClose(phStdIn); AssertRC(rc2);
+ phStdIn = NULL;
+ rc2 = RTHandleClose(phStdOut); AssertRC(rc2);
+ phStdOut = NULL;
+ rc2 = RTHandleClose(phStdErr); AssertRC(rc2);
+ phStdErr = NULL;
+
+ /* Enter the process loop. */
+ rc = VBoxServiceControlThreadProcLoop(pThread,
+ hProcess, pThread->uTimeLimitMS, hPollSet,
+ &pThread->pipeStdInW, &pipeStdOutR, &pipeStdErrR);
+
+ /*
+ * The handles that are no longer in the set have
+ * been closed by the above call in order to prevent
+ * the guest from getting stuck accessing them.
+ * So, NIL the handles to avoid closing them again.
+ */
+ if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_IPC_NOTIFY, NULL)))
+ {
+ pThread->hNotificationPipeR = NIL_RTPIPE;
+ pThread->hNotificationPipeW = NIL_RTPIPE;
+ }
+ if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDERR, NULL)))
+ pipeStdErrR = NIL_RTPIPE;
+ if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDOUT, NULL)))
+ pipeStdOutR = NIL_RTPIPE;
+ if (RT_FAILURE(RTPollSetQueryHandle(hPollSet, VBOXSERVICECTRLPIPEID_STDIN, NULL)))
+ pThread->pipeStdInW = NIL_RTPIPE;
+ }
+ }
+ RTPollSetDestroy(hPollSet);
+
+ RTPipeClose(pThread->hNotificationPipeR);
+ pThread->hNotificationPipeR = NIL_RTPIPE;
+ RTPipeClose(pThread->hNotificationPipeW);
+ pThread->hNotificationPipeW = NIL_RTPIPE;
+ }
+ RTPipeClose(pipeStdErrR);
+ pipeStdErrR = NIL_RTPIPE;
+ RTHandleClose(phStdErr);
+ if (phStdErr)
+ RTHandleClose(phStdErr);
+ }
+ RTPipeClose(pipeStdOutR);
+ pipeStdOutR = NIL_RTPIPE;
+ RTHandleClose(&hStdOut);
+ if (phStdOut)
+ RTHandleClose(phStdOut);
+ }
+ RTPipeClose(pThread->pipeStdInW);
+ pThread->pipeStdInW = NIL_RTPIPE;
+ RTHandleClose(phStdIn);
+ }
+ }
+ RTEnvDestroy(hEnv);
+ }
+
+ /* Move thread to stopped thread list. */
+ int rc2 = VBoxServiceControlListSet(VBOXSERVICECTRLTHREADLIST_STOPPED, pThread);
+ AssertRC(rc2);
+
+ if (pThread->uClientID)
+ {
+ if (RT_FAILURE(rc))
+ {
+ rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pThread->uPID,
+ PROC_STS_ERROR, rc,
+ NULL /* pvData */, 0 /* cbData */);
+ if (RT_FAILURE(rc2))
+ VBoxServiceError("ControlThread: Could not report process failure error; rc=%Rrc (process error %Rrc)\n",
+ rc2, rc);
+ }
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Cancelling pending host requests (client ID=%u)\n",
+ pThread->uPID, pThread->uClientID);
+ rc2 = VbglR3GuestCtrlCancelPendingWaits(pThread->uClientID);
+ if (RT_FAILURE(rc2))
+ {
+ VBoxServiceError("ControlThread: [PID %u]: Cancelling pending host requests failed; rc=%Rrc\n",
+ pThread->uPID, rc2);
+ if (RT_SUCCESS(rc))
+ rc = rc2;
+ }
+
+ /* Disconnect from guest control service. */
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Disconnecting (client ID=%u) ...\n",
+ pThread->uPID, pThread->uClientID);
+ VbglR3GuestCtrlDisconnect(pThread->uClientID);
+ pThread->uClientID = 0;
+ }
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Thread of process \"%s\" ended with rc=%Rrc\n",
+ pThread->uPID, pThread->pszCmd, rc);
+
+ /* Update started/stopped status. */
+ ASMAtomicXchgBool(&pThread->fStopped, true);
+ ASMAtomicXchgBool(&pThread->fStarted, false);
+
+ /*
+ * If something went wrong signal the user event so that others don't wait
+ * forever on this thread.
+ */
+ if (RT_FAILURE(rc) && !fSignalled)
+ RTThreadUserSignal(RTThreadSelf());
+
+ return rc;
+}
+
+
+/**
+ * Thread main routine for a started process.
+ *
+ * @return IPRT status code.
+ * @param RTTHREAD Pointer to the thread's data.
+ * @param void* User-supplied argument pointer.
+ *
+ */
+static DECLCALLBACK(int) VBoxServiceControlThread(RTTHREAD ThreadSelf, void *pvUser)
+{
+ PVBOXSERVICECTRLTHREAD pThread = (VBOXSERVICECTRLTHREAD*)pvUser;
+ AssertPtrReturn(pThread, VERR_INVALID_POINTER);
+ return VBoxServiceControlThreadProcessWorker(pThread);
+}
+
+
+/**
+ * Executes (starts) a process on the guest. This causes a new thread to be created
+ * so that this function will not block the overall program execution.
+ *
+ * @return IPRT status code.
+ * @param uContextID Context ID to associate the process to start with.
+ * @param pProcess Process info.
+ */
+int VBoxServiceControlThreadStart(uint32_t uContextID,
+ PVBOXSERVICECTRLPROCESS pProcess)
+{
+ AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
+
+ /*
+ * Allocate new thread data and assign it to our thread list.
+ */
+ PVBOXSERVICECTRLTHREAD pThread = (PVBOXSERVICECTRLTHREAD)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREAD));
+ if (!pThread)
+ return VERR_NO_MEMORY;
+
+ int rc = gstsvcCntlExecThreadInit(pThread, pProcess, uContextID);
+ if (RT_SUCCESS(rc))
+ {
+ static uint32_t s_uCtrlExecThread = 0;
+ if (s_uCtrlExecThread++ == UINT32_MAX)
+ s_uCtrlExecThread = 0; /* Wrap around to not let IPRT freak out. */
+ rc = RTThreadCreateF(&pThread->Thread, VBoxServiceControlThread,
+ pThread /*pvUser*/, 0 /*cbStack*/,
+ RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "gctl%u", s_uCtrlExecThread);
+ if (RT_FAILURE(rc))
+ {
+ VBoxServiceError("ControlThread: RTThreadCreate failed, rc=%Rrc\n, pThread=%p\n",
+ rc, pThread);
+ }
+ else
+ {
+ VBoxServiceVerbose(4, "ControlThread: Waiting for thread to initialize ...\n");
+
+ /* Wait for the thread to initialize. */
+ rc = RTThreadUserWait(pThread->Thread, 60 * 1000 /* 60 seconds max. */);
+ AssertRC(rc);
+ if ( ASMAtomicReadBool(&pThread->fShutdown)
+ || RT_FAILURE(rc))
+ {
+ VBoxServiceError("ControlThread: Thread for process \"%s\" failed to start, rc=%Rrc\n",
+ pProcess->szCmd, rc);
+ }
+ else
+ {
+ ASMAtomicXchgBool(&pThread->fStarted, true);
+ }
+ }
+ }
+
+ if (RT_FAILURE(rc))
+ RTMemFree(pThread);
+
+ return rc;
+}
+
+
+/**
+ * Performs a request to a specific (formerly started) guest process and waits
+ * for its response.
+ *
+ * @return IPRT status code.
+ * @param uPID PID of guest process to perform a request to.
+ * @param pRequest Pointer to request to perform.
+ */
+int VBoxServiceControlThreadPerform(uint32_t uPID, PVBOXSERVICECTRLREQUEST pRequest)
+{
+ AssertPtrReturn(pRequest, VERR_INVALID_POINTER);
+ AssertReturn(pRequest->enmType > VBOXSERVICECTRLREQUEST_UNKNOWN, VERR_INVALID_PARAMETER);
+ /* Rest in pRequest is optional (based on the request type). */
+
+ int rc = VINF_SUCCESS;
+ PVBOXSERVICECTRLTHREAD pThread = VBoxServiceControlLockThread(uPID);
+ if (pThread)
+ {
+ if (ASMAtomicReadBool(&pThread->fShutdown))
+ {
+ rc = VERR_CANCELLED;
+ }
+ else
+ {
+ /* Set request structure pointer. */
+ pThread->pRequest = pRequest;
+
+ /** @todo To speed up simultaneous guest process handling we could add a worker threads
+ * or queue in order to wait for the request to happen. Later. */
+ /* Wake up guest thrad by sending a wakeup byte to the notification pipe so
+ * that RTPoll unblocks (returns) and we then can do our requested operation. */
+ Assert(pThread->hNotificationPipeW != NIL_RTPIPE);
+ size_t cbWritten;
+ if (RT_SUCCESS(rc))
+ rc = RTPipeWrite(pThread->hNotificationPipeW, "i", 1, &cbWritten);
+
+ if ( RT_SUCCESS(rc)
+ && cbWritten)
+ {
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Waiting for response on enmType=%u, pvData=0x%p, cbData=%u\n",
+ uPID, pRequest->enmType, pRequest->pvData, pRequest->cbData);
+
+ rc = VBoxServiceControlThreadRequestWait(pRequest);
+ }
+ }
+
+ VBoxServiceControlUnlockThread(pThread);
+ }
+ else /* PID not found! */
+ rc = VERR_NOT_FOUND;
+
+ VBoxServiceVerbose(3, "ControlThread: [PID %u]: Performed enmType=%u, uCID=%u, pvData=0x%p, cbData=%u, rc=%Rrc\n",
+ uPID, pRequest->enmType, pRequest->uCID, pRequest->pvData, pRequest->cbData, rc);
+ return rc;
+}
+
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
index 600ef09b0..431b30ec1 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceCpuHotPlug.cpp
@@ -378,7 +378,8 @@ static DECLCALLBACK(int) VBoxServiceCpuHotPlugOption(const char **ppszShort, int
NOREF(argc);
NOREF(argv);
NOREF(pi);
- return VINF_SUCCESS;
+
+ return -1;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
index df22915c2..4ce09b681 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
@@ -28,6 +28,7 @@
#include <iprt/critsect.h>
#include <VBox/VBoxGuestLib.h>
+#include <VBox/HostServices/GuestControlSvc.h>
/**
* A service descriptor.
@@ -107,95 +108,145 @@ typedef VBOXSERVICE const *PCVBOXSERVICE;
#endif /* RT_OS_WINDOWS */
#ifdef VBOX_WITH_GUEST_CONTROL
-typedef enum VBOXSERVICECTRLTHREADDATATYPE
-{
- kVBoxServiceCtrlThreadDataUnknown = 0,
- kVBoxServiceCtrlThreadDataExec
-} VBOXSERVICECTRLTHREADDATATYPE;
-
+/**
+ * Pipe IDs for handling the guest process poll set.
+ */
typedef enum VBOXSERVICECTRLPIPEID
{
- VBOXSERVICECTRLPIPEID_STDIN = 0,
- VBOXSERVICECTRLPIPEID_STDIN_ERROR,
- VBOXSERVICECTRLPIPEID_STDIN_WRITABLE,
- VBOXSERVICECTRLPIPEID_STDIN_INPUT_NOTIFY,
- VBOXSERVICECTRLPIPEID_STDOUT,
- VBOXSERVICECTRLPIPEID_STDERR
+ VBOXSERVICECTRLPIPEID_UNKNOWN = 0,
+ VBOXSERVICECTRLPIPEID_STDIN = 10,
+ VBOXSERVICECTRLPIPEID_STDIN_WRITABLE = 11,
+ /** Pipe for reading from guest process' stdout. */
+ VBOXSERVICECTRLPIPEID_STDOUT = 40,
+ /** Pipe for reading from guest process' stderr. */
+ VBOXSERVICECTRLPIPEID_STDERR = 50,
+ /** Notification pipe for waking up the guest process
+ * control thread. */
+ VBOXSERVICECTRLPIPEID_IPC_NOTIFY = 100
} VBOXSERVICECTRLPIPEID;
/**
- * Structure for holding buffered pipe data.
+ * Request types to perform on a started guest process.
*/
-typedef struct
+typedef enum VBOXSERVICECTRLREQUESTTYPE
{
- /** The PID the pipe is assigned to. */
- uint32_t uPID;
- /** The pipe's Id of enum VBOXSERVICECTRLPIPEID. */
- uint8_t uPipeId;
- /** The data buffer. */
- uint8_t *pbData;
- /** The amount of allocated buffer space. */
- uint32_t cbAllocated;
- /** The actual used/occupied buffer space. */
- uint32_t cbSize;
- /** Helper variable for keeping track of what
- * already was processed and what not. */
- uint32_t cbOffset;
- /** Critical section protecting this buffer structure. */
- RTCRITSECT CritSect;
- /** Flag indicating whether this pipe buffer accepts new
- * data to be written to or not. If not enabled, already
- * (allocated) buffered data still can be read out. */
- bool fEnabled;
- /** Set if it's necessary to write to the notification pipe. */
- bool fNeedNotification;
- /** Set if the pipe needs to be closed after the next read/write. */
- bool fPendingClose;
- /** The notification pipe associated with this buffer.
- * This is NIL_RTPIPE for output pipes. */
- RTPIPE hNotificationPipeW;
- /** The other end of hNotificationPipeW. */
- RTPIPE hNotificationPipeR;
- /** The event semaphore for getting notified whether something
- * has changed, e.g. written to this buffer or enabled/disabled it. */
- RTSEMEVENT hEventSem;
-} VBOXSERVICECTRLEXECPIPEBUF;
-/** Pointer to buffered pipe data. */
-typedef VBOXSERVICECTRLEXECPIPEBUF *PVBOXSERVICECTRLEXECPIPEBUF;
+ /** Unknown request. */
+ VBOXSERVICECTRLREQUEST_UNKNOWN = 0,
+ /** Main control thread asked used to quit. */
+ VBOXSERVICECTRLREQUEST_QUIT = 1,
+ /** Performs reading from stdout. */
+ VBOXSERVICECTRLREQUEST_STDOUT_READ = 50,
+ /** Performs reading from stderr. */
+ VBOXSERVICECTRLREQUEST_STDERR_READ = 60,
+ /** Performs writing to stdin. */
+ VBOXSERVICECTRLREQUEST_STDIN_WRITE = 70,
+ /** Same as VBOXSERVICECTRLREQUEST_STDIN_WRITE, but
+ * marks the end of input. */
+ VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF = 71,
+ /** Kill/terminate process.
+ * @todo Implement this! */
+ VBOXSERVICECTRLREQUEST_KILL = 90,
+ /** Gently ask process to terminate.
+ * @todo Implement this! */
+ VBOXSERVICECTRLREQUEST_HANGUP = 91,
+ /** Ask the process in which status it
+ * currently is.
+ * @todo Implement this! */
+ VBOXSERVICECTRLREQUEST_STATUS = 100
+} VBOXSERVICECTRLREQUESTTYPE;
/**
- * Structure for holding guest exection relevant data.
+ * Thread list types.
*/
-typedef struct
+typedef enum VBOXSERVICECTRLTHREADLISTTYPE
{
- uint32_t uPID;
- char *pszCmd;
- uint32_t uFlags;
- char **papszArgs;
- uint32_t uNumArgs;
- char **papszEnv;
- uint32_t uNumEnvVars;
- char *pszUser;
- char *pszPassword;
- uint32_t uTimeLimitMS;
-
- RTPIPE pipeStdInW;
- VBOXSERVICECTRLEXECPIPEBUF stdIn;
- VBOXSERVICECTRLEXECPIPEBUF stdOut;
- VBOXSERVICECTRLEXECPIPEBUF stdErr;
-
-} VBOXSERVICECTRLTHREADDATAEXEC;
-/** Pointer to thread data. */
-typedef VBOXSERVICECTRLTHREADDATAEXEC *PVBOXSERVICECTRLTHREADDATAEXEC;
+ /** Unknown list -- uncool to use. */
+ VBOXSERVICECTRLTHREADLIST_UNKNOWN = 0,
+ /** Stopped list: Here all guest threads end up
+ * when they reached the stopped state and can
+ * be shut down / free'd safely. */
+ VBOXSERVICECTRLTHREADLIST_STOPPED = 1,
+ /**
+ * Started list: Here all threads are registered
+ * when they're up and running (that is, accepting
+ * commands).
+ */
+ VBOXSERVICECTRLTHREADLIST_RUNNING = 2
+} VBOXSERVICECTRLTHREADLISTTYPE;
-/* Structure for holding thread relevant data. */
+/**
+ * Structure to perform a request on a started guest
+ * process. Needed for letting the main guest control thread
+ * to communicate (and wait) for a certain operation which
+ * will be done in context of the started guest process thread.
+ */
+typedef struct VBOXSERVICECTRLREQUEST
+{
+ /** Event semaphore to serialize access. */
+ RTSEMEVENTMULTI Event;
+ /** The request type to handle. */
+ VBOXSERVICECTRLREQUESTTYPE enmType;
+ /** Payload size; on input, this contains the (maximum) amount
+ * of data the caller wants to write or to read. On output,
+ * this show the actual amount of data read/written. */
+ size_t cbData;
+ /** Payload data; a pre-allocated data buffer for input/output. */
+ void *pvData;
+ /** The context ID which is required to complete the
+ * request. Not used at the moment. */
+ uint32_t uCID;
+ /** The overall result of the operation. */
+ int rc;
+} VBOXSERVICECTRLREQUEST;
+/** Pointer to request. */
+typedef VBOXSERVICECTRLREQUEST *PVBOXSERVICECTRLREQUEST;
+
+/**
+ * Structure holding information for starting a guest
+ * process.
+ */
+typedef struct VBOXSERVICECTRLPROCESS
+{
+ /** Full qualified path of process to start (without arguments). */
+ char szCmd[GUESTPROCESS_MAX_CMD_LEN];
+ /** Process execution flags. @sa */
+ uint32_t uFlags;
+ /** Command line arguments. */
+ char szArgs[GUESTPROCESS_MAX_ARGS_LEN];
+ /** Number of arguments specified in pszArgs. */
+ uint32_t uNumArgs;
+ /** String of environment variables ("FOO=BAR") to pass to the process
+ * to start. */
+ char szEnv[GUESTPROCESS_MAX_ENV_LEN];
+ /** Size (in bytes) of environment variables block. */
+ uint32_t cbEnv;
+ /** Number of environment variables specified in pszEnv. */
+ uint32_t uNumEnvVars;
+ /** User name (account) to start the process under. */
+ char szUser[GUESTPROCESS_MAX_USER_LEN];
+ /** Password of specified user name (account). */
+ char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];
+ /** Time limit (in ms) of the process' life time. */
+ uint32_t uTimeLimitMS;
+} VBOXSERVICECTRLPROCESS;
+/** Pointer to a guest process block. */
+typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS;
+
+/**
+ * Structure for holding data for one (started) guest process.
+ */
typedef struct VBOXSERVICECTRLTHREAD
{
+ /** Pointer to list archor of following
+ * list node.
+ * @todo Would be nice to have a RTListGetAnchor(). */
+ PRTLISTNODE pAnchor;
/** Node. */
RTLISTNODE Node;
/** The worker thread. */
RTTHREAD Thread;
- /** Shutdown indicator. */
+ /** Shutdown indicator; will be set when the thread
+ * needs (or is asked) to shutdown. */
bool volatile fShutdown;
/** Indicator set by the service thread exiting. */
bool volatile fStopped;
@@ -205,10 +256,36 @@ typedef struct VBOXSERVICECTRLTHREAD
uint32_t uClientID;
/** Context ID. */
uint32_t uContextID;
- /** Type of thread. See VBOXSERVICECTRLTHREADDATATYPE for more info. */
- VBOXSERVICECTRLTHREADDATATYPE enmType;
- /** Pointer to actual thread data, depending on enmType. */
- void *pvData;
+ /** Critical section for thread-safe use. */
+ RTCRITSECT CritSect;
+
+ /** @todo Document me! */
+ uint32_t uPID;
+ char *pszCmd;
+ uint32_t uFlags;
+ char **papszArgs;
+ uint32_t uNumArgs;
+ char **papszEnv;
+ uint32_t uNumEnvVars;
+ /** Name of specified user account to run the
+ * guest process under. */
+ char *pszUser;
+ /** Password of specified user account. */
+ char *pszPassword;
+ /** Overall time limit (in ms) that the guest process
+ * is allowed to run. 0 for indefinite time. */
+ uint32_t uTimeLimitMS;
+ /** Pointer to the current IPC request being
+ * processed. */
+ PVBOXSERVICECTRLREQUEST pRequest;
+ /** StdIn pipe for addressing writes to the
+ * guest process' stdin.*/
+ RTPIPE pipeStdInW;
+ /** The notification pipe associated with this guest process.
+ * This is NIL_RTPIPE for output pipes. */
+ RTPIPE hNotificationPipeW;
+ /** The other end of hNotificationPipeW. */
+ RTPIPE hNotificationPipeR;
} VBOXSERVICECTRLTHREAD;
/** Pointer to thread data. */
typedef VBOXSERVICECTRLTHREAD *PVBOXSERVICECTRLTHREAD;
@@ -307,26 +384,38 @@ extern int VBoxServiceWinGetComponentVersions(uint32_t uiClientID);
#endif /* RT_OS_WINDOWS */
#ifdef VBOX_WITH_GUEST_CONTROL
-extern void VBoxServiceControlThreadSignalShutdown(const PVBOXSERVICECTRLTHREAD pThread);
-extern int VBoxServiceControlThreadWaitForShutdown(const PVBOXSERVICECTRLTHREAD pThread);
-
-extern int VBoxServiceControlExecHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms);
-extern int VBoxServiceControlExecHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, size_t cbMaxBufSize);
-extern int VBoxServiceControlExecHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms);
-extern int VBoxServiceControlExecProcess(uint32_t uClientID, uint32_t uContext,
- const char *pszCmd, uint32_t uFlags,
- const char *pszArgs, uint32_t uNumArgs,
- const char *pszEnv, uint32_t cbEnv, uint32_t uNumEnvVars,
- const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS);
-extern void VBoxServiceControlExecThreadDataDestroy(PVBOXSERVICECTRLTHREADDATAEXEC pThread);
+/* Guest control main thread functions. */
+extern int VBoxServiceControlAssignPID(PVBOXSERVICECTRLTHREAD pThread, uint32_t uPID);
+extern int VBoxServiceControlListSet(VBOXSERVICECTRLTHREADLISTTYPE enmList,
+ PVBOXSERVICECTRLTHREAD pThread);
+extern PVBOXSERVICECTRLTHREAD VBoxServiceControlLockThread(uint32_t uPID);
+extern void VBoxServiceControlUnlockThread(const PVBOXSERVICECTRLTHREAD pThread);
+extern int VBoxServiceControlSetInactive(PVBOXSERVICECTRLTHREAD pThread);
+/* Per-thread guest process functions. */
+extern int VBoxServiceControlThreadStart(uint32_t uContext,
+ PVBOXSERVICECTRLPROCESS pProcess);
+extern int VBoxServiceControlThreadPerform(uint32_t uPID, PVBOXSERVICECTRLREQUEST pRequest);
+extern int VBoxServiceControlThreadStop(const PVBOXSERVICECTRLTHREAD pThread);
+extern int VBoxServiceControlThreadWait(const PVBOXSERVICECTRLTHREAD pThread, RTMSINTERVAL msTimeout);
+extern int VBoxServiceControlThreadFree(PVBOXSERVICECTRLTHREAD pThread);
+/* Request handling. */
+extern int VBoxServiceControlThreadRequestAlloc(PVBOXSERVICECTRLREQUEST *ppReq,
+ VBOXSERVICECTRLREQUESTTYPE enmType);
+extern int VBoxServiceControlThreadRequestAllocEx(PVBOXSERVICECTRLREQUEST *ppReq,
+ VBOXSERVICECTRLREQUESTTYPE enmType,
+ void* pbData,
+ size_t cbData,
+ uint32_t uCID);
+extern void VBoxServiceControlThreadRequestFree(PVBOXSERVICECTRLREQUEST pReq);
#endif /* VBOX_WITH_GUEST_CONTROL */
#ifdef VBOXSERVICE_MANAGEMENT
-extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage);
+extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage);
#endif
#if defined(VBOX_WITH_PAGE_SHARING) && defined(RT_OS_WINDOWS)
-extern RTEXITCODE VBoxServicePageSharingInitFork(void);
+extern RTEXITCODE VBoxServicePageSharingInitFork(void);
#endif
+extern int VBoxServiceVMInfoSignal(void);
RT_C_DECLS_END
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
index c051f1220..39c9912de 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
@@ -241,17 +241,10 @@ void VBoxServicePageSharingRegisterModule(PKNOWN_MODULE pModule, bool fValidateM
idxRegion++;
}
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VbglR3RegisterSharedModule %s %s base=%p size=%x cregions=%d\n", pModule->Info.szModule, pModule->szFileVersion, pModule->Info.modBaseAddr, pModule->Info.modBaseSize, idxRegion);
-#ifdef RT_ARCH_X86
- int rc = VbglR3RegisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR32)pModule->Info.modBaseAddr,
- pModule->Info.modBaseSize, idxRegion, aRegions);
-#else
- int rc = VbglR3RegisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR64)pModule->Info.modBaseAddr,
+ int rc = VbglR3RegisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (uintptr_t)pModule->Info.modBaseAddr,
pModule->Info.modBaseSize, idxRegion, aRegions);
-#endif
-
-// AssertRC(rc);
if (RT_FAILURE(rc))
- VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VbglR3RegisterSharedModule failed with %d\n", rc);
+ VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VbglR3RegisterSharedModule failed with %Rrc\n", rc);
end:
RTMemFree(pVersionInfo);
@@ -292,7 +285,7 @@ void VBoxServicePageSharingInspectModules(DWORD dwProcessId, PAVLPVNODECORE *ppN
bRet = Module32First(hSnapshot, &ModuleInfo);
do
{
- /** todo when changing this make sure VBoxService.exe is excluded! */
+ /** @todo when changing this make sure VBoxService.exe is excluded! */
char *pszDot = strrchr(ModuleInfo.szModule, '.');
if ( pszDot
&& (pszDot[1] == 'e' || pszDot[1] == 'E'))
@@ -504,14 +497,11 @@ static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE
VBoxServiceVerbose(3, "VBoxServicePageSharingEmptyTreeCallback %s %s\n", pModule->Info.szModule, pModule->szFileVersion);
/* Dereference module in the hypervisor. */
- if ( !pfUnregister
- || *pfUnregister == true)
+ if ( !pfUnregister
+ || *pfUnregister)
{
- #ifdef RT_ARCH_X86
- int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR32)pModule->Info.modBaseAddr, pModule->Info.modBaseSize);
- #else
- int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR64)pModule->Info.modBaseAddr, pModule->Info.modBaseSize);
- #endif
+ int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion,
+ (uintptr_t)pModule->Info.modBaseAddr, pModule->Info.modBaseSize);
AssertRC(rc);
}
@@ -548,7 +538,8 @@ static DECLCALLBACK(int) VBoxServicePageSharingOption(const char **ppszShort, in
NOREF(argc);
NOREF(argv);
NOREF(pi);
- return VINF_SUCCESS;
+
+ return -1;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp
deleted file mode 100644
index f38868bf5..000000000
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-/* $Id: VBoxServicePipeBuf.cpp $ */
-/** @file
- * VBoxServicePipeBuf - Pipe buffering.
- */
-
-/*
- * Copyright (C) 2010-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 <iprt/assert.h>
-#include <iprt/mem.h>
-#include <iprt/pipe.h>
-#include <iprt/semaphore.h>
-#include <iprt/string.h>
-
-#include "VBoxServicePipeBuf.h"
-
-/**
- * Initializes a pipe buffer.
- *
- * @returns IPRT status code.
- * @param pBuf The pipe buffer to initialize.
- * @param uId The pipe's ID handle.
- * @param fNeedNotificationPipe Whether the buffer needs a notification
- * pipe or not.
- */
-int VBoxServicePipeBufInit(PVBOXSERVICECTRLEXECPIPEBUF pBuf, uint8_t uId, bool fNeedNotificationPipe)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
-
- /** @todo Add allocation size as function parameter! */
- pBuf->uPID = 0; /* We don't have the PID yet. */
- pBuf->uPipeId = uId;
- pBuf->pbData = (uint8_t *)RTMemAlloc(_64K); /* Start with a 64k buffer. */
- AssertReturn(pBuf->pbData, VERR_NO_MEMORY);
- pBuf->cbAllocated = _64K;
- pBuf->cbSize = 0;
- pBuf->cbOffset = 0;
- pBuf->fEnabled = true;
- pBuf->fPendingClose = false;
- pBuf->fNeedNotification = fNeedNotificationPipe;
- pBuf->hNotificationPipeW = NIL_RTPIPE;
- pBuf->hNotificationPipeR = NIL_RTPIPE;
- pBuf->hEventSem = NIL_RTSEMEVENT;
-
- int rc = RTSemEventCreate(&pBuf->hEventSem);
- if (RT_SUCCESS(rc))
- {
- rc = RTCritSectInit(&pBuf->CritSect);
- if (RT_SUCCESS(rc) && fNeedNotificationPipe)
- rc = RTPipeCreate(&pBuf->hNotificationPipeR, &pBuf->hNotificationPipeW, 0);
- }
-
- if (RT_FAILURE(rc))
- {
- if (RTCritSectIsInitialized(&pBuf->CritSect))
- RTCritSectDelete(&pBuf->CritSect);
- if (pBuf->hEventSem != NIL_RTSEMEVENT)
- RTSemEventDestroy(pBuf->hEventSem);
- }
- return rc;
-}
-
-
-/**
- * Reads out data from a specififed pipe buffer.
- *
- * @return IPRT status code.
- * @param pBuf Pointer to pipe buffer to read the data from.
- * @param pbBuffer Pointer to buffer to store the read out data.
- * @param cbBuffer Size (in bytes) of the buffer where to store the data.
- * @param pcbToRead Pointer to desired amount (in bytes) of data to read,
- * will reflect the actual amount read on return.
- */
-int VBoxServicePipeBufRead(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
- uint8_t *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
- AssertPtrReturn(pbBuffer, VERR_INVALID_POINTER);
- AssertReturn(cbBuffer, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pcbToRead, VERR_INVALID_POINTER);
- AssertReturn(*pcbToRead > 0, VERR_INVALID_PARAMETER); /* Nothing to read makes no sense ... */
-
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- Assert(pBuf->cbSize >= pBuf->cbOffset);
- uint32_t cbToRead = *pcbToRead;
-
- if (cbToRead > pBuf->cbSize - pBuf->cbOffset)
- cbToRead = pBuf->cbSize - pBuf->cbOffset;
-
- if (cbToRead > cbBuffer)
- cbToRead = cbBuffer;
-
- if (cbToRead)
- {
- memcpy(pbBuffer, &pBuf->pbData[pBuf->cbOffset], cbToRead);
- pBuf->cbOffset += cbToRead;
-
-#ifdef DEBUG_andy
- VBoxServiceVerbose(4, "Pipe [%u %u 0x%p %s] read cbToRead=%u, cbSize=%u, cbAlloc=%u, cbOff=%u\n",
- pBuf->uPID, pBuf->uPipeId, pBuf, pBuf->fEnabled ? "EN" : "DIS", cbToRead, pBuf->cbSize, pBuf->cbAllocated, pBuf->cbOffset);
-#endif
- /* Don't signal event semaphore here -- we only read out something from
- * this pipe buffer. */
-
- *pcbToRead = cbToRead;
- }
- else
- {
- *pcbToRead = 0;
- }
-
- int rc2 = RTCritSectLeave(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
- return rc;
-}
-
-
-/**
- * Peeks for buffer data without moving the buffer's offset
- * or touching any other internal data.
- *
- * @return IPRT status code.
- * @param pBuf Pointer to pipe buffer to read the data from.
- * @param pbBuffer Pointer to buffer to store the read out data.
- * @param cbBuffer Size (in bytes) of the buffer where to store the data.
- * @param cbOffset Offset (in bytes) where to start reading.
- * @param pcbRead Pointer to desired amount (in bytes) of data to read,
- * will reflect the actual amount read on return.
- * @param pcbLeft Pointer to bytes left in buffer after the current read
- * operation.
- */
-int VBoxServicePipeBufPeek(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
- uint8_t *pbBuffer, uint32_t cbBuffer,
- uint32_t cbOffset,
- uint32_t *pcbRead, uint32_t *pcbLeft)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
- AssertPtrReturn(pbBuffer, VERR_INVALID_POINTER);
- AssertReturn(cbBuffer, VERR_INVALID_PARAMETER);
- AssertReturn(pBuf->cbSize >= pBuf->cbOffset, VERR_BUFFER_OVERFLOW);
-
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- if (cbOffset > pBuf->cbSize)
- cbOffset = pBuf->cbSize;
- uint32_t cbToRead = pBuf->cbSize - cbOffset;
- if (cbToRead > cbBuffer)
- cbToRead = cbBuffer;
- if (cbToRead)
- {
- memcpy(pbBuffer, &pBuf->pbData[cbOffset], cbToRead);
- pbBuffer[cbBuffer - 1] = '\0';
- }
- if (pcbRead)
- *pcbRead = cbToRead;
- if (pcbLeft)
- *pcbLeft = pBuf->cbSize - (cbOffset + cbToRead);
-
- int rc2 = RTCritSectLeave(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
- return rc;
-}
-
-
-/**
- * Writes data into a specififed pipe buffer.
- *
- * @return IPRT status code.
- * @param pBuf Pointer to pipe buffer to write data into.
- * @param pbData Pointer to byte data to write.
- * @param cbData Data size (in bytes) to write.
- * @param fPendingClose Needs the pipe (buffer) to be closed next time we have the chance to?
- * @param pcbWritten Pointer to where the amount of written bytes get stored. Optional.
- */
-int VBoxServicePipeBufWriteToBuf(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
- uint8_t *pbData, uint32_t cbData, bool fPendingClose,
- uint32_t *pcbWritten)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
- AssertPtrReturn(pbData, VERR_INVALID_POINTER);
-
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- if (pBuf->fEnabled)
- {
- /* Rewind the buffer if it's empty. */
- size_t cbInBuf = pBuf->cbSize - pBuf->cbOffset;
- bool const fAddToSet = cbInBuf == 0;
- if (fAddToSet)
- pBuf->cbSize = pBuf->cbOffset = 0;
-
- /* Try and see if we can simply append the data. */
- if (cbData + pBuf->cbSize <= pBuf->cbAllocated)
- {
- memcpy(&pBuf->pbData[pBuf->cbSize], pbData, cbData);
- pBuf->cbSize += cbData;
- }
- else
- {
- /* Move any buffered data to the front. */
- cbInBuf = pBuf->cbSize - pBuf->cbOffset;
- if (cbInBuf == 0)
- pBuf->cbSize = pBuf->cbOffset = 0;
- else if (pBuf->cbOffset) /* Do we have something to move? */
- {
- memmove(pBuf->pbData, &pBuf->pbData[pBuf->cbOffset], cbInBuf);
- pBuf->cbSize = cbInBuf;
- pBuf->cbOffset = 0;
- }
-
- /* Do we need to grow the buffer? */
- if (cbData + pBuf->cbSize > pBuf->cbAllocated)
- {
- size_t cbAlloc = pBuf->cbSize + cbData;
- cbAlloc = RT_ALIGN_Z(cbAlloc, _64K);
- void *pvNew = RTMemRealloc(pBuf->pbData, cbAlloc);
- if (pvNew)
- {
- pBuf->pbData = (uint8_t *)pvNew;
- pBuf->cbAllocated = cbAlloc;
- }
- else
- rc = VERR_NO_MEMORY;
- }
-
- /* Finally, copy the data. */
- if (RT_SUCCESS(rc))
- {
- if (cbData + pBuf->cbSize <= pBuf->cbAllocated)
- {
- memcpy(&pBuf->pbData[pBuf->cbSize], pbData, cbData);
- pBuf->cbSize += cbData;
- }
- else
- rc = VERR_BUFFER_OVERFLOW;
- }
- }
-
- if (RT_SUCCESS(rc))
- {
- /*
- * Was this the final read/write to do on this buffer? Then close it
- * next time we have the chance to.
- */
- if (fPendingClose)
- pBuf->fPendingClose = fPendingClose;
-
- /*
- * Wake up the thread servicing the process so it can feed it
- * (if we have a notification helper pipe).
- */
- if (pBuf->fNeedNotification)
- {
- size_t cbWritten;
- int rc2 = RTPipeWrite(pBuf->hNotificationPipeW, "i", 1, &cbWritten);
-
- /* Disable notification until it is set again on successful write. */
- pBuf->fNeedNotification = !RT_SUCCESS(rc2);
- }
-
- /* Report back written bytes (if wanted). */
- if (pcbWritten)
- *pcbWritten = cbData;
-
- /* Only trigger signal if we really wrote something. */
- if ( cbData
- && pBuf->hEventSem != NIL_RTSEMEVENT)
- {
- rc = RTSemEventSignal(pBuf->hEventSem);
- AssertRC(rc);
- }
-
-#ifdef DEBUG_andy
- VBoxServiceVerbose(4, "Pipe [%u %u 0x%p %s] written cbData=%u, cbSize=%u, cbAlloc=%u, cbOff=%u\n",
- pBuf->uPID, pBuf->uPipeId, pBuf, pBuf->fEnabled ? "EN" : "DIS", cbData, pBuf->cbSize, pBuf->cbAllocated, pBuf->cbOffset);
-#endif
- }
- }
- else
- rc = VERR_BAD_PIPE;
-
- int rc2 = RTCritSectLeave(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
- return rc;
-}
-
-
-int VBoxServicePipeBufWriteToPipe(PVBOXSERVICECTRLEXECPIPEBUF pBuf, RTPIPE hPipe,
- size_t *pcbWritten, size_t *pcbLeft)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
- AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER);
- AssertPtrReturn(pcbLeft, VERR_INVALID_POINTER);
-
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- Assert(pBuf->cbSize >= pBuf->cbOffset);
- size_t cbToWrite = pBuf->cbSize - pBuf->cbOffset;
- cbToWrite = RT_MIN(cbToWrite, _64K);
-
- /* Set current bytes left in pipe buffer. It's okay
- * to have no data in yet ... */
- *pcbLeft = pBuf->cbSize - pBuf->cbOffset;
-
- if ( pBuf->fEnabled
- && cbToWrite)
- {
- rc = RTPipeWrite(hPipe, &pBuf->pbData[pBuf->cbOffset], cbToWrite, pcbWritten);
- if (RT_SUCCESS(rc))
- {
- pBuf->fNeedNotification = true;
- if (rc != VINF_TRY_AGAIN)
- pBuf->cbOffset += *pcbWritten;
-
- /* Did somebody tell us that we should come to an end,
- * e.g. no more data coming in? */
- if (pBuf->fPendingClose)
- {
- /* Is there more data to write out? */
- if (pBuf->cbSize > pBuf->cbOffset)
- {
- /* We have a pending close, but there's more data that we can write out
- * from buffer to pipe ... */
- if (pBuf->fNeedNotification)
- {
- /* Still data to push out - so we need another
- * poll round! Write something into the notification pipe. */
- size_t cbWrittenIgnore;
- int rc2 = RTPipeWrite(pBuf->hNotificationPipeW, "i", 1, &cbWrittenIgnore);
- AssertRC(rc2);
-
- /* Disable notification until it is set again on successful write. */
- pBuf->fNeedNotification = !RT_SUCCESS(rc2);
- }
- }
- }
-
- /* Set new bytes left in pipe buffer afer we wrote to the pipe above. */
- *pcbLeft = pBuf->cbSize - pBuf->cbOffset;
- }
- else
- {
- *pcbWritten = 0;
- /* Don't set pBuf->fEnabled to false here! We just didn't write
- * anything -- that doesn't mean this buffer is disabled (again). */
- }
- }
- else
- {
- *pcbWritten = 0;
- pBuf->fNeedNotification = pBuf->fEnabled;
- }
-
- int rc2 = RTCritSectLeave(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- rc = rc2;
- }
- return rc;
-}
-
-
-/**
- * Returns whether a pipe buffer is active or not.
- *
- * @return bool True if pipe buffer is active, false if not.
- * @param pBuf The pipe buffer.
- */
-bool VBoxServicePipeBufIsEnabled(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
-{
- AssertPtrReturn(pBuf, false);
-
- bool fEnabled = false;
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- fEnabled = pBuf->fEnabled;
- rc = RTCritSectLeave(&pBuf->CritSect);
- AssertRC(rc);
- }
- return fEnabled;
-}
-
-
-/**
- * Returns whether a pipe buffer is in a pending close state or
- * not. This means that someone has written the last chunk into
- * the pipe buffer with the fPendingClose flag set.
- *
- * @return bool True if pipe buffer is in pending
- * close state, false if not.
- * @param pBuf The pipe buffer.
- */
-bool VBoxServicePipeBufIsClosing(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
-{
- AssertPtrReturn(pBuf, false);
-
- if (!RTCritSectIsInitialized(&pBuf->CritSect))
- return false;
-
- bool fClosing = false;
- if (RT_SUCCESS(RTCritSectEnter(&pBuf->CritSect)))
- {
- fClosing = pBuf->fPendingClose;
- RTCritSectLeave(&pBuf->CritSect);
- }
- return fClosing;
-}
-
-
-/**
- * Sets the current status (enabled/disabled) of a pipe buffer.
- *
- * @return IPRT status code.
- * @param pBuf The pipe buffer.
- * @param fEnabled Pipe buffer status to set.
- */
-int VBoxServicePipeBufSetStatus(PVBOXSERVICECTRLEXECPIPEBUF pBuf, bool fEnabled)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
-
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- bool fEnabledOld = pBuf->fEnabled;
- pBuf->fEnabled = fEnabled;
- if ( pBuf->fEnabled != fEnabledOld
- && pBuf->hEventSem)
- {
-#ifdef DEBUG_andy
- VBoxServiceVerbose(4, "Pipe [%u %u] status %s -> %s\n",
- pBuf->uPID, pBuf->uPipeId,
- fEnabledOld ? "EN" : "DIS", pBuf->fEnabled ? "EN" : "DIS");
-#endif
- /* Let waiter know that something has changed ... */
- RTSemEventSignal(pBuf->hEventSem);
- }
- rc = RTCritSectLeave(&pBuf->CritSect);
- }
- return rc;
-}
-
-
-/**
- * Assigns a PID to the specified pipe buffer. Does not allow
- * setting a new PID after a PID already was set.
- *
- * @return IPRT status code.
- * @param pBuf The pipe buffer.
- * @param uPID PID to assign.
- */
-int VBoxServicePipeBufSetPID(PVBOXSERVICECTRLEXECPIPEBUF pBuf, uint32_t uPID)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
-
- int rc = RTCritSectEnter(&pBuf->CritSect);
- if (RT_SUCCESS(rc))
- {
- if (!pBuf->uPID)
- pBuf->uPID = uPID;
- rc = RTCritSectLeave(&pBuf->CritSect);
- }
- return rc;
-}
-
-
-/**
- * Waits for the pipe buffer to get notified when something changed, like
- * new data was written to or the buffer was disabled, i.e. not used anymore.
- *
- * @return IPRT status code.
- * @param pBuf The pipe buffer.
- * @param cMillies The maximum time (in ms) to wait for the event.
- */
-int VBoxServicePipeBufWaitForEvent(PVBOXSERVICECTRLEXECPIPEBUF pBuf, RTMSINTERVAL cMillies)
-{
- AssertPtrReturn(pBuf, VERR_INVALID_POINTER);
-
- /* Don't enter the critical section here; someone else could signal the event semaphore
- * and this will deadlock then ... */
- return RTSemEventWait(pBuf->hEventSem, cMillies);
-}
-
-
-/**
- * Deletes a pipe buffer.
- *
- * @note Not thread safe -- only call this when nobody is relying on the
- * data anymore!
- *
- * @param pBuf The pipe buffer.
- */
-void VBoxServicePipeBufDestroy(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
-{
- AssertPtrReturnVoid(pBuf);
-
- if (pBuf->pbData)
- {
- pBuf->uPID = 0;
- pBuf->uPipeId = 0;
- pBuf->cbAllocated = 0;
- pBuf->cbSize = 0;
- pBuf->cbOffset = 0;
-
- RTPipeClose(pBuf->hNotificationPipeR);
- pBuf->hNotificationPipeR = NIL_RTPIPE;
- RTPipeClose(pBuf->hNotificationPipeW);
- pBuf->hNotificationPipeW = NIL_RTPIPE;
-
- if (RTCritSectIsInitialized(&pBuf->CritSect))
- RTCritSectDelete(&pBuf->CritSect);
- if (pBuf->hEventSem != NIL_RTSEMEVENT)
- RTSemEventDestroy(pBuf->hEventSem);
-
- RTMemFree(pBuf->pbData);
- pBuf->pbData = NULL;
- }
-}
-
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h b/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h
deleted file mode 100644
index 587e263ea..000000000
--- a/src/VBox/Additions/common/VBoxService/VBoxServicePipeBuf.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id: VBoxServicePipeBuf.h $ */
-/** @file
- * VBoxServicePipeBuf - Pipe buffering.
- */
-
-/*
- * Copyright (C) 2010-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 ___VBoxServicePipeBuf_h
-#define ___VBoxServicePipeBuf_h
-
-#include "VBoxServiceInternal.h"
-
-int VBoxServicePipeBufInit(PVBOXSERVICECTRLEXECPIPEBUF pBuf, uint8_t uId, bool fNeedNotificationPipe);
-int VBoxServicePipeBufRead(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
- uint8_t *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead);
-int VBoxServicePipeBufPeek(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
- uint8_t *pbBuffer, uint32_t cbBuffer,
- uint32_t cbOffset,
- uint32_t *pcbRead, uint32_t *pcbLeft);
-int VBoxServicePipeBufWriteToBuf(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
- uint8_t *pbData, uint32_t cbData, bool fPendingClose, uint32_t *pcbWritten);
-int VBoxServicePipeBufWriteToPipe(PVBOXSERVICECTRLEXECPIPEBUF pBuf, RTPIPE hPipe,
- size_t *pcbWritten, size_t *pcbLeft);
-bool VBoxServicePipeBufIsEnabled(PVBOXSERVICECTRLEXECPIPEBUF pBuf);
-bool VBoxServicePipeBufIsClosing(PVBOXSERVICECTRLEXECPIPEBUF pBuf);
-int VBoxServicePipeBufSetPID(PVBOXSERVICECTRLEXECPIPEBUF pBuf, uint32_t uPID);
-int VBoxServicePipeBufSetStatus(PVBOXSERVICECTRLEXECPIPEBUF pBuf, bool fEnabled);
-int VBoxServicePipeBufWaitForEvent(PVBOXSERVICECTRLEXECPIPEBUF pBuf, RTMSINTERVAL cMillies);
-void VBoxServicePipeBufDestroy(PVBOXSERVICECTRLEXECPIPEBUF pBuf);
-
-#endif /* !___VBoxServicePipeBuf_h */
-
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
index 6f51be217..c7c259ae7 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceStats.cpp
@@ -97,7 +97,8 @@ static DECLCALLBACK(int) VBoxServiceVMStatsOption(const char **ppszShort, int ar
NOREF(argc);
NOREF(argv);
NOREF(pi);
- return VINF_SUCCESS;
+
+ return -1;
}
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
index 06fe3f239..060a030c5 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
@@ -143,6 +143,18 @@ static void VBoxServiceToolboxShowVersion(void)
/**
+ * Initializes the parseable stream(s).
+ *
+ * @return IPRT status code.
+ */
+static int VBoxServiceToolboxStrmInit(void)
+{
+ /* Nothing to do here yet. */
+ return VINF_SUCCESS;
+}
+
+
+/**
* Prints a parseable stream header which contains the actual tool
* which was called/used along with its stream version.
*
@@ -156,6 +168,7 @@ static void VBoxServiceToolboxPrintStrmHeader(const char *pszToolName, uint32_t
RTPrintf("hdr_id=%s%chdr_ver=%u%c", pszToolName, 0, uVersion, 0);
}
+
/**
* Prints a standardized termination sequence indicating that the
* parseable stream just ended.
@@ -166,6 +179,7 @@ static void VBoxServiceToolboxPrintStrmTermination()
RTPrintf("%c%c%c%c", 0, 0, 0, 0);
}
+
/**
* Destroys a path buffer list.
*
@@ -254,7 +268,11 @@ static int VBoxServiceToolboxCatOutput(RTFILE hInput, RTFILE hOutput)
if (RT_SUCCESS(rc) && cbRead > 0)
{
rc = RTFileWrite(hOutput, abBuf, cbRead, NULL /* Try to write all at once! */);
- cbRead = 0;
+ if (RT_FAILURE(rc))
+ {
+ RTMsgError("Error while writing output, rc=%Rrc\n", rc);
+ break;
+ }
}
else
{
@@ -828,7 +846,12 @@ static RTEXITCODE VBoxServiceToolboxLs(int argc, char **argv)
/* Print magic/version. */
if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)
+ {
+ rc = VBoxServiceToolboxStrmInit();
+ if (RT_FAILURE(rc))
+ RTMsgError("Error while initializing parseable streams, rc=%Rrc\n", rc);
VBoxServiceToolboxPrintStrmHeader("vbt_ls", 1 /* Stream version */);
+ }
PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
RTListForEach(&fileList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
@@ -1063,7 +1086,12 @@ static RTEXITCODE VBoxServiceToolboxStat(int argc, char **argv)
if (RT_SUCCESS(rc))
{
if (fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE) /* Output termination. */
+ {
+ rc = VBoxServiceToolboxStrmInit();
+ if (RT_FAILURE(rc))
+ RTMsgError("Error while initializing parseable streams, rc=%Rrc\n", rc);
VBoxServiceToolboxPrintStrmHeader("vbt_stat", 1 /* Stream version */);
+ }
PVBOXSERVICETOOLBOXPATHENTRY pNodeIt;
RTListForEach(&fileList, pNodeIt, VBOXSERVICETOOLBOXPATHENTRY, Node)
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
index 7bbbd9a09..21dd401fd 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
@@ -29,6 +29,7 @@
#include <Ntsecapi.h> /* Needed for process security information. */
#include <iprt/assert.h>
+#include <iprt/ldr.h>
#include <iprt/mem.h>
#include <iprt/thread.h>
#include <iprt/string.h>
@@ -51,6 +52,11 @@ typedef struct
WCHAR wszLogonDomain[_MAX_PATH];
/** Number of assigned user processes. */
ULONG ulNumProcs;
+ /** Last (highest) session number. This
+ * is needed for distinguishing old session
+ * process counts from new (current) session
+ * ones. */
+ ULONG ulSession;
} VBOXSERVICEVMINFOUSER, *PVBOXSERVICEVMINFOUSER;
/** Structure for the file information lookup. */
@@ -63,24 +69,109 @@ typedef struct
/** Structure for process information lookup. */
typedef struct
{
+ /** The PID. */
DWORD id;
+ /** The LUID. */
LUID luid;
+ /** Interactive process. */
+ bool fInteractive;
} VBOXSERVICEVMINFOPROC, *PVBOXSERVICEVMINFOPROC;
/*******************************************************************************
* Prototypes
*******************************************************************************/
-uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs);
+uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs);
bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession);
int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount);
void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs);
+typedef BOOL WINAPI FNQUERYFULLPROCESSIMAGENAME(HANDLE, DWORD, LPTSTR, PDWORD);
+typedef FNQUERYFULLPROCESSIMAGENAME *PFNQUERYFULLPROCESSIMAGENAME;
#ifndef TARGET_NT4
/**
+ * Retrieves the module name of a given process.
+ *
+ * @return IPRT status code.
+ * @param pProc
+ * @param pszBuf
+ * @param cbBuf
+ */
+static int VBoxServiceVMInfoWinProcessesGetModuleName(PVBOXSERVICEVMINFOPROC const pProc,
+ TCHAR *pszName, size_t cbName)
+{
+ AssertPtrReturn(pProc, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszName, VERR_INVALID_POINTER);
+ AssertReturn(cbName, VERR_INVALID_PARAMETER);
+
+ OSVERSIONINFOEX OSInfoEx;
+ RT_ZERO(OSInfoEx);
+ OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if ( !GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
+ || OSInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ {
+ /* Platform other than NT (e.g. Win9x) not supported. */
+ return VERR_NOT_SUPPORTED;
+ }
+
+ int rc = VINF_SUCCESS;
+
+ DWORD dwFlags = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
+ if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
+ dwFlags = 0x1000; /* = PROCESS_QUERY_LIMITED_INFORMATION; less privileges needed. */
+
+ HANDLE h = OpenProcess(dwFlags, FALSE, pProc->id);
+ if (h == NULL)
+ {
+ DWORD dwErr = GetLastError();
+ if (g_cVerbosity)
+ VBoxServiceError("Unable to open process with PID=%ld, error=%ld\n",
+ pProc->id, dwErr);
+ rc = RTErrConvertFromWin32(dwErr);
+ }
+ else
+ {
+ /* Since GetModuleFileNameEx has trouble with cross-bitness stuff (32-bit apps cannot query 64-bit
+ apps and vice verse) we have to use a different code path for Vista and up. */
+
+ /* Note: For 2000 + NT4 we might just use GetModuleFileName() instead. */
+ if (OSInfoEx.dwMajorVersion >= 6 /* Vista or later */)
+ {
+ /* Loading the module and getting the symbol for each and every process is expensive
+ * -- since this function (at the moment) only is used for debugging purposes it's okay. */
+ RTLDRMOD hMod;
+ rc = RTLdrLoad("kernel32.dll", &hMod);
+ if (RT_SUCCESS(rc))
+ {
+ PFNQUERYFULLPROCESSIMAGENAME pfnQueryFullProcessImageName;
+ rc = RTLdrGetSymbol(hMod, "QueryFullProcessImageNameA", (void **)&pfnQueryFullProcessImageName);
+ if (RT_SUCCESS(rc))
+ {
+ DWORD dwLen = cbName / sizeof(TCHAR);
+ if (!pfnQueryFullProcessImageName(h, 0 /*PROCESS_NAME_NATIVE*/, pszName, &dwLen))
+ rc = VERR_ACCESS_DENIED;
+ }
+
+ RTLdrClose(hMod);
+ }
+ }
+ else
+ {
+ if (!GetModuleFileNameEx(h, NULL /* Get main executable */, pszName, cbName / sizeof(TCHAR)))
+ rc = VERR_ACCESS_DENIED;
+ }
+
+ CloseHandle(h);
+ }
+
+ return rc;
+}
+
+
+/**
* Fills in more data for a process.
*
* @returns VBox status code.
@@ -90,61 +181,156 @@ void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs);
static int VBoxServiceVMInfoWinProcessesGetTokenInfo(PVBOXSERVICEVMINFOPROC pProc,
TOKEN_INFORMATION_CLASS tkClass)
{
- AssertPtr(pProc);
+ AssertPtrReturn(pProc, VERR_INVALID_POINTER);
+
+ DWORD dwErr = ERROR_SUCCESS;
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pProc->id);
if (h == NULL)
- return RTErrConvertFromWin32(GetLastError());
-
- int rc = VERR_NO_MEMORY;
- HANDLE hToken;
- if (OpenProcessToken(h, TOKEN_QUERY, &hToken))
- {
- void *pvTokenInfo = NULL;
- DWORD dwTokenInfoSize;
- switch (tkClass)
- {
- case TokenStatistics:
- dwTokenInfoSize = sizeof(TOKEN_STATISTICS);
- pvTokenInfo = RTMemAlloc(dwTokenInfoSize);
- break;
-
- /** @todo Implement more token classes here. */
-
- default:
- VBoxServiceError("Token class not implemented: %ld", tkClass);
- rc = VERR_NOT_IMPLEMENTED;
- break;
- }
-
- if (pvTokenInfo)
- {
- DWORD dwRetLength;
- if (GetTokenInformation(hToken, tkClass, pvTokenInfo, dwTokenInfoSize, &dwRetLength))
- {
- switch (tkClass)
- {
- case TokenStatistics:
- {
- TOKEN_STATISTICS *pStats = (TOKEN_STATISTICS*)pvTokenInfo;
- pProc->luid = pStats->AuthenticationId;
- /** @todo Add more information of TOKEN_STATISTICS as needed. */
- break;
- }
-
- default:
- /* Should never get here! */
- break;
- }
- rc = VINF_SUCCESS;
- }
- else
- rc = RTErrConvertFromWin32(GetLastError());
- RTMemFree(pvTokenInfo);
- }
- CloseHandle(hToken);
+ {
+ dwErr = GetLastError();
+ if (g_cVerbosity > 4)
+ VBoxServiceError("Unable to open process with PID=%ld, error=%ld\n",
+ pProc->id, dwErr);
+ return RTErrConvertFromWin32(dwErr);
+ }
+
+ int rc = VINF_SUCCESS;
+ HANDLE hToken;
+ if (OpenProcessToken(h, TOKEN_QUERY, &hToken))
+ {
+ void *pvTokenInfo = NULL;
+ DWORD dwTokenInfoSize;
+ switch (tkClass)
+ {
+ case TokenStatistics:
+ dwTokenInfoSize = sizeof(TOKEN_STATISTICS);
+ pvTokenInfo = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, dwTokenInfoSize);
+ AssertPtr(pvTokenInfo);
+ break;
+
+ case TokenGroups:
+ dwTokenInfoSize = 0;
+ /* Allocating will follow in a second step. */
+ break;
+
+ /** @todo Implement more token classes here. */
+
+ default:
+ VBoxServiceError("Token class not implemented: %ld", tkClass);
+ rc = VERR_NOT_IMPLEMENTED;
+ break;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ DWORD dwRetLength;
+ if (!GetTokenInformation(hToken, tkClass, pvTokenInfo, dwTokenInfoSize, &dwRetLength))
+ {
+ dwErr = GetLastError();
+ if (dwErr == ERROR_INSUFFICIENT_BUFFER)
+ {
+ dwErr = ERROR_SUCCESS;
+
+ switch (tkClass)
+ {
+ case TokenGroups:
+ pvTokenInfo = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, dwRetLength);
+ if (!pvTokenInfo)
+ dwErr = GetLastError();
+ dwTokenInfoSize = dwRetLength;
+ break;
+
+ default:
+ AssertMsgFailed(("Re-allocating of token information for token class not implemented\n"));
+ break;
+ }
+
+ if (dwErr == ERROR_SUCCESS)
+ {
+ if (!GetTokenInformation(hToken, tkClass, pvTokenInfo, dwTokenInfoSize, &dwRetLength))
+ dwErr = GetLastError();
+ }
+ }
+ }
+
+ if (dwErr == ERROR_SUCCESS)
+ {
+ rc = VINF_SUCCESS;
+
+ switch (tkClass)
+ {
+ case TokenStatistics:
+ {
+ PTOKEN_STATISTICS pStats = (PTOKEN_STATISTICS)pvTokenInfo;
+ memcpy(&pProc->luid, &pStats->AuthenticationId, sizeof(LUID));
+ /** @todo Add more information of TOKEN_STATISTICS as needed. */
+ break;
+ }
+
+ case TokenGroups:
+ {
+ pProc->fInteractive = false;
+
+ SID_IDENTIFIER_AUTHORITY sidAuthNT = SECURITY_NT_AUTHORITY;
+ PSID pSidInteractive = NULL; /* S-1-5-4 */
+ if (!AllocateAndInitializeSid(&sidAuthNT, 1, 4, 0, 0, 0, 0, 0, 0, 0, &pSidInteractive))
+ dwErr = GetLastError();
+
+ PSID pSidLocal = NULL; /* S-1-2-0 */
+ if (dwErr == ERROR_SUCCESS)
+ {
+ SID_IDENTIFIER_AUTHORITY sidAuthLocal = SECURITY_LOCAL_SID_AUTHORITY;
+ if (!AllocateAndInitializeSid(&sidAuthLocal, 1, 0, 0, 0, 0, 0, 0, 0, 0, &pSidLocal))
+ dwErr = GetLastError();
+ }
+
+ if (dwErr == ERROR_SUCCESS)
+ {
+ PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)pvTokenInfo;
+ AssertPtr(pGroups);
+ for (DWORD i = 0; i < pGroups->GroupCount; i++)
+ {
+ if ( EqualSid(pGroups->Groups[i].Sid, pSidInteractive)
+ || EqualSid(pGroups->Groups[i].Sid, pSidLocal)
+ || pGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID)
+ {
+ pProc->fInteractive = true;
+ break;
+ }
+ }
+ }
+
+ if (pSidInteractive)
+ FreeSid(pSidInteractive);
+ if (pSidLocal)
+ FreeSid(pSidLocal);
+ break;
+ }
+
+ default:
+ AssertMsgFailed(("Unhandled token information class\n"));
+ break;
+ }
+ }
+
+ if (pvTokenInfo)
+ HeapFree(GetProcessHeap(), 0 /* Flags */, pvTokenInfo);
+ }
+ CloseHandle(hToken);
}
else
- rc = RTErrConvertFromWin32(GetLastError());
+ dwErr = GetLastError();
+
+ if (dwErr != ERROR_SUCCESS)
+ {
+ if (g_cVerbosity)
+ VBoxServiceError("Unable to query token information for PID=%ld, error=%ld\n",
+ pProc->id, dwErr);
+ rc = RTErrConvertFromWin32(dwErr);
+ }
+
CloseHandle(h);
return rc;
}
@@ -170,23 +356,23 @@ int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppaProcs, PDW
* or we think something is screwed up.
*/
DWORD cProcesses = 64;
- PDWORD paPids = NULL;
+ PDWORD paPID = NULL;
int rc = VINF_SUCCESS;
do
{
/* Allocate / grow the buffer first. */
cProcesses *= 2;
- void *pvNew = RTMemRealloc(paPids, cProcesses * sizeof(DWORD));
+ void *pvNew = RTMemRealloc(paPID, cProcesses * sizeof(DWORD));
if (!pvNew)
{
rc = VERR_NO_MEMORY;
break;
}
- paPids = (PDWORD)pvNew;
+ paPID = (PDWORD)pvNew;
/* Query the processes. Not the cbRet == buffer size means there could be more work to be done. */
DWORD cbRet;
- if (!EnumProcesses(paPids, cProcesses * sizeof(DWORD), &cbRet))
+ if (!EnumProcesses(paPID, cProcesses * sizeof(DWORD), &cbRet))
{
rc = RTErrConvertFromWin32(GetLastError());
break;
@@ -196,7 +382,7 @@ int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppaProcs, PDW
cProcesses = cbRet / sizeof(DWORD);
break;
}
- } while (cProcesses <= 32768); /* Should be enough; see: http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx */
+ } while (cProcesses <= _32K); /* Should be enough; see: http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx */
if (RT_SUCCESS(rc))
{
/*
@@ -209,14 +395,24 @@ int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppaProcs, PDW
{
for (DWORD i = 0; i < cProcesses; i++)
{
- paProcs[i].id = paPids[i];
- rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics);
+ paProcs[i].id = paPID[i];
+ rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenGroups);
if (RT_FAILURE(rc))
{
/* Because some processes cannot be opened/parsed on
- Windows, we should not consider to be this an error here. */
+ Windows, we should not consider to be this an error here. */
rc = VINF_SUCCESS;
}
+ else
+ {
+ rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics);
+ if (RT_FAILURE(rc))
+ {
+ /* Because some processes cannot be opened/parsed on
+ Windows, we should not consider to be this an error here. */
+ rc = VINF_SUCCESS;
+ }
+ }
}
/* Save number of processes */
@@ -232,7 +428,7 @@ int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppaProcs, PDW
rc = VERR_NO_MEMORY;
}
- RTMemFree(paPids);
+ RTMemFree(paPID);
return rc;
}
@@ -254,12 +450,15 @@ void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs)
* @param pSession The session.
* @param paProcs The process snapshot.
* @param cProcs The number of processes in the snaphot.
+ * @param puSession Looked up session number. Optional.
*/
-uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs)
+uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession,
+ PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs,
+ PULONG puSession)
{
if (!pSession)
{
- VBoxServiceVerbose(1, "VMInfo/Users: Session became invalid while enumerating!\n");
+ VBoxServiceVerbose(1, "Session became invalid while enumerating!\n");
return 0;
}
@@ -267,7 +466,7 @@ uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMIN
NTSTATUS rcNt = LsaGetLogonSessionData(pSession, &pSessionData);
if (rcNt != STATUS_SUCCESS)
{
- VBoxServiceError("VMInfo/Users: Could not get logon session data! rcNt=%#x", rcNt);
+ VBoxServiceError("Could not get logon session data! rcNt=%#x", rcNt);
return 0;
}
@@ -279,25 +478,39 @@ uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMIN
uint32_t cNumProcs = 0;
for (DWORD i = 0; i < cProcs; i++)
{
- /*VBoxServiceVerbose(3, "%ld:%ld <-> %ld:%ld\n",
- paProcs[i].luid.HighPart, paProcs[i].luid.LowPart,
- pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);*/
- if ( paProcs[i].luid.HighPart == pSessionData->LogonId.HighPart
- && paProcs[i].luid.LowPart == pSessionData->LogonId.LowPart)
+ VBoxServiceVerbose(4, "PID=%ld: (Interactive: %RTbool) %ld:%ld <-> %ld:%ld\n",
+ paProcs[i].id, paProcs[i].fInteractive,
+ paProcs[i].luid.HighPart, paProcs[i].luid.LowPart,
+ pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);
+ if (g_cVerbosity)
+ {
+ TCHAR szModule[_1K];
+ int rc2 = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule));
+ if (RT_SUCCESS(rc2))
+ VBoxServiceVerbose(4, "PID=%ld: %s\n",
+ paProcs[i].id, szModule);
+ }
+
+ if ( paProcs[i].fInteractive
+ && ( paProcs[i].luid.HighPart == pSessionData->LogonId.HighPart
+ && paProcs[i].luid.LowPart == pSessionData->LogonId.LowPart))
{
cNumProcs++;
- if (g_cVerbosity < 4) /* We want a bit more info on high verbosity. */
+ if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */
break;
}
}
- if (g_cVerbosity >= 4)
- VBoxServiceVerbose(3, "VMInfo/Users: Session %u has %u processes\n",
+ if (g_cVerbosity)
+ VBoxServiceVerbose(3, "Session %u has %u processes total\n",
pSessionData->Session, cNumProcs);
else
- VBoxServiceVerbose(3, "VMInfo/Users: Session %u has at least one process\n",
+ VBoxServiceVerbose(3, "Session %u has at least one process\n",
pSessionData->Session);
+ if (puSession)
+ *puSession = pSessionData->Session;
+
LsaFreeReturnBuffer(pSessionData);
return cNumProcs;
}
@@ -337,7 +550,7 @@ static void VBoxServiceVMInfoWinSafeCopy(PWCHAR pwszDst, size_t cbDst, LSA_UNICO
*/
bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSession)
{
- AssertPtr(pUserInfo);
+ AssertPtrReturn(pUserInfo, false);
if (!pSession)
return false;
@@ -351,7 +564,7 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
case ERROR_NOT_ENOUGH_MEMORY:
/* If we don't have enough memory it's hard to judge whether the specified user
* is logged in or not, so just assume he/she's not. */
- VBoxServiceVerbose(3, "VMInfo/Users: Not enough memory to retrieve logon session data!\n");
+ VBoxServiceVerbose(3, "Not enough memory to retrieve logon session data!\n");
break;
case ERROR_NO_SUCH_LOGON_SESSION:
@@ -360,7 +573,7 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
break;
default:
- VBoxServiceError("VMInfo/Users: LsaGetLogonSessionData failed with error %ul\n", ulError);
+ VBoxServiceError("LsaGetLogonSessionData failed with error %u\n", ulError);
break;
}
if (pSessionData)
@@ -369,7 +582,7 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
}
if (!pSessionData)
{
- VBoxServiceError("VMInfo/Users: Invalid logon session data!\n");
+ VBoxServiceError("Invalid logon session data!\n");
return false;
}
@@ -381,14 +594,11 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
DWORD dwErr = NO_ERROR;
if ( IsValidSid(pSessionData->Sid)
&& ( (SECURITY_LOGON_TYPE)pSessionData->LogonType == Interactive
- || (SECURITY_LOGON_TYPE)pSessionData->LogonType == RemoteInteractive
- || (SECURITY_LOGON_TYPE)pSessionData->LogonType == CachedInteractive
- || (SECURITY_LOGON_TYPE)pSessionData->LogonType == CachedRemoteInteractive))
+ || (SECURITY_LOGON_TYPE)pSessionData->LogonType == RemoteInteractive))
{
- VBoxServiceVerbose(3, "VMInfo/Users: Session data: Name=%ls, Len=%d, SID=%s, LogonID=%ld,%ld, LogonType=%ld\n",
+ VBoxServiceVerbose(3, "Session data: Name=%ls, Session=%u, LogonID=%ld,%ld, LogonType=%ld\n",
pSessionData->UserName.Buffer,
- pSessionData->UserName.Length,
- pSessionData->Sid != NULL ? "1" : "0",
+ pSessionData->Session,
pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart,
pSessionData->LogonType);
@@ -423,14 +633,14 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
* here that we just skip.
*/
if (dwErr != ERROR_NONE_MAPPED)
- VBoxServiceError("VMInfo/Users: Failed looking up account info for user=%ls, error=$ld!\n",
+ VBoxServiceError("Failed looking up account info for user=%ls, error=$ld!\n",
pUserInfo->wszUser, dwErr);
}
else
{
if (enmOwnerType == SidTypeUser) /* Only recognize users; we don't care about the rest! */
{
- VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls, Session=%ld, LUID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n",
+ VBoxServiceVerbose(3, "Account User=%ls, Session=%ld, LogonID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n",
pUserInfo->wszUser, pSessionData->Session, pSessionData->LogonId.HighPart,
pSessionData->LogonId.LowPart, pUserInfo->wszAuthenticationPackage,
pUserInfo->wszLogonDomain);
@@ -438,7 +648,7 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
/* Detect RDP sessions as well. */
LPTSTR pBuffer = NULL;
DWORD cbRet = 0;
- int iState = 0;
+ int iState = -1;
if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
pSessionData->Session,
WTSConnectState,
@@ -447,15 +657,15 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
{
if (cbRet)
iState = *pBuffer;
- VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls, WTSConnectState=%d\n",
- pUserInfo->wszUser, iState);
+ VBoxServiceVerbose(3, "Account User=%ls, WTSConnectState=%d (%ld)\n",
+ pUserInfo->wszUser, iState, cbRet);
if ( iState == WTSActive /* User logged on to WinStation. */
|| iState == WTSShadow /* Shadowing another WinStation. */
|| iState == WTSDisconnected) /* WinStation logged on without client. */
{
/** @todo On Vista and W2K, always "old" user name are still
* there. Filter out the old one! */
- VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls using TCS/RDP, state=%d\n",
+ VBoxServiceVerbose(3, "Account User=%ls using TCS/RDP, state=%d \n",
pUserInfo->wszUser, iState);
fFoundUser = true;
}
@@ -473,12 +683,12 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
* fast user switching page!
*/
case ERROR_CTX_WINSTATION_NOT_FOUND:
- VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls, no WinSta found\n",
+ VBoxServiceVerbose(3, "No WinStation found for user=%ls\n",
pUserInfo->wszUser);
break;
default:
- VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls, error=%ld\n",
+ VBoxServiceVerbose(3, "Cannot query WTS connection state for user=%ls, error=%ld\n",
pUserInfo->wszUser, dwLastErr);
break;
}
@@ -488,7 +698,7 @@ bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSes
}
}
- VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls %s logged in\n",
+ VBoxServiceVerbose(3, "Account User=%ls %s logged in\n",
pUserInfo->wszUser, fFoundUser ? "is" : "is not");
}
@@ -520,24 +730,24 @@ int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
switch (ulError)
{
case ERROR_NOT_ENOUGH_MEMORY:
- VBoxServiceError("VMInfo/Users: Not enough memory to enumerate logon sessions!\n");
+ VBoxServiceError("Not enough memory to enumerate logon sessions!\n");
break;
case ERROR_SHUTDOWN_IN_PROGRESS:
/* If we're about to shutdown when we were in the middle of enumerating the logon
* sessions, skip the error to not confuse the user with an unnecessary log message. */
- VBoxServiceVerbose(3, "VMInfo/Users: Shutdown in progress ...\n");
+ VBoxServiceVerbose(3, "Shutdown in progress ...\n");
ulError = ERROR_SUCCESS;
break;
default:
- VBoxServiceError("VMInfo/Users: LsaEnumerate failed with error %ul\n", ulError);
+ VBoxServiceError("LsaEnumerate failed with error %u\n", ulError);
break;
}
return RTErrConvertFromWin32(ulError);
}
- VBoxServiceVerbose(3, "VMInfo/Users: Found %ld sessions\n", cSessions);
+ VBoxServiceVerbose(3, "Found %ld sessions\n", cSessions);
PVBOXSERVICEVMINFOPROC paProcs;
DWORD cProcs;
@@ -545,16 +755,16 @@ int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
if (RT_FAILURE(rc))
{
if (rc == VERR_NO_MEMORY)
- VBoxServiceError("VMInfo/Users: Not enough memory to enumerate processes for a session!\n");
+ VBoxServiceError("Not enough memory to enumerate processes\n");
else
- VBoxServiceError("VMInfo/Users: Failed to enumerate processes for a session, rc=%Rrc\n", rc);
+ VBoxServiceError("Failed to enumerate processes, rc=%Rrc\n", rc);
}
else
{
PVBOXSERVICEVMINFOUSER pUserInfo;
pUserInfo = (PVBOXSERVICEVMINFOUSER)RTMemAllocZ(cSessions * sizeof(VBOXSERVICEVMINFOUSER) + 1);
if (!pUserInfo)
- VBoxServiceError("VMInfo/Users: Not enough memory to store enumerated users!\n");
+ VBoxServiceError("Not enough memory to store enumerated users!\n");
else
{
ULONG cUniqueUsers = 0;
@@ -563,31 +773,51 @@ int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
VBOXSERVICEVMINFOUSER UserInfo;
if (VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i]))
{
- uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs);
- if (!cSessionProcs)
- continue;
+ VBoxServiceVerbose(4, "Handling user=%ls, domain=%ls, package=%ls\n",
+ UserInfo.wszUser, UserInfo.wszLogonDomain, UserInfo.wszAuthenticationPackage);
+
+ /* Retrieve assigned processes of current session. */
+ ULONG ulSession;
+ uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs, &ulSession);
+ /* Don't return here when current session does not have assigned processes
+ * anymore -- in that case we have to search through the unique users list below
+ * and see if got a stale user/session entry. */
bool fFoundUser = false;
for (ULONG i = 0; i < cUniqueUsers; i++)
{
if ( !wcscmp(UserInfo.wszUser, pUserInfo[i].wszUser)
&& !wcscmp(UserInfo.wszLogonDomain, pUserInfo[i].wszLogonDomain)
- && !wcscmp(UserInfo.wszAuthenticationPackage, pUserInfo[i].wszAuthenticationPackage))
+ && !wcscmp(UserInfo.wszAuthenticationPackage, pUserInfo[i].wszAuthenticationPackage)
+ && cSessionProcs)
{
- /* If the process-per-user count was higher than 0 before but another session was
- * was detected which also belongs to this user but has no assigned processes anymore,
- * we detected a stale session. */
- if ( pUserInfo[i].ulNumProcs > 0
- && !cSessionProcs)
+ /*
+ * Only respect the highest session for the current user.
+ */
+ if (ulSession > pUserInfo[i].ulSession)
{
- VBoxServiceVerbose(3, "VMInfo/Users: Stale session for user=%ls detected! Old processes: %u, new: %u\n",
- pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, cSessionProcs);
+ VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last session: %u)\n",
+ UserInfo.wszUser, cSessionProcs, ulSession);
+
+ pUserInfo[i].ulNumProcs = cSessionProcs;
+ pUserInfo[i].ulSession = ulSession;
+
+ if (!cSessionProcs)
+ VBoxServiceVerbose(3, "Stale session for user=%ls detected! Old processes: %u, new: %u\n",
+ pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, cSessionProcs);
}
+ /* There can be multiple session objects using the same session ID for the
+ * current user -- so when we got the same session again just add the found
+ * processes to it. */
+ else if (pUserInfo[i].ulSession == ulSession)
+ {
+ VBoxServiceVerbose(4, "Adding %u processes to user=%ls (session %u)\n",
+ cSessionProcs, UserInfo.wszUser, ulSession);
- VBoxServiceVerbose(4, "VMInfo/Users: Updating user=%ls to %u processes\n",
- UserInfo.wszUser, cSessionProcs);
+ pUserInfo[i].ulNumProcs += cSessionProcs;
+ pUserInfo[i].ulSession = ulSession;
+ }
- pUserInfo[i].ulNumProcs = cSessionProcs;
fFoundUser = true;
break;
}
@@ -595,17 +825,19 @@ int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
if (!fFoundUser)
{
- VBoxServiceVerbose(4, "VMInfo/Users: Adding new user=%ls with %u processes\n",
- UserInfo.wszUser, cSessionProcs);
+ VBoxServiceVerbose(4, "Adding new user=%ls (session %u) with %u processes\n",
+ UserInfo.wszUser, ulSession, cSessionProcs);
memcpy(&pUserInfo[cUniqueUsers], &UserInfo, sizeof(VBOXSERVICEVMINFOUSER));
- pUserInfo[cUniqueUsers++].ulNumProcs = cSessionProcs;
+ pUserInfo[cUniqueUsers].ulNumProcs = cSessionProcs;
+ pUserInfo[cUniqueUsers].ulSession = ulSession;
+ cUniqueUsers++;
Assert(cUniqueUsers <= cSessions);
}
}
}
- VBoxServiceVerbose(3, "VMInfo/Users: Found %u unique logged-in user(s) with processes\n",
+ VBoxServiceVerbose(3, "Found %u unique logged-in user(s)\n",
cUniqueUsers);
*pcUsersInList = 0;
@@ -613,6 +845,9 @@ int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
{
if (pUserInfo[i].ulNumProcs)
{
+ VBoxServiceVerbose(3, "User %ls has %ld processes (session %u)\n",
+ pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, pUserInfo[i].ulSession);
+
if (*pcUsersInList > 0)
{
rc = RTStrAAppend(ppszUserList, ",");
diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
index 273a879de..9a3f5ed35 100644
--- a/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
+++ b/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
@@ -82,32 +82,22 @@ static VBOXSERVICEVEPROPCACHE g_VMInfoPropCache;
static uint64_t g_idVMInfoSession;
-#ifdef RT_OS_WINDOWS
-static BOOL WINAPI VBoxServiceVMInfoConsoleControlHandler(DWORD dwCtrlType)
+
+/**
+ * Signals the event so that a re-enumeration of VM-specific
+ * information (like logged in users) can happen.
+ *
+ * @return IPRT status code.
+ */
+int VBoxServiceVMInfoSignal(void)
{
- int rc = VINF_SUCCESS;
- bool fEventHandled = FALSE;
- switch (dwCtrlType)
- {
- case CTRL_LOGOFF_EVENT:
- VBoxServiceVerbose(2, "VMInfo: Received logged-off event\n");
- /* Trigger a re-enumeration of all logged-in users by unblocking
- * the multi event semaphore of the VMInfo thread. */
- if (g_hVMInfoEvent)
- rc = RTSemEventMultiSignal(g_hVMInfoEvent);
- fEventHandled = TRUE;
- break;
- default:
- break;
- /** @todo Add other events here. */
- }
+ /* Trigger a re-enumeration of all logged-in users by unblocking
+ * the multi event semaphore of the VMInfo thread. */
+ if (g_hVMInfoEvent)
+ return RTSemEventMultiSignal(g_hVMInfoEvent);
- if (RT_FAILURE(rc))
- VBoxServiceError("VMInfo: Event %ld handled with error rc=%Rrc\n",
- dwCtrlType, rc);
- return fEventHandled;
+ return VINF_SUCCESS;
}
-#endif /* RT_OS_WINDOWS */
/** @copydoc VBOXSERVICE::pfnPreInit */
@@ -181,17 +171,6 @@ static DECLCALLBACK(int) VBoxServiceVMInfoInit(void)
VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_TRANSIENT, "true");
VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */);
-
-#ifdef RT_OS_WINDOWS
-# ifndef RT_OS_NT4
- /* Install console control handler. */
- if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)VBoxServiceVMInfoConsoleControlHandler, TRUE /* Add handler */))
- {
- VBoxServiceError("VMInfo: Unable to add console control handler, error=%ld\n", GetLastError());
- /* Just skip this error, not critical. */
- }
-# endif /* !RT_OS_NT4 */
-#endif /* RT_OS_WINDOWS */
}
return rc;
}
@@ -300,7 +279,7 @@ static int vboxserviceVMInfoWriteUsers(void)
while ( (ut_user = getutxent())
&& RT_SUCCESS(rc))
{
- VBoxServiceVerbose(4, "VMInfo/Users: Found logged in user \"%s\"\n",
+ VBoxServiceVerbose(4, "Found logged in user \"%s\"\n",
ut_user->ut_user);
if (cUsersInList > cListSize)
{
@@ -368,7 +347,7 @@ static int vboxserviceVMInfoWriteUsers(void)
{
static int s_iVMInfoBitchedOOM = 0;
if (s_iVMInfoBitchedOOM++ < 3)
- VBoxServiceVerbose(0, "VMInfo/Users: Warning: Not enough memory available to enumerate users! Keeping old value (%u)\n",
+ VBoxServiceVerbose(0, "Warning: Not enough memory available to enumerate users! Keeping old value (%u)\n",
g_cVMInfoLoggedInUsers);
cUsersInList = g_cVMInfoLoggedInUsers;
}
@@ -376,7 +355,7 @@ static int vboxserviceVMInfoWriteUsers(void)
cUsersInList = 0;
}
- VBoxServiceVerbose(4, "VMInfo/Users: cUsersInList: %u, pszUserList: %s, rc=%Rrc\n",
+ VBoxServiceVerbose(4, "cUsersInList: %u, pszUserList: %s, rc=%Rrc\n",
cUsersInList, pszUserList ? pszUserList : "<NULL>", rc);
if (pszUserList && cUsersInList > 0)
@@ -877,19 +856,6 @@ static DECLCALLBACK(void) VBoxServiceVMInfoStop(void)
/** @copydoc VBOXSERVICE::pfnTerm */
static DECLCALLBACK(void) VBoxServiceVMInfoTerm(void)
{
- int rc;
-
-#ifdef RT_OS_WINDOWS
-# ifndef RT_OS_NT4
- /* Install console control handler. */
- if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */))
- {
- VBoxServiceError("VMInfo: Unable to remove console control handler, error=%ld\n", GetLastError());
- /* Just skip this error, not critical. */
- }
-# endif /* !RT_OS_NT4 */
-#endif
-
if (g_hVMInfoEvent != NIL_RTSEMEVENTMULTI)
{
/** @todo temporary solution: Zap all values which are not valid
@@ -905,7 +871,7 @@ static DECLCALLBACK(void) VBoxServiceVMInfoTerm(void)
* since it remembers what we've written. */
/* Delete the "../Net" branch. */
const char *apszPat[1] = { "/VirtualBox/GuestInfo/Net/*" };
- rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat));
+ int rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat));
/* Destroy property cache. */
VBoxServicePropCacheDestroy(&g_VMInfoPropCache);
diff --git a/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp b/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
index 5f37c56f0..0e5fa467c 100644
--- a/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
+++ b/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
@@ -127,10 +127,11 @@ RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
uint8_t u8Ch,
uint16_t u16Op)
{
-#ifdef VBOX_WITH_WDDM
- /* @todo: add synchronization */
-#endif
+#ifdef VBOX_WDDM_MINIPORT
+ return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
+#else
return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
+#endif
}
@@ -143,10 +144,11 @@ RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
RTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
void *pvBuffer)
{
-#ifdef VBOX_WITH_WDDM
- /* @todo: add synchronization */
-#endif
+#ifdef VBOX_WDDM_MINIPORT
+ VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
+#else
HGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
+#endif
}
@@ -160,7 +162,7 @@ RTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
void *pvBuffer)
{
/* Initialize the buffer and get the offset for port IO. */
- HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pCtx->heapCtx, pvBuffer);
+ HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer);
Assert(offBuffer != HGSMIOFFSET_VOID);
if (offBuffer != HGSMIOFFSET_VOID)
@@ -183,7 +185,7 @@ static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
int rc = VINF_SUCCESS;
/* Allocate the IO buffer. */
- p = (HGSMIBUFFERLOCATION *)HGSMIHeapAlloc(&pCtx->heapCtx,
+ p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
sizeof(HGSMIBUFFERLOCATION),
HGSMI_CH_HGSMI,
HGSMI_CC_HOST_FLAGS_LOCATION);
@@ -194,7 +196,7 @@ static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
p->cbLocation = sizeof(HGSMIHOSTFLAGS);
rc = VBoxHGSMIBufferSubmit(pCtx, p);
/* Free the IO buffer. */
- HGSMIHeapFree (&pCtx->heapCtx, p);
+ VBoxHGSMIBufferFree(pCtx, p);
}
else
rc = VERR_NO_MEMORY;
@@ -211,7 +213,7 @@ static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
int rc = VINF_SUCCESS;
/* Allocate the IO buffer. */
- pCaps = (VBVACAPS *)HGSMIHeapAlloc(&pCtx->heapCtx,
+ pCaps = (VBVACAPS *)VBoxHGSMIBufferAlloc(pCtx,
sizeof(VBVACAPS), HGSMI_CH_VBVA,
VBVA_INFO_CAPS);
@@ -227,7 +229,7 @@ static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
rc = pCaps->rc;
}
/* Free the IO buffer. */
- HGSMIHeapFree(&pCtx->heapCtx, pCaps);
+ VBoxHGSMIBufferFree(pCtx, pCaps);
}
else
rc = VERR_NO_MEMORY;
@@ -244,7 +246,7 @@ static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
int rc = VINF_SUCCESS;
/* Allocate the IO buffer. */
- p = (VBVAINFOHEAP *)HGSMIHeapAlloc(&pCtx->heapCtx,
+ p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx,
sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
VBVA_INFO_HEAP);
if (p)
@@ -254,7 +256,7 @@ static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
p->u32HeapSize = u32AreaSize;
rc = VBoxHGSMIBufferSubmit(pCtx, p);
/* Free the IO buffer. */
- HGSMIHeapFree(&pCtx->heapCtx, p);
+ VBoxHGSMIBufferFree(pCtx, p);
}
else
rc = VERR_NO_MEMORY;
@@ -321,9 +323,15 @@ RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
{
/** @todo should we be using a fixed ISA port value here? */
pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
+#ifdef VBOX_WDDM_MINIPORT
+ return VBoxSHGSMIInit(&pCtx->heapCtx, pvGuestHeapMemory,
+ cbGuestHeapMemory, offVRAMGuestHeapMemory,
+ false /*fOffsetBased*/);
+#else
return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory,
cbGuestHeapMemory, offVRAMGuestHeapMemory,
false /*fOffsetBased*/);
+#endif
}
@@ -459,7 +467,7 @@ RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
LogFunc(("u32Index = %d\n", u32Index));
/* Allocate the IO buffer. */
- p = (VBVACONF32 *)HGSMIHeapAlloc(&pCtx->heapCtx,
+ p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx,
sizeof(VBVACONF32), HGSMI_CH_VBVA,
VBVA_QUERY_CONF32);
if (p)
@@ -474,7 +482,7 @@ RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
LogFunc(("u32Value = %d\n", p->u32Value));
}
/* Free the IO buffer. */
- HGSMIHeapFree(&pCtx->heapCtx, p);
+ VBoxHGSMIBufferFree(pCtx, p);
}
else
rc = VERR_NO_MEMORY;
@@ -527,7 +535,7 @@ RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
return false;
}
/* Allocate the IO buffer. */
- p = (VBVAMOUSEPOINTERSHAPE *)HGSMIHeapAlloc(&pCtx->heapCtx,
+ p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx,
sizeof(VBVAMOUSEPOINTERSHAPE)
+ cbData,
HGSMI_CH_VBVA,
@@ -550,7 +558,7 @@ RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
if (RT_SUCCESS(rc))
rc = p->i32Result;
/* Free the IO buffer. */
- HGSMIHeapFree(&pCtx->heapCtx, p);
+ VBoxHGSMIBufferFree(pCtx, p);
}
else
rc = VERR_NO_MEMORY;
diff --git a/src/VBox/Additions/common/crOpenGL/icd_drv.c b/src/VBox/Additions/common/crOpenGL/icd_drv.c
index 76dd2f5a4..842b04ac6 100644
--- a/src/VBox/Additions/common/crOpenGL/icd_drv.c
+++ b/src/VBox/Additions/common/crOpenGL/icd_drv.c
@@ -74,12 +74,14 @@ static GLuint ComputeVisBits( HDC hdc )
void APIENTRY DrvReleaseContext(HGLRC hglrc)
{
+ CR_DDI_PROLOGUE();
/*crDebug( "DrvReleaseContext(0x%x) called", hglrc );*/
stubMakeCurrent( NULL, NULL );
}
BOOL APIENTRY DrvValidateVersion(DWORD version)
{
+ CR_DDI_PROLOGUE();
if (stubInit()) {
crDebug("DrvValidateVersion %x -> TRUE\n", version);
return TRUE;
@@ -96,6 +98,8 @@ PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback)
WindowInfo *window;
BOOL ret;
+ CR_DDI_PROLOGUE();
+
/*crDebug( "DrvSetContext called(0x%x, 0x%x)", hdc, hglrc );*/
(void) (callback);
@@ -115,6 +119,7 @@ PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback)
BOOL APIENTRY DrvSetPixelFormat(HDC hdc, int iPixelFormat)
{
+ CR_DDI_PROLOGUE();
crDebug( "DrvSetPixelFormat(0x%x, %i) called.", hdc, iPixelFormat );
if ( (iPixelFormat<1) || (iPixelFormat>2) ) {
@@ -129,6 +134,8 @@ HGLRC APIENTRY DrvCreateContext(HDC hdc)
char dpyName[MAX_DPY_NAME];
ContextInfo *context;
+ CR_DDI_PROLOGUE();
+
crDebug( "DrvCreateContext(0x%x) called.", hdc);
stubInit();
@@ -148,6 +155,7 @@ HGLRC APIENTRY DrvCreateContext(HDC hdc)
HGLRC APIENTRY DrvCreateLayerContext(HDC hdc, int iLayerPlane)
{
+ CR_DDI_PROLOGUE();
crDebug( "DrvCreateLayerContext(0x%x, %i) called.", hdc, iLayerPlane);
//We don't support more than 1 layers.
if (iLayerPlane == 0) {
@@ -163,6 +171,7 @@ BOOL APIENTRY DrvDescribeLayerPlane(HDC hdc,int iPixelFormat,
int iLayerPlane, UINT nBytes,
LPLAYERPLANEDESCRIPTOR plpd)
{
+ CR_DDI_PROLOGUE();
crWarning( "DrvDescribeLayerPlane: unimplemented" );
CRASSERT(false);
return 0;
@@ -172,6 +181,7 @@ int APIENTRY DrvGetLayerPaletteEntries(HDC hdc, int iLayerPlane,
int iStart, int cEntries,
COLORREF *pcr)
{
+ CR_DDI_PROLOGUE();
crWarning( "DrvGetLayerPaletteEntries: unsupported" );
CRASSERT(false);
return 0;
@@ -179,6 +189,7 @@ int APIENTRY DrvGetLayerPaletteEntries(HDC hdc, int iLayerPlane,
int APIENTRY DrvDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR pfd)
{
+ CR_DDI_PROLOGUE();
if ( !pfd ) {
return 2;
}
@@ -197,6 +208,9 @@ int APIENTRY DrvDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPI
pfd->dwFlags = (PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER);
+
+ pfd->dwFlags |= 0x8000; /* <- Needed for VSG Open Inventor to be happy */
+
pfd->iPixelType = PFD_TYPE_RGBA;
pfd->cColorBits = 32;
pfd->cRedBits = 8;
@@ -259,6 +273,7 @@ int APIENTRY DrvDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPI
BOOL APIENTRY DrvDeleteContext(HGLRC hglrc)
{
+ CR_DDI_PROLOGUE();
/*crDebug( "DrvDeleteContext(0x%x) called", hglrc );*/
stubDestroyContext( (unsigned long) hglrc );
return 1;
@@ -266,12 +281,14 @@ BOOL APIENTRY DrvDeleteContext(HGLRC hglrc)
BOOL APIENTRY DrvCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
+ CR_DDI_PROLOGUE();
crWarning( "DrvCopyContext: unsupported" );
return 0;
}
BOOL APIENTRY DrvShareLists(HGLRC hglrc1, HGLRC hglrc2)
{
+ CR_DDI_PROLOGUE();
crWarning( "DrvShareLists: unsupported" );
return 1;
}
@@ -280,6 +297,7 @@ int APIENTRY DrvSetLayerPaletteEntries(HDC hdc, int iLayerPlane,
int iStart, int cEntries,
CONST COLORREF *pcr)
{
+ CR_DDI_PROLOGUE();
crWarning( "DrvSetLayerPaletteEntries: unsupported" );
return 0;
}
@@ -287,12 +305,14 @@ int APIENTRY DrvSetLayerPaletteEntries(HDC hdc, int iLayerPlane,
BOOL APIENTRY DrvRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize)
{
+ CR_DDI_PROLOGUE();
crWarning( "DrvRealizeLayerPalette: unsupported" );
return 0;
}
BOOL APIENTRY DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes)
{
+ CR_DDI_PROLOGUE();
if (fuPlanes == 1)
{
return DrvSwapBuffers(hdc);
@@ -308,6 +328,8 @@ BOOL APIENTRY DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes)
BOOL APIENTRY DrvSwapBuffers(HDC hdc)
{
WindowInfo *window;
+
+ CR_DDI_PROLOGUE();
/*crDebug( "DrvSwapBuffers(0x%x) called", hdc );*/
window = stubGetWindowInfo(hdc);
stubSwapBuffers( window, 0 );
diff --git a/src/VBox/Additions/common/crOpenGL/load.c b/src/VBox/Additions/common/crOpenGL/load.c
index b083ff64e..34413b90f 100644
--- a/src/VBox/Additions/common/crOpenGL/load.c
+++ b/src/VBox/Additions/common/crOpenGL/load.c
@@ -854,7 +854,7 @@ static void stubSyncTrUpdateWindowCB(unsigned long key, void *data1, void *data2
stub.spu->dispatch_table.WindowShow(pWindow->spuWindow, pWindow->mapped);
}
- if (pRegions->pRegions->fFlags.bSetVisibleRects || pRegions->pRegions->fFlags.bSetViewRect)
+ if (pRegions->pRegions->fFlags.bAddVisibleRects || pRegions->pRegions->fFlags.bSetViewRect)
{
/* ensure data integrity */
Assert(!pRegions->pRegions->fFlags.bAddHiddenRects);
@@ -896,7 +896,7 @@ static void stubSyncTrUpdateWindowCB(unsigned long key, void *data1, void *data2
}
}
- if (pRegions->pRegions->fFlags.bSetVisibleRects)
+ if (pRegions->pRegions->fFlags.bAddVisibleRects)
{
hNewRgn = stubMakeRegionFromRects(pRegions->pRegions, pRegions->pRegions->fFlags.bSetViewRect ? 1 : 0);
}
@@ -914,7 +914,7 @@ static void stubSyncTrUpdateWindowCB(unsigned long key, void *data1, void *data2
if (hNewRgn!=INVALID_HANDLE_VALUE)
{
- if (pRegions->pRegions->fFlags.bSetVisibleRects)
+ if (pRegions->pRegions->fFlags.bAddVisibleRects)
{
HRGN hEmptyRgn = CreateRectRgn(0, 0, 0, 0);
@@ -954,7 +954,7 @@ static void stubSyncTrUpdateWindowCB(unsigned long key, void *data1, void *data2
}
else
{
- if (pRegions->pRegions->fFlags.bSetVisibleRects)
+ if (pRegions->pRegions->fFlags.bAddVisibleRects)
{
pWindow->hVisibleRegion = hNewRgn;
stubDispatchVisibleRegions(pWindow);
diff --git a/src/VBox/Additions/common/crOpenGL/wgl.c b/src/VBox/Additions/common/crOpenGL/wgl.c
index 0c2198319..c12314011 100644
--- a/src/VBox/Additions/common/crOpenGL/wgl.c
+++ b/src/VBox/Additions/common/crOpenGL/wgl.c
@@ -55,6 +55,8 @@ int WINAPI wglChoosePixelFormat_prox( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd
{
DWORD okayFlags;
+ CR_DDI_PROLOGUE();
+
stubInit();
/*
@@ -77,7 +79,11 @@ int WINAPI wglChoosePixelFormat_prox( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd
PFD_DOUBLEBUFFER_DONTCARE |
PFD_SWAP_EXCHANGE |
PFD_SWAP_COPY |
- PFD_STEREO |
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+// PFD_STEREO |
PFD_STEREO_DONTCARE |
PFD_DEPTH_DONTCARE );
if ( pfd->dwFlags & ~okayFlags ) {
@@ -114,8 +120,12 @@ int WINAPI wglChoosePixelFormat_prox( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd
crWarning( "wglChoosePixelFormat: asked for accumulation buffer, ignoring\n" );
}
- if ( pfd->cAccumBits > 0 )
- desiredVisual |= CR_ACCUM_BIT;
+ /* @todo: although this is not needed by VSG Open Inventor interop,
+ * still it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+// if ( pfd->cAccumBits > 0 )
+// desiredVisual |= CR_ACCUM_BIT;
if ( pfd->cDepthBits > 32 ) {
crError( "wglChoosePixelFormat; asked for too many depth bits\n" );
@@ -145,6 +155,8 @@ int WINAPI wglChoosePixelFormat_prox( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd
BOOL WINAPI wglSetPixelFormat_prox( HDC hdc, int pixelFormat,
CONST PIXELFORMATDESCRIPTOR *pdf )
{
+ CR_DDI_PROLOGUE();
+
if ( pixelFormat != 1 ) {
crError( "wglSetPixelFormat: pixelFormat=%d?\n", pixelFormat );
}
@@ -154,6 +166,7 @@ BOOL WINAPI wglSetPixelFormat_prox( HDC hdc, int pixelFormat,
BOOL WINAPI wglDeleteContext_prox( HGLRC hglrc )
{
+ CR_DDI_PROLOGUE();
stubDestroyContext( (unsigned long) hglrc );
return 1;
}
@@ -164,6 +177,8 @@ BOOL WINAPI wglMakeCurrent_prox( HDC hdc, HGLRC hglrc )
WindowInfo *window;
BOOL ret;
+ CR_DDI_PROLOGUE();
+
crHashtableLock(stub.windowTable);
crHashtableLock(stub.contextTable);
@@ -186,12 +201,14 @@ BOOL WINAPI wglMakeCurrent_prox( HDC hdc, HGLRC hglrc )
HGLRC WINAPI wglGetCurrentContext_prox( void )
{
ContextInfo *context = stubGetCurrentContext();
+ CR_DDI_PROLOGUE();
return (HGLRC) (context ? context->id : 0);
}
HDC WINAPI wglGetCurrentDC_prox( void )
{
ContextInfo *context = stubGetCurrentContext();
+ CR_DDI_PROLOGUE();
if (context && context->currentDrawable)
return (HDC) context->currentDrawable->drawable;
else
@@ -200,6 +217,7 @@ HDC WINAPI wglGetCurrentDC_prox( void )
int WINAPI wglGetPixelFormat_prox( HDC hdc )
{
+ CR_DDI_PROLOGUE();
/* this is what we call our generic pixelformat, regardless of the HDC */
return 1;
}
@@ -207,6 +225,8 @@ int WINAPI wglGetPixelFormat_prox( HDC hdc )
int WINAPI wglDescribePixelFormat_prox( HDC hdc, int pixelFormat, UINT nBytes,
LPPIXELFORMATDESCRIPTOR pfd )
{
+ CR_DDI_PROLOGUE();
+
/* if ( pixelFormat != 1 ) {
* crError( "wglDescribePixelFormat: pixelFormat=%d?\n", pixelFormat );
* return 0;
@@ -258,6 +278,7 @@ int WINAPI wglDescribePixelFormat_prox( HDC hdc, int pixelFormat, UINT nBytes,
BOOL WINAPI wglShareLists_prox( HGLRC hglrc1, HGLRC hglrc2 )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglShareLists: unsupported" );
return 0;
}
@@ -268,6 +289,8 @@ HGLRC WINAPI wglCreateContext_prox( HDC hdc )
char dpyName[MAX_DPY_NAME];
ContextInfo *context;
+ CR_DDI_PROLOGUE();
+
stubInit();
CRASSERT(stub.contextTable);
@@ -287,18 +310,21 @@ BOOL WINAPI
wglSwapBuffers_prox( HDC hdc )
{
WindowInfo *window = stubGetWindowInfo(hdc);
+ CR_DDI_PROLOGUE();
stubSwapBuffers( window, 0 );
return 1;
}
BOOL WINAPI wglCopyContext_prox( HGLRC src, HGLRC dst, UINT mask )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglCopyContext: unsupported" );
return 0;
}
HGLRC WINAPI wglCreateLayerContext_prox( HDC hdc, int layerPlane )
{
+ CR_DDI_PROLOGUE();
stubInit();
crWarning( "wglCreateLayerContext: unsupported" );
return 0;
@@ -306,17 +332,20 @@ HGLRC WINAPI wglCreateLayerContext_prox( HDC hdc, int layerPlane )
PROC WINAPI wglGetProcAddress_prox( LPCSTR name )
{
+ CR_DDI_PROLOGUE();
return (PROC) crGetProcAddress( name );
}
BOOL WINAPI wglUseFontBitmapsA_prox( HDC hdc, DWORD first, DWORD count, DWORD listBase )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglUseFontBitmapsA: unsupported" );
return 0;
}
BOOL WINAPI wglUseFontBitmapsW_prox( HDC hdc, DWORD first, DWORD count, DWORD listBase )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglUseFontBitmapsW: unsupported" );
return 0;
}
@@ -324,6 +353,7 @@ BOOL WINAPI wglUseFontBitmapsW_prox( HDC hdc, DWORD first, DWORD count, DWORD li
BOOL WINAPI wglDescribeLayerPlane_prox( HDC hdc, int pixelFormat, int layerPlane,
UINT nBytes, LPLAYERPLANEDESCRIPTOR lpd )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglDescribeLayerPlane: unimplemented" );
return 0;
}
@@ -331,6 +361,7 @@ BOOL WINAPI wglDescribeLayerPlane_prox( HDC hdc, int pixelFormat, int layerPlane
int WINAPI wglSetLayerPaletteEntries_prox( HDC hdc, int layerPlane, int start,
int entries, CONST COLORREF *cr )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglSetLayerPaletteEntries: unsupported" );
return 0;
}
@@ -338,18 +369,21 @@ int WINAPI wglSetLayerPaletteEntries_prox( HDC hdc, int layerPlane, int start,
int WINAPI wglGetLayerPaletteEntries_prox( HDC hdc, int layerPlane, int start,
int entries, COLORREF *cr )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglGetLayerPaletteEntries: unsupported" );
return 0;
}
BOOL WINAPI wglRealizeLayerPalette_prox( HDC hdc, int layerPlane, BOOL realize )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglRealizeLayerPalette: unsupported" );
return 0;
}
DWORD WINAPI wglSwapMultipleBuffers_prox( UINT a, CONST void *b )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglSwapMultipleBuffer: unsupported" );
return 0;
}
@@ -358,6 +392,7 @@ BOOL WINAPI wglUseFontOutlinesA_prox( HDC hdc, DWORD first, DWORD count, DWORD l
FLOAT deviation, FLOAT extrusion, int format,
LPGLYPHMETRICSFLOAT gmf )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglUseFontOutlinesA: unsupported" );
return 0;
}
@@ -366,12 +401,14 @@ BOOL WINAPI wglUseFontOutlinesW_prox( HDC hdc, DWORD first, DWORD count, DWORD l
FLOAT deviation, FLOAT extrusion, int format,
LPGLYPHMETRICSFLOAT gmf )
{
+ CR_DDI_PROLOGUE();
crWarning( "wglUseFontOutlinesW: unsupported" );
return 0;
}
BOOL WINAPI wglSwapLayerBuffers_prox( HDC hdc, UINT planes )
{
+ CR_DDI_PROLOGUE();
if (planes == WGL_SWAP_MAIN_PLANE)
{
return wglSwapBuffers_prox(hdc);
@@ -389,6 +426,8 @@ BOOL WINAPI wglChoosePixelFormatEXT_prox
int *pi;
int wants_rgb = 0;
+ CR_DDI_PROLOGUE();
+
stubInit();
/* TODO : Need to check pfAttributes too ! */
@@ -426,7 +465,15 @@ BOOL WINAPI wglChoosePixelFormatEXT_prox
case WGL_STEREO_EXT:
if (pi[1] > 0)
- desiredVisual |= CR_STEREO_BIT;
+ {
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ crWarning("WGL_STEREO_EXT not supporteed!");
+ return 0;
+// desiredVisual |= CR_STEREO_BIT;
+ }
pi++;
break;
@@ -446,14 +493,30 @@ BOOL WINAPI wglChoosePixelFormatEXT_prox
case WGL_ACCUM_GREEN_BITS_EXT:
case WGL_ACCUM_BLUE_BITS_EXT:
if (pi[1] > 0)
- desiredVisual |= CR_ACCUM_BIT;
+ {
+ /* @todo: although this is not needed by VSG Open Inventor interop,
+ * still it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ crWarning("WGL_ACCUM_XXX not supporteed!");
+ return 0;
+// desiredVisual |= CR_ACCUM_BIT;
+ }
pi++;
break;
case WGL_SAMPLE_BUFFERS_EXT:
case WGL_SAMPLES_EXT:
if (pi[1] > 0)
- desiredVisual |= CR_MULTISAMPLE_BIT;
+ {
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ crWarning("WGL_SAMPLE_BUFFERS_EXT & WGL_SAMPLES_EXT not supporteed!");
+ return 0;
+// desiredVisual |= CR_MULTISAMPLE_BIT;
+ }
pi++;
break;
@@ -492,6 +555,8 @@ BOOL WINAPI wglGetPixelFormatAttribivEXT_prox
{
UINT i;
+ CR_DDI_PROLOGUE();
+
if (!pValues || !piAttributes) return 0;
if ((nAttributes!=1) || (piAttributes && piAttributes[0]!=WGL_NUMBER_PIXEL_FORMATS_ARB))
@@ -513,9 +578,15 @@ BOOL WINAPI wglGetPixelFormatAttribivEXT_prox
case WGL_DRAW_TO_WINDOW_ARB:
case WGL_SUPPORT_OPENGL_ARB:
case WGL_DOUBLE_BUFFER_ARB:
- case WGL_STEREO_ARB:
pValues[i] = 1;
break;
+ case WGL_STEREO_ARB:
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0;
+ break;
case WGL_DRAW_TO_BITMAP_ARB:
case WGL_NEED_PALETTE_ARB:
case WGL_NEED_SYSTEM_PALETTE_ARB:
@@ -589,10 +660,21 @@ BOOL WINAPI wglGetPixelFormatAttribivEXT_prox
pValues[i] = 0;
break;
case WGL_SAMPLE_BUFFERS_EXT:
- pValues[i] = 1;
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0;
break;
case WGL_SAMPLES_EXT:
- pValues[i] = 1;
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0;
+ break;
+ case 0x202d: /* <- WGL_DRAW_TO_PBUFFER_ARB this is to make VSG Open Inventor happy */
+ pValues[i] = 0;
break;
default:
crWarning("wglGetPixelFormatAttribivARB: bad attrib=0x%x", piAttributes[i]);
@@ -608,6 +690,8 @@ BOOL WINAPI wglGetPixelFormatAttribfvEXT_prox
{
UINT i;
+ CR_DDI_PROLOGUE();
+
if (!pValues || !piAttributes) return 0;
if ((nAttributes!=1) || (piAttributes && piAttributes[0]!=WGL_NUMBER_PIXEL_FORMATS_ARB))
@@ -629,9 +713,15 @@ BOOL WINAPI wglGetPixelFormatAttribfvEXT_prox
case WGL_DRAW_TO_WINDOW_ARB:
case WGL_SUPPORT_OPENGL_ARB:
case WGL_DOUBLE_BUFFER_ARB:
- case WGL_STEREO_ARB:
pValues[i] = 1.f;
break;
+ case WGL_STEREO_ARB:
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0.f;
+ break;
case WGL_DRAW_TO_BITMAP_ARB:
case WGL_NEED_PALETTE_ARB:
case WGL_NEED_SYSTEM_PALETTE_ARB:
@@ -705,10 +795,21 @@ BOOL WINAPI wglGetPixelFormatAttribfvEXT_prox
pValues[i] = 0.f;
break;
case WGL_SAMPLE_BUFFERS_EXT:
- pValues[i] = 1.f;
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0.f;
break;
case WGL_SAMPLES_EXT:
- pValues[i] = 1.f;
+ /* @todo: this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0.f;
+ break;
+ case 0x202d: /* <- WGL_DRAW_TO_PBUFFER_ARB this is to make VSG Open Inventor happy */
+ pValues[i] = 0.f;
break;
default:
crWarning("wglGetPixelFormatAttribivARB: bad attrib=0x%x", piAttributes[i]);
@@ -721,11 +822,13 @@ BOOL WINAPI wglGetPixelFormatAttribfvEXT_prox
BOOL WINAPI wglSwapIntervalEXT_prox(int interval)
{
+ CR_DDI_PROLOGUE();
return TRUE;
}
int WINAPI wglGetSwapIntervalEXT_prox()
{
+ CR_DDI_PROLOGUE();
return 1;
}
@@ -733,11 +836,13 @@ static GLubyte *gsz_wgl_extensions = "WGL_EXT_pixel_format WGL_ARB_pixel_format
const GLubyte * WINAPI wglGetExtensionsStringEXT_prox()
{
+ CR_DDI_PROLOGUE();
return gsz_wgl_extensions;
}
const GLubyte * WINAPI wglGetExtensionsStringARB_prox(HDC hdc)
{
+ CR_DDI_PROLOGUE();
(void) hdc;
return gsz_wgl_extensions;
diff --git a/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py b/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
index d0d69d9d0..5de8cee95 100644
--- a/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
+++ b/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
@@ -135,8 +135,19 @@ CR_PROC CR_APIENTRY crGetProcAddress( const char *name )
if (!crStrcmp( name, "wglGetPixelFormatAttribfvARB" )) return (CR_PROC) wglGetPixelFormatAttribfvEXT;
if (!crStrcmp( name, "wglSwapIntervalEXT" )) return (CR_PROC) wglSwapIntervalEXT;
-
- crDebug("Returning GetProcAddress:NULL for %s", name);
+
+ /* this is needed for VSG Open Inventor stuff.
+ * @todo: make all these auto-generated!!! */
+ if (!crStrcmp( name, "glBeginQuery" )) return (CR_PROC) cr_glBeginQueryARB;
+ if (!crStrcmp( name, "glDeleteQueries" )) return (CR_PROC) cr_glDeleteQueriesARB;
+ if (!crStrcmp( name, "glEndQuery" )) return (CR_PROC) cr_glEndQueryARB;
+ if (!crStrcmp( name, "glGenQueries" )) return (CR_PROC) cr_glGenQueriesARB;
+ if (!crStrcmp( name, "glGetQueryObjectiv" )) return (CR_PROC) cr_glGetQueryObjectivARB;
+ if (!crStrcmp( name, "glGetQueryObjectuiv" )) return (CR_PROC) cr_glGetQueryObjectuivARB;
+ if (!crStrcmp( name, "glGetQueryiv" )) return (CR_PROC) cr_glGetQueryivARB;
+ if (!crStrcmp( name, "glIsQuery" )) return (CR_PROC) cr_glIsQueryARB;
+
+ crWarning("Returning GetProcAddress:NULL for %s", name);
return NULL;
}
diff --git a/src/VBox/Additions/linux/Makefile.kmk b/src/VBox/Additions/linux/Makefile.kmk
index f3b37f475..dfca67cdd 100644
--- a/src/VBox/Additions/linux/Makefile.kmk
+++ b/src/VBox/Additions/linux/Makefile.kmk
@@ -143,6 +143,7 @@ VBOX_ADD_STRIP_MOD.linux = \
vboxvideo_drv_19.so \
vboxvideo_drv_110.so \
vboxvideo_drv_111.so \
+ vboxvideo_drv_112.so \
pam_vbox.so \
mount.vboxsf
@@ -369,12 +370,14 @@ $(VBOX_LNX_ADD_INST_STAGE_DIR)install.sh: \
$(RM) -f -- $@
$(QUIET)$(SED) \
-e "s;_VERSION_;$(VBOX_VERSION_STRING);g" \
- -e "s;_PACKAGE_NAME_;VirtualBox Guest Additions;g" \
+ -e "s;_SVNREV_;$(VBOX_SVN_REV);g" \
+ -e "s;_PACKAGE_NAME_;VirtualBox Guest Additions;g" \
-e "s;_PACKAGE_;VBoxGuestAdditions;g" \
-e "s;_VERSION_;$(VBOX_VERSION_STRING);g" \
-e "s;_BUILD_;$(shell date);g" \
-e "s;_OSE_;$(VBOX_OSE);g" \
-e "s;_BUILDTYPE_;$(KBUILD_TYPE);g" \
+ -e "s;_USERNAME_;$(USERNAME);g" \
-e "s;_ARCH_;$(KBUILD_TARGET_ARCH);g" \
-e "s;_UNINSTALL_SCRIPTS_;vboxadd-x11 vboxadd-timesync vboxadd-service vboxadd;g" \
--output $@ \
diff --git a/src/VBox/Additions/linux/drm/vboxvideo_drm.c b/src/VBox/Additions/linux/drm/vboxvideo_drm.c
index b335f76eb..c0d8bb0fa 100644
--- a/src/VBox/Additions/linux/drm/vboxvideo_drm.c
+++ b/src/VBox/Additions/linux/drm/vboxvideo_drm.c
@@ -85,6 +85,19 @@ int vboxvideo_driver_load(struct drm_device * dev, unsigned long flags)
return 0;
#endif
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
+/* since linux-3.3.0-rc1 drm_driver::fops is pointer */
+static struct file_operations driver_fops =
+{
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+};
+#endif
static struct drm_driver driver =
{
@@ -96,6 +109,7 @@ 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,3,0)
.fops =
{
.owner = THIS_MODULE,
@@ -112,7 +126,10 @@ static struct drm_driver driver =
.poll = drm_poll,
.fasync = drm_fasync,
},
-#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 39)
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0) */
+ .fops = &driver_fops,
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 39) && !defined(DRM_RHEL61)
.pci_driver =
{
.name = DRIVER_NAME,
@@ -127,7 +144,7 @@ static struct drm_driver driver =
.patchlevel = DRIVER_PATCHLEVEL,
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 6, 39)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 6, 39) || defined(DRM_RHEL61)
static struct pci_driver pci_driver =
{
.name = DRIVER_NAME,
@@ -137,7 +154,7 @@ static struct pci_driver pci_driver =
static int __init vboxvideo_init(void)
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 39)
+#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 39) && !defined(DRM_RHEL61)
return drm_init(&driver);
#else
return drm_pci_init(&driver, &pci_driver);
@@ -146,7 +163,7 @@ static int __init vboxvideo_init(void)
static void __exit vboxvideo_exit(void)
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 39)
+#if LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 39) && !defined(DRM_RHEL61)
drm_exit(&driver);
#else
drm_pci_exit(&driver, &pci_driver);
diff --git a/src/VBox/Additions/linux/installer/vboxadd-x11.sh b/src/VBox/Additions/linux/installer/vboxadd-x11.sh
index 2f29e5be0..50be32d39 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: 74559 $)
+# Linux Additions X11 setup init script ($Revision: 76664 $)
#
#
@@ -326,6 +326,11 @@ setup()
echo "installing the X.Org drivers."
dox11config=""
;;
+ 1.12.* )
+ xserver_version="X.Org Server 1.12"
+ vboxvideo_src=vboxvideo_drv_112.so
+ test "$system" = "redhat" || setupxorgconf=""
+ ;;
1.11.* )
xserver_version="X.Org Server 1.11"
vboxvideo_src=vboxvideo_drv_111.so
diff --git a/src/VBox/Additions/linux/installer/vboxadd.sh b/src/VBox/Additions/linux/installer/vboxadd.sh
index 3e10345f1..f85a0c941 100755
--- a/src/VBox/Additions/linux/installer/vboxadd.sh
+++ b/src/VBox/Additions/linux/installer/vboxadd.sh
@@ -1,6 +1,6 @@
#! /bin/sh
#
-# Linux Additions kernel module init script ($Revision: 75121 $)
+# Linux Additions kernel module init script ($Revision: 75651 $)
#
#
@@ -28,6 +28,10 @@
# Description: VirtualBox Linux Additions kernel modules
### END INIT INFO
+. /var/lib/VBoxGuestAdditions/config
+export BUILD_TYPE
+export USERNAME
+
PATH=$PATH:/bin:/sbin:/usr/sbin
PACKAGE=VBoxGuestAdditions
BUILDVBOXGUEST=`/bin/ls /usr/src/vboxguest*/vboxguest/build_in_tmp 2>/dev/null|cut -d' ' -f1`
@@ -376,6 +380,11 @@ setup_modules()
cleanup_modules
begin "Building the VirtualBox Guest Additions kernel modules"
+ chcon -t bin_t "$BUILDVBOXGUEST" > /dev/null 2>&1
+ chcon -t bin_t "$BUILDVBOXSF" > /dev/null 2>&1
+ chcon -t bin_t "$BUILDVBOXVIDEO" > /dev/null 2>&1
+ chcon -t bin_t "$DODKMS" > /dev/null 2>&1
+
# Short cut out if a dkms build succeeds
if $DODKMS install >> $LOG 2>&1; then
succ_msg
diff --git a/src/VBox/Additions/linux/sharedfolders/dirops.c b/src/VBox/Additions/linux/sharedfolders/dirops.c
index 5bea7de3f..4a8144b62 100644
--- a/src/VBox/Additions/linux/sharedfolders/dirops.c
+++ b/src/VBox/Additions/linux/sharedfolders/dirops.c
@@ -477,7 +477,7 @@ fail0:
* @returns 0 on success, Linux error code otherwise
*/
static int sf_create_aux(struct inode *parent, struct dentry *dentry,
- int mode, int fDirectory)
+ umode_t mode, int fDirectory)
{
int rc, err;
SHFLCREATEPARMS params;
@@ -575,11 +575,13 @@ fail0:
* @param mode file mode
* @returns 0 on success, Linux error code otherwise
*/
-static int sf_create(struct inode *parent, struct dentry *dentry, int mode
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
- , struct nameidata *nd
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+static int sf_create(struct inode *parent, struct dentry *dentry, umode_t mode, struct nameidata *nd)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+static int sf_create(struct inode *parent, struct dentry *dentry, int mode, struct nameidata *nd)
+#else
+static int sf_create(struct inode *parent, struct dentry *dentry, int mode)
#endif
- )
{
TRACE();
return sf_create_aux(parent, dentry, mode, 0);
@@ -593,7 +595,11 @@ static int sf_create(struct inode *parent, struct dentry *dentry, int mode
* @param mode file mode
* @returns 0 on success, Linux error code otherwise
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+static int sf_mkdir(struct inode *parent, struct dentry *dentry, umode_t mode)
+#else
static int sf_mkdir(struct inode *parent, struct dentry *dentry, int mode)
+#endif
{
TRACE();
return sf_create_aux(parent, dentry, mode, 1);
diff --git a/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c b/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c
index 16f814ebf..5bae460d3 100644
--- a/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c
+++ b/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c
@@ -382,8 +382,8 @@ main (int argc, char **argv)
0, /* uid */
0, /* gid */
0, /* ttl */
- ~0, /* dmode */
- ~0, /* fmode*/
+ ~0U, /* dmode */
+ ~0U, /* fmode*/
0, /* dmask */
0, /* fmask */
0, /* ronly */
diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c b/src/VBox/Additions/linux/sharedfolders/regops.c
index 523c458e1..438fdff88 100644
--- a/src/VBox/Additions/linux/sharedfolders/regops.c
+++ b/src/VBox/Additions/linux/sharedfolders/regops.c
@@ -429,6 +429,16 @@ static int sf_reg_release(struct inode *inode, struct file *file)
BUG_ON(!sf_g);
BUG_ON(!sf_r);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+ /* See the smbfs source (file.c). mmap in particular can cause data to be
+ * written to the file after it is closed, which we can't cope with. We
+ * copy and paste the body of filemap_write_and_wait() here as it was not
+ * defined before 2.6.6 and not exported until quite a bit later. */
+ /* filemap_write_and_wait(inode->i_mapping); */
+ if ( inode->i_mapping->nrpages
+ && filemap_fdatawrite(inode->i_mapping) != -EIO)
+ filemap_fdatawait(inode->i_mapping);
+#endif
rc = vboxCallClose(&client_handle, &sf_g->map, sf_r->handle);
if (RT_FAILURE(rc))
LogFunc(("vboxCallClose failed rc=%Rrc\n", rc));
diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.c b/src/VBox/Additions/linux/sharedfolders/vfsmod.c
index 95aad5279..0699756b0 100644
--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.c
+++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.c
@@ -487,7 +487,7 @@ static struct file_system_type vboxsf_fs_type =
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
static int follow_symlinks = 0;
-module_param(follow_symlinks, bool, 0);
+module_param(follow_symlinks, int, 0);
MODULE_PARM_DESC(follow_symlinks, "Let host resolve symlinks rather than showing them");
#endif
diff --git a/src/VBox/Additions/solaris/Installer/postinstall.sh b/src/VBox/Additions/solaris/Installer/postinstall.sh
index c748f3cc5..f9095b6a8 100755
--- a/src/VBox/Additions/solaris/Installer/postinstall.sh
+++ b/src/VBox/Additions/solaris/Installer/postinstall.sh
@@ -22,6 +22,10 @@
# terms and conditions of either the GPL or the CDDL or both.
#
+# LC_ALL should take precedence over LC_* and LANG but whatever...
+LC_ALL=C
+export LC_ALL
+
LANG=C
export LANG
@@ -398,6 +402,7 @@ if test "$currentzone" = "global"; then
# Setup our VBoxService SMF service
echo "Configuring service..."
+ /usr/sbin/svcadm restart svc:/system/manifest-import:default
/usr/sbin/svcadm enable -s virtualbox/vboxservice
# Update boot archive
diff --git a/src/VBox/Additions/solaris/Installer/preremove.sh b/src/VBox/Additions/solaris/Installer/preremove.sh
index d2ff98674..9985c96f9 100755
--- a/src/VBox/Additions/solaris/Installer/preremove.sh
+++ b/src/VBox/Additions/solaris/Installer/preremove.sh
@@ -22,12 +22,19 @@
# terms and conditions of either the GPL or the CDDL or both.
#
+LC_ALL=C
+export LC_ALL
+
+LANG=C
+export LANG
+
echo "Removing VirtualBox service..."
# stop and unregister VBoxService
/usr/sbin/svcadm disable -s virtualbox/vboxservice
# Don't need to delete, taken care of by the manifest action
# /usr/sbin/svccfg delete svc:/application/virtualbox/vboxservice:default
+/usr/sbin/svcadm restart svc:/system/manifest-import:default
# stop VBoxClient
pkill -INT VBoxClient
diff --git a/src/VBox/Additions/solaris/Installer/vboxguest.sh b/src/VBox/Additions/solaris/Installer/vboxguest.sh
index dbe9c965b..84f97301b 100755
--- a/src/VBox/Additions/solaris/Installer/vboxguest.sh
+++ b/src/VBox/Additions/solaris/Installer/vboxguest.sh
@@ -22,6 +22,12 @@
# terms and conditions of either the GPL or the CDDL or both.
#
+LC_ALL=C
+export LC_ALL
+
+LANG=C
+export LANG
+
SILENTUNLOAD=""
MODNAME="vboxguest"
VFSMODNAME="vboxfs"
@@ -95,18 +101,13 @@ check_root()
start_module()
{
- if vboxguest_loaded; then
- info "VirtualBox guest kernel module already loaded."
+ /usr/sbin/add_drv -i'pci80ee,cafe' -m'* 0666 root sys' $MODNAME
+ if test ! vboxguest_loaded; then
+ abort "Failed to load VirtualBox guest kernel module."
+ elif test -c "/devices/pci@0,0/pci80ee,cafe@4:$MODNAME"; then
+ info "VirtualBox guest kernel module loaded."
else
- /usr/sbin/add_drv -i'pci80ee,cafe' -m'* 0666 root sys' $MODNAME
- sync
- if test ! vboxguest_loaded; then
- abort "Failed to load VirtualBox guest kernel module."
- elif test -c "/devices/pci@0,0/pci80ee,cafe@4:$MODNAME"; then
- info "VirtualBox guest kernel module loaded."
- else
- abort "Aborting due to attach failure."
- fi
+ abort "Aborting due to attach failure."
fi
}
diff --git a/src/VBox/Additions/solaris/Makefile.kmk b/src/VBox/Additions/solaris/Makefile.kmk
index eee07f105..99a6ae25c 100644
--- a/src/VBox/Additions/solaris/Makefile.kmk
+++ b/src/VBox/Additions/solaris/Makefile.kmk
@@ -233,9 +233,10 @@ ifdef VBOX_WITH_COMBINED_SOLARIS_GUEST_PACKAGE
SOLARIS_ARCH_ADD_DEPFILES = \
$(addprefix $(SOLARIS_VBOXADDINST_DIR_64)/,$(SOLARIS_ADD_STRIP_BINS)) \
$(addprefix $(SOLARIS_ADD_SYSLIBINST_DIR_32)/,$(SOLARIS_ADD_SYSLIBS)) \
- $(addprefix $(SOLARIS_ADD_DRIVERINST_DIR_64)/,$(SOLARIS_ADD_DRIVERS)) \
+ $(addprefix $(SOLARIS_ADD_SYSLIBINST_DIR_64)/,$(SOLARIS_ADD_SYSLIBS)) \
$(addprefix $(SOLARIS_VBOXADDINST_DIR_64)/,$(SOLARIS_ADD_XORG_DRIVERS)) \
$(addprefix $(SOLARIS_VBOXADDINST_DIR_32)/,$(SOLARIS_ADD_STRIP_BINS)) \
+ $(addprefix $(SOLARIS_ADD_DRIVERINST_DIR_64)/,$(SOLARIS_ADD_DRIVERS)) \
$(addprefix $(SOLARIS_ADD_DRIVERINST_DIR_32)/,$(SOLARIS_ADD_DRIVERS)) \
$(addprefix $(SOLARIS_ADD_DRIVERINST_DIR)/,$(SOLARIS_ADD_DRIVERS_CONF)) \
$(addprefix $(SOLARIS_VBOXADDINST_DIR_32)/,$(SOLARIS_ADD_XORG_DRIVERS))
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
index bc15e6b78..603f6f228 100644
--- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
+++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
@@ -1719,8 +1719,7 @@ sffs_putpage(
)
{
/*
- * We don't support PROT_WRITE mmaps. For normal writes we do not map and IO via
- * vop_putpage() either, therefore, afaik this shouldn't ever be called.
+ * We don't support PROT_WRITE mmaps.
*/
return (ENOSYS);
}
@@ -1871,6 +1870,7 @@ sffs_delmap(
{
if (dvp->v_flag & VNOMAP)
return (ENOSYS);
+
return (0);
}
#endif /* VBOXVFS_WITH_MMAP */
diff --git a/src/VBox/Additions/x11/vboxmouse/undefined_15 b/src/VBox/Additions/x11/vboxmouse/undefined_15
index 2e01a28c0..8758a47a1 100644
--- a/src/VBox/Additions/x11/vboxmouse/undefined_15
+++ b/src/VBox/Additions/x11/vboxmouse/undefined_15
@@ -4,6 +4,8 @@ InitButtonClassDeviceStruct
InitPointerDeviceStruct
InitPtrFeedbackClassDeviceStruct
InitValuatorClassDeviceStruct
+_ITM_registerTMCloneTable
+_ITM_deregisterTMCloneTable
_Jv_RegisterClasses
___errno
__cxa_finalize
diff --git a/src/VBox/Additions/x11/vboxmouse/undefined_70 b/src/VBox/Additions/x11/vboxmouse/undefined_70
index 5443bc061..b273ad569 100644
--- a/src/VBox/Additions/x11/vboxmouse/undefined_70
+++ b/src/VBox/Additions/x11/vboxmouse/undefined_70
@@ -14,6 +14,8 @@ XisbFree
XisbNew
XisbRead
Xstrdup
+_ITM_registerTMCloneTable
+_ITM_deregisterTMCloneTable
_Jv_RegisterClasses
___errno
__cxa_finalize
diff --git a/src/VBox/Additions/x11/vboxmouse/undefined_71 b/src/VBox/Additions/x11/vboxmouse/undefined_71
index b88a88a6a..6bdd0ba04 100644
--- a/src/VBox/Additions/x11/vboxmouse/undefined_71
+++ b/src/VBox/Additions/x11/vboxmouse/undefined_71
@@ -14,6 +14,8 @@ XisbFree
XisbNew
XisbRead
Xstrdup
+_ITM_registerTMCloneTable
+_ITM_deregisterTMCloneTable
_Jv_RegisterClasses
___errno
__cxa_finalize
diff --git a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
index 24cdccffb..8c92fc02c 100644
--- a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
+++ b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
@@ -352,6 +352,33 @@ vboxvideo_drv_111_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
vboxvideo_drv_111_SOURCES := $(vboxvideo_drv_15_SOURCES)
+#
+# vboxvideo_drv_112
+#
+DLLS += vboxvideo_drv_112
+vboxvideo_drv_112_TEMPLATE = VBOXGUESTR3XORGMOD
+vboxvideo_drv_112_CFLAGS := $(vboxvideo_drv_70_CFLAGS)
+vboxvideo_drv_112_DEFS := $(vboxvideo_drv_15_DEFS)
+## @todo replace $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local
+vboxvideo_drv_112_INCS = \
+ $(VBOX_PATH_X11_ROOT)/fontsproto-2.1.0 \
+ $(VBOX_PATH_X11_ROOT)/glproto-1.4.10 \
+ $(VBOX_PATH_X11_ROOT)/mesa-7.2/include \
+ $(VBOX_PATH_X11_ROOT)/inputproto-1.9.99.902 \
+ $(VBOX_PATH_X11_ROOT)/libdrm-2.4.13 \
+ $(VBOX_PATH_X11_ROOT)/libpciaccess-0.10.8 \
+ $(VBOX_PATH_X11_ROOT)/pixman-0.16.0 \
+ $(VBOX_PATH_X11_ROOT)/randrproto-1.3.0 \
+ $(VBOX_PATH_X11_ROOT)/renderproto-0.11 \
+ $(VBOX_PATH_X11_ROOT)/xextproto-7.1.1 \
+ $(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0 \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.12.0 \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
+ $(VBOX_PATH_X11_ROOT)/xproto-7.0.18
+vboxvideo_drv_112_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
+vboxvideo_drv_112_SOURCES := $(vboxvideo_drv_15_SOURCES)
+
+
# Check the undefined symbols in the X.Org modules against lists of allowed
# symbols. Not very elegant, but it will catch problems early.
ifdef VBOX_WITH_TESTCASES
@@ -459,6 +486,14 @@ $$(vboxvideo_drv_111_0_OUTDIR)/tstvboxvideo111.run: $$(vboxvideo_drv_111_1_STAGE
$(vboxvideo_drv_111_1_STAGE_TARGET) $(VBOXVIDEO_SRC_PATH)/undefined
$(QUIET)$(APPEND) -t "$@" "done"
+ TESTING += $(vboxvideo_drv_112_0_OUTDIR)/tstvboxvideo112.run
+ OTHERS += $(vboxvideo_drv_112_0_OUTDIR)/tstvboxvideo112.run
+$$(vboxvideo_drv_112_0_OUTDIR)/tstvboxvideo112.run: $$(vboxvideo_drv_112_1_STAGE_TARGET)
+ $(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
+ $(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \
+ $(vboxvideo_drv_112_1_STAGE_TARGET) $(VBOXVIDEO_SRC_PATH)/undefined
+ $(QUIET)$(APPEND) -t "$@" "done"
+
endif # ! VBOX_ONLY_SDK
endif # eq ($(KBUILD_HOST_ARCH),$(KBUILD_TARGET_ARCH))
endif # eq ($(KBUILD_TARGET),linux)
diff --git a/src/VBox/Additions/x11/vboxvideo/undefined b/src/VBox/Additions/x11/vboxvideo/undefined
index b5152bd88..7964d0c37 100644
--- a/src/VBox/Additions/x11/vboxvideo/undefined
+++ b/src/VBox/Additions/x11/vboxvideo/undefined
@@ -18,6 +18,8 @@ ShadowFBInit2
XNFcalloc
XNFstrdup
Xalloc
+_ITM_registerTMCloneTable
+_ITM_deregisterTMCloneTable
_Jv_RegisterClasses
___errno
__cxa_finalize
@@ -127,6 +129,7 @@ vgaHWGetIndex
vgaHWGetIOBase
vgaHWRestore
vgaHWSave
+vgaHWSetStdFuncs
write
xf86AddDriver
xf86ConfigPciEntity
diff --git a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
index dd32da3af..f103a5f7a 100644
--- a/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
+++ b/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
@@ -208,6 +208,7 @@ static const char *vgahwSymbols[] = {
"vgaHWGetIndex",
"vgaHWRestore",
"vgaHWSave",
+ "vgaHWSetStdFuncs",
NULL
};
#endif /* !XORG_7X */
@@ -849,6 +850,7 @@ VBOXPreInit(ScrnInfoPtr pScrn, int flags)
if (!vgaHWGetHWRec(pScrn))
return FALSE;
/* Must be called before any VGA registers are saved or restored */
+ vgaHWSetStdFuncs(VGAHWPTR(pScrn));
vgaHWGetIOBase(VGAHWPTR(pScrn));
/* Colour weight - we always call this, since we are always in
diff --git a/src/VBox/Debugger/DBGCCommands.cpp b/src/VBox/Debugger/DBGCCommands.cpp
index d4d9282b7..13301b4fc 100644
--- a/src/VBox/Debugger/DBGCCommands.cpp
+++ b/src/VBox/Debugger/DBGCCommands.cpp
@@ -87,7 +87,7 @@ static const DBGCVARDESC g_aArgAny[] =
static const DBGCVARDESC g_aArgMultiStr[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 1, ~0, DBGCVAR_CAT_STRING, 0, "strings", "One or more strings." },
+ { 1, ~0U, DBGCVAR_CAT_STRING, 0, "strings", "One or more strings." },
};
/** Filename string. */
@@ -110,7 +110,7 @@ static const DBGCVARDESC g_aArgCpu[] =
static const DBGCVARDESC g_aArgHelp[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 0, ~0, DBGCVAR_CAT_STRING, 0, "cmd/op", "Zero or more command or operator names." },
+ { 0, ~0U, DBGCVAR_CAT_STRING, 0, "cmd/op", "Zero or more command or operator names." },
};
@@ -224,12 +224,12 @@ const DBGCCMD g_aCmds[] =
/* pszCmd, cArgsMin, cArgsMax, paArgDescs, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
{ "bye", 0, 0, NULL, 0, 0, dbgcCmdQuit, "", "Exits the debugger." },
{ "cpu", 0, 1, &g_aArgCpu[0], RT_ELEMENTS(g_aArgCpu), 0, dbgcCmdCpu, "[idCpu]", "If no argument, display the current CPU, else change to the specified CPU." },
- { "echo", 1, ~0, &g_aArgMultiStr[0], RT_ELEMENTS(g_aArgMultiStr), 0, dbgcCmdEcho, "<str1> [str2..[strN]]", "Displays the strings separated by one blank space and the last one followed by a newline." },
+ { "echo", 1, ~0U, &g_aArgMultiStr[0], RT_ELEMENTS(g_aArgMultiStr), 0, dbgcCmdEcho, "<str1> [str2..[strN]]", "Displays the strings separated by one blank space and the last one followed by a newline." },
{ "exit", 0, 0, NULL, 0, 0, dbgcCmdQuit, "", "Exits the debugger." },
{ "format", 1, 1, &g_aArgAny[0], RT_ELEMENTS(g_aArgAny), 0, dbgcCmdFormat, "", "Evaluates an expression and formats it." },
{ "detect", 0, 0, NULL, 0, 0, dbgcCmdDetect, "", "Detects or re-detects the guest os and starts the OS specific digger." },
{ "harakiri", 0, 0, NULL, 0, 0, dbgcCmdHarakiri, "", "Kills debugger process." },
- { "help", 0, ~0, &g_aArgHelp[0], RT_ELEMENTS(g_aArgHelp), 0, dbgcCmdHelp, "[cmd/op [..]]", "Display help. For help about info items try 'info help'." },
+ { "help", 0, ~0U, &g_aArgHelp[0], RT_ELEMENTS(g_aArgHelp), 0, dbgcCmdHelp, "[cmd/op [..]]", "Display help. For help about info items try 'info help'." },
{ "info", 1, 2, &g_aArgInfo[0], RT_ELEMENTS(g_aArgInfo), 0, dbgcCmdInfo, "<info> [args]", "Display info register in the DBGF. For a list of info items try 'info help'." },
{ "loadimage", 2, 3, &g_aArgLoadImage[0], RT_ELEMENTS(g_aArgLoadImage), 0, dbgcCmdLoadImage, "<filename> <address> [name]",
"Loads the symbols of an executable image at the specified address. "
@@ -254,8 +254,8 @@ const DBGCCMD g_aCmds[] =
{ "showplugins",0, 0, NULL, 0, 0, dbgcCmdShowPlugIns,"", "List loaded plugins." },
{ "showvars", 0, 0, NULL, 0, 0, dbgcCmdShowVars, "", "List all the defined variables." },
{ "stop", 0, 0, NULL, 0, 0, dbgcCmdStop, "", "Stop execution." },
- { "unloadplugin", 1, ~0, &g_aArgPlugIn[0], RT_ELEMENTS(g_aArgPlugIn), 0, dbgcCmdUnloadPlugIn, "<plugin1> [plugin2..N]", "Unloads one or more plugins." },
- { "unset", 1, ~0, &g_aArgMultiStr[0], RT_ELEMENTS(g_aArgMultiStr), 0, dbgcCmdUnset, "<var1> [var1..[varN]]", "Unsets (delete) one or more global variables." },
+ { "unloadplugin", 1, ~0U, &g_aArgPlugIn[0], RT_ELEMENTS(g_aArgPlugIn), 0, dbgcCmdUnloadPlugIn, "<plugin1> [plugin2..N]", "Unloads one or more plugins." },
+ { "unset", 1, ~0U, &g_aArgMultiStr[0], RT_ELEMENTS(g_aArgMultiStr), 0, dbgcCmdUnset, "<var1> [var1..[varN]]", "Unsets (delete) one or more global variables." },
{ "writecore", 1, 1, &g_aArgWriteCore[0], RT_ELEMENTS(g_aArgWriteCore), 0, dbgcCmdWriteCore, "<filename>", "Write core to file." },
};
diff --git a/src/VBox/Debugger/DBGCEmulateCodeView.cpp b/src/VBox/Debugger/DBGCEmulateCodeView.cpp
index 0be0cb5a9..6239142d6 100644
--- a/src/VBox/Debugger/DBGCEmulateCodeView.cpp
+++ b/src/VBox/Debugger/DBGCEmulateCodeView.cpp
@@ -96,7 +96,7 @@ static const DBGCVARDESC g_aArgBrkAcc[] =
static const DBGCVARDESC g_aArgBrks[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 0, ~0, DBGCVAR_CAT_NUMBER, 0, "#bp", "Breakpoint number." },
+ { 0, ~0U, DBGCVAR_CAT_NUMBER, 0, "#bp", "Breakpoint number." },
{ 0, 1, DBGCVAR_CAT_STRING, 0, "all", "All breakpoints." },
};
@@ -135,8 +135,8 @@ static const DBGCVARDESC g_aArgDumpMem[] =
static const DBGCVARDESC g_aArgDumpDT[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 0, ~0, DBGCVAR_CAT_NUMBER, 0, "sel", "Selector or selector range." },
- { 0, ~0, DBGCVAR_CAT_POINTER, 0, "address", "Far address which selector should be dumped." },
+ { 0, ~0U, DBGCVAR_CAT_NUMBER, 0, "sel", "Selector or selector range." },
+ { 0, ~0U, DBGCVAR_CAT_POINTER, 0, "address", "Far address which selector should be dumped." },
};
@@ -144,7 +144,7 @@ static const DBGCVARDESC g_aArgDumpDT[] =
static const DBGCVARDESC g_aArgDumpIDT[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 0, ~0, DBGCVAR_CAT_NUMBER, 0, "int", "The interrupt vector or interrupt vector range." },
+ { 0, ~0U, DBGCVAR_CAT_NUMBER, 0, "int", "The interrupt vector or interrupt vector range." },
};
@@ -205,7 +205,7 @@ static const DBGCVARDESC g_aArgEditMem[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
{ 1, 1, DBGCVAR_CAT_POINTER, 0, "address", "Address where to write." },
- { 1, ~0, DBGCVAR_CAT_NUMBER, 0, "value", "Value to write." },
+ { 1, ~0U, DBGCVAR_CAT_NUMBER, 0, "value", "Value to write." },
};
@@ -213,7 +213,7 @@ static const DBGCVARDESC g_aArgEditMem[] =
static const DBGCVARDESC g_aArgListMods[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 0, ~0, DBGCVAR_CAT_STRING, 0, "module", "Module name." },
+ { 0, ~0U, DBGCVAR_CAT_STRING, 0, "module", "Module name." },
};
@@ -221,8 +221,8 @@ static const DBGCVARDESC g_aArgListMods[] =
static const DBGCVARDESC g_aArgListNear[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
- { 0, ~0, DBGCVAR_CAT_POINTER, 0, "address", "Address of the symbol to look up." },
- { 0, ~0, DBGCVAR_CAT_SYMBOL, 0, "symbol", "Symbol to lookup." },
+ { 0, ~0U, DBGCVAR_CAT_POINTER, 0, "address", "Address of the symbol to look up." },
+ { 0, ~0U, DBGCVAR_CAT_SYMBOL, 0, "symbol", "Symbol to lookup." },
};
@@ -263,7 +263,7 @@ static const DBGCVARDESC g_aArgSearchMem[] =
{ 0, 1, DBGCVAR_CAT_OPTION, 0, "-u", "Unicode string." },
{ 0, 1, DBGCVAR_CAT_OPTION_NUMBER, 0, "-n <Hits>", "Maximum number of hits." },
{ 0, 1, DBGCVAR_CAT_GC_POINTER, 0, "range", "Register to show or set." },
- { 0, ~0, DBGCVAR_CAT_ANY, 0, "pattern", "Pattern to search for." },
+ { 0, ~0U, DBGCVAR_CAT_ANY, 0, "pattern", "Pattern to search for." },
};
@@ -272,7 +272,7 @@ static const DBGCVARDESC g_aArgSearchMemType[] =
{
/* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */
{ 1, 1, DBGCVAR_CAT_GC_POINTER, 0, "range", "Register to show or set." },
- { 1, ~0, DBGCVAR_CAT_ANY, 0, "pattern", "Pattern to search for." },
+ { 1, ~0U, DBGCVAR_CAT_ANY, 0, "pattern", "Pattern to search for." },
};
@@ -292,9 +292,9 @@ const DBGCCMD g_aCmdsCodeView[] =
/* pszCmd, cArgsMin, cArgsMax, paArgDescs, cArgDescs, fFlags, pfnHandler pszSyntax, ....pszDescription */
{ "ba", 3, 6, &g_aArgBrkAcc[0], RT_ELEMENTS(g_aArgBrkAcc), 0, dbgcCmdBrkAccess, "<access> <size> <address> [passes [max passes]] [cmds]",
"Sets a data access breakpoint." },
- { "bc", 1, ~0, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), 0, dbgcCmdBrkClear, "all | <bp#> [bp# []]", "Enabled a set of breakpoints." },
- { "bd", 1, ~0, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), 0, dbgcCmdBrkDisable, "all | <bp#> [bp# []]", "Disables a set of breakpoints." },
- { "be", 1, ~0, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), 0, dbgcCmdBrkEnable, "all | <bp#> [bp# []]", "Enabled a set of breakpoints." },
+ { "bc", 1, ~0U, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), 0, dbgcCmdBrkClear, "all | <bp#> [bp# []]", "Enabled a set of breakpoints." },
+ { "bd", 1, ~0U, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), 0, dbgcCmdBrkDisable, "all | <bp#> [bp# []]", "Disables a set of breakpoints." },
+ { "be", 1, ~0U, &g_aArgBrks[0], RT_ELEMENTS(g_aArgBrks), 0, dbgcCmdBrkEnable, "all | <bp#> [bp# []]", "Enabled a set of breakpoints." },
{ "bl", 0, 0, NULL, 0, 0, dbgcCmdBrkList, "", "Lists all the breakpoints." },
{ "bp", 1, 4, &g_aArgBrkSet[0], RT_ELEMENTS(g_aArgBrkSet), 0, dbgcCmdBrkSet, "<address> [passes [max passes]] [cmds]",
"Sets a breakpoint (int 3)." },
@@ -305,12 +305,12 @@ const DBGCCMD g_aCmdsCodeView[] =
{ "db", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory in bytes." },
{ "dd", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory in double words." },
{ "da", 0, 1, &g_aArgDumpMem[0], RT_ELEMENTS(g_aArgDumpMem), 0, dbgcCmdDumpMem, "[addr]", "Dump memory as ascii string." },
- { "dg", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT)." },
- { "dga", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT) including not-present entries." },
- { "di", 0, ~0, &g_aArgDumpIDT[0], RT_ELEMENTS(g_aArgDumpIDT), 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT)." },
- { "dia", 0, ~0, &g_aArgDumpIDT[0], RT_ELEMENTS(g_aArgDumpIDT), 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT) including not-present entries." },
- { "dl", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT)." },
- { "dla", 0, ~0, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT) including not-present entries." },
+ { "dg", 0, ~0U, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT)." },
+ { "dga", 0, ~0U, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT) including not-present entries." },
+ { "di", 0, ~0U, &g_aArgDumpIDT[0], RT_ELEMENTS(g_aArgDumpIDT), 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT)." },
+ { "dia", 0, ~0U, &g_aArgDumpIDT[0], RT_ELEMENTS(g_aArgDumpIDT), 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT) including not-present entries." },
+ { "dl", 0, ~0U, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT)." },
+ { "dla", 0, ~0U, &g_aArgDumpDT[0], RT_ELEMENTS(g_aArgDumpDT), 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT) including not-present entries." },
{ "dpd", 0, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the default context." },
{ "dpda", 0, 1, &g_aArgDumpPDAddr[0],RT_ELEMENTS(g_aArgDumpPDAddr), 0, dbgcCmdDumpPageDir, "[addr]", "Dumps specified page directory." },
{ "dpdb", 1, 1, &g_aArgDumpPD[0], RT_ELEMENTS(g_aArgDumpPD), 0, dbgcCmdDumpPageDirBoth, "[addr] [index]", "Dumps page directory entries of the guest and the hypervisor. " },
@@ -340,9 +340,9 @@ const DBGCCMD g_aCmdsCodeView[] =
{ "k", 0, 0, NULL, 0, 0, dbgcCmdStack, "", "Callstack." },
{ "kg", 0, 0, NULL, 0, 0, dbgcCmdStack, "", "Callstack - guest." },
{ "kh", 0, 0, NULL, 0, 0, dbgcCmdStack, "", "Callstack - hypervisor." },
- { "lm", 0, ~0, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules." },
- { "lmo", 0, ~0, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules and their segments." },
- { "ln", 0, ~0, &g_aArgListNear[0], RT_ELEMENTS(g_aArgListNear), 0, dbgcCmdListNear, "[addr/sym [..]]", "List symbols near to the address. Default address is CS:EIP." },
+ { "lm", 0, ~0U, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules." },
+ { "lmo", 0, ~0U, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules and their segments." },
+ { "ln", 0, ~0U, &g_aArgListNear[0], RT_ELEMENTS(g_aArgListNear), 0, dbgcCmdListNear, "[addr/sym [..]]", "List symbols near to the address. Default address is CS:EIP." },
{ "ls", 0, 1, &g_aArgListSource[0],RT_ELEMENTS(g_aArgListSource), 0, dbgcCmdListSource, "[addr]", "Source." },
{ "m", 1, 1, &g_aArgMemoryInfo[0],RT_ELEMENTS(g_aArgMemoryInfo), 0, dbgcCmdMemoryInfo, "<addr>", "Display information about that piece of memory." },
{ "r", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdReg, "[reg [newval]]", "Show or set register(s) - active reg set." },
@@ -351,13 +351,13 @@ const DBGCCMD g_aCmdsCodeView[] =
{ "rg64", 0, 0, NULL, 0, 0, dbgcCmdRegGuest, "", "Show 64-bit guest registers." },
{ "rh", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegHyper, "[reg [newval]]", "Show or set register(s) - hypervisor reg set." },
{ "rt", 0, 0, NULL, 0, 0, dbgcCmdRegTerse, "", "Toggles terse / verbose register info." },
- { "s", 0, ~0, &g_aArgSearchMem[0], RT_ELEMENTS(g_aArgSearchMem), 0, dbgcCmdSearchMem, "[options] <range> <pattern>", "Continue last search." },
- { "sa", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for an ascii string." },
- { "sb", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more bytes." },
- { "sd", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more double words." },
- { "sq", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more quad words." },
- { "su", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for an unicode string." },
- { "sw", 2, ~0, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more words." },
+ { "s", 0, ~0U, &g_aArgSearchMem[0], RT_ELEMENTS(g_aArgSearchMem), 0, dbgcCmdSearchMem, "[options] <range> <pattern>", "Continue last search." },
+ { "sa", 2, ~0U, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for an ascii string." },
+ { "sb", 2, ~0U, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more bytes." },
+ { "sd", 2, ~0U, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more double words." },
+ { "sq", 2, ~0U, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more quad words." },
+ { "su", 2, ~0U, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for an unicode string." },
+ { "sw", 2, ~0U, &g_aArgSearchMemType[0], RT_ELEMENTS(g_aArgSearchMemType),0, dbgcCmdSearchMemType, "<range> <pattern>", "Search memory for one or more words." },
{ "t", 0, 0, NULL, 0, 0, dbgcCmdTrace, "", "Instruction trace (step into)." },
{ "u", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0, dbgcCmdUnassemble, "[addr]", "Unassemble." },
{ "u64", 0, 1, &g_aArgUnassemble[0],RT_ELEMENTS(g_aArgUnassemble), 0, dbgcCmdUnassemble, "[addr]", "Unassemble 64-bit code." },
diff --git a/src/VBox/Debugger/VBoxDbgStatsQt4.cpp b/src/VBox/Debugger/VBoxDbgStatsQt4.cpp
index 33c846da1..5e42c2742 100644
--- a/src/VBox/Debugger/VBoxDbgStatsQt4.cpp
+++ b/src/VBox/Debugger/VBoxDbgStatsQt4.cpp
@@ -125,6 +125,8 @@ typedef struct DBGGUISTATSNODE
uint32_t u32;
/** STAMTYPE_U64 & STAMTYPE_U64_RESET. */
uint64_t u64;
+ /** STAMTYPE_BOOL and STAMTYPE_BOOL_RESET. */
+ bool f;
/** STAMTYPE_CALLBACK. */
QString *pStr;
} Data;
@@ -1086,6 +1088,11 @@ VBoxDbgStatsModel::initNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSa
pNode->Data.u64 = *(uint64_t *)pvSample;
break;
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
+ pNode->Data.f = *(bool *)pvSample;
+ break;
+
default:
AssertMsgFailed(("%d\n", enmType));
break;
@@ -1254,6 +1261,21 @@ VBoxDbgStatsModel::updateNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pv
}
break;
}
+
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
+ {
+ bool fPrev = pNode->Data.f;
+ pNode->Data.f = *(bool *)pvSample;
+ iDelta = pNode->Data.f - fPrev;
+ if (iDelta || pNode->i64Delta)
+ {
+ pNode->i64Delta = iDelta;
+ pNode->enmState = kDbgGuiStatsNodeState_kRefresh;
+ }
+ break;
+ }
+
default:
AssertMsgFailed(("%d\n", enmType));
break;
@@ -1474,9 +1496,11 @@ VBoxDbgStatsModel::updateCallbackHandleOutOfOrder(const char *pszName)
for (;;)
{
int32_t i = iStart + (iLast + 1 - iStart) / 2;
- int iDiff = memcmp(pszSubName, pNode->papChildren[i]->pszName, cchSubName);
+ int iDiff;
+ size_t const cchCompare = RT_MIN(pNode->papChildren[i]->cchName, cchSubName);
+ iDiff = memcmp(pszSubName, pNode->papChildren[i]->pszName, cchCompare);
if (!iDiff)
- iDiff = '\0' - pNode->papChildren[i]->pszName[cchSubName];
+ iDiff = cchSubName == cchCompare ? 0 : cchSubName > cchCompare ? 1 : -1;
if (iDiff > 0)
{
iStart = i + 1;
@@ -2151,6 +2175,10 @@ VBoxDbgStatsModel::strValueTimes(PCDBGGUISTATSNODE pNode)
case STAMTYPE_X64_RESET:
return formatHexNumber(sz, pNode->Data.u64, 16);
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
+ return pNode->Data.f ? "true" : "false";
+
default:
AssertMsgFailed(("%d\n", pNode->enmType));
case STAMTYPE_INVALID:
@@ -2262,6 +2290,8 @@ VBoxDbgStatsModel::strDeltaValue(PCDBGGUISTATSNODE pNode)
case STAMTYPE_U64_RESET:
case STAMTYPE_X64:
case STAMTYPE_X64_RESET:
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
return formatNumberSigned(sz, pNode->i64Delta);
default:
return "";
@@ -2424,6 +2454,11 @@ VBoxDbgStatsModel::stringifyNodeNoRecursion(PDBGGUISTATSNODE a_pNode, QString &a
RTStrPrintf(szBuf, sizeof(szBuf), "%8llx %s", a_pNode->Data.u64, STAMR3GetUnit(a_pNode->enmUnit));
break;
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
+ RTStrPrintf(szBuf, sizeof(szBuf), "%s %s", a_pNode->Data.f ? "true " : "false ", STAMR3GetUnit(a_pNode->enmUnit));
+ break;
+
default:
AssertMsgFailed(("enmType=%d\n", a_pNode->enmType));
return;
diff --git a/src/VBox/Devices/Audio/noaudio.c b/src/VBox/Devices/Audio/noaudio.c
index e1155a593..dbee48f34 100644
--- a/src/VBox/Devices/Audio/noaudio.c
+++ b/src/VBox/Devices/Audio/noaudio.c
@@ -45,7 +45,7 @@ static int no_run_out (HWVoiceOut *hw)
int live, decr, samples;
int64_t now;
int64_t ticks;
- int64_t bytes;
+ int64_t ticks_per_second;
live = audio_pcm_hw_get_live_out (&no->hw);
if (!live) {
@@ -54,9 +54,10 @@ static int no_run_out (HWVoiceOut *hw)
now = audio_get_clock ();
ticks = now - no->old_ticks;
- bytes = (ticks * hw->info.bytes_per_second) / audio_get_ticks_per_sec ();
- bytes = audio_MIN (bytes, INT_MAX);
- samples = bytes >> hw->info.shift;
+
+ ticks_per_second = audio_get_ticks_per_sec ();
+ /* Minimize the rounding error: samples = int((ticks * freq) / ticks_per_second + 0.5). */
+ samples = (2 * ticks * hw->info.freq + ticks_per_second) / ticks_per_second / 2;
no->old_ticks = now;
decr = audio_MIN (live, samples);
diff --git a/src/VBox/Devices/Bus/DevPCI.cpp b/src/VBox/Devices/Bus/DevPCI.cpp
index 473c4eae3..59782feb2 100644
--- a/src/VBox/Devices/Bus/DevPCI.cpp
+++ b/src/VBox/Devices/Bus/DevPCI.cpp
@@ -2553,7 +2553,7 @@ const PDMDEVREG g_DevicePCIBridge =
/* fClass */
PDM_DEVREG_CLASS_BUS_PCI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(PCIBUS),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Bus/DevPciIch9.cpp b/src/VBox/Devices/Bus/DevPciIch9.cpp
index 8fed9c13f..572d0dad2 100644
--- a/src/VBox/Devices/Bus/DevPciIch9.cpp
+++ b/src/VBox/Devices/Bus/DevPciIch9.cpp
@@ -2874,7 +2874,7 @@ const PDMDEVREG g_DevicePciIch9Bridge =
/* fClass */
PDM_DEVREG_CLASS_BUS_PCI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(ICH9PCIBUS),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
index 8aa9d0d1e..3bd4971d6 100644
--- a/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
+++ b/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
@@ -172,11 +172,11 @@ static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA,
return true;
}
- VBVARECORD *pRecord = &pVBVA->aRecords[indexRecordFirst];
+ uint32_t cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[indexRecordFirst].cbRecord);
- LOGVBVABUFFER(("cbRecord = 0x%08X\n", pRecord->cbRecord));
+ LOGVBVABUFFER(("cbRecord = 0x%08X, pPartialRecord->cb = 0x%08X\n", cbRecordCurrent, pPartialRecord->cb));
- uint32_t cbRecord = pRecord->cbRecord & ~VBVA_F_RECORD_PARTIAL;
+ uint32_t cbRecord = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
if (pPartialRecord->cb)
{
@@ -184,7 +184,7 @@ static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA,
Assert (pPartialRecord->pu8);
LOGVBVABUFFER(("continue partial record cb = %d cbRecord 0x%08X, first = %d, free = %d\n",
- pPartialRecord->cb, pRecord->cbRecord, indexRecordFirst, indexRecordFree));
+ pPartialRecord->cb, cbRecordCurrent, indexRecordFirst, indexRecordFree));
if (cbRecord > pPartialRecord->cb)
{
@@ -195,7 +195,7 @@ static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA,
}
}
- if (!(pRecord->cbRecord & VBVA_F_RECORD_PARTIAL))
+ if (!(cbRecordCurrent & VBVA_F_RECORD_PARTIAL))
{
/* The record is completed by guest. Return it to the caller. */
*ppHdr = (VBVACMDHDR *)pPartialRecord->pu8;
@@ -215,7 +215,7 @@ static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA,
}
/* A new record need to be processed. */
- if (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL)
+ if (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
{
/* Current record is being written by guest. '=' is important here,
* because the guest will do a FLUSH at this condition.
@@ -231,7 +231,7 @@ static bool vbvaFetchCmd (VBVAPARTIALRECORD *pPartialRecord, VBVABUFFER *pVBVA,
}
LOGVBVABUFFER(("started partial record cb = 0x%08X cbRecord 0x%08X, first = %d, free = %d\n",
- pPartialRecord->cb, pRecord->cbRecord, indexRecordFirst, indexRecordFree));
+ pPartialRecord->cb, cbRecordCurrent, indexRecordFirst, indexRecordFree));
}
return true;
@@ -467,7 +467,7 @@ static int vbvaResize (PVGASTATE pVGAState, VBVAVIEW *pView, const VBVAINFOSCREE
return rc;
}
-static int vbvaEnable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset)
+static int vbvaEnable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCtx, VBVABUFFER *pVBVA, uint32_t u32Offset, bool fRestored)
{
/* @todo old code did a UpdateDisplayAll at this place. */
@@ -491,8 +491,17 @@ static int vbvaEnable (unsigned uScreenId, PVGASTATE pVGAState, VBVACONTEXT *pCt
LogFlowFunc(("u32HostEvents 0x%08X, u32SupportedOrders 0x%08X\n",
pVBVA->hostFlags.u32HostEvents, pVBVA->hostFlags.u32SupportedOrders));
- pCtx->aViews[uScreenId].partialRecord.pu8 = NULL;
- pCtx->aViews[uScreenId].partialRecord.cb = 0;
+ if (!fRestored)
+ {
+ /* @todo Actually this function must not touch the partialRecord structure at all,
+ * because initially it is a zero and when VBVA is disabled this should be set to zero.
+ * But I'm not sure that no code depends on zeroing partialRecord here.
+ * So for now (a quick fix for 4.1) just do not do this if the VM was restored,
+ * when partialRecord might be loaded already from the saved state.
+ */
+ pCtx->aViews[uScreenId].partialRecord.pu8 = NULL;
+ pCtx->aViews[uScreenId].partialRecord.cb = 0;
+ }
pCtx->aViews[uScreenId].pVBVA = pVBVA;
pCtx->aViews[uScreenId].u32VBVAOffset = u32Offset;
@@ -1599,7 +1608,7 @@ int vboxVBVALoadStateDone (PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
if (pView->pVBVA)
{
- vbvaEnable (iView, pVGAState, pCtx, pView->pVBVA, pView->u32VBVAOffset);
+ vbvaEnable (iView, pVGAState, pCtx, pView->pVBVA, pView->u32VBVAOffset, true /* fRestored */);
vbvaResize (pVGAState, pView, &pView->screen);
}
}
@@ -1891,7 +1900,7 @@ static DECLCALLBACK(int) vbvaChannelHandler (void *pvHandler, uint16_t u16Channe
/* Process any pending orders and empty the VBVA ring buffer. */
vbvaFlush (pVGAState, pCtx);
- rc = vbvaEnable (uScreenId, pVGAState, pCtx, pVBVA, u32Offset);
+ rc = vbvaEnable (uScreenId, pVGAState, pCtx, pVBVA, u32Offset, false /* fRestored */);
}
else
{
diff --git a/src/VBox/Devices/Input/DrvKeyboardQueue.cpp b/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
index 449744dac..e0ceb2313 100644
--- a/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
+++ b/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
@@ -347,7 +347,7 @@ const PDMDRVREG g_DrvKeyboardQueue =
/* fClass. */
PDM_DRVREG_CLASS_KEYBOARD,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVKBDQUEUE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Input/DrvMouseQueue.cpp b/src/VBox/Devices/Input/DrvMouseQueue.cpp
index f63fdfe1d..19a843108 100644
--- a/src/VBox/Devices/Input/DrvMouseQueue.cpp
+++ b/src/VBox/Devices/Input/DrvMouseQueue.cpp
@@ -370,7 +370,7 @@ const PDMDRVREG g_DrvMouseQueue =
/* fClass. */
PDM_DRVREG_CLASS_MOUSE,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMOUSEQUEUE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Input/UsbKbd.cpp b/src/VBox/Devices/Input/UsbKbd.cpp
index d9a1fa3ca..e2c18e44b 100644
--- a/src/VBox/Devices/Input/UsbKbd.cpp
+++ b/src/VBox/Devices/Input/UsbKbd.cpp
@@ -363,6 +363,10 @@ static const PDMUSBDESCCACHE g_UsbHidDescCache =
*/
/** Lookup table for converting PC/XT scan codes to USB HID usage codes. */
+/** We map the scan codes for F13 to F23 to the usage codes for Sun keyboard
+ * left-hand side function keys rather than to the standard F13 to F23 usage
+ * codes, since we suspect that there are more people wanting Sun keyboard
+ * emulation than emulation of other keyboards with extended function keys. */
static uint8_t aScancode2Hid[] =
{
0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, /* 00-07 */
@@ -377,8 +381,10 @@ static uint8_t aScancode2Hid[] =
0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, /* 48-4F */
0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x64, 0x44, /* 50-57 */
0x45, 0x67, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 58-5F */
- 0x00, 0x00, 0x00, 0x00, 0x68, 0x69, 0x6a, 0x6b, /* 60-67 */
- 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x00, /* 68-6F */
+ /* Sun keys: Props Undo Front Copy */
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x7a, 0x77, 0x7c, /* 60-67 */
+ /* Open Paste Find Cut Stop Again Help */
+ 0x74, 0x7d, 0x7e, 0x7b, 0x78, 0x79, 0x75, 0x00, /* 68-6F */
0x88, 0x91, 0x90, 0x87, 0x00, 0x00, 0x00, 0x00, /* 70-77 */
0x00, 0x8a, 0x00, 0x8b, 0x00, 0x89, 0x85, 0x00 /* 78-7F */
};
@@ -393,9 +399,8 @@ static uint8_t aExtScan2Hid[] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20-27 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28-2F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, /* 30-37 */
- /* Sun-specific keys. Most of the XT codes are made up */
- 0xe6, 0x00, 0x00, 0x75, 0x76, 0x77, 0xA3, 0x78, /* 38-3F */
- 0x80, 0x81, 0x82, 0x79, 0x00, 0x48, 0x00, 0x4a, /* 40-47 */
+ 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38-3F */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a, /* 40-47 */
0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d, /* 48-4F */
0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00, /* 50-57 */
0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x66, 0x00, /* 58-5F */
@@ -1450,7 +1455,7 @@ const PDMUSBREG g_UsbHidKbd =
/* fFlags */
0,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(USBHID),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Input/UsbMouse.cpp b/src/VBox/Devices/Input/UsbMouse.cpp
index d6e48c6f6..6edd8c813 100644
--- a/src/VBox/Devices/Input/UsbMouse.cpp
+++ b/src/VBox/Devices/Input/UsbMouse.cpp
@@ -1330,7 +1330,7 @@ const PDMUSBREG g_UsbHidMou =
/* fFlags */
0,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(USBHID),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Makefile.kmk b/src/VBox/Devices/Makefile.kmk
index d294b1076..269418456 100644
--- a/src/VBox/Devices/Makefile.kmk
+++ b/src/VBox/Devices/Makefile.kmk
@@ -880,7 +880,9 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
Network/slirp/libalias/alias_nbt.c \
Network/slirp/libalias/alias_util.c
- # some day will be deleted
+ # Enable VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER here for a while, then move to $(file)_DEFS or clean the code
+ # disabled with this definition
+ VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER=1
Drivers_SOURCES += $(VBOX_SLIRP_SOURCES)
define def_vbox_slirp_cflags
@@ -888,6 +890,7 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
$(if $(VBOX_WITH_SLIRP_BSD_SBUF),VBOX_WITH_SLIRP_BSD_SBUF,) \
$(if $(VBOX_WITH_SLIRP_MEMORY_CHECK),RTMEM_WRAP_TO_EF_APIS,) \
$(if $(VBOX_WITH_DEBUG_NAT_SOCKETS),VBOX_WITH_DEBUG_NAT_SOCKETS,) \
+ $(if $(VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER),VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER,) \
$(if $(VBOX_WITH_SLIRP_MT),VBOX_WITH_SLIRP_MT,)
$(file)_INCS += $(1)/slirp/bsd/sys
$(file)_INCS += $(1)/slirp/bsd/sys/sys
@@ -1201,7 +1204,7 @@ if !defined(VBOX_ONLY_EXTPACKS) # Goes on almost to the end of the file.
endif # !VBOX_ONLY_EXTPACKS
-ifdef VBOX_WITH_EXTPACK_PUEL
+if defined(VBOX_WITH_EXTPACK_PUEL) && defined(VBOX_WITH_EXTPACK_PUEL_BUILD)
#
# The EHCI (USB 2.0) Extension Pack Modules.
#
diff --git a/src/VBox/Devices/Network/DevE1000.cpp b/src/VBox/Devices/Network/DevE1000.cpp
index dd16f28cc..e2d5af233 100644
--- a/src/VBox/Devices/Network/DevE1000.cpp
+++ b/src/VBox/Devices/Network/DevE1000.cpp
@@ -5557,7 +5557,7 @@ static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
static DECLCALLBACK(void) e1kInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
{
E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
- int i;
+ unsigned i;
bool fRcvRing = false;
bool fXmtRing = false;
diff --git a/src/VBox/Devices/Network/DrvDedicatedNic.cpp b/src/VBox/Devices/Network/DrvDedicatedNic.cpp
index 0196d30b1..a037d8a48 100644
--- a/src/VBox/Devices/Network/DrvDedicatedNic.cpp
+++ b/src/VBox/Devices/Network/DrvDedicatedNic.cpp
@@ -525,7 +525,7 @@ const PDMDRVREG g_DrvDedicatedNic =
/* fClass. */
PDM_DRVREG_CLASS_NETWORK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVDEDICATEDNIC),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Network/DrvIntNet.cpp b/src/VBox/Devices/Network/DrvIntNet.cpp
index 5b81661f7..59f0cc039 100644
--- a/src/VBox/Devices/Network/DrvIntNet.cpp
+++ b/src/VBox/Devices/Network/DrvIntNet.cpp
@@ -1816,7 +1816,7 @@ const PDMDRVREG g_DrvIntNet =
/* fClass. */
PDM_DRVREG_CLASS_NETWORK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVINTNET),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Network/DrvNAT.cpp b/src/VBox/Devices/Network/DrvNAT.cpp
index 4fa49552a..6bc0dcae6 100644
--- a/src/VBox/Devices/Network/DrvNAT.cpp
+++ b/src/VBox/Devices/Network/DrvNAT.cpp
@@ -1008,6 +1008,48 @@ static DECLCALLBACK(void) drvNATInfo(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, con
slirp_info(pThis->pNATState, pHlp, pszArgs);
}
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+static int drvNATConstructDNSMappings(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pMappingsCfg)
+{
+ int rc = VINF_SUCCESS;
+ LogFlowFunc(("ENTER: iInstance:%d\n", iInstance));
+ for (PCFGMNODE pNode = CFGMR3GetFirstChild(pMappingsCfg); pNode; pNode = CFGMR3GetNextChild(pNode))
+ {
+ if (!CFGMR3AreValuesValid(pNode, "HostName\0HostNamePattern\0HostIP\0"))
+ return PDMDRV_SET_ERROR(pThis->pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
+ N_("Unknown configuration in dns mapping"));
+ char szHostNameOrPattern[255];
+ /* fMatch = false used for equal matching, and true if regex is used */
+ bool fMatch = false;
+ RT_ZERO(szHostNameOrPattern);
+ GET_STRING(rc, pThis, pNode, "HostName", szHostNameOrPattern[0], sizeof(szHostNameOrPattern));
+ if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+ {
+ GET_STRING(rc, pThis, pNode, "HostNamePattern", szHostNameOrPattern[0], sizeof(szHostNameOrPattern));
+ if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+ {
+ char szNodeName[225];
+ RT_ZERO(szNodeName);
+ CFGMR3GetName(pNode, szNodeName, sizeof(szNodeName));
+ LogRel(("NAT: Neither 'HostName' nor 'HostNamePattern' is specified for mapping %s\n", szNodeName));
+ continue;
+ }
+ fMatch = true;
+ }
+ struct in_addr HostIP;
+ GETIP_DEF(rc, pThis, pNode, HostIP, INADDR_ANY);
+ if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+ {
+ LogRel(("NAT: DNS mapping %s is ignored (address not pointed)\n", szHostNameOrPattern));
+ continue;
+ }
+ slirp_add_host_resolver_mapping(pThis->pNATState, fMatch ? NULL : szHostNameOrPattern, fMatch ? szHostNameOrPattern : NULL, HostIP.s_addr);
+ }
+ LogFlowFunc(("LEAVE: %Rrc\n", rc));
+ return rc;
+}
+#endif /* !VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER */
+
/**
* Sets up the redirectors.
@@ -1025,6 +1067,13 @@ static int drvNATConstructRedir(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pCf
*/
for (PCFGMNODE pNode = CFGMR3GetFirstChild(pCfg); pNode; pNode = CFGMR3GetNextChild(pNode))
{
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+ char szNodeName[32];
+ CFGMR3GetName(pNode, szNodeName, 32);
+ if ( !RTStrICmp(szNodeName, "HostResolverMappings")
+ || !RTStrICmp(szNodeName, "AttachedDriver"))
+ continue;
+#endif
/*
* Validate the port forwarding config.
*/
@@ -1158,7 +1207,11 @@ static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
"SlirpMTU\0AliasMode\0"
"SockRcv\0SockSnd\0TcpRcv\0TcpSnd\0"
"ICMPCacheLimit\0"
- "SoMaxConnection\0"))
+ "SoMaxConnection\0"
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+ "HostResolverMappings\0"
+#endif
+ ))
return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
N_("Unknown NAT configuration option, only supports PassDomain,"
" TFTPPrefix, BootFile and Network"));
@@ -1292,6 +1345,15 @@ static DECLCALLBACK(int) drvNATConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin
# include "counters.h"
#endif
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+ PCFGMNODE pMappingsCfg = CFGMR3GetChild(pCfg, "HostResolverMappings");
+
+ if (pMappingsCfg)
+ {
+ rc = drvNATConstructDNSMappings(pDrvIns->iInstance, pThis, pMappingsCfg);
+ AssertRC(rc);
+ }
+#endif
rc = drvNATConstructRedir(pDrvIns->iInstance, pThis, pCfg, Network);
if (RT_SUCCESS(rc))
{
diff --git a/src/VBox/Devices/Network/DrvTAP.cpp b/src/VBox/Devices/Network/DrvTAP.cpp
index c08792f33..bf65958a9 100644
--- a/src/VBox/Devices/Network/DrvTAP.cpp
+++ b/src/VBox/Devices/Network/DrvTAP.cpp
@@ -1195,7 +1195,7 @@ const PDMDRVREG g_DrvHostInterface =
/* fClass. */
PDM_DRVREG_CLASS_NETWORK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVTAP),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Network/DrvUDPTunnel.cpp b/src/VBox/Devices/Network/DrvUDPTunnel.cpp
index b0dbf1659..e97b68e31 100644
--- a/src/VBox/Devices/Network/DrvUDPTunnel.cpp
+++ b/src/VBox/Devices/Network/DrvUDPTunnel.cpp
@@ -617,7 +617,7 @@ const PDMDRVREG g_DrvUDPTunnel =
/* fClass. */
PDM_DRVREG_CLASS_NETWORK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVUDPTUNNEL),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Network/DrvVDE.cpp b/src/VBox/Devices/Network/DrvVDE.cpp
index 9ffc45050..5dd5ed2ea 100644
--- a/src/VBox/Devices/Network/DrvVDE.cpp
+++ b/src/VBox/Devices/Network/DrvVDE.cpp
@@ -631,7 +631,7 @@ const PDMDRVREG g_DrvVDE =
/* fClass. */
PDM_DRVREG_CLASS_NETWORK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVVDE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Network/slirp/libalias/alias_dns.c b/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
index 194779957..a64784762 100644
--- a/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
+++ b/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
@@ -67,12 +67,15 @@ struct dnsmsg_answer
};
/* see RFC 1035(4.1) */
-static int dns_alias_handler(PNATState pData, int type);
+static int dns_alias_handler(PNATState pData, int type);
static void CStr2QStr(const char *pcszStr, char *pszQStr, size_t cQStr);
static void QStr2CStr(const char *pcszQStr, char *pszStr, size_t cStr);
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+static void alterHostentWithDataFromDNSMap(PNATState pData, struct hostent *pHostent);
+#endif
static int
-fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
+fingerprint(struct libalias *la, struct ip *pIp, struct alias_data *ah)
{
if (!ah->dport || !ah->sport || !ah->lnk)
@@ -90,16 +93,16 @@ fingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
return -1;
}
-static void doanswer(struct libalias *la, union dnsmsg_header *hdr, struct dns_meta_data *pReqMeta, char *qname, struct ip *pip, struct hostent *h)
+static void doanswer(union dnsmsg_header *pHdr, struct dns_meta_data *pReqMeta, char *pszQname, struct ip *pIp, struct hostent *pHostent)
{
int i;
- if (!h)
+ if (!pHostent)
{
- hdr->X.qr = 1; /* response */
- hdr->X.aa = 1;
- hdr->X.rd = 1;
- hdr->X.rcode = 3;
+ pHdr->X.qr = 1; /* response */
+ pHdr->X.aa = 1;
+ pHdr->X.rd = 1;
+ pHdr->X.rcode = 3;
}
else
{
@@ -114,17 +117,17 @@ static void doanswer(struct libalias *la, union dnsmsg_header *hdr, struct dns_m
#if 0
/* here is no compressed names+answers + new query */
- m_inc(m, h->h_length * sizeof(struct dnsmsg_answer) + strlen(qname) + 2 * sizeof(uint16_t));
+ m_inc(m, pHostent->h_length * sizeof(struct dnsmsg_answer) + strlen(pszQname) + 2 * sizeof(uint16_t));
#endif
- packet_len = (pip->ip_hl << 2)
+ packet_len = (pIp->ip_hl << 2)
+ sizeof(struct udphdr)
+ sizeof(union dnsmsg_header)
- + strlen(qname)
+ + strlen(pszQname)
+ sizeof(struct dns_meta_data); /* ip + udp + header + query */
- query = (char *)&hdr[1];
+ query = (char *)&pHdr[1];
- strcpy(query, qname);
- query += strlen(qname) + 1;
+ strcpy(query, pszQname);
+ query += strlen(pszQname) + 1;
/* class & type informations lay right after symbolic inforamtion. */
meta = (struct dns_meta_data *)query;
meta->type = pReqMeta->type;
@@ -133,11 +136,11 @@ static void doanswer(struct libalias *la, union dnsmsg_header *hdr, struct dns_m
/* answers zone lays after query in response packet */
answers = (char *)&meta[1];
- off = (char *)&hdr[1] - (char *)hdr;
+ off = (char *)&pHdr[1] - (char *)pHdr;
off |= (0x3 << 14);
/* add aliases */
- for (cstr = h->h_aliases; *cstr; cstr++)
+ for (cstr = pHostent->h_aliases; *cstr; cstr++)
{
uint16_t len;
struct dnsmsg_answer *ans = (struct dnsmsg_answer *)answers;
@@ -145,22 +148,22 @@ static void doanswer(struct libalias *la, union dnsmsg_header *hdr, struct dns_m
ans->meta.type = htons(5); /* CNAME */
ans->meta.class = htons(1);
*(uint32_t *)ans->ttl = htonl(3600); /* 1h */
- c = (addr_off == (uint16_t)~0 ? h->h_name : *cstr);
+ c = (addr_off == (uint16_t)~0 ? pHostent->h_name : *cstr);
len = strlen(c) + 2;
ans->rdata_len = htons(len);
ans->rdata[len - 1] = 0;
CStr2QStr(c, (char *)ans->rdata, len);
- off = (char *)&ans->rdata - (char *)hdr;
+ off = (char *)&ans->rdata - (char *)pHdr;
off |= (0x3 << 14);
if (addr_off == (uint16_t)~0)
addr_off = off;
answers = (char *)&ans[1] + len - 2; /* note: 1 symbol already counted */
packet_len += sizeof(struct dnsmsg_answer) + len - 2;
- hdr->X.ancount++;
+ pHdr->X.ancount++;
}
/* add addresses */
- for(i = 0; i < h->h_length && h->h_addr_list[i] != NULL; ++i)
+ for(i = 0; i < pHostent->h_length && pHostent->h_addr_list[i] != NULL; ++i)
{
struct dnsmsg_answer *ans = (struct dnsmsg_answer *)answers;
@@ -169,46 +172,44 @@ static void doanswer(struct libalias *la, union dnsmsg_header *hdr, struct dns_m
ans->meta.class = htons(1);
*(uint32_t *)ans->ttl = htonl(3600); /* 1h */
ans->rdata_len = htons(4); /* IPv4 */
- *(uint32_t *)ans->rdata = *(uint32_t *)h->h_addr_list[i];
+ *(uint32_t *)ans->rdata = *(uint32_t *)pHostent->h_addr_list[i];
answers = (char *)&ans[1] + 2;
packet_len += sizeof(struct dnsmsg_answer) + 3;
- hdr->X.ancount++;
+ pHdr->X.ancount++;
}
- hdr->X.qr = 1; /* response */
- hdr->X.aa = 1;
- hdr->X.rd = 1;
- hdr->X.ra = 1;
- hdr->X.rcode = 0;
- HTONS(hdr->X.ancount);
+ pHdr->X.qr = 1; /* response */
+ pHdr->X.aa = 1;
+ pHdr->X.rd = 1;
+ pHdr->X.ra = 1;
+ pHdr->X.rcode = 0;
+ HTONS(pHdr->X.ancount);
/* don't forget update m_len */
- pip->ip_len = htons(packet_len);
+ pIp->ip_len = htons(packet_len);
}
}
static int
-protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
+protohandler(struct libalias *la, struct ip *pIp, struct alias_data *ah)
{
int i;
/* Parse dns request */
char *qw_qname = NULL;
- uint16_t *qw_qtype = NULL;
- uint16_t *qw_qclass = NULL;
- struct hostent *h = NULL;
- char cname[255];
+ struct hostent *pHostent = NULL;
+ char pszCname[255];
int cname_len = 0;
struct dns_meta_data *meta;
struct udphdr *udp = NULL;
- union dnsmsg_header *hdr = NULL;
- udp = (struct udphdr *)ip_next(pip);
- hdr = (union dnsmsg_header *)udp_next(udp);
+ union dnsmsg_header *pHdr = NULL;
+ udp = (struct udphdr *)ip_next(pIp);
+ pHdr = (union dnsmsg_header *)udp_next(udp);
- if (hdr->X.qr == 1)
+ if (pHdr->X.qr == 1)
return 0; /* this is respose */
- memset(cname, 0, sizeof(cname));
- qw_qname = (char *)&hdr[1];
- Assert((ntohs(hdr->X.qdcount) == 1));
- if ((ntohs(hdr->X.qdcount) != 1))
+ memset(pszCname, 0, sizeof(pszCname));
+ qw_qname = (char *)&pHdr[1];
+ Assert((ntohs(pHdr->X.qdcount) == 1));
+ if ((ntohs(pHdr->X.qdcount) != 1))
{
static bool fMultiWarn;
if (!fMultiWarn)
@@ -219,28 +220,33 @@ protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
return 1;
}
- for (i = 0; i < ntohs(hdr->X.qdcount); ++i)
+ for (i = 0; i < ntohs(pHdr->X.qdcount); ++i)
{
meta = (struct dns_meta_data *)(qw_qname + strlen(qw_qname) + 1);
- Log(("qname:%s qtype:%hd qclass:%hd\n",
+ Log(("pszQname:%s qtype:%hd qclass:%hd\n",
qw_qname, ntohs(meta->type), ntohs(meta->class)));
- QStr2CStr(qw_qname, cname, sizeof(cname));
- cname_len = RTStrNLen(cname, sizeof(cname));
+ QStr2CStr(qw_qname, pszCname, sizeof(pszCname));
+ cname_len = RTStrNLen(pszCname, sizeof(pszCname));
/* Some guests like win-xp adds _dot_ after host name
* and after domain name (not passed with host resolver)
* that confuses host resolver.
*/
if ( cname_len > 2
- && cname[cname_len - 1] == '.'
- && cname[cname_len - 2] == '.')
+ && pszCname[cname_len - 1] == '.'
+ && pszCname[cname_len - 2] == '.')
{
- cname[cname_len - 1] = 0;
- cname[cname_len - 2] = 0;
+ pszCname[cname_len - 1] = 0;
+ pszCname[cname_len - 2] = 0;
}
- h = gethostbyname(cname);
- fprintf(stderr, "cname:%s\n", cname);
- doanswer(la, hdr, meta, qw_qname, pip, h);
+ pHostent = gethostbyname(pszCname);
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+ if ( pHostent
+ && !LIST_EMPTY(&la->pData->DNSMapHead))
+ alterHostentWithDataFromDNSMap(la->pData, pHostent);
+#endif
+ fprintf(stderr, "pszCname:%s\n", pszCname);
+ doanswer(pHdr, meta, qw_qname, pIp, pHostent);
}
/*
@@ -248,9 +254,9 @@ protohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
* will assign to zero
*/
udp->uh_sum = 0;
- udp->uh_ulen = ntohs(htons(pip->ip_len) - (pip->ip_hl << 2));
- pip->ip_sum = 0;
- pip->ip_sum = LibAliasInternetChecksum(la, (uint16_t *)pip, pip->ip_hl << 2);
+ udp->uh_ulen = ntohs(htons(pIp->ip_len) - (pIp->ip_hl << 2));
+ pIp->ip_sum = 0;
+ pIp->ip_sum = LibAliasInternetChecksum(la, (uint16_t *)pIp, pIp->ip_hl << 2);
return 0;
}
@@ -363,3 +369,66 @@ dns_alias_handler(PNATState pData, int type)
}
return error;
}
+
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+static bool isDnsMappingEntryMatchOrEqual2Str(const PDNSMAPPINGENTRY pDNSMapingEntry, const char *pcszString)
+{
+ return ( ( pDNSMapingEntry->pszCName
+ && !strcmp(pDNSMapingEntry->pszCName, pcszString))
+ || ( pDNSMapingEntry->pszPattern
+ && RTStrSimplePatternMultiMatch(pDNSMapingEntry->pszPattern, RTSTR_MAX, pcszString, RTSTR_MAX, NULL)));
+}
+
+static void alterHostentWithDataFromDNSMap(PNATState pData, struct hostent *pHostent)
+{
+ PDNSMAPPINGENTRY pDNSMapingEntry = NULL;
+ bool fMatch = false;
+ LIST_FOREACH(pDNSMapingEntry, &pData->DNSMapHead, MapList)
+ {
+ char **pszAlias = NULL;
+ if (isDnsMappingEntryMatchOrEqual2Str(pDNSMapingEntry, pHostent->h_name))
+ {
+ fMatch = true;
+ break;
+ }
+
+ for (pszAlias = pHostent->h_aliases; *pszAlias && !fMatch; pszAlias++)
+ {
+ if (isDnsMappingEntryMatchOrEqual2Str(pDNSMapingEntry, *pszAlias))
+ {
+
+ PDNSMAPPINGENTRY pDnsMapping = RTMemAllocZ(sizeof(DNSMAPPINGENTRY));
+ fMatch = true;
+ if (!pDnsMapping)
+ {
+ LogFunc(("Can't allocate DNSMAPPINGENTRY\n"));
+ LogFlowFuncLeave();
+ return;
+ }
+ pDnsMapping->u32IpAddress = pDNSMapingEntry->u32IpAddress;
+ pDnsMapping->pszCName = RTStrDup(pHostent->h_name);
+ if (!pDnsMapping->pszCName)
+ {
+ LogFunc(("Can't allocate enough room for %s\n", pHostent->h_name));
+ RTMemFree(pDnsMapping);
+ LogFlowFuncLeave();
+ return;
+ }
+ LIST_INSERT_HEAD(&pData->DNSMapHead, pDnsMapping, MapList);
+ }
+ }
+ if (fMatch)
+ break;
+ }
+
+ /* h_lenght is lenght of h_addr_list in bytes, so we check that we have enough space for IPv4 address */
+ if ( fMatch
+ && pHostent->h_length >= sizeof(uint32_t)
+ && pDNSMapingEntry)
+ {
+ pHostent->h_length = 1;
+ *(uint32_t *)pHostent->h_addr_list[0] = pDNSMapingEntry->u32IpAddress;
+ }
+
+}
+#endif
diff --git a/src/VBox/Devices/Network/slirp/libslirp.h b/src/VBox/Devices/Network/slirp/libslirp.h
index bc3dcbe5d..b3fcfe313 100644
--- a/src/VBox/Devices/Network/slirp/libslirp.h
+++ b/src/VBox/Devices/Network/slirp/libslirp.h
@@ -147,6 +147,10 @@ unsigned int slirp_get_timeout_ms(PNATState pData);
int slirp_get_nsock(PNATState pData);
# endif
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+void slirp_add_host_resolver_mapping(PNATState pData, const char *pszHostName, const char *pszHostNamePattern, uint32_t u32HostIP);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/src/VBox/Devices/Network/slirp/slirp.c b/src/VBox/Devices/Network/slirp/slirp.c
index 53a449459..004e7c595 100644
--- a/src/VBox/Devices/Network/slirp/slirp.c
+++ b/src/VBox/Devices/Network/slirp/slirp.c
@@ -785,7 +785,18 @@ void slirp_term(PNATState pData)
ftp_alias_unload(pData);
nbt_alias_unload(pData);
if (pData->fUseHostResolver)
+ {
dns_alias_unload(pData);
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+ while (!LIST_EMPTY(&pData->DNSMapHead))
+ {
+ PDNSMAPPINGENTRY pDnsEntry = LIST_FIRST(&pData->DNSMapHead);
+ LIST_REMOVE(pDnsEntry, MapList);
+ RTStrFree(pDnsEntry->pszCName);
+ RTMemFree(pDnsEntry);
+ }
+#endif
+ }
while (!LIST_EMPTY(&instancehead))
{
struct libalias *la = LIST_FIRST(&instancehead);
@@ -2129,6 +2140,43 @@ void slirp_arp_who_has(PNATState pData, uint32_t dst)
if_encap(pData, ETH_P_ARP, m, ETH_ENCAP_URG);
LogFlowFuncLeave();
}
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+void slirp_add_host_resolver_mapping(PNATState pData, const char *pszHostName, const char *pszHostNamePattern, uint32_t u32HostIP)
+{
+ LogFlowFunc(("ENTER: pszHostName:%s, pszHostNamePattern:%s u32HostIP:%RTnaipv4\n",
+ pszHostName ? pszHostName : "(null)",
+ pszHostNamePattern ? pszHostNamePattern : "(null)",
+ u32HostIP));
+ if ( ( pszHostName
+ || pszHostNamePattern)
+ && u32HostIP != INADDR_ANY
+ && u32HostIP != INADDR_BROADCAST)
+ {
+ PDNSMAPPINGENTRY pDnsMapping = RTMemAllocZ(sizeof(DNSMAPPINGENTRY));
+ if (!pDnsMapping)
+ {
+ LogFunc(("Can't allocate DNSMAPPINGENTRY\n"));
+ LogFlowFuncLeave();
+ return;
+ }
+ pDnsMapping->u32IpAddress = u32HostIP;
+ if (pszHostName)
+ pDnsMapping->pszCName = RTStrDup(pszHostName);
+ else if (pszHostNamePattern)
+ pDnsMapping->pszPattern = RTStrDup(pszHostNamePattern);
+ if ( !pDnsMapping->pszCName
+ && !pDnsMapping->pszPattern)
+ {
+ LogFunc(("Can't allocate enough room for %s\n", pszHostName ? pszHostName : pszHostNamePattern));
+ RTMemFree(pDnsMapping);
+ LogFlowFuncLeave();
+ return;
+ }
+ LIST_INSERT_HEAD(&pData->DNSMapHead, pDnsMapping, MapList);
+ }
+ LogFlowFuncLeave();
+}
+#endif
/* updates the arp cache
* @note: this is helper function, slirp_arp_cache_update_or_add should be used.
diff --git a/src/VBox/Devices/Network/slirp/slirp_state.h b/src/VBox/Devices/Network/slirp/slirp_state.h
index 1bc354ec0..6618673d5 100644
--- a/src/VBox/Devices/Network/slirp/slirp_state.h
+++ b/src/VBox/Devices/Network/slirp/slirp_state.h
@@ -65,6 +65,22 @@ struct dns_domain_entry
};
LIST_HEAD(dns_domain_list_head, dns_domain_entry);
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+typedef struct DNSMAPPINGENTRY
+{
+ /*
+ * host name to map
+ * Note: if pszCName isn't null pszPattern won't be used (see alias_dns.c for details)
+ */
+ char *pszCName;
+ /* pattern of hostnames to map to specifaied IP */
+ char *pszPattern;
+ uint32_t u32IpAddress;
+ LIST_ENTRY(DNSMAPPINGENTRY) MapList;
+} DNSMAPPINGENTRY, *PDNSMAPPINGENTRY;
+typedef LIST_HEAD(DNSMAPPINGLISTHEAD, DNSMAPPINGENTRY) DNSMAPPINGLISTHEAD;
+#endif
+
struct dns_entry
{
struct in_addr de_addr;
@@ -292,6 +308,9 @@ typedef struct NATState
struct proto_handler *nbt_module;
struct proto_handler *dns_module;
+#ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER
+ DNSMAPPINGLISTHEAD DNSMapHead;
+#endif
} NATState;
diff --git a/src/VBox/Devices/PC/DevACPI.cpp b/src/VBox/Devices/PC/DevACPI.cpp
index 7c197c7da..e4e39752d 100644
--- a/src/VBox/Devices/PC/DevACPI.cpp
+++ b/src/VBox/Devices/PC/DevACPI.cpp
@@ -3168,7 +3168,7 @@ const PDMDEVREG g_DeviceACPI =
/* fClass */
PDM_DEVREG_CLASS_ACPI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(ACPIState),
/* pfnConstruct */
diff --git a/src/VBox/Devices/PC/DevPIC.cpp b/src/VBox/Devices/PC/DevPIC.cpp
index 32e1a229d..bf35527e7 100644
--- a/src/VBox/Devices/PC/DevPIC.cpp
+++ b/src/VBox/Devices/PC/DevPIC.cpp
@@ -425,8 +425,8 @@ PDMBOTHCBDECL(int) picGetInterrupt(PPDMDEVINS pDevIns)
}
else
{
- /* spurious IRQ on slave controller (impossible) */
- AssertMsgFailed(("picGetInterrupt: spurious IRQ on slave controller\n"));
+ /* Interrupt went away or is now masked. */
+ Log(("picGetInterrupt: spurious IRQ on slave controller, converted to IRQ15\n"));
irq2 = 7;
}
intno = pThis->aPics[1].irq_base + irq2;
@@ -440,8 +440,8 @@ PDMBOTHCBDECL(int) picGetInterrupt(PPDMDEVINS pDevIns)
}
else
{
- /* spurious IRQ on host controller (impossible) */
- AssertMsgFailed(("picGetInterrupt: spurious IRQ on master controller\n"));
+ /* Interrupt went away or is now masked. */
+ Log(("picGetInterrupt: spurious IRQ on master controller, converted to IRQ7\n"));
irq = 7;
intno = pThis->aPics[0].irq_base + irq;
}
diff --git a/src/VBox/Devices/PC/DrvACPI.cpp b/src/VBox/Devices/PC/DrvACPI.cpp
index 37e8cd569..250a8a402 100644
--- a/src/VBox/Devices/PC/DrvACPI.cpp
+++ b/src/VBox/Devices/PC/DrvACPI.cpp
@@ -1014,7 +1014,7 @@ const PDMDRVREG g_DrvACPI =
/* fClass. */
PDM_DRVREG_CLASS_ACPI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVACPI),
/* pfnConstruct */
diff --git a/src/VBox/Devices/PC/DrvAcpiCpu.cpp b/src/VBox/Devices/PC/DrvAcpiCpu.cpp
index eebcfcb6b..a69ac838f 100644
--- a/src/VBox/Devices/PC/DrvAcpiCpu.cpp
+++ b/src/VBox/Devices/PC/DrvAcpiCpu.cpp
@@ -104,7 +104,7 @@ const PDMDRVREG g_DrvAcpiCpu =
/* fClass. */
PDM_DRVREG_CLASS_ACPI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(PDMDRVINS),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Parallel/DrvHostParallel.cpp b/src/VBox/Devices/Parallel/DrvHostParallel.cpp
index 070caf7ed..807cb4162 100644
--- a/src/VBox/Devices/Parallel/DrvHostParallel.cpp
+++ b/src/VBox/Devices/Parallel/DrvHostParallel.cpp
@@ -394,7 +394,7 @@ const PDMDRVREG g_DrvHostParallel =
/* fClass. */
PDM_DRVREG_CLASS_CHAR,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVHOSTPARALLEL),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Serial/DrvChar.cpp b/src/VBox/Devices/Serial/DrvChar.cpp
index 5ab6caa21..881c77a28 100644
--- a/src/VBox/Devices/Serial/DrvChar.cpp
+++ b/src/VBox/Devices/Serial/DrvChar.cpp
@@ -427,7 +427,7 @@ const PDMDRVREG g_DrvChar =
/* fClass. */
PDM_DRVREG_CLASS_CHAR,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVCHAR),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Serial/DrvHostSerial.cpp b/src/VBox/Devices/Serial/DrvHostSerial.cpp
index e3213f7e4..09f6b05b9 100644
--- a/src/VBox/Devices/Serial/DrvHostSerial.cpp
+++ b/src/VBox/Devices/Serial/DrvHostSerial.cpp
@@ -694,6 +694,16 @@ static DECLCALLBACK(int) drvHostSerialRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD
if (rc < 0)
{
int err = errno;
+ if (err == EINTR)
+ {
+ /*
+ * EINTR errors should be harmless, even if they are not supposed to occur in our setup.
+ */
+ Log(("rc=%d revents=%#x,%#x errno=%p %s\n", rc, aFDs[0].revents, aFDs[1].revents, err, strerror(err)));
+ RTThreadYield();
+ continue;
+ }
+
rcThread = RTErrConvertFromErrno(err);
LogRel(("HostSerial#%d: poll failed with errno=%d / %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, err, rcThread));
break;
@@ -1314,7 +1324,7 @@ const PDMDRVREG g_DrvHostSerial =
/* fClass. */
PDM_DRVREG_CLASS_CHAR,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVHOSTSERIAL),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Serial/DrvNamedPipe.cpp b/src/VBox/Devices/Serial/DrvNamedPipe.cpp
index f23160b46..43f8d4297 100644
--- a/src/VBox/Devices/Serial/DrvNamedPipe.cpp
+++ b/src/VBox/Devices/Serial/DrvNamedPipe.cpp
@@ -681,7 +681,7 @@ const PDMDRVREG g_DrvNamedPipe =
/* fClass. */
PDM_DRVREG_CLASS_STREAM,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVNAMEDPIPE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Serial/DrvRawFile.cpp b/src/VBox/Devices/Serial/DrvRawFile.cpp
index 57c52e050..1850a7f01 100644
--- a/src/VBox/Devices/Serial/DrvRawFile.cpp
+++ b/src/VBox/Devices/Serial/DrvRawFile.cpp
@@ -214,7 +214,7 @@ const PDMDRVREG g_DrvRawFile =
/* fClass. */
PDM_DRVREG_CLASS_STREAM,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVRAWFILE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DevAHCI.cpp b/src/VBox/Devices/Storage/DevAHCI.cpp
index 1086c98e0..efdfed2fc 100644
--- a/src/VBox/Devices/Storage/DevAHCI.cpp
+++ b/src/VBox/Devices/Storage/DevAHCI.cpp
@@ -8785,7 +8785,7 @@ const PDMDEVREG g_DeviceAHCI =
/* fClass */
PDM_DEVREG_CLASS_STORAGE,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(AHCI),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DevBusLogic.cpp b/src/VBox/Devices/Storage/DevBusLogic.cpp
index 905966a8e..a57309a7a 100644
--- a/src/VBox/Devices/Storage/DevBusLogic.cpp
+++ b/src/VBox/Devices/Storage/DevBusLogic.cpp
@@ -3220,7 +3220,7 @@ const PDMDEVREG g_DeviceBusLogic =
/* fClass */
PDM_DEVREG_CLASS_STORAGE,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(BUSLOGIC),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
index 18afdec9d..2e3485cfa 100644
--- a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
+++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
@@ -5293,7 +5293,7 @@ const PDMDEVREG g_DeviceLsiLogicSCSI =
/* fClass */
PDM_DEVREG_CLASS_STORAGE,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(LSILOGICSCSI),
/* pfnConstruct */
@@ -5349,7 +5349,7 @@ const PDMDEVREG g_DeviceLsiLogicSAS =
/* fClass */
PDM_DEVREG_CLASS_STORAGE,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(LSILOGICSCSI),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvBlock.cpp b/src/VBox/Devices/Storage/DrvBlock.cpp
index 7a92757fa..fc0405aaa 100644
--- a/src/VBox/Devices/Storage/DrvBlock.cpp
+++ b/src/VBox/Devices/Storage/DrvBlock.cpp
@@ -1001,7 +1001,7 @@ const PDMDRVREG g_DrvBlock =
/* fClass. */
PDM_DRVREG_CLASS_BLOCK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVBLOCK),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp b/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
index 6fc17a927..fb8038f26 100644
--- a/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
+++ b/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
@@ -1005,7 +1005,7 @@ const PDMDRVREG g_DrvDiskIntegrity =
/* fClass. */
PDM_DRVREG_CLASS_BLOCK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVDISKINTEGRITY),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvHostDVD.cpp b/src/VBox/Devices/Storage/DrvHostDVD.cpp
index 08ed929db..0b661cf2f 100644
--- a/src/VBox/Devices/Storage/DrvHostDVD.cpp
+++ b/src/VBox/Devices/Storage/DrvHostDVD.cpp
@@ -852,7 +852,7 @@ const PDMDRVREG g_DrvHostDVD =
/* fClass. */
PDM_DRVREG_CLASS_BLOCK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVHOSTBASE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvHostFloppy.cpp b/src/VBox/Devices/Storage/DrvHostFloppy.cpp
index 925d90c6c..a65185b62 100644
--- a/src/VBox/Devices/Storage/DrvHostFloppy.cpp
+++ b/src/VBox/Devices/Storage/DrvHostFloppy.cpp
@@ -249,7 +249,7 @@ const PDMDRVREG g_DrvHostFloppy =
/* fClass. */
PDM_DRVREG_CLASS_BLOCK,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVHOSTFLOPPY),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvMediaISO.cpp b/src/VBox/Devices/Storage/DrvMediaISO.cpp
index 746a6977d..873c02b82 100644
--- a/src/VBox/Devices/Storage/DrvMediaISO.cpp
+++ b/src/VBox/Devices/Storage/DrvMediaISO.cpp
@@ -293,7 +293,7 @@ const PDMDRVREG g_DrvMediaISO =
/* fClass. */
PDM_DRVREG_CLASS_MEDIA,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMEDIAISO),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvRawImage.cpp b/src/VBox/Devices/Storage/DrvRawImage.cpp
index 1570813d2..944b3c46f 100644
--- a/src/VBox/Devices/Storage/DrvRawImage.cpp
+++ b/src/VBox/Devices/Storage/DrvRawImage.cpp
@@ -352,7 +352,7 @@ const PDMDRVREG g_DrvRawImage =
/* fClass. */
PDM_DRVREG_CLASS_MEDIA,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVRAWIMAGE),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvSCSI.cpp b/src/VBox/Devices/Storage/DrvSCSI.cpp
index 81de28295..7e42d2db6 100644
--- a/src/VBox/Devices/Storage/DrvSCSI.cpp
+++ b/src/VBox/Devices/Storage/DrvSCSI.cpp
@@ -863,7 +863,7 @@ const PDMDRVREG g_DrvSCSI =
/* fClass. */
PDM_DRVREG_CLASS_SCSI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVSCSI),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvSCSIHost.cpp b/src/VBox/Devices/Storage/DrvSCSIHost.cpp
index 2a45c671b..7cd518155 100644
--- a/src/VBox/Devices/Storage/DrvSCSIHost.cpp
+++ b/src/VBox/Devices/Storage/DrvSCSIHost.cpp
@@ -509,7 +509,7 @@ const PDMDRVREG g_DrvSCSIHost =
/* fClass. */
PDM_DRVREG_CLASS_SCSI,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVSCSIHOST),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/DrvVD.cpp b/src/VBox/Devices/Storage/DrvVD.cpp
index 7b63057cd..1abd1e951 100644
--- a/src/VBox/Devices/Storage/DrvVD.cpp
+++ b/src/VBox/Devices/Storage/DrvVD.cpp
@@ -2759,7 +2759,7 @@ const PDMDRVREG g_DrvVD =
/* fClass. */
PDM_DRVREG_CLASS_MEDIA,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(VBOXDISK),
/* pfnConstruct */
diff --git a/src/VBox/Devices/Storage/UsbMsd.cpp b/src/VBox/Devices/Storage/UsbMsd.cpp
index 73648559c..d41b929ac 100644
--- a/src/VBox/Devices/Storage/UsbMsd.cpp
+++ b/src/VBox/Devices/Storage/UsbMsd.cpp
@@ -1604,7 +1604,7 @@ const PDMUSBREG g_UsbMsd =
/* fFlags */
0,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(USBMSD),
/* pfnConstruct */
diff --git a/src/VBox/Devices/USB/DevOHCI.cpp b/src/VBox/Devices/USB/DevOHCI.cpp
index edf071f9e..7940f63b3 100644
--- a/src/VBox/Devices/USB/DevOHCI.cpp
+++ b/src/VBox/Devices/USB/DevOHCI.cpp
@@ -5549,7 +5549,7 @@ const PDMDEVREG g_DeviceOHCI =
/* fClass */
PDM_DEVREG_CLASS_BUS_USB,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(OHCI),
/* pfnConstruct */
diff --git a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
index cbc37c060..b55775a21 100644
--- a/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
+++ b/src/VBox/Devices/USB/DrvVUSBRootHub.cpp
@@ -1115,7 +1115,7 @@ const PDMDRVREG g_DrvVUSBRootHub =
/* fClass. */
PDM_DRVREG_CLASS_USB,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(VUSBROOTHUB),
/* pfnConstruct */
diff --git a/src/VBox/Devices/USB/USBProxyDevice.cpp b/src/VBox/Devices/USB/USBProxyDevice.cpp
index c218bbc5b..77e79ae87 100644
--- a/src/VBox/Devices/USB/USBProxyDevice.cpp
+++ b/src/VBox/Devices/USB/USBProxyDevice.cpp
@@ -1076,7 +1076,7 @@ const PDMUSBREG g_UsbDevProxy =
/* fFlags */
0,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(USBPROXYDEV),
/* pfnConstruct */
diff --git a/src/VBox/Devices/VMMDev/VMMDev.cpp b/src/VBox/Devices/VMMDev/VMMDev.cpp
index 13a744569..4fa3374cc 100644
--- a/src/VBox/Devices/VMMDev/VMMDev.cpp
+++ b/src/VBox/Devices/VMMDev/VMMDev.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * 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;
@@ -34,6 +34,7 @@
#include <VBox/err.h>
#include <VBox/vmm/vm.h> /* for VM_IS_EMT */
#include <VBox/dbg.h>
+#include <VBox/version.h>
#include <iprt/asm.h>
#include <iprt/asm-amd64-x86.h>
@@ -85,10 +86,14 @@
&& RT_LOWORD(additionsVersion) > RT_LOWORD(VMMDEV_VERSION) ) )
/** The saved state version. */
-#define VMMDEV_SAVED_STATE_VERSION 13
+#define VMMDEV_SAVED_STATE_VERSION 15
+/** The saved state version which is missing the guest facility statuses. */
+#define VMMDEV_SAVED_STATE_VERSION_MISSING_FACILITY_STATUSES 14
+/** The saved state version which is missing the guestInfo2 bits. */
+#define VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2 13
/** The saved state version used by VirtualBox 3.0.
* This doesn't have the config part. */
-#define VMMDEV_SAVED_STATE_VERSION_VBOX_30 11
+#define VMMDEV_SAVED_STATE_VERSION_VBOX_30 11
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
@@ -387,14 +392,416 @@ static DECLCALLBACK(int) vmmdevTimesyncBackdoorRead(PPDMDEVINS pDevIns, void *pv
}
#endif /* TIMESYNC_BACKDOOR */
+/**
+ * Validates a publisher tag.
+ *
+ * @returns true / false.
+ * @param pszTag Tag to validate.
+ */
+static bool vmmdevReqIsValidPublisherTag(const char *pszTag)
+{
+ /* Note! This character set is also found in Config.kmk. */
+ static char const s_szValidChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz()[]{}+-.,";
+
+ while (*pszTag != '\0')
+ {
+ if (!strchr(s_szValidChars, *pszTag))
+ return false;
+ pszTag++;
+ }
+ return true;
+}
+
+
+/**
+ * Validates a build tag.
+ *
+ * @returns true / false.
+ * @param pszTag Tag to validate.
+ */
+static bool vmmdevReqIsValidBuildTag(const char *pszTag)
+{
+ int cchPrefix;
+ if (!strncmp(pszTag, "RC", 2))
+ cchPrefix = 2;
+ else if (!strncmp(pszTag, "BETA", 4))
+ cchPrefix = 4;
+ else if (!strncmp(pszTag, "ALPHA", 5))
+ cchPrefix = 5;
+ else
+ return false;
+
+ if (pszTag[cchPrefix] == '\0')
+ return true;
+
+ uint8_t u8;
+ int rc = RTStrToUInt8Full(&pszTag[cchPrefix], 10, &u8);
+ return rc == VINF_SUCCESS;
+}
+
+/**
+ * Handles VMMDevReq_ReportGuestInfo2.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pThis The VMMDev instance data.
+ * @param pRequestHeader The header of the request to handle.
+ */
+static int vmmdevReqHandler_ReportGuestInfo2(VMMDevState *pThis, VMMDevRequestHeader *pRequestHeader)
+{
+ AssertMsgReturn(pRequestHeader->size == sizeof(VMMDevReportGuestInfo2), ("%u\n", pRequestHeader->size), VERR_INVALID_PARAMETER);
+ VBoxGuestInfo2 const *pInfo2 = &((VMMDevReportGuestInfo2 *)pRequestHeader)->guestInfo;
+
+ LogRel(("Guest Additions information report: Version %d.%d.%d r%d '%.*s'\n",
+ pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild,
+ pInfo2->additionsRevision, sizeof(pInfo2->szName), pInfo2->szName));
+
+ /* The interface was introduced in 3.2 and will definitely not be
+ backported beyond 3.0 (bird). */
+ AssertMsgReturn(pInfo2->additionsMajor >= 3,
+ ("%u.%u.%u\n", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild),
+ VERR_INVALID_PARAMETER);
+
+ /* The version must fit in a full version compression. */
+ uint32_t uFullVersion = VBOX_FULL_VERSION_MAKE(pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild);
+ AssertMsgReturn( VBOX_FULL_VERSION_GET_MAJOR(uFullVersion) == pInfo2->additionsMajor
+ && VBOX_FULL_VERSION_GET_MINOR(uFullVersion) == pInfo2->additionsMinor
+ && VBOX_FULL_VERSION_GET_BUILD(uFullVersion) == pInfo2->additionsBuild,
+ ("%u.%u.%u\n", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild),
+ VERR_OUT_OF_RANGE);
+
+ /*
+ * Validate the name.
+ * Be less strict towards older additions (< v4.1.50).
+ */
+ AssertCompile(sizeof(pThis->guestInfo2.szName) == sizeof(pInfo2->szName));
+ AssertReturn(memchr(pInfo2->szName, '\0', sizeof(pInfo2->szName)) != NULL, VERR_INVALID_PARAMETER);
+ const char *pszName = pInfo2->szName;
+
+ /* The version number which shouldn't be there. */
+ char szTmp[sizeof(pInfo2->szName)];
+ size_t cchStart = RTStrPrintf(szTmp, sizeof(szTmp), "%u.%u.%u", pInfo2->additionsMajor, pInfo2->additionsMinor, pInfo2->additionsBuild);
+ AssertMsgReturn(!strncmp(pszName, szTmp, cchStart), ("%s != %s\n", pszName, szTmp), VERR_INVALID_PARAMETER);
+ pszName += cchStart;
+
+ /* Now we can either have nothing or a build tag or/and a publisher tag. */
+ if (*pszName != '\0')
+ {
+ const char *pszRelaxedName = "";
+ bool const fStrict = pInfo2->additionsMajor > 4
+ || (pInfo2->additionsMajor == 4 && pInfo2->additionsMinor > 1)
+ || (pInfo2->additionsMajor == 4 && pInfo2->additionsMinor == 1 && pInfo2->additionsBuild >= 50);
+ bool fOk = false;
+ if (*pszName == '_')
+ {
+ pszName++;
+ strcpy(szTmp, pszName);
+ char *pszTag2 = strchr(szTmp, '_');
+ if (!pszTag2)
+ {
+ fOk = vmmdevReqIsValidBuildTag(szTmp)
+ || vmmdevReqIsValidPublisherTag(szTmp);
+ }
+ else
+ {
+ *pszTag2++ = '\0';
+ fOk = vmmdevReqIsValidBuildTag(szTmp);
+ if (fOk)
+ {
+ fOk = vmmdevReqIsValidPublisherTag(pszTag2);
+ if (!fOk)
+ pszRelaxedName = szTmp;
+ }
+ }
+ }
+
+ if (!fOk)
+ {
+ AssertLogRelMsgReturn(!fStrict, ("%s", pszName), VERR_INVALID_PARAMETER);
+
+ /* non-strict mode, just zap the extra stuff. */
+ LogRel(("ReportGuestInfo2: Ignoring unparsable version name bits: '%s' -> '%s'.\n", pszName, pszRelaxedName));
+ pszName = pszRelaxedName;
+ }
+ }
+
+ /*
+ * Save the info and tell Main or whoever is listening.
+ */
+ pThis->guestInfo2.uFullVersion = uFullVersion;
+ pThis->guestInfo2.uRevision = pInfo2->additionsRevision;
+ pThis->guestInfo2.fFeatures = pInfo2->additionsFeatures;
+ strcpy(pThis->guestInfo2.szName, pszName);
+
+ if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestInfo2)
+ pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, uFullVersion, pszName, pInfo2->additionsRevision, pInfo2->additionsFeatures);
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Allocates a new facility status entry, initializing it to inactive.
+ *
+ * @returns Pointer to a facility status entry on success, NULL on failure
+ * (table full).
+ * @param pThis The VMMDev instance data.
+ * @param uFacility The facility type code - VBoxGuestFacilityType.
+ * @param fFixed This is set when allocating the standard entries
+ * from the constructor.
+ * @param pTimeSpecNow Optionally giving the entry timestamp to use (ctor).
+ */
+static PVMMDEVFACILITYSTATUSENTRY
+vmmdevAllocFacilityStatusEntry(VMMDevState *pThis, uint32_t uFacility, bool fFixed, PCRTTIMESPEC pTimeSpecNow)
+{
+ /* If full, expunge one inactive entry. */
+ if (pThis->cFacilityStatuses == RT_ELEMENTS(pThis->aFacilityStatuses))
+ {
+ uint32_t i = pThis->cFacilityStatuses;
+ while (i-- > 0)
+ {
+ if ( pThis->aFacilityStatuses[i].uStatus == VBoxGuestFacilityStatus_Inactive
+ && !pThis->aFacilityStatuses[i].fFixed)
+ {
+ pThis->cFacilityStatuses--;
+ int cToMove = pThis->cFacilityStatuses - i;
+ if (cToMove)
+ memmove(&pThis->aFacilityStatuses[i], &pThis->aFacilityStatuses[i + 1],
+ cToMove * sizeof(pThis->aFacilityStatuses[i]));
+ RT_ZERO(pThis->aFacilityStatuses[pThis->cFacilityStatuses]);
+ break;
+ }
+ }
+
+ if (pThis->cFacilityStatuses == RT_ELEMENTS(pThis->aFacilityStatuses))
+ return NULL;
+ }
+
+ /* Find location in array (it's sorted). */
+ uint32_t i = pThis->cFacilityStatuses;
+ while (i-- > 0)
+ if (pThis->aFacilityStatuses[i].uFacility < uFacility)
+ break;
+ i++;
+
+ /* Move. */
+ int cToMove = pThis->cFacilityStatuses - i;
+ if (cToMove > 0)
+ memmove(&pThis->aFacilityStatuses[i + 1], &pThis->aFacilityStatuses[i],
+ cToMove * sizeof(pThis->aFacilityStatuses[i]));
+ pThis->cFacilityStatuses++;
+
+ /* Initialize. */
+ pThis->aFacilityStatuses[i].uFacility = uFacility;
+ pThis->aFacilityStatuses[i].uStatus = VBoxGuestFacilityStatus_Inactive;
+ pThis->aFacilityStatuses[i].fFixed = fFixed;
+ pThis->aFacilityStatuses[i].fPadding = 0;
+ pThis->aFacilityStatuses[i].fFlags = 0;
+ pThis->aFacilityStatuses[i].uPadding = 0;
+ if (pTimeSpecNow)
+ pThis->aFacilityStatuses[i].TimeSpecTS = *pTimeSpecNow;
+ else
+ RTTimeSpecSetNano(&pThis->aFacilityStatuses[i].TimeSpecTS, 0);
+
+ return &pThis->aFacilityStatuses[i];
+
+}
+
+/**
+ * Gets a facility status entry, allocating a new one if not already present.
+ *
+ * @returns Pointer to a facility status entry on success, NULL on failure
+ * (table full).
+ * @param pThis The VMMDev instance data.
+ * @param uFacility The facility type code - VBoxGuestFacilityType.
+ */
+static PVMMDEVFACILITYSTATUSENTRY vmmdevGetFacilityStatusEntry(VMMDevState *pThis, uint32_t uFacility)
+{
+ /** @todo change to binary search. */
+ uint32_t i = pThis->cFacilityStatuses;
+ while (i-- > 0)
+ {
+ if (pThis->aFacilityStatuses[i].uFacility == uFacility)
+ return &pThis->aFacilityStatuses[i];
+ if (pThis->aFacilityStatuses[i].uFacility < uFacility)
+ break;
+ }
+ return vmmdevAllocFacilityStatusEntry(pThis, uFacility, false /*fFixed*/, NULL);
+}
+
+/**
+ * Handles VMMDevReq_ReportGuestStatus.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pThis The VMMDev instance data.
+ * @param pRequestHeader The header of the request to handle.
+ */
+static int vmmdevReqHandler_ReportGuestStatus(VMMDevState *pThis, VMMDevRequestHeader *pRequestHeader)
+{
+ /*
+ * Validate input.
+ */
+ AssertMsgReturn(pRequestHeader->size == sizeof(VMMDevReportGuestStatus), ("%u\n", pRequestHeader->size), VERR_INVALID_PARAMETER);
+ VBoxGuestStatus *pStatus = &((VMMDevReportGuestStatus *)pRequestHeader)->guestStatus;
+ AssertMsgReturn( pStatus->facility > VBoxGuestFacilityType_Unknown
+ && pStatus->facility <= VBoxGuestFacilityType_All,
+ ("%d\n", pStatus->facility),
+ VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pStatus->status == (VBoxGuestFacilityStatus)(uint16_t)pStatus->status,
+ ("%#x (%u)\n", pStatus->status, pStatus->status),
+ VERR_OUT_OF_RANGE);
+
+ /*
+ * Do the update.
+ */
+ RTTIMESPEC Now;
+ RTTimeNow(&Now);
+ if (pStatus->facility == VBoxGuestFacilityType_All)
+ {
+ uint32_t i = pThis->cFacilityStatuses;
+ while (i-- > 0)
+ {
+ pThis->aFacilityStatuses[i].TimeSpecTS = Now;
+ pThis->aFacilityStatuses[i].uStatus = (uint16_t)pStatus->status;
+ pThis->aFacilityStatuses[i].fFlags = pStatus->flags;
+ }
+ }
+ else
+ {
+ PVMMDEVFACILITYSTATUSENTRY pEntry = vmmdevGetFacilityStatusEntry(pThis, pStatus->facility);
+ if (!pEntry)
+ {
+ static int g_cLogEntries = 0;
+ if (g_cLogEntries++ < 10)
+ LogRel(("VMM: Facility table is full - facility=%u status=%u.\n", pStatus->facility, pStatus->status));
+ return VERR_OUT_OF_RESOURCES;
+ }
+
+ pEntry->TimeSpecTS = Now;
+ pEntry->uStatus = (uint16_t)pStatus->status;
+ pEntry->fFlags = pStatus->flags;
+ }
+
+ if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestStatus)
+ pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, pStatus->facility, pStatus->status, pStatus->flags, &Now);
+
+ return VINF_SUCCESS;
+}
+
+#ifdef VBOX_WITH_PAGE_SHARING
+
+/**
+ * Handles VMMDevReq_RegisterSharedModule.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pDevIns The VMMDev device instance.
+ * @param pReq Pointer to the request.
+ */
+static int vmmdevReqHandler_RegisterSharedModule(PPDMDEVINS pDevIns, VMMDevSharedModuleRegistrationRequest *pReq)
+{
+ /*
+ * Basic input validation (more done by GMM).
+ */
+ AssertMsgReturn(pReq->header.size >= sizeof(VMMDevSharedModuleRegistrationRequest),
+ ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
+ AssertMsgReturn(pReq->header.size == RT_UOFFSETOF(VMMDevSharedModuleRegistrationRequest, aRegions[pReq->cRegions]),
+ ("%u cRegions=%u\n", pReq->header.size, pReq->cRegions), VERR_INVALID_PARAMETER);
+
+ AssertReturn(memchr(pReq->szName, '\0', sizeof(pReq->szName)), VERR_INVALID_PARAMETER);
+ AssertReturn(memchr(pReq->szVersion, '\0', sizeof(pReq->szVersion)), VERR_INVALID_PARAMETER);
+
+ /*
+ * Forward the request to the VMM.
+ */
+ return PGMR3SharedModuleRegister(PDMDevHlpGetVM(pDevIns), pReq->enmGuestOS, pReq->szName, pReq->szVersion,
+ pReq->GCBaseAddr, pReq->cbModule, pReq->cRegions, pReq->aRegions);
+}
+
+/**
+ * Handles VMMDevReq_UnregisterSharedModule.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pDevIns The VMMDev device instance.
+ * @param pReq Pointer to the request.
+ */
+static int vmmdevReqHandler_UnregisterSharedModule(PPDMDEVINS pDevIns, VMMDevSharedModuleUnregistrationRequest *pReq)
+{
+ /*
+ * Basic input validation.
+ */
+ AssertMsgReturn(pReq->header.size == sizeof(VMMDevSharedModuleUnregistrationRequest),
+ ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
+
+ AssertReturn(memchr(pReq->szName, '\0', sizeof(pReq->szName)), VERR_INVALID_PARAMETER);
+ AssertReturn(memchr(pReq->szVersion, '\0', sizeof(pReq->szVersion)), VERR_INVALID_PARAMETER);
+
+ /*
+ * Forward the request to the VMM.
+ */
+ return PGMR3SharedModuleUnregister(PDMDevHlpGetVM(pDevIns), pReq->szName, pReq->szVersion,
+ pReq->GCBaseAddr, pReq->cbModule);
+}
+
+/**
+ * Handles VMMDevReq_CheckSharedModules.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pDevIns The VMMDev device instance.
+ * @param pReq Pointer to the request.
+ */
+static int vmmdevReqHandler_CheckSharedModules(PPDMDEVINS pDevIns, VMMDevSharedModuleCheckRequest *pReq)
+{
+ AssertMsgReturn(pReq->header.size == sizeof(VMMDevSharedModuleCheckRequest),
+ ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
+ return PGMR3SharedModuleCheckAll(PDMDevHlpGetVM(pDevIns));
+}
+
+/**
+ * Handles VMMDevReq_GetPageSharingStatus.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pThis The VMMDev instance data.
+ * @param pReq Pointer to the request.
+ */
+static int vmmdevReqHandler_GetPageSharingStatus(VMMDevState *pThis, VMMDevPageSharingStatusRequest *pReq)
+{
+ AssertMsgReturn(pReq->header.size == sizeof(VMMDevPageSharingStatusRequest),
+ ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
+
+ pReq->fEnabled = false;
+ int rc = pThis->pDrv->pfnIsPageFusionEnabled(pThis->pDrv, &pReq->fEnabled);
+ if (RT_FAILURE(rc))
+ pReq->fEnabled = false;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Handles VMMDevReq_DebugIsPageShared.
+ *
+ * @returns VBox status code that the guest should see.
+ * @param pDevIns The VMMDev device instance.
+ * @param pReq Pointer to the request.
+ */
+static int vmmdevReqHandler_DebugIsPageShared(PPDMDEVINS pDevIns, VMMDevPageIsSharedRequest *pReq)
+{
+ AssertMsgReturn(pReq->header.size == sizeof(VMMDevPageIsSharedRequest),
+ ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
+
+#ifdef DEBUG
+ return PGMR3SharedModuleGetPageState(PDMDevHlpGetVM(pDevIns), pReq->GCPtrPage, &pReq->fShared, &pReq->uPageFlags);
+#else
+ return VERR_NOT_IMPLEMENTED;
+#endif
+}
+
+#endif /* VBOX_WITH_PAGE_SHARING */
/**
* Port I/O Handler for the generic request interface
* @see FNIOMIOPORTOUT for details.
*
- * @todo Too long, suggest doing the request copying here and moving the
- * switch into a different function (or better case -> functions), and
- * looing the gotos.
+ * @todo This function is too long!! All new request SHALL be implemented as
+ * functions called from the switch! When making changes, please move the
+ * relevant cases into functions.
*/
static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
@@ -495,58 +902,35 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
*/
case VMMDevReq_ReportGuestInfo:
{
- if (pRequestHeader->size != sizeof(VMMDevReportGuestInfo))
- {
- AssertMsgFailed(("VMMDev guest information structure has an invalid size!\n"));
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- VBoxGuestInfo *guestInfo = &((VMMDevReportGuestInfo*)pRequestHeader)->guestInfo;
+ AssertMsgBreakStmt(pRequestHeader->size == sizeof(VMMDevReportGuestInfo), ("%u\n", pRequestHeader->size),
+ pRequestHeader->rc = VERR_INVALID_PARAMETER);
+ VBoxGuestInfo *pGuestInfo = &((VMMDevReportGuestInfo*)pRequestHeader)->guestInfo;
- if (memcmp (&pThis->guestInfo, guestInfo, sizeof(*guestInfo)) != 0)
- {
- /* make a copy of supplied information */
- pThis->guestInfo = *guestInfo;
+ if (memcmp(&pThis->guestInfo, pGuestInfo, sizeof(*pGuestInfo)) != 0)
+ {
+ /* make a copy of supplied information */
+ pThis->guestInfo = *pGuestInfo;
- /* Check additions version */
- pThis->fu32AdditionsOk = VBOX_GUEST_INTERFACE_VERSION_OK(pThis->guestInfo.interfaceVersion);
+ /* Check additions version */
+ pThis->fu32AdditionsOk = VBOX_GUEST_INTERFACE_VERSION_OK(pThis->guestInfo.interfaceVersion);
- LogRel(("Guest Additions information report: Interface = 0x%08X osType = 0x%08X\n",
- pThis->guestInfo.interfaceVersion,
- pThis->guestInfo.osType));
+ LogRel(("Guest Additions information report: Interface = 0x%08X osType = 0x%08X\n",
+ pThis->guestInfo.interfaceVersion,
+ pThis->guestInfo.osType));
+ if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestInfo)
pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
- }
-
- if (pThis->fu32AdditionsOk)
- {
- pRequestHeader->rc = VINF_SUCCESS;
- }
- else
- {
- pRequestHeader->rc = VERR_VERSION_MISMATCH;
- }
}
+
+ if (pThis->fu32AdditionsOk)
+ pRequestHeader->rc = VINF_SUCCESS;
+ else
+ pRequestHeader->rc = VERR_VERSION_MISMATCH;
break;
}
case VMMDevReq_ReportGuestInfo2:
{
- if (pRequestHeader->size != sizeof(VMMDevReportGuestInfo2))
- {
- AssertMsgFailed(("VMMDev guest information 2 structure has an invalid size!\n"));
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- VBoxGuestInfo2 *pGuestInfo2 = &((VMMDevReportGuestInfo2*)pRequestHeader)->guestInfo;
- AssertPtr(pGuestInfo2);
- LogRel(("Guest Additions information report: Version %d.%d.%d r%d '%.*s'\n",
- pGuestInfo2->additionsMajor, pGuestInfo2->additionsMinor, pGuestInfo2->additionsBuild,
- pGuestInfo2->additionsRevision, sizeof(pGuestInfo2->szName), pGuestInfo2->szName));
- pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, pGuestInfo2);
- pRequestHeader->rc = VINF_SUCCESS;
- }
+ pRequestHeader->rc = vmmdevReqHandler_ReportGuestInfo2(pThis, pRequestHeader);
break;
}
@@ -603,21 +987,8 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
}
case VMMDevReq_ReportGuestStatus:
- {
- if (pRequestHeader->size != sizeof(VMMDevReportGuestStatus))
- {
- AssertMsgFailed(("VMMDev guest status structure has an invalid size!\n"));
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- VBoxGuestStatus *guestStatus = &((VMMDevReportGuestStatus*)pRequestHeader)->guestStatus;
- pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, guestStatus);
-
- pRequestHeader->rc = VINF_SUCCESS;
- }
+ pRequestHeader->rc = vmmdevReqHandler_ReportGuestStatus(pThis, pRequestHeader);
break;
- }
/* Report guest capabilities */
case VMMDevReq_ReportGuestCapabilities:
@@ -649,7 +1020,8 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
guestCaps->caps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no",
guestCaps->caps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? "yes" : "no"));
- pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, guestCaps->caps);
+ if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
+ pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, guestCaps->caps);
}
pRequestHeader->rc = VINF_SUCCESS;
}
@@ -680,7 +1052,8 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
pThis->guestCaps & VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING ? "yes" : "no",
pThis->guestCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? "yes" : "no"));
- pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
+ if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
+ pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
pRequestHeader->rc = VINF_SUCCESS;
}
break;
@@ -1882,87 +2255,30 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser,
#ifdef VBOX_WITH_PAGE_SHARING
case VMMDevReq_RegisterSharedModule:
- {
- VMMDevSharedModuleRegistrationRequest *pReqModule = (VMMDevSharedModuleRegistrationRequest *)pRequestHeader;
-
- if ( pRequestHeader->size < sizeof(VMMDevSharedModuleRegistrationRequest)
- || pRequestHeader->size != RT_UOFFSETOF(VMMDevSharedModuleRegistrationRequest, aRegions[pReqModule->cRegions]))
- {
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- pRequestHeader->rc = PGMR3SharedModuleRegister(PDMDevHlpGetVM(pDevIns), pReqModule->enmGuestOS, pReqModule->szName, pReqModule->szVersion,
- pReqModule->GCBaseAddr, pReqModule->cbModule,
- pReqModule->cRegions, pReqModule->aRegions);
- }
+ pRequestHeader->rc = vmmdevReqHandler_RegisterSharedModule(pDevIns,
+ (VMMDevSharedModuleRegistrationRequest *)pRequestHeader);
break;
- }
case VMMDevReq_UnregisterSharedModule:
- {
- VMMDevSharedModuleUnregistrationRequest *pReqModule = (VMMDevSharedModuleUnregistrationRequest *)pRequestHeader;
-
- if (pRequestHeader->size != sizeof(VMMDevSharedModuleUnregistrationRequest))
- {
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- pRequestHeader->rc = PGMR3SharedModuleUnregister(PDMDevHlpGetVM(pDevIns), pReqModule->szName, pReqModule->szVersion,
- pReqModule->GCBaseAddr, pReqModule->cbModule);
- }
+ pRequestHeader->rc = vmmdevReqHandler_UnregisterSharedModule(pDevIns,
+ (VMMDevSharedModuleUnregistrationRequest *)pRequestHeader);
break;
- }
case VMMDevReq_CheckSharedModules:
- {
- VMMDevSharedModuleCheckRequest *pReqModule = (VMMDevSharedModuleCheckRequest *)pRequestHeader;
-
- if (pRequestHeader->size != sizeof(VMMDevSharedModuleCheckRequest))
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- else
- pRequestHeader->rc = PGMR3SharedModuleCheckAll(PDMDevHlpGetVM(pDevIns));
+ pRequestHeader->rc = vmmdevReqHandler_CheckSharedModules(pDevIns,
+ (VMMDevSharedModuleCheckRequest *)pRequestHeader);
break;
- }
case VMMDevReq_GetPageSharingStatus:
- {
- VMMDevPageSharingStatusRequest *pReqStatus = (VMMDevPageSharingStatusRequest *)pRequestHeader;
-
- if (pRequestHeader->size != sizeof(VMMDevPageSharingStatusRequest))
- {
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- pReqStatus->fEnabled = false;
- pThis->pDrv->pfnIsPageFusionEnabled(pThis->pDrv, &pReqStatus->fEnabled);
- pRequestHeader->rc = VINF_SUCCESS;
- }
+ pRequestHeader->rc = vmmdevReqHandler_GetPageSharingStatus(pThis,
+ (VMMDevPageSharingStatusRequest *)pRequestHeader);
break;
- }
case VMMDevReq_DebugIsPageShared:
- {
-# ifdef DEBUG
- VMMDevPageIsSharedRequest *pReq = (VMMDevPageIsSharedRequest *)pRequestHeader;
-
- if (pRequestHeader->size != sizeof(VMMDevPageIsSharedRequest))
- {
- pRequestHeader->rc = VERR_INVALID_PARAMETER;
- }
- else
- {
- pRequestHeader->rc = PGMR3SharedModuleGetPageState(PDMDevHlpGetVM(pDevIns), pReq->GCPtrPage, &pReq->fShared, &pReq->uPageFlags);
- }
-# else
- pRequestHeader->rc = VERR_NOT_IMPLEMENTED;
-# endif
+ pRequestHeader->rc = vmmdevReqHandler_DebugIsPageShared(pDevIns, (VMMDevPageIsSharedRequest *)pRequestHeader);
break;
- }
-#endif
+#endif /* VBOX_WITH_PAGE_SHARING */
#ifdef DEBUG
case VMMDevReq_LogString:
@@ -2561,7 +2877,7 @@ static DECLCALLBACK(int) vmmdevSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
/* The following is not strictly necessary as PGM restores MMIO2, keeping it for historical reasons. */
SSMR3PutMem(pSSM, &pThis->pVMMDevRAMR3->V, sizeof(pThis->pVMMDevRAMR3->V));
- SSMR3PutMem(pSSM, &pThis->guestInfo, sizeof (pThis->guestInfo));
+ SSMR3PutMem(pSSM, &pThis->guestInfo, sizeof(pThis->guestInfo));
SSMR3PutU32(pSSM, pThis->fu32AdditionsOk);
SSMR3PutU32(pSSM, pThis->u32VideoAccelEnabled);
SSMR3PutBool(pSSM, pThis->displayChangeData.fGuestSentChangeEventAck);
@@ -2574,6 +2890,19 @@ static DECLCALLBACK(int) vmmdevSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
SSMR3PutU32(pSSM, pThis->fHostCursorRequested);
+ SSMR3PutU32(pSSM, pThis->guestInfo2.uFullVersion);
+ SSMR3PutU32(pSSM, pThis->guestInfo2.uRevision);
+ SSMR3PutU32(pSSM, pThis->guestInfo2.fFeatures);
+ SSMR3PutStrZ(pSSM, pThis->guestInfo2.szName);
+ SSMR3PutU32(pSSM, pThis->cFacilityStatuses);
+ for (uint32_t i = 0; i < pThis->cFacilityStatuses; i++)
+ {
+ SSMR3PutU32(pSSM, pThis->aFacilityStatuses[i].uFacility);
+ SSMR3PutU32(pSSM, pThis->aFacilityStatuses[i].fFlags);
+ SSMR3PutU16(pSSM, pThis->aFacilityStatuses[i].uStatus);
+ SSMR3PutS64(pSSM, RTTimeSpecGetNano(&pThis->aFacilityStatuses[i].TimeSpecTS));
+ }
+
return VINF_SUCCESS;
}
@@ -2657,6 +2986,44 @@ static DECLCALLBACK(int) vmmdevLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uin
rc = SSMR3GetU32(pSSM, &pThis->fHostCursorRequested);
AssertRCReturn(rc, rc);
+ if (uVersion > VMMDEV_SAVED_STATE_VERSION_MISSING_GUEST_INFO_2)
+ {
+ SSMR3GetU32(pSSM, &pThis->guestInfo2.uFullVersion);
+ SSMR3GetU32(pSSM, &pThis->guestInfo2.uRevision);
+ SSMR3GetU32(pSSM, &pThis->guestInfo2.fFeatures);
+ rc = SSMR3GetStrZ(pSSM, &pThis->guestInfo2.szName[0], sizeof(pThis->guestInfo2.szName));
+ AssertRCReturn(rc, rc);
+ }
+
+ if (uVersion > VMMDEV_SAVED_STATE_VERSION_MISSING_FACILITY_STATUSES)
+ {
+ uint32_t cFacilityStatuses;
+ rc = SSMR3GetU32(pSSM, &cFacilityStatuses);
+ AssertRCReturn(rc, rc);
+
+ for (uint32_t i = 0; i < cFacilityStatuses; i++)
+ {
+ uint32_t uFacility, fFlags;
+ uint16_t uStatus;
+ int64_t iTimeStampNano;
+
+ SSMR3GetU32(pSSM, &uFacility);
+ SSMR3GetU32(pSSM, &fFlags);
+ SSMR3GetU16(pSSM, &uStatus);
+ rc = SSMR3GetS64(pSSM, &iTimeStampNano);
+ AssertRCReturn(rc, rc);
+
+ PVMMDEVFACILITYSTATUSENTRY pEntry = vmmdevGetFacilityStatusEntry(pThis, uFacility);
+ AssertLogRelMsgReturn(pEntry,
+ ("VMMDev: Ran out of entries restoring the guest facility statuses. Saved state has %u.\n", cFacilityStatuses),
+ VERR_OUT_OF_RESOURCES);
+ pEntry->uStatus = uStatus;
+ pEntry->fFlags = fFlags;
+ RTTimeSpecSetNano(&pEntry->TimeSpecTS, iTimeStampNano);
+ }
+ }
+
+
/*
* On a resume, we send the capabilities changed message so
* that listeners can sync their state again
@@ -2678,7 +3045,7 @@ static DECLCALLBACK(int) vmmdevLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uin
if ( pThis->u32VideoAccelEnabled
&& pThis->pDrv)
{
- pThis->pDrv->pfnVideoAccelEnable (pThis->pDrv, !!pThis->u32VideoAccelEnabled, &pThis->pVMMDevRAMR3->vbvaMemory);
+ pThis->pDrv->pfnVideoAccelEnable(pThis->pDrv, !!pThis->u32VideoAccelEnabled, &pThis->pVMMDevRAMR3->vbvaMemory);
}
if (pThis->fu32AdditionsOk)
@@ -2687,10 +3054,27 @@ static DECLCALLBACK(int) vmmdevLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uin
pThis->guestInfo.interfaceVersion,
pThis->guestInfo.osType));
if (pThis->pDrv)
- pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
-/** @todo Missing pfnUpdateGuestInfo2 */
+ {
+ if (pThis->guestInfo2.uFullVersion && pThis->pDrv->pfnUpdateGuestInfo2)
+ pThis->pDrv->pfnUpdateGuestInfo2(pThis->pDrv, pThis->guestInfo2.uFullVersion, pThis->guestInfo2.szName,
+ pThis->guestInfo2.uRevision, pThis->guestInfo2.fFeatures);
+ if (pThis->pDrv->pfnUpdateGuestInfo)
+ pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
+
+ if (pThis->pDrv->pfnUpdateGuestStatus)
+ {
+ for (uint32_t i = 0; i < pThis->cFacilityStatuses; i++) /* ascending order! */
+ if ( pThis->aFacilityStatuses[i].uStatus != VBoxGuestFacilityStatus_Inactive
+ || !pThis->aFacilityStatuses[i].fFixed)
+ pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv,
+ pThis->aFacilityStatuses[i].uFacility,
+ pThis->aFacilityStatuses[i].uStatus,
+ pThis->aFacilityStatuses[i].fFlags,
+ &pThis->aFacilityStatuses[i].TimeSpecTS);
+ }
+ }
}
- if (pThis->pDrv)
+ if (pThis->pDrv && pThis->pDrv->pfnUpdateGuestCapabilities)
pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
return VINF_SUCCESS;
@@ -2779,6 +3163,18 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
pThis->fu32AdditionsOk, pThis->guestInfo.interfaceVersion, pThis->guestInfo.osType));
pThis->fu32AdditionsOk = false;
memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo));
+ RT_ZERO(pThis->guestInfo2);
+
+ /* Clear facilities. No need to tell Main as it will get a
+ pfnUpdateGuestInfo callback. */
+ RTTIMESPEC TimeStampNow;
+ RTTimeNow(&TimeStampNow);
+ uint32_t iFacility = pThis->cFacilityStatuses;
+ while (iFacility-- > 0)
+ {
+ pThis->aFacilityStatuses[iFacility].uStatus = VBoxGuestFacilityStatus_Inactive;
+ pThis->aFacilityStatuses[iFacility].TimeSpecTS = TimeStampNow;
+ }
/* clear pending display change request. */
for (unsigned i = 0; i < RT_ELEMENTS(pThis->displayChangeData.aRequests); i++)
@@ -2824,9 +3220,9 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
/*
* Call the update functions as required.
*/
- if (fVersionChanged)
+ if (fVersionChanged && pThis->pDrv && pThis->pDrv->pfnUpdateGuestInfo)
pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo);
- if (fCapsChanged)
+ 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.
@@ -2898,6 +3294,15 @@ static DECLCALLBACK(int) vmmdevConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG
/* interrupt on pin 0 */
PCIDevSetInterruptPin(&pThis->dev, 0x01);
+ RTTIMESPEC TimeStampNow;
+ RTTimeNow(&TimeStampNow);
+ vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxGuestDriver, true /*fFixed*/, &TimeStampNow);
+ vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxService, true /*fFixed*/, &TimeStampNow);
+ vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_VBoxTrayClient, true /*fFixed*/, &TimeStampNow);
+ vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_Seamless, true /*fFixed*/, &TimeStampNow);
+ vmmdevAllocFacilityStatusEntry(pThis, VBoxGuestFacilityType_Graphics, true /*fFixed*/, &TimeStampNow);
+ Assert(pThis->cFacilityStatuses == 5);
+
/*
* Interfaces
*/
diff --git a/src/VBox/Devices/VMMDev/VMMDevState.h b/src/VBox/Devices/VMMDev/VMMDevState.h
index 41f3d7cee..c62995563 100644
--- a/src/VBox/Devices/VMMDev/VMMDevState.h
+++ b/src/VBox/Devices/VMMDev/VMMDevState.h
@@ -80,6 +80,30 @@ typedef struct VMMDEVCREDS
} VMMDEVCREDS;
+/**
+ * Facility status entry.
+ */
+typedef struct VMMDEVFACILITYSTATUSENTRY
+{
+ /** The facility, see VBoxGuestFacilityType. */
+ uint32_t uFacility;
+ /** The status, see VBoxGuestFacilityStatus. */
+ uint16_t uStatus;
+ /** Whether this entry is fixed and cannot be reused when inactive. */
+ bool fFixed;
+ /** Explicit alignment padding / reserved for future use. MBZ. */
+ bool fPadding;
+ /** The facility flags (yet to be defined). */
+ uint32_t fFlags;
+ /** Explicit alignment padding / reserved for future use. MBZ. */
+ uint32_t uPadding;
+ /** Last update timestamp. */
+ RTTIMESPEC TimeSpecTS;
+} VMMDEVFACILITYSTATUSENTRY;
+/** Pointer to a facility status entry. */
+typedef VMMDEVFACILITYSTATUSENTRY *PVMMDEVFACILITYSTATUSENTRY;
+
+
/** device structure containing all state information */
typedef struct VMMDevState
{
@@ -163,6 +187,19 @@ typedef struct VMMDevState
* Until this information is reported the VMMDev refuses any other requests.
*/
VBoxGuestInfo guestInfo;
+ /** Information report \#2, chewed a litte. */
+ struct
+ {
+ uint32_t uFullVersion; /**< non-zero if info is present. */
+ uint32_t uRevision;
+ uint32_t fFeatures;
+ char szName[128];
+ } guestInfo2;
+
+ /** Array of guest facility statuses. */
+ VMMDEVFACILITYSTATUSENTRY aFacilityStatuses[32];
+ /** The number of valid entries in the facility status array. */
+ uint32_t cFacilityStatuses;
/** Information reported by guest via VMMDevReportGuestCapabilities. */
uint32_t guestCaps;
@@ -310,6 +347,7 @@ typedef struct VMMDevState
AssertCompileMemberAlignment(VMMDevState, CritSect, 8);
AssertCompileMemberAlignment(VMMDevState, cbGuestRAM, 8);
AssertCompileMemberAlignment(VMMDevState, enmCpuHotPlugEvent, 4);
+AssertCompileMemberAlignment(VMMDevState, aFacilityStatuses, 8);
#ifndef VBOX_WITHOUT_TESTING_FEATURES
AssertCompileMemberAlignment(VMMDevState, TestingData.Value.u64Value, 8);
#endif
diff --git a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h
index 5457a35f2..72ad33562 100644
--- a/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h
+++ b/src/VBox/Frontends/Common/VBoxKeyboard/keyboard-tables.h
@@ -68,8 +68,17 @@ static const struct {
{NULL, NULL} /* sentinel */
};
-/* Scan code table for non-character keys */
+/** @note On the whole we use Microsoft's "USB HID to PS/2 Scan Code
+ * Translation Table" and
+ * http://www.win.tue.nl/~aeb/linux/kbd/scancodes-6.html
+ * as a reference for scan code numbers.
+ * Sun keyboards have eleven additional keys on the left-hand side.
+ * These keys never had PC scan codes assigned to them. We map all X11
+ * keycodes which can correspond to these keys to the PC scan codes for
+ * F13 to F23 (as per Microsoft's translation table) and the USB keyboard
+ * code translates them back to the correct usage codes. */
+/* Scan code table for non-character keys */
static const unsigned nonchar_key_scan[256] =
{
/* unused */
@@ -96,14 +105,12 @@ static const unsigned nonchar_key_scan[256] =
0x147, 0x14B, 0x148, 0x14D, 0x150, 0x149, 0x151, 0x14F, /* FF50 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF58 */
/* misc keys */
- /* Menu */
-#ifdef sun
- /*?*/ 0, 0x137, 0x7b, 0x152, 0x00, 0x00, 0x00, 0x15D, /* FF60 */
-#else
- /*?*/ 0, 0x137, 0, 0x152, 0x00, 0x00, 0x00, 0x15D, /* FF60 */
-#endif /* sun */
- /* Help */
- 0x00, 0x00, 0x13B, 0x146, 0x00, 0x00, 0x00, 0x00, /* FF68 */
+ /* Print Open Insert Undo Again Menu */
+ /* ->F17 ->F14 ->F22 */
+ 0x00, 0x137, 0x68, 0x152, 0x00, 0x65, 0x6d, 0x15D, /* FF60 */
+ /* Find Stop Help Break */
+ /* ->F19 ->F21 ->F23 */
+ 0x6a, 0x6c, 0x6e, 0x146, 0x00, 0x00, 0x00, 0x00, /* FF68 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF70 */
/* keypad keys */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x138, 0x45, /* FF78 */
@@ -119,17 +126,15 @@ static const unsigned nonchar_key_scan[256] =
0x3B, 0x3C,
0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, /* FFC0 */
#ifdef sun
- /* On Solaris, F11 to F20 are actually keys on the left function block.
- * Since just one of them has a set 1 PS/2 scan code, we arbitrarily assign
- * the rest scan codes which are extended versions of F2 to F10. With
- * the emulated PS/2 keyboard this will not help anyone, but with the
- * emulated USB one we can translate them to the proper USB scan codes. */
- 0x13C, 0x13D, 0x72, 0x13E, 0x13F, 0x140, 0x141, 0x142, /* FFC8 */
- 0x143, 0x144, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD0 */
+ /* Stop Again F13 F14 F15 F16 F17 F18 */
+ /* ->F21 ->F22 */
+ 0x6c, 0x6d, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* FFC8 */
#else
- 0x57, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFC8 */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD0 */
+ /* F11 F12 */
+ 0x57, 0x58, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* FFC8 */
#endif
+ /* F19 F20 F21 F22 F23 F24 */
+ 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x76, 0x00, 0x00, /* FFD0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD8 */
/* modifier keys */
0x00, 0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0x00, 0x15B, /* FFE0 */
@@ -139,7 +144,7 @@ static const unsigned nonchar_key_scan[256] =
};
/* This list was put together using /usr/include/X11/XF86keysym.h and
- http://www.win.tue.nl/~aeb/linux/kbd/scancodes-6.html. It has not yet
+ the documents referenced above for scan code numbers. It has not yet
been extensively tested. The scancodes are those used by MicroSoft
keyboards. */
static const unsigned xfree86_vendor_key_scan[256] =
@@ -160,13 +165,16 @@ static const unsigned xfree86_vendor_key_scan[256] =
0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF40 */
0, 0, 0, 0, 0, 0, 0, 0, /* 1008FF48 */
/* AppL AppR Calc Close Copy */
- 0x109, 0x11e, 0, 0, 0x121, 0, 0x140, 0x118, /* 1008FF50 */
- /* Cut Docmnts Excel */
- 0x117, 0, 0, 0x105, 0x114, 0, 0, 0, /* 1008FF58 */
+ /* ->F16 */
+ 0x109, 0x11e, 0, 0, 0x121, 0, 0x140, 0x67, /* 1008FF50 */
+ /* Cut Docmnts Excel */
+ /* ->F20 */
+ 0x6b, 0, 0, 0x105, 0x114, 0, 0, 0, /* 1008FF58 */
/* LogOff */
0, 0x116, 0, 0, 0, 0, 0, 0, /* 1008FF60 */
- /* OffcHm Open Paste */
- 0, 0, 0x13c, 0x13f, 0, 0x10a, 0, 0, /* 1008FF68 */
+ /* OffcHm Open Paste */
+ /* ->F17 ->F18 */
+ 0, 0, 0x13c, 0x68, 0, 0x69, 0, 0, /* 1008FF68 */
/* Reply Refresh Save */
0, 0, 0x141, 0x167, 0, 0, 0, 0x157, /* 1008FF70 */
/* ScrlUp ScrlDn Send Spell TaskPane */
@@ -193,8 +201,7 @@ static const unsigned xfree86_vendor_key_scan[256] =
/* This list was put together using /usr/include/X11/Sunkeysym.h and
comparing the scancodes produced by a Sun type 7 USB keyboard. Note that
- Sun call F11 and F12 F36 and F37 respectively, as they already had 35
- function keys when those two physical keys were added. */
+ Sun call F11 and F12 F36 and F37 respectively. */
static const unsigned sun_key_scan[256] =
{
/* FAGrav, FACirc, FATild, FAAcut, FADiae, FACed */
@@ -214,8 +221,9 @@ static const unsigned sun_key_scan[256] =
/* SysReq */
0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF60 */
0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF68 */
- /* Props Front Copy Paste Cut Power Vol- Mute */
- 0x106, 0x10c, 0x178, 0x65, 0x13c, 0x15e, 0x12e, 0x120, /* 1005FF70 */
+ /* Props Front Copy Paste Cut Power Vol- Mute */
+ /* ->F13 ->F15 ->F16 ->F18 ->F20 */
+ 0x64, 0x66, 0x67, 0x69, 0x6b, 0x15e, 0x12e, 0x120, /* 1005FF70 */
/* Vol+ */
0x130, 0, 0, 0, 0, 0, 0, 0, /* 1005FF78 */
0, 0, 0, 0, 0, 0, 0, 0, /* 1005FF80 */
diff --git a/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp b/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
index 42eab9381..7613b3198 100644
--- a/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
+++ b/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
@@ -1261,7 +1261,7 @@ const PDMDRVREG Display::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_DISPLAY,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINDISPLAY),
/* pfnConstruct */
diff --git a/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp b/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp
index 9c40b20e4..62f6333e4 100644
--- a/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp
+++ b/src/VBox/Frontends/VBoxBFE/KeyboardImpl.cpp
@@ -271,7 +271,7 @@ const PDMDRVREG Keyboard::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_KEYBOARD,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINKEYBOARD),
/* pfnConstruct */
diff --git a/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp b/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp
index c4906487a..c4bc449c5 100644
--- a/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp
+++ b/src/VBox/Frontends/VBoxBFE/StatusImpl.cpp
@@ -205,7 +205,7 @@ const PDMDRVREG VMStatus::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_STATUS,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINSTATUS),
/* pfnConstruct */
diff --git a/src/VBox/Frontends/VBoxBFE/VMMDev.h b/src/VBox/Frontends/VBoxBFE/VMMDev.h
index 5be26a50a..c414139bc 100644
--- a/src/VBox/Frontends/VBoxBFE/VMMDev.h
+++ b/src/VBox/Frontends/VBoxBFE/VMMDev.h
@@ -43,9 +43,6 @@ public:
int hgcmHostCall (const char *pszServiceName, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms);
private:
- static DECLCALLBACK(void) UpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus);
- static DECLCALLBACK(void) UpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo *guestInfo);
- static DECLCALLBACK(void) UpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities);
static DECLCALLBACK(void) UpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities);
static DECLCALLBACK(void) UpdatePointerShape(PPDMIVMMDEVCONNECTOR pInterface, bool fVisible, bool fAlpha,
uint32_t xHot, uint32_t yHot,
diff --git a/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp b/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
index 425909501..74a10c06d 100644
--- a/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
+++ b/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
@@ -102,47 +102,6 @@ PPDMIVMMDEVPORT VMMDev::getVMMDevPort()
return mpDrv->pUpPort;
}
-
-/**
- * Reports Guest Additions status.
- * Called whenever the Additions issue a guest status report request or the VM is reset.
- *
- * @param pInterface Pointer to this interface.
- * @param guestInfo Pointer to guest information structure
- * @thread The emulation thread.
- */
-DECLCALLBACK(void) VMMDev::UpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus)
-{
- return;
-}
-
-/**
- * Report guest information.
- * Called whenever the Additions issue a guest version report request.
- *
- * @param pInterface Pointer to this interface.
- * @param guestInfo Pointer to guest information structure
- * @thread The emulation thread.
- */
-DECLCALLBACK(void) VMMDev::UpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo *guestInfo)
-{
- return;
-}
-
-/**
- * Update the guest additions capabilities.
- * This is called when the guest additions capabilities change. The new capabilities
- * are given and the connector should update its internal state.
- *
- * @param pInterface Pointer to this interface.
- * @param newCapabilities New capabilities.
- * @thread The emulation thread.
- */
-DECLCALLBACK(void) VMMDev::UpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
-{
- return;
-}
-
/**
* Update the mouse capabilities.
* This is called when the mouse capabilities change. The new capabilities
@@ -389,9 +348,9 @@ DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint3
*/
pDrvIns->IBase.pfnQueryInterface = VMMDev::drvQueryInterface;
- pData->Connector.pfnUpdateGuestStatus = VMMDev::UpdateGuestStatus;
- pData->Connector.pfnUpdateGuestInfo = VMMDev::UpdateGuestInfo;
- pData->Connector.pfnUpdateGuestCapabilities = VMMDev::UpdateGuestCapabilities;
+ //pData->Connector.pfnUpdateGuestStatus = VMMDev::UpdateGuestStatus;
+ //pData->Connector.pfnUpdateGuestInfo = VMMDev::UpdateGuestInfo;
+ //pData->Connector.pfnUpdateGuestCapabilities = VMMDev::UpdateGuestCapabilities;
pData->Connector.pfnUpdateMouseCapabilities = VMMDev::UpdateMouseCapabilities;
pData->Connector.pfnUpdatePointerShape = VMMDev::UpdatePointerShape;
pData->Connector.pfnVideoAccelEnable = iface_VideoAccelEnable;
@@ -484,7 +443,7 @@ const PDMDRVREG VMMDev::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_VMMDEV,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINVMMDEV),
/* pfnConstruct */
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
index b07c81b43..e45f2ae1c 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
@@ -81,33 +81,60 @@ typedef struct COPYCONTEXT
/**
* An entry for a source element, including an optional DOS-like wildcard (*,?).
*/
-typedef struct SOURCEFILEENTRY
+class SOURCEFILEENTRY
{
- SOURCEFILEENTRY(const char *pszSource, const char *pszFilter)
- : mSource(pszSource),
- mFilter(pszFilter) {}
- SOURCEFILEENTRY(const char *pszSource)
- : mSource(pszSource)
- {
- if ( !RTFileExists(pszSource)
- && !RTDirExists(pszSource))
+ public:
+
+ SOURCEFILEENTRY(const char *pszSource, const char *pszFilter)
+ : mSource(pszSource),
+ mFilter(pszFilter) {}
+
+ SOURCEFILEENTRY(const char *pszSource)
+ : mSource(pszSource)
+ {
+ Parse(pszSource);
+ }
+
+ const char* GetSource() const
+ {
+ return mSource.c_str();
+ }
+
+ const char* GetFilter() const
{
- /* No file and no directory -- maybe a filter? */
- char *pszFilename = RTPathFilename(pszSource);
- if ( pszFilename
- && strpbrk(pszFilename, "*?"))
+ return mFilter.c_str();
+ }
+
+ private:
+
+ int Parse(const char *pszPath)
+ {
+ AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
+
+ if ( !RTFileExists(pszPath)
+ && !RTDirExists(pszPath))
{
- /* Yep, get the actual filter part. */
- mFilter = RTPathFilename(pszSource);
- /* Remove the filter from actual sourcec directory name. */
- RTPathStripFilename(mSource.mutableRaw());
- mSource.jolt();
+ /* No file and no directory -- maybe a filter? */
+ char *pszFilename = RTPathFilename(pszPath);
+ if ( pszFilename
+ && strpbrk(pszFilename, "*?"))
+ {
+ /* Yep, get the actual filter part. */
+ mFilter = RTPathFilename(pszPath);
+ /* Remove the filter from actual sourcec directory name. */
+ RTPathStripFilename(mSource.mutableRaw());
+ mSource.jolt();
+ }
}
+
+ return VINF_SUCCESS; /* @todo */
}
- }
- Utf8Str mSource;
- Utf8Str mFilter;
-} SOURCEFILEENTRY, *PSOURCEFILEENTRY;
+
+ private:
+
+ Utf8Str mSource;
+ Utf8Str mFilter;
+};
typedef std::vector<SOURCEFILEENTRY> SOURCEVEC, *PSOURCEVEC;
/**
@@ -197,6 +224,8 @@ enum OUTPUTTYPE
OUTPUTTYPE_UNIX2DOS = 20
};
+static int ctrlCopyDirExists(PCOPYCONTEXT pContext, bool bGuest, const char *pszDir, bool *fExists);
+
#endif /* VBOX_ONLY_DOCS */
void usageGuestControl(PRTSTREAM pStrm)
@@ -452,8 +481,112 @@ static int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest>
return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
}
+/**
+ * Prints the desired guest output to a stream.
+ *
+ * @return IPRT status code.
+ * @param pGuest Pointer to IGuest interface.
+ * @param uPID PID of guest process to get the output from.
+ * @param fOutputFlags Output flags of type ProcessOutputFlag.
+ * @param cMsTimeout Timeout value (in ms) to wait for output.
+ */
+static int ctrlExecPrintOutput(IGuest *pGuest, ULONG uPID,
+ PRTSTREAM pStrmOutput, uint32_t fOutputFlags,
+ uint32_t cMsTimeout)
+{
+ AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
+ AssertReturn(uPID, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(pStrmOutput, VERR_INVALID_POINTER);
+
+ SafeArray<BYTE> aOutputData;
+ ULONG cbOutputData = 0;
+
+ int vrc = VINF_SUCCESS;
+ HRESULT rc = pGuest->GetProcessOutput(uPID, fOutputFlags,
+ cMsTimeout,
+ _64K, ComSafeArrayAsOutParam(aOutputData));
+ if (FAILED(rc))
+ {
+ vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ cbOutputData = 0;
+ }
+ else
+ {
+ cbOutputData = aOutputData.size();
+ if (cbOutputData > 0)
+ {
+ BYTE *pBuf = aOutputData.raw();
+ AssertPtr(pBuf);
+ pBuf[cbOutputData - 1] = 0; /* Properly terminate buffer. */
+
+ /** @todo r=bird: Use a VFS I/O stream filter for doing this, it's a
+ * generic problem and the new VFS APIs will handle it more
+ * transparently. (requires writing dos2unix/unix2dos filters ofc) */
+
+ /*
+ * If aOutputData is text data from the guest process' stdout or stderr,
+ * it has a platform dependent line ending. So standardize on
+ * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
+ * Windows. Otherwise we end up with CR/CR/LF on Windows.
+ */
+
+ char *pszBufUTF8;
+ vrc = RTStrCurrentCPToUtf8(&pszBufUTF8, (const char*)aOutputData.raw());
+ if (RT_SUCCESS(vrc))
+ {
+ cbOutputData = strlen(pszBufUTF8);
+
+ ULONG cbOutputDataPrint = cbOutputData;
+ for (char *s = pszBufUTF8, *d = s;
+ s - pszBufUTF8 < (ssize_t)cbOutputData;
+ s++, d++)
+ {
+ if (*s == '\r')
+ {
+ /* skip over CR, adjust destination */
+ d--;
+ cbOutputDataPrint--;
+ }
+ else if (s != d)
+ *d = *s;
+ }
+
+ vrc = RTStrmWrite(pStrmOutput, pszBufUTF8, cbOutputDataPrint);
+ if (RT_FAILURE(vrc))
+ RTMsgError("Unable to write output, rc=%Rrc\n", vrc);
+
+ RTStrFree(pszBufUTF8);
+ }
+ else
+ RTMsgError("Unable to convert output, rc=%Rrc\n", vrc);
+ }
+ }
+
+ return vrc;
+}
+
+/**
+ * Returns the remaining time (in ms) based on the start time and a set
+ * timeout value. Returns RT_INDEFINITE_WAIT if no timeout was specified.
+ *
+ * @return RTMSINTERVAL Time left (in ms).
+ * @param u64StartMs Start time (in ms).
+ * @param u32TimeoutMs Timeout value (in ms).
+ */
+inline RTMSINTERVAL ctrlExecGetRemainingTime(uint64_t u64StartMs, uint32_t u32TimeoutMs)
+{
+ if (!u32TimeoutMs) /* If no timeout specified, wait forever. */
+ return RT_INDEFINITE_WAIT;
+
+ uint64_t u64ElapsedMs = RTTimeMilliTS() - u64StartMs;
+ if (u64ElapsedMs >= u32TimeoutMs)
+ return 0;
+
+ return u32TimeoutMs - u64ElapsedMs;
+}
+
/* <Missing docuemntation> */
-static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
+static int handleCtrlExecProgram(ComPtr<IGuest> pGuest, HandlerArg *pArg)
{
AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
@@ -487,8 +620,7 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
RTGetOptInit(&GetState, pArg->argc, pArg->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
Utf8Str Utf8Cmd;
- uint32_t fExecFlags = ExecuteProcessFlag_None;
- uint32_t fOutputFlags = ProcessOutputFlag_None;
+ uint32_t fExecFlags = ExecuteProcessFlag_None;
com::SafeArray<IN_BSTR> args;
com::SafeArray<IN_BSTR> env;
Utf8Str Utf8UserName;
@@ -497,7 +629,6 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
OUTPUTTYPE eOutputType = OUTPUTTYPE_UNDEFINED;
bool fOutputBinary = false;
bool fWaitForExit = false;
- bool fWaitForStdOut = false;
bool fVerbose = false;
int vrc = VINF_SUCCESS;
@@ -569,12 +700,13 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
break;
case GETOPTDEF_EXEC_WAITFORSTDOUT:
+ fExecFlags |= ExecuteProcessFlag_WaitForStdOut;
fWaitForExit = true;
- fWaitForStdOut = true;
break;
case GETOPTDEF_EXEC_WAITFORSTDERR:
- fWaitForExit = (fOutputFlags |= ProcessOutputFlag_StdErr) ? true : false;
+ fExecFlags |= ExecuteProcessFlag_WaitForStdErr;
+ fWaitForExit = true;
break;
case VINF_GETOPT_NOT_OPTION:
@@ -620,7 +752,7 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
int rcProc = RTEXITCODE_FAILURE;
ComPtr<IProgress> progress;
ULONG uPID = 0;
- rc = guest->ExecuteProcess(Bstr(Utf8Cmd).raw(),
+ rc = pGuest->ExecuteProcess(Bstr(Utf8Cmd).raw(),
fExecFlags,
ComSafeArrayAsInParam(args),
ComSafeArrayAsInParam(env),
@@ -630,7 +762,7 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
&uPID,
progress.asOutParam());
if (FAILED(rc))
- return ctrlPrintError(guest, COM_IIDOF(IGuest));
+ return ctrlPrintError(pGuest, COM_IIDOF(IGuest));
if (fVerbose)
RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID);
@@ -662,91 +794,33 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
if (fCancelable)
ctrlSignalHandlerInstall();
+ PRTSTREAM pStream = g_pStdOut; /* StdOut by default. */
+ AssertPtr(pStream);
+
/* Wait for process to exit ... */
BOOL fCompleted = FALSE;
BOOL fCanceled = FALSE;
- while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
+ while ( SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))
+ && !fCompleted)
{
- SafeArray<BYTE> aOutputData;
- ULONG cbOutputData = 0;
-
- /*
- * Some data left to output?
- */
- if (fOutputFlags || fWaitForStdOut)
+ /* Do we need to output stuff? */
+ uint32_t cMsTimeLeft;
+ if (fExecFlags & ExecuteProcessFlag_WaitForStdOut)
{
- /** @todo r=bird: The timeout argument is bogus in several
- * ways:
- * 1. RT_MAX will evaluate the arguments twice, which may
- * result in different values because RTTimeMilliTS()
- * returns a higher value the 2nd time. Worst case:
- * Imagine when RT_MAX calculates the remaining time
- * out (first expansion) there is say 60 ms left. Then
- * we're preempted and rescheduled after, say, 120 ms.
- * We call RTTimeMilliTS() again and ends up with a
- * value -60 ms, which translate to a UINT32_MAX - 59
- * ms timeout.
- *
- * 2. When the period expires, we will wait forever since
- * both 0 and -1 mean indefinite timeout with this API,
- * at least that's one way of reading the main code.
- *
- * 3. There is a signed/unsigned ambiguity in the
- * RT_MAX expression. The left hand side is signed
- * integer (0), the right side is unsigned 64-bit. From
- * what I can tell, the compiler will treat this as
- * unsigned 64-bit and never return 0.
- */
- rc = guest->GetProcessOutput(uPID, fOutputFlags,
- RT_MAX(0, cMsTimeout - (RTTimeMilliTS() - u64StartMS)) /* Timeout in ms */,
- _64K, ComSafeArrayAsOutParam(aOutputData));
- if (FAILED(rc))
- {
- vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
- cbOutputData = 0;
- }
- else
- {
- cbOutputData = aOutputData.size();
- if (cbOutputData > 0)
- {
- /** @todo r=bird: Use a VFS I/O stream filter for doing this, it's a
- * generic problem and the new VFS APIs will handle it more
- * transparently. (requires writing dos2unix/unix2dos filters ofc) */
-
- /*
- * If aOutputData is text data from the guest process' stdout or stderr,
- * it has a platform dependent line ending. So standardize on
- * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on
- * Windows. Otherwise we end up with CR/CR/LF on Windows.
- */
- ULONG cbOutputDataPrint = cbOutputData;
- for (BYTE *s = aOutputData.raw(), *d = s;
- s - aOutputData.raw() < (ssize_t)cbOutputData;
- s++, d++)
- {
- if (*s == '\r')
- {
- /* skip over CR, adjust destination */
- d--;
- cbOutputDataPrint--;
- }
- else if (s != d)
- *d = *s;
- }
- RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint);
- }
- }
+ cMsTimeLeft = ctrlExecGetRemainingTime(u64StartMS, cMsTimeout);
+ if (cMsTimeLeft)
+ vrc = ctrlExecPrintOutput(pGuest, uPID,
+ pStream, ProcessOutputFlag_None /* StdOut */,
+ cMsTimeLeft == RT_INDEFINITE_WAIT ? 0 : cMsTimeLeft);
}
- /* No more output data left? */
- if (cbOutputData <= 0)
+ if (fExecFlags & ExecuteProcessFlag_WaitForStdErr)
{
- /* Only break out from process handling loop if we processed (displayed)
- * all output data or if there simply never was output data and the process
- * has been marked as complete. */
- if (fCompleted)
- break;
+ cMsTimeLeft = ctrlExecGetRemainingTime(u64StartMS, cMsTimeout);
+ if (cMsTimeLeft)
+ vrc = ctrlExecPrintOutput(pGuest, uPID,
+ pStream, ProcessOutputFlag_StdErr /* StdErr */,
+ cMsTimeLeft == RT_INDEFINITE_WAIT ? 0 : cMsTimeLeft);
}
/* Process async cancelation */
@@ -795,10 +869,18 @@ static int handleCtrlExecProgram(ComPtr<IGuest> guest, HandlerArg *pArg)
{
ExecuteProcessStatus_T retStatus;
ULONG uRetExitCode, uRetFlags;
- rc = guest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
- if (SUCCEEDED(rc) && fVerbose)
- RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, retStatus, ctrlExecProcessStatusToText(retStatus), uRetFlags);
- rcProc = ctrlExecProcessStatusToExitCode(retStatus, uRetExitCode);
+ rc = pGuest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
+ if (SUCCEEDED(rc))
+ {
+ if (fVerbose)
+ RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, retStatus, ctrlExecProcessStatusToText(retStatus), uRetFlags);
+ rcProc = ctrlExecProcessStatusToExitCode(retStatus, uRetExitCode);
+ }
+ else
+ {
+ ctrlPrintError(pGuest, COM_IIDOF(IGuest));
+ rcProc = RTEXITCODE_FAILURE;
+ }
}
}
else
@@ -912,16 +994,47 @@ static int ctrlCopyTranslatePath(const char *pszSourceRoot, const char *pszSourc
char szTranslated[RTPATH_MAX];
size_t srcOff = strlen(pszSourceRoot);
AssertReturn(srcOff, VERR_INVALID_PARAMETER);
- int rc = RTPathJoin(szTranslated, sizeof(szTranslated),
- pszDest, &pszSource[srcOff]);
+
+ char *pszDestPath = RTStrDup(pszDest);
+ AssertPtrReturn(pszDestPath, VERR_NO_MEMORY);
+
+ int rc;
+ if (!RTPathFilename(pszDestPath))
+ {
+ rc = RTPathJoin(szTranslated, sizeof(szTranslated),
+ pszDestPath, &pszSource[srcOff]);
+ }
+ else
+ {
+ char *pszDestFileName = RTStrDup(RTPathFilename(pszDestPath));
+ if (pszDestFileName)
+ {
+ RTPathStripFilename(pszDestPath);
+ rc = RTPathJoin(szTranslated, sizeof(szTranslated),
+ pszDestPath, pszDestFileName);
+ RTStrFree(pszDestFileName);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ RTStrFree(pszDestPath);
+
if (RT_SUCCESS(rc))
+ {
*ppszTranslated = RTStrDup(szTranslated);
+#if 0
+ RTPrintf("Root: %s, Source: %s, Dest: %s, Translated: %s\n",
+ pszSourceRoot, pszSource, pszDest, *ppszTranslated);
+#endif
+ }
return rc;
}
#ifdef DEBUG_andy
static int tstTranslatePath()
{
+ RTAssertSetMayPanic(false /* Do not freak out, please. */);
+
static struct
{
const char *pszSourceRoot;
@@ -933,15 +1046,20 @@ static int tstTranslatePath()
{
/* Invalid stuff. */
{ NULL, NULL, NULL, NULL, VERR_INVALID_POINTER },
+#ifdef RT_OS_WINDOWS
/* Windows paths. */
{ "c:\\foo", "c:\\foo\\bar.txt", "c:\\test", "c:\\test\\bar.txt", VINF_SUCCESS },
- { "c:\\foo", "c:\\foo\\baz\\bar.txt", "c:\\test", "c:\\test\\baz\\bar.txt", VINF_SUCCESS }
- /* UNIX-like paths. */
+ { "c:\\foo", "c:\\foo\\baz\\bar.txt", "c:\\test", "c:\\test\\baz\\bar.txt", VINF_SUCCESS },
+#else /* RT_OS_WINDOWS */
+ { "/home/test/foo", "/home/test/foo/bar.txt", "/opt/test", "/opt/test/bar.txt", VINF_SUCCESS },
+ { "/home/test/foo", "/home/test/foo/baz/bar.txt", "/opt/test", "/opt/test/baz/bar.txt", VINF_SUCCESS },
+#endif /* !RT_OS_WINDOWS */
/* Mixed paths*/
/** @todo */
+ { NULL }
};
- int iTest = 0;
+ size_t iTest = 0;
for (iTest; iTest < RT_ELEMENTS(aTests); iTest++)
{
RTPrintf("=> Test %d\n", iTest);
@@ -987,24 +1105,33 @@ static int ctrlCopyDirCreate(PCOPYCONTEXT pContext, const char *pszDir)
AssertPtrReturn(pContext, VERR_INVALID_POINTER);
AssertPtrReturn(pszDir, VERR_INVALID_POINTER);
+ bool fDirExists;
+ int rc = ctrlCopyDirExists(pContext, pContext->fHostToGuest, pszDir, &fDirExists);
+ if ( RT_SUCCESS(rc)
+ && fDirExists)
+ {
+ if (pContext->fVerbose)
+ RTPrintf("Directory \"%s\" already exists\n", pszDir);
+ return VINF_SUCCESS;
+ }
+
if (pContext->fVerbose)
RTPrintf("Creating directory \"%s\" ...\n", pszDir);
if (pContext->fDryRun)
return VINF_SUCCESS;
- int rc = VINF_SUCCESS;
if (pContext->fHostToGuest) /* We want to create directories on the guest. */
{
HRESULT hrc = pContext->pGuest->DirectoryCreate(Bstr(pszDir).raw(),
Bstr(pContext->pszUsername).raw(), Bstr(pContext->pszPassword).raw(),
- 700, DirectoryCreateFlag_Parents);
+ 0700, DirectoryCreateFlag_Parents);
if (FAILED(hrc))
rc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
}
else /* ... or on the host. */
{
- rc = RTDirCreateFullPath(pszDir, 700);
+ rc = RTDirCreateFullPath(pszDir, 0700);
if (rc == VERR_ALREADY_EXISTS)
rc = VINF_SUCCESS;
}
@@ -1177,26 +1304,28 @@ static int ctrlCopyFileToDest(PCOPYCONTEXT pContext, const char *pszFileSource,
int vrc = VINF_SUCCESS;
ComPtr<IProgress> progress;
- HRESULT hr;
+ HRESULT rc;
if (pContext->fHostToGuest)
{
- hr = pContext->pGuest->CopyToGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
+ rc = pContext->pGuest->CopyToGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
Bstr(pContext->pszUsername).raw(), Bstr(pContext->pszPassword).raw(),
fFlags, progress.asOutParam());
}
else
{
- hr = pContext->pGuest->CopyFromGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
+ rc = pContext->pGuest->CopyFromGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(),
Bstr(pContext->pszUsername).raw(), Bstr(pContext->pszPassword).raw(),
fFlags, progress.asOutParam());
}
- if (FAILED(hr))
+ if (FAILED(rc))
vrc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
else
{
- hr = showProgress(progress);
- if (FAILED(hr))
+ rc = pContext->fVerbose
+ ? showProgress(progress)
+ : progress->WaitForCompletion(-1 /* No timeout */);
+ if (FAILED(rc))
vrc = ctrlPrintProgressError(progress);
}
@@ -1235,7 +1364,7 @@ static int ctrlCopyDirToGuest(PCOPYCONTEXT pContext,
rc = RTPathAppend(szCurDir, sizeof(szCurDir), pszSubDir);
if (pContext->fVerbose)
- RTPrintf("Processing directory: %s\n", szCurDir);
+ RTPrintf("Processing host directory: %s\n", szCurDir);
/* Flag indicating whether the current directory was created on the
* target or not. */
@@ -1404,7 +1533,7 @@ static int ctrlCopyDirToHost(PCOPYCONTEXT pContext,
return rc;
if (pContext->fVerbose)
- RTPrintf("Processing directory: %s\n", szCurDir);
+ RTPrintf("Processing guest directory: %s\n", szCurDir);
/* Flag indicating whether the current directory was created on the
* target or not. */
@@ -1432,6 +1561,8 @@ static int ctrlCopyDirToHost(PCOPYCONTEXT pContext,
{
case GuestDirEntryType_Directory:
{
+ Assert(!strName.isEmpty());
+
/* Skip "." and ".." entries. */
if ( !strName.compare(Bstr("."))
|| !strName.compare(Bstr("..")))
@@ -1478,6 +1609,8 @@ static int ctrlCopyDirToHost(PCOPYCONTEXT pContext,
case GuestDirEntryType_File:
{
+ Assert(!strName.isEmpty());
+
Utf8Str strFile(strName);
if ( pszFilter
&& !RTStrSimplePatternMatch(pszFilter, strFile.c_str()))
@@ -1525,6 +1658,8 @@ static int ctrlCopyDirToHost(PCOPYCONTEXT pContext,
}
default:
+ RTPrintf("Warning: Directory entry of type %ld not handled, skipping ...\n",
+ enmType);
break;
}
@@ -1532,10 +1667,25 @@ static int ctrlCopyDirToHost(PCOPYCONTEXT pContext,
break;
}
- if (FAILED(hr))
+ if (RT_UNLIKELY(FAILED(hr)))
{
- if (hr != E_ABORT)
- rc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
+ switch (hr)
+ {
+ case E_ABORT: /* No more directory entries left to process. */
+ break;
+
+ case VBOX_E_FILE_ERROR: /* Current entry cannot be accessed to
+ to missing rights. */
+ {
+ RTPrintf("Warning: Cannot access \"%s\", skipping ...\n",
+ szCurDir);
+ break;
+ }
+
+ default:
+ rc = ctrlPrintError(pContext->pGuest, COM_IIDOF(IGuest));
+ break;
+ }
}
HRESULT hr2 = pContext->pGuest->DirectoryClose(uDirHandle);
@@ -1710,8 +1860,8 @@ static int handleCtrlCopyTo(ComPtr<IGuest> guest, HandlerArg *pArg,
case VINF_GETOPT_NOT_OPTION:
{
/* Last argument and no destination specified with
- * --target-directory yet? Then use the current argument
- * as destination. */
+ * --target-directory yet? Then use the current
+ * (= last) argument as destination. */
if ( pArg->argc == GetState.iNext
&& Utf8Dest.isEmpty())
{
@@ -1769,14 +1919,21 @@ static int handleCtrlCopyTo(ComPtr<IGuest> guest, HandlerArg *pArg,
/* If the destination is a path, (try to) create it. */
const char *pszDest = Utf8Dest.c_str();
- AssertPtr(pszDest);
- size_t lenDest = strlen(pszDest);
- if ( lenDest
- ||pszDest[lenDest - 1] == '/'
- || pszDest[lenDest - 1] == '\\')
+ if (!RTPathFilename(pszDest))
{
vrc = ctrlCopyDirCreate(pContext, pszDest);
}
+ else
+ {
+ /* We assume we got a file name as destination -- so strip
+ * the actual file name and make sure the appropriate
+ * directories get created. */
+ char *pszDestDir = RTStrDup(pszDest);
+ AssertPtr(pszDestDir);
+ RTPathStripFilename(pszDestDir);
+ vrc = ctrlCopyDirCreate(pContext, pszDestDir);
+ RTStrFree(pszDestDir);
+ }
if (RT_SUCCESS(vrc))
{
@@ -1786,9 +1943,9 @@ static int handleCtrlCopyTo(ComPtr<IGuest> guest, HandlerArg *pArg,
*/
for (unsigned long s = 0; s < vecSources.size(); s++)
{
- char *pszSource = RTStrDup(vecSources[s].mSource.c_str());
+ char *pszSource = RTStrDup(vecSources[s].GetSource());
AssertPtrBreakStmt(pszSource, vrc = VERR_NO_MEMORY);
- const char *pszFilter = vecSources[s].mFilter.c_str();
+ const char *pszFilter = vecSources[s].GetFilter();
if (!strlen(pszFilter))
pszFilter = NULL; /* If empty filter then there's no filter :-) */
@@ -1804,51 +1961,39 @@ static int handleCtrlCopyTo(ComPtr<IGuest> guest, HandlerArg *pArg,
RTPrintf("Source: %s\n", pszSource);
/** @todo Files with filter?? */
- bool fIsFile = false;
- bool fExists;
+ bool fSourceIsFile = false;
+ bool fSourceExists;
size_t cchSource = strlen(pszSource);
if ( cchSource > 1
&& RTPATH_IS_SLASH(pszSource[cchSource - 1]))
{
-#ifndef DEBUG_andy
- if (pContext->fHostToGuest)
- {
-#endif
- if (pszFilter) /* Directory with filter (so use source root w/o the actual filter). */
- vrc = ctrlCopyDirExistsOnSource(pContext, pszSourceRoot, &fExists);
- else /* Regular directory without filter. */
- vrc = ctrlCopyDirExistsOnSource(pContext, pszSource, &fExists);
+ if (pszFilter) /* Directory with filter (so use source root w/o the actual filter). */
+ vrc = ctrlCopyDirExistsOnSource(pContext, pszSourceRoot, &fSourceExists);
+ else /* Regular directory without filter. */
+ vrc = ctrlCopyDirExistsOnSource(pContext, pszSource, &fSourceExists);
- if (fExists)
- {
- /* Strip trailing slash from our source element so that other functions
- * can use this stuff properly (like RTPathStartsWith). */
- RTPathStripTrailingSlash(pszSource);
- }
-#ifndef DEBUG_andy
- }
- else
+ if (fSourceExists)
{
- RTMsgError("Copying of guest directories to the host is not supported yet!\n");
- vrc = VERR_NOT_IMPLEMENTED;
+ /* Strip trailing slash from our source element so that other functions
+ * can use this stuff properly (like RTPathStartsWith). */
+ RTPathStripTrailingSlash(pszSource);
}
-#endif
}
else
{
- vrc = ctrlCopyFileExistsOnSource(pContext, pszSource, &fExists);
+ vrc = ctrlCopyFileExistsOnSource(pContext, pszSource, &fSourceExists);
if ( RT_SUCCESS(vrc)
- && fExists)
+ && fSourceExists)
{
- fIsFile = true;
+ fSourceIsFile = true;
}
}
if ( RT_SUCCESS(vrc)
- && fExists)
+ && fSourceExists)
{
- if (fIsFile)
+ if (fSourceIsFile)
{
/* Single file. */
char *pszDestFile;
@@ -1875,7 +2020,7 @@ static int handleCtrlCopyTo(ComPtr<IGuest> guest, HandlerArg *pArg,
ctrlCopyFreeSourceRoot(pszSourceRoot);
if ( RT_SUCCESS(vrc)
- && !fExists)
+ && !fSourceExists)
{
RTMsgError("Warning: Source \"%s\" does not exist, skipping!\n",
pszSource);
@@ -2225,7 +2370,9 @@ static int handleCtrlUpdateAdditions(ComPtr<IGuest> guest, HandlerArg *pArg)
vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
else
{
- rc = showProgress(progress);
+ rc = fVerbose
+ ? showProgress(progress)
+ : progress->WaitForCompletion(-1 /* No timeout */);
if (FAILED(rc))
vrc = ctrlPrintProgressError(progress);
else if ( SUCCEEDED(rc)
@@ -2249,7 +2396,7 @@ int handleGuestControl(HandlerArg *pArg)
{
AssertPtrReturn(pArg, VERR_INVALID_PARAMETER);
-#ifdef DEBUG_andy
+#ifdef DEBUG_andy_disabled
if (RT_FAILURE(tstTranslatePath()))
return RTEXITCODE_FAILURE;
#endif
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
index 69249f451..dc2715b5f 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMetrics.cpp
@@ -288,6 +288,9 @@ static int handleMetricsSetup(int argc, char *argv[],
SetupMetrics(ComSafeArrayAsInParam(metrics),
ComSafeArrayAsInParam(objects), period, samples,
ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(rc))
+ return 2;
+
if (listMatches)
listAffectedMetrics(aVirtualBox,
ComSafeArrayAsInParam(affectedMetrics));
@@ -460,6 +463,9 @@ static int handleMetricsCollect(int argc, char *argv[],
SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
ComSafeArrayAsInParam(objects), period, samples,
ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(rc))
+ return 2;
+
if (listMatches)
listAffectedMetrics(aVirtualBox,
ComSafeArrayAsInParam(affectedMetrics));
@@ -566,6 +572,9 @@ static int handleMetricsEnable(int argc, char *argv[],
EnableMetrics(ComSafeArrayAsInParam(metrics),
ComSafeArrayAsInParam(objects),
ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(rc))
+ return 2;
+
if (listMatches)
listAffectedMetrics(aVirtualBox,
ComSafeArrayAsInParam(affectedMetrics));
@@ -608,6 +617,9 @@ static int handleMetricsDisable(int argc, char *argv[],
DisableMetrics(ComSafeArrayAsInParam(metrics),
ComSafeArrayAsInParam(objects),
ComSafeArrayAsOutParam(affectedMetrics)));
+ if (FAILED(rc))
+ return 2;
+
if (listMatches)
listAffectedMetrics(aVirtualBox,
ComSafeArrayAsInParam(affectedMetrics));
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
index 8278debb7..709f460ba 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
@@ -1019,7 +1019,7 @@ int handleSharedFolder(HandlerArg *a)
}
}
else
- return errorSyntax(USAGE_SETPROPERTY, "Invalid parameter '%s'", Utf8Str(a->argv[0]).c_str());
+ return errorSyntax(USAGE_SHAREDFOLDER, "Invalid parameter '%s'", Utf8Str(a->argv[0]).c_str());
return 0;
}
diff --git a/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp b/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
index c8a29e7e2..f3f856f49 100644
--- a/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
+++ b/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
@@ -1183,9 +1183,9 @@ void VBoxSDLFB::paintSecureLabel(int x, int y, int w, int h, bool fForce)
&& !mSecureLabelText.isEmpty()
)
{
- SDL_Color clrFg = {(mSecureLabelColorFG & 0x00FF0000) >> 16,
- (mSecureLabelColorFG & 0x0000FF00) >> 8,
- mSecureLabelColorFG & 0x000000FF, 0};
+ SDL_Color clrFg = {(uint8_t)((mSecureLabelColorFG & 0x00FF0000) >> 16),
+ (uint8_t)((mSecureLabelColorFG & 0x0000FF00) >> 8),
+ (uint8_t)( mSecureLabelColorFG & 0x000000FF ), 0};
SDL_Surface *sText = (pTTF_RenderUTF8_Blended != NULL)
? pTTF_RenderUTF8_Blended(mLabelFont, mSecureLabelText.c_str(), clrFg)
: pTTF_RenderUTF8_Solid(mLabelFont, mSecureLabelText.c_str(), clrFg);
diff --git a/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp b/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
index 454c65ef3..0568df856 100644
--- a/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
+++ b/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
@@ -816,7 +816,7 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
char *hdaFile = NULL;
char *cdromFile = NULL;
char *fdaFile = NULL;
- const char *portVRDP = NULL;
+ const char *pszPortVRDP = NULL;
bool fDiscardState = false;
#ifdef VBOX_SECURELABEL
BOOL fSecureLabel = false;
@@ -1161,14 +1161,14 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
|| !strcmp(argv[curArg], "-vrdp"))
{
// start with the standard VRDP port
- portVRDP = "0";
+ pszPortVRDP = "0";
// is there another argument
if (argc > (curArg + 1))
{
curArg++;
- portVRDP = argv[curArg];
- LogFlow(("Using non standard VRDP port %s\n", portVRDP));
+ pszPortVRDP = argv[curArg];
+ LogFlow(("Using non standard VRDP port %s\n", pszPortVRDP));
}
}
else if ( !strcmp(argv[curArg], "--discardstate")
@@ -1910,16 +1910,16 @@ DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp)
pConsoleListener->getWrapped()->ignorePowerOffEvents(true);
}
- if (portVRDP)
+ if (pszPortVRDP)
{
rc = gpMachine->COMGETTER(VRDEServer)(gpVRDEServer.asOutParam());
AssertMsg((rc == S_OK) && gpVRDEServer, ("Could not get VRDP Server! rc = 0x%x\n", rc));
if (gpVRDEServer)
{
// has a non standard VRDP port been requested?
- if (portVRDP > 0)
+ if (strcmp(pszPortVRDP, "0"))
{
- rc = gpVRDEServer->SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr(portVRDP).raw());
+ rc = gpVRDEServer->SetVRDEProperty(Bstr("TCP/Ports").raw(), Bstr(pszPortVRDP).raw());
if (rc != S_OK)
{
RTPrintf("Error: could not set VRDP port! rc = 0x%x\n", rc);
diff --git a/src/VBox/Frontends/VBoxShell/vboxshell.py b/src/VBox/Frontends/VBoxShell/vboxshell.py
index e3d10dfa6..324758ea6 100755
--- a/src/VBox/Frontends/VBoxShell/vboxshell.py
+++ b/src/VBox/Frontends/VBoxShell/vboxshell.py
@@ -294,7 +294,11 @@ def asFlag(var):
else:
return 'no'
-def perfStats(ctx,mach):
+def getFacilityStatus(ctx, guest, facilityType):
+ (status, ts) = guest.getFacilityStatus(facilityType)
+ return asEnumElem(ctx, 'AdditionsFacilityStatus', status)
+
+def perfStats(ctx, mach):
if not ctx['perf']:
return
for metric in ctx['perf'].query(["*"], [mach]):
@@ -628,12 +632,11 @@ def printSf(ctx,sf):
def ginfo(ctx,console, args):
guest = console.guest
- if guest.additionsActive:
- vers = int(str(guest.additionsVersion))
- print "Additions active, version %d.%d" %(vers >> 16, vers & 0xffff)
- print "Support seamless: %s" %(asFlag(guest.supportsSeamless))
- print "Support graphics: %s" %(asFlag(guest.supportsGraphics))
- print "Baloon size: %d" %(guest.memoryBalloonSize)
+ if guest.additionsRunLevel != ctx['const'].AdditionsRunLevelType_None:
+ print "Additions active, version %s" %(guest.additionsVersion)
+ print "Support seamless: %s" %(getFacilityStatus(ctx, guest, ctx['const'].AdditionsFacilityType_Seamless))
+ print "Support graphics: %s" %(getFacilityStatus(ctx, guest, ctx['const'].AdditionsFacilityType_Graphics))
+ print "Balloon size: %d" %(guest.memoryBalloonSize)
print "Statistic update interval: %d" %(guest.statisticsUpdateInterval)
else:
print "No additions"
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts
index d698a3ffd..69457fa8d 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ar.ts
@@ -58,10 +58,6 @@
<context>
<name>QApplication</name>
<message>
- <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Please try completely uninstalling and reinstalling VirtualBox.</source>
<translation type="unfinished"></translation>
</message>
@@ -113,6 +109,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -4635,6 +4635,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts
index 791a63c26..4f0bf2c3f 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_bg.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Драйверът за Linux Ñдрото на VirtualBox (vboxdrv) не е зареден или има проблем Ñ Ð¿Ñ€Ð°Ð²Ð°Ñ‚Ð° на /dev/vboxdrv. ПренаÑтройте модула на Ñдрото като изпълните&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;Ñ root права. Потребителите Ñ Ubuntu, Fedora или Mandriva трÑбва първо да инÑталират пакета DKMS. Този пакет Ñледи за промени в Linux Ñдрото и прекомпилира модула vboxdrv, ако е необходимо.</translation>
+ <translation type="obsolete">Драйверът за Linux Ñдрото на VirtualBox (vboxdrv) не е зареден или има проблем Ñ Ð¿Ñ€Ð°Ð²Ð°Ñ‚Ð° на /dev/vboxdrv. ПренаÑтройте модула на Ñдрото като изпълните&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;Ñ root права. Потребителите Ñ Ubuntu, Fedora или Mandriva трÑбва първо да инÑталират пакета DKMS. Този пакет Ñледи за промени в Linux Ñдрото и прекомпилира модула vboxdrv, ако е необходимо.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Тази грешка означава, че драйверът на Ñдрото не може да задели доÑтатъчно памет или че нÑÐºÐ¾Ñ Ð°Ð´Ñ€ÐµÑираща Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ðµ неуÑпешна.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5777,6 +5781,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;ÐеуÑпех при изтеглÑнето на &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; от &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts
index 220131bb3..c890c1f42 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts
@@ -93,7 +93,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>El controlador del nucli del VirtualBox (vboxdrv) no s&apos;ha carregat o existeix un problema de permisos amb /dev/vboxdrv. Torneu a configurar el mòdul del nucli executant com a root a una terminal &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Usuaris d&apos;Ubuntu, Fedora o Mandriva haurien d&apos;instal·lar abans el paquet DKMS. Aquest paquet manté actiu el mòdul quan hi ha canvis al nucli i el recompila si és necessari.</translation>
+ <translation type="obsolete">El controlador del nucli del VirtualBox (vboxdrv) no s&apos;ha carregat o existeix un problema de permisos amb /dev/vboxdrv. Torneu a configurar el mòdul del nucli executant com a root a una terminal &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Usuaris d&apos;Ubuntu, Fedora o Mandriva haurien d&apos;instal·lar abans el paquet DKMS. Aquest paquet manté actiu el mòdul quan hi ha canvis al nucli i el recompila si és necessari.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -147,6 +147,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Aquest error pot ser degut al fet que el nucli no ha pogut assignar memòria suficient o bé que alguna operació de mapatge ha fallat.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6230,6 +6234,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts
index 8c45f04c6..7d4e5e1dc 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca_VA.ts
@@ -93,7 +93,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>El controlador del nucli del VirtualBox (vboxdrv) no s&apos;ha carregat o existeix un problema de permisos amb /dev/vboxdrv. Torneu a configurar el mòdul del nucli executant com a root a una terminal &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Usuaris d&apos;Ubuntu, Fedora o Mandriva haurien d&apos;instal·lar abans el paquet DKMS. Este paquet manté actiu el mòdul quan hi ha canvis al nucli i el recompila si és necessari.</translation>
+ <translation type="obsolete">El controlador del nucli del VirtualBox (vboxdrv) no s&apos;ha carregat o existeix un problema de permisos amb /dev/vboxdrv. Torneu a configurar el mòdul del nucli executant com a root a una terminal &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Usuaris d&apos;Ubuntu, Fedora o Mandriva haurien d&apos;instal·lar abans el paquet DKMS. Este paquet manté actiu el mòdul quan hi ha canvis al nucli i el recompila si és necessari.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -147,6 +147,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Este error pot ser degut al fet que el nucli no ha pogut assignar memòria suficient o bé que alguna operació de mapatge ha fallat.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6230,6 +6234,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts
index 269d89d6c..eb9ee9439 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_cs.ts
@@ -93,7 +93,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>OvladaÄ jádra pro VirtualBox (vboxdrv) není buÄ zaveden, nebo je problém s přístupem na zařízení /dev/vboxdrv. SpusÅ¥te znovu modul jádra zadáním příkazu &lt;br/&gt;&lt;br/&gt; &lt;font color=&quot;blue&quot;&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; jako uživatel root. Uživatelé distribucí Ubuntu, Fedora nebo Mandriva by mÄ›li nainstalovat balíÄek DKMS. Ten udržuje vÅ¡echny zmÄ›ny v jádÅ™e Linuxu a pokud je potÅ™eba provede rekompilaci modulu vboxdrv.</translation>
+ <translation type="obsolete">OvladaÄ jádra pro VirtualBox (vboxdrv) není buÄ zaveden, nebo je problém s přístupem na zařízení /dev/vboxdrv. SpusÅ¥te znovu modul jádra zadáním příkazu &lt;br/&gt;&lt;br/&gt; &lt;font color=&quot;blue&quot;&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; jako uživatel root. Uživatelé distribucí Ubuntu, Fedora nebo Mandriva by mÄ›li nainstalovat balíÄek DKMS. Ten udržuje vÅ¡echny zmÄ›ny v jádÅ™e Linuxu a pokud je potÅ™eba provede rekompilaci modulu vboxdrv.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -147,6 +147,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Tato chyba znamená, že ovladaÄ jádra nebyl schopen alokovat dostatek pamÄ›ti nebo selhala operace mapování.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -1080,7 +1084,7 @@
<message>
<source>Execution Cap</source>
<comment>details report</comment>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Omezení procesoru</translation>
</message>
<message>
<source>&lt;nobr&gt;%1%&lt;/nobr&gt;</source>
@@ -6058,6 +6062,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Stažení souboru &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; z &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt; selhalo.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts
index 9cd78c50a..89ffef3c7 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_da.ts
@@ -75,7 +75,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>VirtualBox&apos; Linux kernemodul (vboxdrv) er enten ikke indlæst eller der er et problem med rettighederne på /dev/vboxdrv. Geninstaller kernemodulet ved at køre&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;som root. Brugere af Ubuntu, Fedora eller Mandriva bør installere DKMS pakken først. Denne pakke holder styr på Linux kerneændringer og rekompilerer vboxdrv kernemodulet om nødvendigt.</translation>
+ <translation type="obsolete">VirtualBox&apos; Linux kernemodul (vboxdrv) er enten ikke indlæst eller der er et problem med rettighederne på /dev/vboxdrv. Geninstaller kernemodulet ved at køre&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;som root. Brugere af Ubuntu, Fedora eller Mandriva bør installere DKMS pakken først. Denne pakke holder styr på Linux kerneændringer og rekompilerer vboxdrv kernemodulet om nødvendigt.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -109,6 +109,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Denne fejl skyldes enten at kernemodulet ikke kunne allokere hukommelse nok eller at en adresseoversættelse fejlede.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5615,6 +5619,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Kunne ikke hente &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; fra &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts
index b402f9092..8c38d3b23 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_de.ts
@@ -2122,6 +2122,10 @@
<source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source>
<translation>haben Sie 2D-Video-Beschleunigung aktiviert. Diese Funktion wird momentan nur für Windows-Gäste unterstützt und wird daher deaktiviert.</translation>
</message>
+ <message>
+ <source>you enabled 3D acceleration. However, 3D acceleration is not working on the current host setup so you will not be able to start the VM.</source>
+ <translation>haben Sie die 3D-Unterstützung aktiviert. Allderings funktioniert die 3D-Hardwarebeschleunigung nicht auf dem Host, und daher die VM kann nicht gestartet werden.</translation>
+ </message>
</context>
<context>
<name>UIMachineSettingsGeneral</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts
index 8efb15899..026c29b05 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_el.ts
@@ -32,10 +32,6 @@
<context>
<name>QApplication</name>
<message>
- <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Make sure the kernel module has been loaded successfully.</source>
<translation type="unfinished"></translation>
</message>
@@ -87,6 +83,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -4407,6 +4407,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetUserManual</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_en.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_en.ts
index 9809cbef5..659495d16 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_en.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_en.ts
@@ -4,7 +4,7 @@
<context>
<name>UIMessageCenter</name>
<message numerus="yes">
- <location filename="../src/globals/UIMessageCenter.cpp" line="2279"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2345"/>
<source>&lt;p&gt;The virtual machine(s) &lt;b&gt;%1&lt;/b&gt; are currently in a saved state.&lt;/p&gt;&lt;p&gt;If you continue the runtime state of the exported machine(s) will be discarded. Note that the existing machine(s) are not changed.&lt;/p&gt;</source>
<translation>
<numerusform>&lt;p&gt;The virtual machine &lt;b&gt;%1&lt;/b&gt; is currently in a saved state.&lt;/p&gt;&lt;p&gt;If you continue the runtime state of the exported machine will be discarded. Note that the existing machine is not changed.&lt;/p&gt;</numerusform>
@@ -15,7 +15,7 @@
<context>
<name>VBoxGlobal</name>
<message numerus="yes">
- <location filename="../src/globals/VBoxGlobal.h" line="219"/>
+ <location filename="../src/globals/VBoxGlobal.h" line="222"/>
<source>%n year(s)</source>
<translation>
<numerusform>%n year</numerusform>
@@ -23,7 +23,7 @@
</translation>
</message>
<message numerus="yes">
- <location filename="../src/globals/VBoxGlobal.h" line="224"/>
+ <location filename="../src/globals/VBoxGlobal.h" line="227"/>
<source>%n month(s)</source>
<translation>
<numerusform>%n month</numerusform>
@@ -31,7 +31,7 @@
</translation>
</message>
<message numerus="yes">
- <location filename="../src/globals/VBoxGlobal.h" line="229"/>
+ <location filename="../src/globals/VBoxGlobal.h" line="232"/>
<source>%n day(s)</source>
<translation>
<numerusform>%n day</numerusform>
@@ -39,7 +39,7 @@
</translation>
</message>
<message numerus="yes">
- <location filename="../src/globals/VBoxGlobal.h" line="234"/>
+ <location filename="../src/globals/VBoxGlobal.h" line="237"/>
<source>%n hour(s)</source>
<translation>
<numerusform>%n hour</numerusform>
@@ -47,7 +47,7 @@
</translation>
</message>
<message numerus="yes">
- <location filename="../src/globals/VBoxGlobal.h" line="244"/>
+ <location filename="../src/globals/VBoxGlobal.h" line="247"/>
<source>%n second(s)</source>
<translation>
<numerusform>%n second</numerusform>
@@ -55,7 +55,7 @@
</translation>
</message>
<message numerus="yes">
- <location filename="../src/globals/VBoxGlobal.h" line="239"/>
+ <location filename="../src/globals/VBoxGlobal.h" line="242"/>
<source>%n minute(s)</source>
<translation>
<numerusform>%n minute</numerusform>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts
index 864362a2c..fe5a1aa5f 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_es.ts
@@ -101,7 +101,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>El controlador de VirtualBox del kernel Linux (vboxdrv) no se encuentra cargado o existe un problema de permisos con /dev/vboxdrv. Reconfigure el módulo del kernel ejecuntando &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; como usuario root. Los usuarios de Ubuntu, Fedora o Mandriva deberían instalar el paquete DKMS primero. Este paquete monitoriza los cambios en el kernel y recompila el módulo vboxdrv de ser necesario.</translation>
+ <translation type="obsolete">El controlador de VirtualBox del kernel Linux (vboxdrv) no se encuentra cargado o existe un problema de permisos con /dev/vboxdrv. Reconfigure el módulo del kernel ejecuntando &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; como usuario root. Los usuarios de Ubuntu, Fedora o Mandriva deberían instalar el paquete DKMS primero. Este paquete monitoriza los cambios en el kernel y recompila el módulo vboxdrv de ser necesario.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -155,6 +155,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Este error significa que el controlador del kernel no fue capaz de reservar suficiente memoria o que alguna operación de asignación falló.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6035,6 +6039,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Fallo al descargar el &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; desde &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts
index b8e1b4f9c..6aff0bc87 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_eu.ts
@@ -72,10 +72,6 @@
<context>
<name>QApplication</name>
<message>
- <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Make sure the kernel module has been loaded successfully.</source>
<translation type="unfinished"></translation>
</message>
@@ -127,6 +123,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5150,6 +5150,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts
index 584db753e..53f4b0c50 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fi.ts
@@ -82,7 +82,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>VirtualBoxin Linux-ytimen ajuri (vboxdrv) ei ole joko ladattu tai laitetiedoston /dev/vboxdrv oikeudet ovat väärin. Määrittele ytimen moduulin asetukset uudestaan root-käyttäjänä komennolla &lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Ubuntun, fedoran ja mandrivan käyttäjien tulisi ensin asentaa paketti dkms. Tämä paketti pitää kirjaa ytimen muutoksista ja kääntää moduulit automaattisesti tarvittaessa.</translation>
+ <translation type="obsolete">VirtualBoxin Linux-ytimen ajuri (vboxdrv) ei ole joko ladattu tai laitetiedoston /dev/vboxdrv oikeudet ovat väärin. Määrittele ytimen moduulin asetukset uudestaan root-käyttäjänä komennolla &lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Ubuntun, fedoran ja mandrivan käyttäjien tulisi ensin asentaa paketti dkms. Tämä paketti pitää kirjaa ytimen muutoksista ja kääntää moduulit automaattisesti tarvittaessa.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -136,6 +136,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5709,6 +5713,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts
index 8b8c6d205..ba0ee653e 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_fr.ts
@@ -53,7 +53,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Soit le pilote noyau Linux de VirtualBox (vboxdrv) n&apos;est pas en mémoire, soit il y a un problème de permissions avec /dev/vboxdrv. Veuillez réinitialiser le module noyau en exécutant en tant qu&apos;administrateur &lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Les utilisateurs des distributions Ubuntu, Fedora et Mandriva devraient installer le paquet DKMS au préalable. Ce paquet suit les changements du noyau Linux et recompile si besoin est le module noyau vboxdrv.</translation>
+ <translation type="obsolete">Soit le pilote noyau Linux de VirtualBox (vboxdrv) n&apos;est pas en mémoire, soit il y a un problème de permissions avec /dev/vboxdrv. Veuillez réinitialiser le module noyau en exécutant en tant qu&apos;administrateur &lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Les utilisateurs des distributions Ubuntu, Fedora et Mandriva devraient installer le paquet DKMS au préalable. Ce paquet suit les changements du noyau Linux et recompile si besoin est le module noyau vboxdrv.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -87,6 +87,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Cette erreur signifie que le module noyau n&apos;a pas pu allouer suffisamment de mémoire, ou bien qu&apos;une opération de translation a échoué.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -493,6 +497,174 @@
<source>Session I&amp;nformation...</source>
<translation>I&amp;nformation de session...</translation>
</message>
+ <message>
+ <source>&amp;File</source>
+ <comment>Mac OS X version</comment>
+ <translation>&amp;Fichier</translation>
+ </message>
+ <message>
+ <source>&amp;File</source>
+ <comment>Non Mac OS X version</comment>
+ <translation>&amp;Fichier</translation>
+ </message>
+ <message>
+ <source>&amp;Virtual Media Manager...</source>
+ <translation>&amp;Gestionnaire de médias...</translation>
+ </message>
+ <message>
+ <source>Display the Virtual Media Manager dialog</source>
+ <translation>Afficher la fenêtre du Gestionnaire de médias virtuels</translation>
+ </message>
+ <message>
+ <source>&amp;Import Appliance...</source>
+ <translation>&amp;Importer application virtuelle...</translation>
+ </message>
+ <message>
+ <source>Import an appliance into VirtualBox</source>
+ <translation>Importer une application virtuelle (ensemble de machines pré-configurées) dans VirtualBox</translation>
+ </message>
+ <message>
+ <source>&amp;Export Appliance...</source>
+ <translation>&amp;Exporter application virtuelle...</translation>
+ </message>
+ <message>
+ <source>Export one or more VirtualBox virtual machines as an appliance</source>
+ <translation>Exporter une ou plusieurs machines de VirtualBox en tant qu&apos;application virtuelle</translation>
+ </message>
+ <message>
+ <source>&amp;Preferences...</source>
+ <comment>global settings</comment>
+ <translatorcomment>In French &quot;(Global) Settings&quot; is &quot;Préférences&quot;, &quot;(Machine) Settings&quot; is &quot;Configuration&quot;</translatorcomment>
+ <translation>&amp;Paramètres...</translation>
+ </message>
+ <message>
+ <source>Display the global settings dialog</source>
+ <translation>Afficher la fenêtre Préférences de VirtualBox</translation>
+ </message>
+ <message>
+ <source>E&amp;xit</source>
+ <translation>&amp;Quitter</translation>
+ </message>
+ <message>
+ <source>Close application</source>
+ <translation>Fermer VirtualBox</translation>
+ </message>
+ <message>
+ <source>&amp;New...</source>
+ <translation>&amp;Créer...</translation>
+ </message>
+ <message>
+ <source>Create a new virtual machine</source>
+ <translation>Créer une nouvelle machine virtuelle</translation>
+ </message>
+ <message>
+ <source>&amp;Add...</source>
+ <translation>&amp;Ajouter...</translation>
+ </message>
+ <message>
+ <source>Add an existing virtual machine</source>
+ <translation>Ajouter une machine virtuelle existante</translation>
+ </message>
+ <message>
+ <source>Cl&amp;one...</source>
+ <translation>Cl&amp;oner...</translation>
+ </message>
+ <message>
+ <source>Clone the selected virtual machine</source>
+ <translation>Cloner la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>&amp;Remove</source>
+ <translation>&amp;Supprimer</translation>
+ </message>
+ <message>
+ <source>Remove the selected virtual machine</source>
+ <translation>Supprimer la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>S&amp;tart</source>
+ <translation>&amp;Démarrer</translation>
+ </message>
+ <message>
+ <source>Start the selected virtual machine</source>
+ <translation>Démarrer la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>S&amp;how</source>
+ <translation>A&amp;fficher</translation>
+ </message>
+ <message>
+ <source>Switch to the window of the selected virtual machine</source>
+ <translation>Montrer la fenêtre de la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>Discard</source>
+ <translation>Oublier</translation>
+ </message>
+ <message>
+ <source>D&amp;iscard Saved State</source>
+ <translation>Oub&amp;lier l&apos;état sauvegardé</translation>
+ </message>
+ <message>
+ <source>Discard the saved state of the selected virtual machine</source>
+ <translation>Oublier l&apos;état sauvegardé de la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>Re&amp;fresh</source>
+ <translation>&amp;Actualiser</translation>
+ </message>
+ <message>
+ <source>Refresh the accessibility state of the selected virtual machine</source>
+ <translation>Actualiser l&apos;état de la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>Show &amp;Log...</source>
+ <translation>Afficher le &amp;journal...</translation>
+ </message>
+ <message>
+ <source>Show the log files of the selected virtual machine</source>
+ <translation>Afficher le journal de la machine virtuelle sélectionnée</translation>
+ </message>
+ <message>
+ <source>Show in Finder</source>
+ <translation>Afficher dans le Finder</translation>
+ </message>
+ <message>
+ <source>Show the VirtualBox Machine Definition file in Finder.</source>
+ <translation>Afficher le fichier de définition de la machine VirtualBox dans le Finder.</translation>
+ </message>
+ <message>
+ <source>Show in Explorer</source>
+ <translation>Afficher dans l&apos;explorateur</translation>
+ </message>
+ <message>
+ <source>Show the VirtualBox Machine Definition file in Explorer.</source>
+ <translation>Afficher le fichier de définition de la machine virtuelle dans l&apos;explorateur.</translation>
+ </message>
+ <message>
+ <source>Show in File Manager</source>
+ <translation>Afficher dans le gestionnaire de fichier</translation>
+ </message>
+ <message>
+ <source>Show the VirtualBox Machine Definition file in the File Manager</source>
+ <translation>Afficher le fichier de définition de la machine virtuelle dans le gestionnaire de fichier</translation>
+ </message>
+ <message>
+ <source>Create Alias on Desktop</source>
+ <translation>Créer un alias sur le bureau</translation>
+ </message>
+ <message>
+ <source>Creates an Alias file to the VirtualBox Machine Definition file on your Desktop.</source>
+ <translation>Créé un alias du fichier de définition de la machine VirtualBox sur votre bureau.</translation>
+ </message>
+ <message>
+ <source>Create Shortcut on Desktop</source>
+ <translation>Créer un raccourci sur le bureau</translation>
+ </message>
+ <message>
+ <source>Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop.</source>
+ <translation>Créé un raccourci vers le fichier de définition de la machine virtuelle sur votre bureau.</translation>
+ </message>
</context>
<context>
<name>UIApplianceEditorWidget</name>
@@ -3836,7 +4008,7 @@
</message>
<message>
<source>&lt;p&gt;You are about to change the attributes of the virtual disk located in &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Please choose one of the following medium types and press &lt;b&gt;%2&lt;/b&gt; to proceed or &lt;b&gt;%3&lt;/b&gt; otherwise.&lt;/p&gt;</source>
- <translation>&lt;p&gt;Vous êtes sur le point de modifier les attributs du disque virtuel correspondant au fichier &lt;b&gt;%1&gt;/b&gt;.&gt;/p&gt;&lt;p&gt;Choisissez un des types de média suivants et utilisez le bouton &lt;b&gt;%2&lt;/b&gt; pour continuer ou bien &lt;b&gt;%3&lt;/b&gt; pour annuler.&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Vous êtes sur le point de modifier les attributs du disque virtuel correspondant au fichier &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Choisissez un des types de média suivants et utilisez le bouton &lt;b&gt;%2&lt;/b&gt; pour continuer ou bien &lt;b&gt;%3&lt;/b&gt; pour annuler.&lt;/p&gt;</translation>
</message>
<message>
<source>Choose medium type:</source>
@@ -4308,7 +4480,7 @@
</message>
<message>
<source>&lt;p&gt;A new version of VirtualBox has been released! Version &lt;b&gt;%1&lt;/b&gt; is available at &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;virtualbox.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can download this version using the link:&lt;/p&gt;&lt;p&gt;&lt;a href=%2&gt;%3&lt;/a&gt;&lt;/p&gt;</source>
- <translation>&lt;p&gt;Une nouvelle version de VirtualBox est disponible ! La version &lt;b&gt;%1&lt;/b&gt; est disponible sur &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;&gt;virtualbox.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Vous pouvez télécharger cette version en utilisant le lien suivant : &lt;/p&gt;&lt;p&gt;&lt;a href=%2&gt;%3&lt;/a&gt;&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;Une nouvelle version de VirtualBox est disponible ! La version &lt;b&gt;%1&lt;/b&gt; est disponible sur &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;virtualbox.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Vous pouvez télécharger cette version en utilisant le lien suivant : &lt;/p&gt;&lt;p&gt;&lt;a href=%2&gt;%3&lt;/a&gt;&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Are you sure you want to release the %1 &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;?&lt;/p&gt;&lt;p&gt;This will detach it from the following virtual machine(s): &lt;b&gt;%3&lt;/b&gt;.&lt;/p&gt;</source>
@@ -5009,6 +5181,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Échec lors du téléchargement de &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; depuis &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
@@ -7471,49 +7652,6 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
</context>
<context>
- <name>VBoxLogSearchPanel</name>
- <message>
- <source>Close the search panel</source>
- <translation>Fermer le panneau de recherche</translation>
- </message>
- <message>
- <source>Find </source>
- <translation>Rechercher </translation>
- </message>
- <message>
- <source>Enter a search string here</source>
- <translation>Entrez ici la chaîne de caractères à rechercher</translation>
- </message>
- <message>
- <source>&amp;Previous</source>
- <translation>&amp;Précédent</translation>
- </message>
- <message>
- <source>Search for the previous occurrence of the string</source>
- <translation>Rechercher l&apos;occurrence précédente de la chaîne de caractères</translation>
- </message>
- <message>
- <source>&amp;Next</source>
- <translation>&amp;Suivant</translation>
- </message>
- <message>
- <source>Search for the next occurrence of the string</source>
- <translation>Rechercher l&apos;occurrence suivante de la chaîne de caractères</translation>
- </message>
- <message>
- <source>C&amp;ase Sensitive</source>
- <translation>&amp;Respecter la casse</translation>
- </message>
- <message>
- <source>Perform case sensitive search (when checked)</source>
- <translation>Si cette case est cochée, la recherche tient compte des majuscules et des minuscules</translation>
- </message>
- <message>
- <source>String not found</source>
- <translation>Chaîne de caractères non trouvée</translation>
- </message>
-</context>
-<context>
<name>VBoxMediaManagerDlg</name>
<message>
<source>&amp;Actions</source>
@@ -7802,32 +7940,6 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<translation type="obsolete">&amp;Détails</translation>
</message>
<message>
- <source>&amp;Preferences...</source>
- <comment>global settings</comment>
- <translatorcomment>In French &quot;(Global) Settings&quot; is &quot;Préférences&quot;, &quot;(Machine) Settings&quot; is &quot;Configuration&quot;</translatorcomment>
- <translation>&amp;Paramètres...</translation>
- </message>
- <message>
- <source>Display the global settings dialog</source>
- <translation>Afficher la fenêtre Préférences de VirtualBox</translation>
- </message>
- <message>
- <source>E&amp;xit</source>
- <translation>&amp;Quitter</translation>
- </message>
- <message>
- <source>Close application</source>
- <translation>Fermer VirtualBox</translation>
- </message>
- <message>
- <source>&amp;New...</source>
- <translation>&amp;Créer...</translation>
- </message>
- <message>
- <source>Create a new virtual machine</source>
- <translation>Créer une nouvelle machine virtuelle</translation>
- </message>
- <message>
<source>&amp;Settings...</source>
<translation>&amp;Configuration...</translation>
</message>
@@ -7848,14 +7960,6 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<translation type="obsolete">&amp;Oublier</translation>
</message>
<message>
- <source>Discard the saved state of the selected virtual machine</source>
- <translation>Oublier l&apos;état sauvegardé de la machine virtuelle sélectionnée</translation>
- </message>
- <message>
- <source>Refresh the accessibility state of the selected virtual machine</source>
- <translation>Actualiser l&apos;état de la machine virtuelle sélectionnée</translation>
- </message>
- <message>
<source>&amp;Help</source>
<translation type="obsolete">&amp;Aide</translation>
</message>
@@ -7872,34 +7976,10 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<translation type="obsolete">D&amp;escription *</translation>
</message>
<message>
- <source>S&amp;how</source>
- <translation>A&amp;fficher</translation>
- </message>
- <message>
- <source>Switch to the window of the selected virtual machine</source>
- <translation>Montrer la fenêtre de la machine virtuelle sélectionnée</translation>
- </message>
- <message>
- <source>S&amp;tart</source>
- <translation>&amp;Démarrer</translation>
- </message>
- <message>
- <source>Start the selected virtual machine</source>
- <translation>Démarrer la machine virtuelle sélectionnée</translation>
- </message>
- <message>
<source>&amp;Machine</source>
<translation>&amp;Machine</translation>
</message>
<message>
- <source>Show &amp;Log...</source>
- <translation>Afficher le &amp;journal...</translation>
- </message>
- <message>
- <source>Show the log files of the selected virtual machine</source>
- <translation>Afficher le journal de la machine virtuelle sélectionnée</translation>
- </message>
- <message>
<source>R&amp;esume</source>
<translation type="obsolete">R&amp;eprendre</translation>
</message>
@@ -7920,49 +8000,11 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<translation>&lt;h3&gt;Bienvenue dans VirtualBox !&lt;/h3&gt;&lt;p&gt;La partie gauche de cette fenêtre affiche la liste des machines virtuelles de votre ordinateur. Cette liste est vide car vous n&apos;avez pas encore créé de machine virtuelle.&lt;img src=:/welcome.png align=right/&gt;&lt;/p&gt;&lt;p&gt;Pour créer une nouvelle machine virtuelle cliquez sur le bouton &lt;b&gt;Créer&lt;/b&gt; en haut de cette liste.&lt;/p&gt;&lt;p&gt;Vous pouvez appuyer sur &lt;b&gt;%1&lt;/b&gt; pour obtenir de l&apos;aide et visiter le site de VirtualBox &lt;a href=http://www.virtualbox.org&gt;www.virtualbox.org&lt;/a&gt; (en anglais).&lt;/p&gt;</translation>
</message>
<message>
- <source>&amp;Virtual Media Manager...</source>
- <translation>&amp;Gestionnaire de médias...</translation>
- </message>
- <message>
- <source>Display the Virtual Media Manager dialog</source>
- <translation>Afficher la fenêtre du Gestionnaire de médias virtuels</translation>
- </message>
- <message>
<source>Log</source>
<comment>icon text</comment>
<translation>Journal</translation>
</message>
<message>
- <source>&amp;Import Appliance...</source>
- <translation>&amp;Importer application virtuelle...</translation>
- </message>
- <message>
- <source>Import an appliance into VirtualBox</source>
- <translation>Importer une application virtuelle (ensemble de machines pré-configurées) dans VirtualBox</translation>
- </message>
- <message>
- <source>&amp;Export Appliance...</source>
- <translation>&amp;Exporter application virtuelle...</translation>
- </message>
- <message>
- <source>Export one or more VirtualBox virtual machines as an appliance</source>
- <translation>Exporter une ou plusieurs machines de VirtualBox en tant qu&apos;application virtuelle</translation>
- </message>
- <message>
- <source>Re&amp;fresh</source>
- <translation>&amp;Actualiser</translation>
- </message>
- <message>
- <source>&amp;File</source>
- <comment>Mac OS X version</comment>
- <translation>&amp;Fichier</translation>
- </message>
- <message>
- <source>&amp;File</source>
- <comment>Non Mac OS X version</comment>
- <translation>&amp;Fichier</translation>
- </message>
- <message>
<source>Select a virtual machine file</source>
<translation>Choisir un fichier machine virtuelle</translation>
</message>
@@ -7976,62 +8018,6 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<translation>-- Gestionnaire de machines</translation>
</message>
<message>
- <source>&amp;Add...</source>
- <translation>&amp;Ajouter...</translation>
- </message>
- <message>
- <source>Add an existing virtual machine</source>
- <translation>Ajouter une machine virtuelle existante</translation>
- </message>
- <message>
- <source>&amp;Remove</source>
- <translation>&amp;Supprimer</translation>
- </message>
- <message>
- <source>Remove the selected virtual machine</source>
- <translation>Supprimer la machine virtuelle sélectionnée</translation>
- </message>
- <message>
- <source>Show in Finder</source>
- <translation>Afficher dans le Finder</translation>
- </message>
- <message>
- <source>Show the VirtualBox Machine Definition file in Finder.</source>
- <translation>Afficher le fichier de définition de la machine VirtualBox dans le Finder.</translation>
- </message>
- <message>
- <source>Create Alias on Desktop</source>
- <translation>Créer un alias sur le bureau</translation>
- </message>
- <message>
- <source>Creates an Alias file to the VirtualBox Machine Definition file on your Desktop.</source>
- <translation>Créé un alias du fichier de définition de la machine VirtualBox sur votre bureau.</translation>
- </message>
- <message>
- <source>Show in Explorer</source>
- <translation>Afficher dans l&apos;explorateur</translation>
- </message>
- <message>
- <source>Show the VirtualBox Machine Definition file in Explorer.</source>
- <translation>Afficher le fichier de définition de la machine virtuelle dans l&apos;explorateur.</translation>
- </message>
- <message>
- <source>Create Shortcut on Desktop</source>
- <translation>Créer un raccourci sur le bureau</translation>
- </message>
- <message>
- <source>Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop.</source>
- <translation>Créé un raccourci vers le fichier de définition de la machine virtuelle sur votre bureau.</translation>
- </message>
- <message>
- <source>Show in File Manager</source>
- <translation>Afficher dans le gestionnaire de fichier</translation>
- </message>
- <message>
- <source>Show the VirtualBox Machine Definition file in the File Manager</source>
- <translation>Afficher le fichier de définition de la machine virtuelle dans le gestionnaire de fichier</translation>
- </message>
- <message>
<source>Show Toolbar</source>
<translation>Afficher la barre d&apos;outils</translation>
</message>
@@ -8039,22 +8025,6 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>Show Statusbar</source>
<translation>Afficher la barre d&apos;état</translation>
</message>
- <message>
- <source>Cl&amp;one...</source>
- <translation>Cl&amp;oner...</translation>
- </message>
- <message>
- <source>Clone the selected virtual machine</source>
- <translation>Cloner la machine virtuelle sélectionnée</translation>
- </message>
- <message>
- <source>Discard</source>
- <translation>Oublier</translation>
- </message>
- <message>
- <source>D&amp;iscard Saved State</source>
- <translation>Oub&amp;lier l&apos;état sauvegardé</translation>
- </message>
</context>
<context>
<name>VBoxSettingsDialog</name>
@@ -8405,7 +8375,7 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
</message>
</context>
<context>
- <name>VBoxVMLogViewer</name>
+ <name>UIVMLogViewer</name>
<message>
<source>Log Viewer</source>
<translation>Affichage des journaux</translation>
@@ -8438,6 +8408,42 @@ And the size is not necessarily &quot;in megabytes&quot;, the slider chooses the
<source>Close</source>
<translation>Fermer</translation>
</message>
+ <message>
+ <source>Close the search panel</source>
+ <translation>Fermer le panneau de recherche</translation>
+ </message>
+ <message>
+ <source>Enter a search string here</source>
+ <translation>Entrez ici la chaîne de caractères à rechercher</translation>
+ </message>
+ <message>
+ <source>&amp;Previous</source>
+ <translation>&amp;Précédent</translation>
+ </message>
+ <message>
+ <source>Search for the previous occurrence of the string</source>
+ <translation>Rechercher l&apos;occurrence précédente de la chaîne de caractères</translation>
+ </message>
+ <message>
+ <source>&amp;Next</source>
+ <translation>&amp;Suivant</translation>
+ </message>
+ <message>
+ <source>Search for the next occurrence of the string</source>
+ <translation>Rechercher l&apos;occurrence suivante de la chaîne de caractères</translation>
+ </message>
+ <message>
+ <source>C&amp;ase Sensitive</source>
+ <translation>&amp;Respecter la casse</translation>
+ </message>
+ <message>
+ <source>Perform case sensitive search (when checked)</source>
+ <translation>Si cette case est cochée, la recherche tient compte des majuscules et des minuscules</translation>
+ </message>
+ <message>
+ <source>String not found</source>
+ <translation>Chaîne de caractères non trouvée</translation>
+ </message>
</context>
<context>
<name>VBoxVMSettingsDlg</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts
index 20b541ec6..663858c66 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_gl_ES.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>O controlador do núcleo Linux de VirtualBox (vboxdrv) non está cargado ou existe un problema cos permisos de /dev/vboxdrv. Reconfigura o módulo do núcleo executando&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;como usuario root. Usuarios de Ubuntu, Fedora ou Mandriva deberían instalar primeiro o paquete DKMS. Este paquete vixía os cambios do núcleo Linux e recompila o módulo do núcleo vboxdrv se é necesario.</translation>
+ <translation type="obsolete">O controlador do núcleo Linux de VirtualBox (vboxdrv) non está cargado ou existe un problema cos permisos de /dev/vboxdrv. Reconfigura o módulo do núcleo executando&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;como usuario root. Usuarios de Ubuntu, Fedora ou Mandriva deberían instalar primeiro o paquete DKMS. Este paquete vixía os cambios do núcleo Linux e recompila o módulo do núcleo vboxdrv se é necesario.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5401,6 +5405,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts
index 4732beae7..00bb2678f 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_hu.ts
@@ -113,7 +113,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>A VirtualBox Linux kernel modulja (vboxdrv) nincs betöltve, vagy jogosultsági problémák léptek fel a /dev/vboxdrv eszközfájlon. Próbáld meg a &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt; futtatásával újrakonfigurálni a kernelmodult root-ként. Ubuntu, Dedora és Mandriva felhasználóknak előbb a DKMS csomagot érdemes feltelepíteniük. Ez a csomag követi a Linux kernel változásait, és újrafordítja a modulokat, ha szükséges. </translation>
+ <translation type="obsolete">A VirtualBox Linux kernel modulja (vboxdrv) nincs betöltve, vagy jogosultsági problémák léptek fel a /dev/vboxdrv eszközfájlon. Próbáld meg a &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt; futtatásával újrakonfigurálni a kernelmodult root-ként. Ubuntu, Dedora és Mandriva felhasználóknak előbb a DKMS csomagot érdemes feltelepíteniük. Ez a csomag követi a Linux kernel változásait, és újrafordítja a modulokat, ha szükséges. </translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -148,6 +148,10 @@
<translatorcomment>CHECK</translatorcomment>
<translation>A kernel driver nem tudott elegendő memóriát lefoglalni, vagy valamilyen memóriaművelet nem sikerült.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6014,6 +6018,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;&lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; letöltése sikertelen a következő helyről: &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts
index 6e7d3d628..383be4207 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_id.ts
@@ -108,10 +108,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Make sure the kernel module has been loaded successfully.</source>
<translation type="unfinished"></translation>
</message>
@@ -143,6 +139,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5304,6 +5304,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts
index 32ff7a51b..6decf0277 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts
@@ -113,7 +113,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Il driver del kernel Linux di VirtualBox (vboxdrv) potrebbe non essere caricato o potrebbe esserci un problema di permessi con /dev/vboxdrv. Riconfigura il modulo del kernel eseguendo &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;come root. Gli utenti di Ubuntu, Fedora o Mandriva dovrebbero installare prima il pacchetto DKMS. Questo pacchetto tiene traccia delle modifiche del kernel e ricompila il modulo vboxdrv se necessario.</translation>
+ <translation type="obsolete">Il driver del kernel Linux di VirtualBox (vboxdrv) potrebbe non essere caricato o potrebbe esserci un problema di permessi con /dev/vboxdrv. Riconfigura il modulo del kernel eseguendo &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;come root. Gli utenti di Ubuntu, Fedora o Mandriva dovrebbero installare prima il pacchetto DKMS. Questo pacchetto tiene traccia delle modifiche del kernel e ricompila il modulo vboxdrv se necessario.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -147,6 +147,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Questo errore significa che il driver del kernel non è stato in grado di allocare memoria sufficiente o che alcune operazioni di mappatura non sono riuscite.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6243,6 +6247,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Scaricamento del &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; non riuscita da &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts
index 4a815bfd4..9cd0fb374 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ja.ts
@@ -122,9 +122,8 @@
<translation type="obsolete">ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€ã‚«ãƒ¼ãƒãƒ« ドライãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã§ããªã„ã‹ã€ã¾ãŸã¯ãƒžãƒƒãƒ”ングæ“作ã«å¤±æ•—ã—ãŸã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚&lt;br/&gt;&lt;br/&gt;ã“れã¯Linux 2.6.29ã®æ—¢çŸ¥ã®å•題ã§ã™ã€‚ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚«ãƒ¼ãƒãƒ«ã‚’使用ã™ã‚‹ãªã‚‰ã°ã€/usr/src/vboxdrv-*/Makefileを編集ã—ã€&lt;i&gt;VBOX_USE_INSERT_PAGE = 1&lt;/i&gt;を有効ã«ã—ã¦ãã ã•ã„。ãã®å¾Œã€root権é™ã§&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;を実行ã—ã¦ã‚«ãƒ¼ãƒãƒ« モジュールをå†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/main.cpp" line="74"/>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>VirtualBoxã®Linuxカーãƒãƒ« ドライãƒ(vboxdrv)ã¯ãƒ­ãƒ¼ãƒ‰ã•れã¾ã›ã‚“。ã¾ãŸã¯/dev/vboxdrvã®ãƒ‘ーミッションã«å•題ãŒã‚りã¾ã™ã€‚root権é™ã§&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;を実行ã—ã¦ã‚«ãƒ¼ãƒãƒ« モジュールをå†ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã—ã¦ãã ã•ã„。Ubuntuã€Fedoraã¾ãŸã¯Mandrivaãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯æœ€åˆã«DKMSパッケージをインストールã—ã¦ãã ã•ã„。ã“ã®ãƒ‘ッケージã¯Linuxカーãƒãƒ«ã®å¤‰æ›´ã‚’把æ¡ã—ã€å¿…è¦ãªã‚‰ã°vboxdrvカーãƒãƒ« モジュールをå†ã‚³ãƒ³ãƒ‘イルã—ã¾ã™ã€‚</translation>
+ <translation type="obsolete">VirtualBoxã®Linuxカーãƒãƒ« ドライãƒ(vboxdrv)ã¯ãƒ­ãƒ¼ãƒ‰ã•れã¾ã›ã‚“。ã¾ãŸã¯/dev/vboxdrvã®ãƒ‘ーミッションã«å•題ãŒã‚りã¾ã™ã€‚root権é™ã§&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;を実行ã—ã¦ã‚«ãƒ¼ãƒãƒ« モジュールをå†ã‚»ãƒƒãƒˆã‚¢ãƒƒãƒ—ã—ã¦ãã ã•ã„。Ubuntuã€Fedoraã¾ãŸã¯Mandrivaãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯æœ€åˆã«DKMSパッケージをインストールã—ã¦ãã ã•ã„。ã“ã®ãƒ‘ッケージã¯Linuxカーãƒãƒ«ã®å¤‰æ›´ã‚’把æ¡ã—ã€å¿…è¦ãªã‚‰ã°vboxdrvカーãƒãƒ« モジュールをå†ã‚³ãƒ³ãƒ‘イルã—ã¾ã™ã€‚</translation>
</message>
<message>
<location filename="../src/main.cpp" line="100"/>
@@ -152,6 +151,11 @@
<translation>カーãƒãƒ«ãƒ‰ãƒ©ã‚¤ãƒã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„</translation>
</message>
<message>
+ <location filename="../src/main.cpp" line="74"/>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../src/main.cpp" line="84"/>
<source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Please try completely uninstalling and reinstalling VirtualBox.</source>
<translation>カーãƒãƒ«ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒé©åˆã—ã¾ã›ã‚“。VirtualBoxã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã¯æˆåŠŸã—ã¾ã›ã‚“ã§ã—ãŸã€‚ã“ã®å•題ã¯VirtualBoxを完全ã«ã‚¢ãƒ³ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«å¾Œã€å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã§è§£æ±ºã™ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。</translation>
@@ -2063,28 +2067,28 @@ p, li { white-space: pre-wrap; }
<translation>ãƒãƒ¼ã‚¸ãƒ§ãƒ³</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="191"/>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="410"/>
+ <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="206"/>
+ <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="425"/>
<source>Extensions</source>
<translation>機能拡張</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="273"/>
+ <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="288"/>
<source>Add package</source>
<translation>パッケージを追加</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="274"/>
+ <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="289"/>
<source>Remove package</source>
<translation>パッケージを除去</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="317"/>
+ <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="332"/>
<source>Select an extension package file</source>
<translation>æ©Ÿèƒ½æ‹¡å¼µãƒ‘ãƒƒã‚±ãƒ¼ã‚¸ã‚’é¸æŠž</translation>
</message>
<message>
- <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="321"/>
+ <location filename="../src/settings/global/UIGlobalSettingsExtension.cpp" line="336"/>
<source>Extension package files (%1)</source>
<translation>機能拡張パッケージファイル(%1)</translation>
</message>
@@ -4716,31 +4720,31 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2293"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="909"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="911"/>
<source>IDE Controller</source>
<translation>IDE コントローラ</translation>
</message>
<message>
<location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2298"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="917"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="919"/>
<source>SATA Controller</source>
<translation>SATA コントローラ</translation>
</message>
<message>
<location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2303"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="925"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="927"/>
<source>SCSI Controller</source>
<translation>SCSI コントローラ</translation>
</message>
<message>
<location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2308"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="933"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="935"/>
<source>Floppy Controller</source>
<translation>フロッピー コントローラ</translation>
</message>
<message>
<location filename="../src/settings/machine/UIMachineSettingsStorage.cpp" line="2313"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="941"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="943"/>
<source>SAS Controller</source>
<translation>SAS コントローラ</translation>
</message>
@@ -5278,120 +5282,120 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§USB 2.0を有効化ã™ã‚‹ã«ã¯&lt;b&gt;%1&lt;/b&gt;ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚VirtualBoxã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚µã‚¤ãƒˆã‹ã‚‰æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージをダウンロードã—ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。機能拡張パッケージをインストールã™ã‚‹ã¨ã€USB 2.0を有効化ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ç¾åœ¨ã®è¨­å®šã‚’キャンセルã—ãªã„å ´åˆã€USB 2.0ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="475"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="477"/>
<source>USB 2.0 is currently enabled for this virtual machine. However, this requires the &lt;b&gt;%1&lt;/b&gt; to be installed. Please install the Extension Pack from the VirtualBox download site. After this you will be able to re-enable USB 2.0. It will be disabled in the meantime unless you cancel the current settings changes.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="499"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="502"/>
<source>&amp;Add Empty Filter</source>
<translation>空ã®ãƒ•ィルタを追加(&amp;A)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="500"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="503"/>
<source>A&amp;dd Filter From Device</source>
<translation>デãƒã‚¤ã‚¹ã‹ã‚‰ãƒ•ィルタを追加ã™ã‚‹(&amp;D)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="501"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="504"/>
<source>&amp;Edit Filter</source>
<translation>フィルタを編集ã™ã‚‹(&amp;E)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="502"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="505"/>
<source>&amp;Remove Filter</source>
<translation>フィルタを除去ã™ã‚‹(&amp;R)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="503"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="506"/>
<source>&amp;Move Filter Up</source>
<translation>フィルタを上ã«ç§»å‹•ã™ã‚‹(&amp;M)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="504"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="507"/>
<source>M&amp;ove Filter Down</source>
<translation>フィルタを下ã«ç§»å‹•(&amp;O)</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="519"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="522"/>
<source>Adds a new USB filter with all fields initially set to empty strings. Note that such a filter will match any attached USB device.</source>
<translation>ã™ã¹ã¦ã®ãƒ•ィールドãŒç©ºã®æ–°è¦USBフィルタを追加ã—ã¾ã™ã€‚注:ã“ã®ãƒ•ィルタã¯ã™ã¹ã¦ã®æŽ¥ç¶šã•れãŸUSB デãƒã‚¤ã‚¹ã«é©åˆã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="523"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="526"/>
<source>Adds a new USB filter with all fields set to the values of the selected USB device attached to the host PC.</source>
<translation>ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れãŸã€é¸æŠžã—ãŸUSB デãƒã‚¤ã‚¹ã®å€¤ã‚’ã™ã¹ã¦ã®ãƒ•ィールドã«è¨­å®šã—ãŸæ–°è¦USBフィルタを追加ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="526"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="529"/>
<source>Edits the selected USB filter.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを編集ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="527"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="530"/>
<source>Removes the selected USB filter.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを除去ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="528"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="531"/>
<source>Moves the selected USB filter up.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを上ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="529"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="532"/>
<source>Moves the selected USB filter down.</source>
<translation>é¸æŠžã—ãŸUSBフィルタを下ã«ç§»å‹•ã—ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="531"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="534"/>
<source>New Filter %1</source>
<comment>usb</comment>
<translation>æ–°è¦ãƒ•ィルタ %1</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="886"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="889"/>
<source>&lt;nobr&gt;Vendor ID: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;ベンダID: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="890"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="893"/>
<source>&lt;nobr&gt;Product ID: %2&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;プロダクトID: %2&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="894"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="897"/>
<source>&lt;nobr&gt;Revision: %3&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;リビジョン: %3&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="898"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="901"/>
<source>&lt;nobr&gt;Product: %4&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;製å“: %4&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="902"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="905"/>
<source>&lt;nobr&gt;Manufacturer: %5&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;メーカー: %5&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="906"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="909"/>
<source>&lt;nobr&gt;Serial No.: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;シリアルNo.: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="910"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="913"/>
<source>&lt;nobr&gt;Port: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;ãƒãƒ¼ãƒˆ: %1&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="915"/>
+ <location filename="../src/settings/machine/UIMachineSettingsUSB.cpp" line="918"/>
<source>&lt;nobr&gt;State: %1&lt;/nobr&gt;</source>
<comment>USB filter tooltip</comment>
<translation>&lt;nobr&gt;状態: %1&lt;/nobr&gt;</translation>
@@ -5561,7 +5565,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>UIMachineWindowNormal</name>
<message>
- <location filename="../src/runtime/normal/UIMachineWindowNormal.cpp" line="287"/>
+ <location filename="../src/runtime/normal/UIMachineWindowNormal.cpp" line="248"/>
<source>Shows the currently assigned Host key.&lt;br&gt;This key, when pressed alone, toggles the keyboard and mouse capture state. It can also be used in combination with other keys to quickly perform actions from the main menu.</source>
<translation>ç¾åœ¨å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„るホストキーを表示ã—ã¾ã™ã€‚&lt;br&gt;ホストキーをå˜ç‹¬ã§æŠ¼ã™ã¨ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒˆã¨ãƒžã‚¦ã‚¹ã®åˆ¶å¾¡ãŒåˆ‡ã‚Šæ›¿ã‚りã¾ã™ã€‚ã¾ãŸã€ä»–ã®ã‚­ãƒ¼ã¨åˆã‚ã›ã¦ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã®æ“作ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</translation>
</message>
@@ -5848,8 +5852,8 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">ホスト ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェース&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2945"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2953"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2958"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2966"/>
<source>Failed to remove the host network interface &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>ホスト ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェース&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã‚’å–り除ã‘ã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
@@ -5866,43 +5870,43 @@ p, li { white-space: pre-wrap; }
<translation>USB デãƒã‚¤ã‚¹&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%2&quot;&lt;/b&gt;ã‹ã‚‰ã®å‰²ã‚Šå½“ã¦è§£é™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2993"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3019"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3006"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3032"/>
<source>Failed to create the shared folder &lt;b&gt;%1&lt;/b&gt; (pointing to &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;) for the virtual machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã®å…±æœ‰ãƒ•ォルダ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;(å‚ç…§å…ˆ &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;)ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3006"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3019"/>
<source>Failed to remove the shared folder &lt;b&gt;%1&lt;/b&gt; (pointing to &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;) from the virtual machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>仮想マシン&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã®å…±æœ‰ãƒ•ォルダ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;(å‚ç…§å…ˆ &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;)ã®é™¤åŽ»ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2021"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2034"/>
<source>&lt;p&gt;The Virtual Machine reports that the guest OS does not support &lt;b&gt;mouse pointer integration&lt;/b&gt; in the current video mode. You need to capture the mouse (by clicking over the VM display or pressing the host key) in order to use the mouse inside the guest OS.&lt;/p&gt;</source>
<translation>&lt;p&gt;ç¾åœ¨ã®ãƒ“デオモードã§ã¯ã‚²ã‚¹ãƒˆOSã§&lt;b&gt;マウス統åˆ&lt;/b&gt;機能ãŒã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“。ゲストOSã§ãƒžã‚¦ã‚¹ã‚’使用ã™ã‚‹ãŸã‚ã«ã¯ãƒžã‚¦ã‚¹ã‚’キャプãƒãƒ£(仮想マシンã®ç”»é¢ã‚’クリックã™ã‚‹ã‹ã€ã¾ãŸã¯ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã‚’押ã™)ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2041"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2054"/>
<source>&lt;p&gt;The Virtual Machine is currently in the &lt;b&gt;Paused&lt;/b&gt; state and not able to see any keyboard or mouse input. If you want to continue to work inside the VM, you need to resume it by selecting the corresponding action from the menu bar.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã¯ç¾åœ¨&lt;b&gt;&quot;ä¸€æ™‚åœæ­¢&quot;&lt;/b&gt;状態ã®ãŸã‚ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã¨ãƒžã‚¦ã‚¹æ“作をå—ã‘付ã‘ã¾ã›ã‚“。仮想マシンã§ã®ä½œæ¥­ã‚’ç¶šã‘ãŸã„å ´åˆã¯ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã‹ã‚‰å¯¾å¿œã™ã‚‹å‹•ä½œã‚’é¸æŠžã—ã¦ã€ä»®æƒ³ãƒžã‚·ãƒ³ã‚’å†é–‹ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2260"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2273"/>
<source>&lt;p&gt;Cannot run VirtualBox in &lt;i&gt;VM Selector&lt;/i&gt; mode due to local restrictions.&lt;/p&gt;&lt;p&gt;The application will now terminate.&lt;/p&gt;</source>
<translation>&lt;p&gt;ローカルã®åˆ¶é™ã®ãŸã‚〠&lt;i&gt;VM Selector&lt;/i&gt;モードã§VirtualBoxを実行ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;アプリケーションを終了ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2399"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2412"/>
<source>Failed to update Guest Additions. The Guest Additions installation image will be mounted to provide a manual installation.</source>
<translation>Guest Additionsã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚Guest Additionsã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚¤ãƒ¡ãƒ¼ã‚¸ã¯æ‰‹å‹•インストールã®ãŸã‚マウントã•れã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2434"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2447"/>
<source>Failed to install the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>機能拡張パッケージ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2447"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2460"/>
<source>Failed to uninstall the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>機能拡張パッケージ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚¢ãƒ³ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
@@ -5911,82 +5915,82 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">機能拡張パッケージ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;を除去ã—ã¾ã™ã€‚本当ã«é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2538"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2551"/>
<source>&amp;Remove</source>
<translation>除去(&amp;R)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2551"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2564"/>
<source>The current port forwarding rules are not valid. None of the host or guest port values may be set to zero.</source>
<translation>ç¾åœ¨ã®ãƒãƒ¼ãƒˆãƒ•ォワーディングルールã¯ç„¡åйã§ã™ã€‚ ホストã¾ãŸã¯ã‚²ã‚¹ãƒˆãƒãƒ¼ãƒˆã®å€¤ã«ã‚¼ãƒ­ãŒè¨­å®šã•れã¦ã„ã¾ã™ã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2558"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2571"/>
<source>&lt;p&gt;There are unsaved changes in the port forwarding configuration.&lt;/p&gt;&lt;p&gt;If you proceed your changes will be discarded.&lt;/p&gt;</source>
<translation>&lt;p&gt;ãƒãƒ¼ãƒˆãƒ•ォワーディング設定ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;続行ã™ã‚‹ã¨å¤‰æ›´ã¯ç ´æ£„ã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2587"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2600"/>
<source>&lt;nobr&gt;Fatal Error&lt;/nobr&gt;</source>
<comment>runtime error info</comment>
<translation>&lt;nobr&gt;致命的ãªã‚¨ãƒ©ãƒ¼&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2593"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2606"/>
<source>&lt;nobr&gt;Non-Fatal Error&lt;/nobr&gt;</source>
<comment>runtime error info</comment>
<translation>&lt;nobr&gt;致命的ã§ãªã„エラー&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2599"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2612"/>
<source>&lt;nobr&gt;Warning&lt;/nobr&gt;</source>
<comment>runtime error info</comment>
<translation>&lt;nobr&gt;警告&lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2616"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2629"/>
<source>&lt;nobr&gt;Error ID: &lt;/nobr&gt;</source>
<comment>runtime error info</comment>
<translation>&lt;nobr&gt;エラーID: &lt;/nobr&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2618"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2631"/>
<source>Severity: </source>
<comment>runtime error info</comment>
<translation>é‡è¦åº¦:</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2629"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2642"/>
<source>&lt;p&gt;A fatal error has occurred during virtual machine execution! The virtual machine will be powered off. Please copy the following error message using the clipboard to help diagnose the problem:&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®å®Ÿè¡Œä¸­ã«è‡´å‘½çš„ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸï¼ä»®æƒ³ãƒžã‚·ãƒ³ã®é›»æºã‚’オフã«ã—ã¾ã™ã€‚調査ã®ãŸã‚ã«ä»¥ä¸‹ã®ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’クリップボードã«ã‚³ãƒ”ーã—ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„:&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2641"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2654"/>
<source>&lt;p&gt;An error has occurred during virtual machine execution! The error details are shown below. You may try to correct the error and resume the virtual machine execution.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®å®Ÿè¡Œä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸï¼ã‚¨ãƒ©ãƒ¼ã®è©³ç´°ã‚’以下ã«ç¤ºã—ã¾ã™ã€‚説明ã•れãŸã‚¨ãƒ©ãƒ¼ã‚’修正ã—ã€ä»®æƒ³ãƒžã‚·ãƒ³ã®å†å®Ÿè¡Œã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2650"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2663"/>
<source>&lt;p&gt;The virtual machine execution may run into an error condition as described below. We suggest that you take an appropriate action to avert the error.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®å®Ÿè¡Œä¸­ã€ä»¥ä¸‹ã§èª¬æ˜Žã•れるエラーãŒç™ºç”Ÿã™ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯ç„¡è¦–ã§ãã¾ã™ãŒã€å‹•作を確実ã«ã™ã‚‹ãŸã‚ã«ã€èª¬æ˜Žã•れãŸèª¤ã‚Šã‚’対策ã™ã‚‹ã“ã¨ãŒæŽ¨å¥¨ã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2832"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2845"/>
<source>Sorry, some generic error happens.</source>
<translation type="unfinished">申ã—訳ã‚りã¾ã›ã‚“ã€‚ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2967"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2980"/>
<source>Failed to attach the hard disk (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) to the slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯(&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;)ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã®ã‚¹ãƒ­ãƒƒãƒˆ&lt;i&gt;&quot;%2&quot;&lt;/i&gt; ã¸ã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2973"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2986"/>
<source>Failed to attach the CD/DVD device (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) to the slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>CD/DVDデãƒã‚¤ã‚¹(&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;)ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã®ã‚¹ãƒ­ãƒƒãƒˆ&lt;i&gt;&quot;%2&quot;&lt;/i&gt; ã¸ã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2979"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2992"/>
<source>Failed to attach the floppy device (&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;) to the slot &lt;i&gt;%2&lt;/i&gt; of the machine &lt;b&gt;%3&lt;/b&gt;.</source>
<translation>フロッピーデãƒã‚¤ã‚¹(&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;)ã®ã€ä»®æƒ³ãƒžã‚·ãƒ³&lt;b&gt;&quot;%3&quot;&lt;/b&gt;ã®ã‚¹ãƒ­ãƒƒãƒˆ&lt;i&gt;&quot;%2&quot;&lt;/i&gt; ã¸ã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
@@ -5995,31 +5999,31 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;ã“ã®ä»®æƒ³ãƒžã‚·ãƒ³ã§USB 2.0を有効化ã™ã‚‹ã«ã¯&lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt;ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚VirtualBoxã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚µã‚¤ãƒˆã‹ã‚‰æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージをダウンロードã—ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。機能拡張パッケージをインストールã™ã‚‹ã¨ã€USB 2.0を有効化ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ç¾åœ¨ã®è¨­å®šã‚’キャンセルã—ãªã„å ´åˆã€USB 2.0ã¯ç„¡åŠ¹åŒ–ã•れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3189"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3202"/>
<source>Result&amp;nbsp;Code: </source>
<comment>error info</comment>
<translation>終了コード&amp;nbsp;: </translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3195"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3208"/>
<source>Component: </source>
<comment>error info</comment>
<translation>コンãƒãƒ¼ãƒãƒ³ãƒˆ: </translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3203"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3216"/>
<source>Interface: </source>
<comment>error info</comment>
<translation>インターフェース: </translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3212"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3225"/>
<source>Callee: </source>
<comment>error info</comment>
<translation>呼ã³å‡ºã—å…ˆ: </translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3220"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3233"/>
<source>Callee&amp;nbsp;RC: </source>
<comment>error info</comment>
<translation>呼ã³å‡ºã—å…ˆ&amp;nbsp;RC: </translation>
@@ -6051,7 +6055,7 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">仮想マシン&lt;b&gt;%1&lt;b&gt;ã®ã‚¹ãƒŠãƒƒãƒ—ショットä¿å­˜ãƒ•ォルダã®ãƒ‘スを&lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3032"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3045"/>
<source>&lt;p&gt;Failed to remove the shared folder &lt;b&gt;%1&lt;/b&gt; (pointing to &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;) from the virtual machine &lt;b&gt;%3&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Please close all programs in the guest OS that may be using this shared folder and try again.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン&lt;b&gt;%3&lt;/b&gt;ã®å…±æœ‰ãƒ•ォルダ&lt;b&gt;%1&lt;/b&gt;(å‚ç…§å…ˆ:&lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;&lt;/nobr&gt;)ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;ã“ã®å…±æœ‰ãƒ•ォルダを使用ã—ã¦ã„るゲストOSã®ã™ã¹ã¦ã®ãƒ—ログラムを終了ã—ã€å†å®Ÿè¡Œã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
@@ -6085,7 +6089,7 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’&quot;シームレス&quot;モードã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚&lt;b&gt;%1&lt;/b&gt;キーを押ã™ã¨ã„ã¤ã§ã‚‚ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦è¡¨ç¤ºã«æˆ»ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚注:ホストキーã¯ç¾åœ¨&lt;b&gt;%2&lt;/b&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:シームレスモードã§ã¯ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã¯è¡¨ç¤ºã•れã¾ã›ã‚“。メニューãƒãƒ¼ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ &lt;b&gt;Host+Home&lt;/b&gt;キーを押ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3056"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3069"/>
<source>&lt;p&gt;The virtual machine window is optimized to work in &lt;b&gt;%1&amp;nbsp;bit&lt;/b&gt; color mode but the virtual display is currently set to &lt;b&gt;%2&amp;nbsp;bit&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Please open the display properties dialog of the guest OS and select a &lt;b&gt;%3&amp;nbsp;bit&lt;/b&gt; color mode, if it is available, for best possible performance of the virtual video subsystem.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;. Some operating systems, like OS/2, may actually work in 32&amp;nbsp;bit mode but report it as 24&amp;nbsp;bit (16 million colors). You may try to select a different color mode to see if this message disappears or you can simply disable the message now if you are sure the required color mode (%4&amp;nbsp;bit) is not available in the guest OS.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンウィンドウã¯&lt;b&gt;%1&amp;nbsp;ビット&lt;/b&gt;ã‚«ãƒ©ãƒ¼ãƒ¢ãƒ¼ãƒ‰ã«æœ€é©åŒ–ã•れã¾ã™ãŒã€ç¾åœ¨ä»®æƒ³ãƒ‡ã‚£ã‚¹ãƒ—レイã¯&lt;b&gt;%2&amp;nbsp;ビット&lt;/b&gt;ã«è¨­å®šã•れã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;最良ã®ä»®æƒ³ãƒ“デオサブシステム性能を得るãŸã‚ã€åˆ©ç”¨å¯èƒ½ã§ã‚ã‚‹ãªã‚‰ã°ã‚²ã‚¹ãƒˆOSã®ç”»é¢è¨­å®šãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãã€&lt;b&gt;%3&amp;nbsp;ビット&lt;/b&gt;ã‚«ãƒ©ãƒ¼ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;b&gt;注:OS/2ãªã©ã€ã„ãã¤ã‹ã®ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã¯32&amp;nbsp;ビットモードã®å‹•作を24&amp;nbsp;ビット(ç´„1600万色)ã¨ã—ã¦å ±å‘Šã—ã¾ã™ã€‚ ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒæ¶ˆãˆã‚‹ã‹ã€ã¾ãŸã¯ã‚²ã‚¹ãƒˆOSã§å¿…è¦ãªè‰²æ·±åº¦(%4&amp;nbsp;ビット) ãŒåˆ©ç”¨ã§ããªã„ã“ã¨ãŒåˆ†ã‹ã£ã¦ã„ã‚‹ãªã‚‰ã°ã€å˜ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’無効ã«ã§ãã‚‹ã‹ç¢ºèªã™ã‚‹ãŸã‚ã«ç•°ãªã£ãŸè‰²æ·±åº¦ã‚’é¸æŠžã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
@@ -6094,7 +6098,7 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;仮想マシン実行中ã«é‡å¤§ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸãŸã‚ã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯åœæ­¢ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;å•題ã®è§£æ±ºã®ãŸã‚ã€&lt;a href=http://www.virtualbox.org&gt;http://www.virtualbox.org&lt;/a&gt;ã®Communityセクションをå‚ç…§ã™ã‚‹ã‹ã€ã‚µãƒãƒ¼ãƒˆå¥‘ç´„ã‚’ç· çµã—ã¦ãã ã•ã„。ã‚ãªãŸãŒã‚¨ãƒ©ãƒ¼ç™ºç”Ÿæ™‚ã«è¡Œã£ãŸæ“作ã¨å…±ã«ã€&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ ¼ç´ã•れã¦ã„るログファイル(&lt;tt&gt;VBox.log&lt;/tt&gt;)ã¨ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイル(&lt;tt&gt;VBox.png&lt;/tt&gt;)ã‚’æä¾›ã—ã¦ãã ã•ã„。注:VirualBoxメインウィンドウã®&lt;b&gt;[仮想マシン]&lt;/b&gt;メニューã‹ã‚‰[ログをå‚ç…§]ã‚’é¸æŠžã—ã¦ã€ä¸Šè¨˜ãƒ•ァイルã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想マシンを電æºã‚ªãƒ•ã™ã‚‹ã«ã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。ã“ã®ã¾ã¾ãƒ‡ãƒãƒƒã‚°ã‚’行ã†ã«ã¯&lt;b&gt;[無視]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。デãƒãƒƒã‚°ã«ã¯ç‰¹åˆ¥ãªçŸ¥è­˜ã¨ãƒ„ールを必è¦ã¨ã™ã‚‹ãŸã‚ã€&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2244"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2257"/>
<source>&lt;p&gt;You didn&apos;t attach a hard disk to the new virtual machine. The machine will not be able to boot unless you attach a hard disk with a guest operating system or some other bootable media to it later using the machine settings dialog or the First Run Wizard.&lt;/p&gt;&lt;p&gt;Do you wish to continue?&lt;/p&gt;</source>
<translation>&lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã«ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã›ã‚“。仮想マシン設定ダイアログã‹åˆå›žèµ·å‹•ウィザードを使用ã—ã¦ã‚²ã‚¹ãƒˆOSをインストールã—ãŸãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã¾ãŸã¯ä»–ã®èµ·å‹•å¯èƒ½ãªãƒ¡ãƒ‡ã‚£ã‚¢ã‚’割り当ã¦ãªã„ã¨ä»®æƒ³ãƒžã‚·ãƒ³ã¯èµ·å‹•ã—ã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;続行ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
@@ -6118,7 +6122,7 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;VirtualBox オンライン登録サービスã¸ã®æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1864"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1877"/>
<source>&lt;p&gt;Congratulations! You have been successfully registered as a user of VirtualBox.&lt;/p&gt;&lt;p&gt;Thank you for finding time to fill out the registration form!&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ç™»éŒ²ãŒå®Œäº†ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;ç™»éŒ²ãƒ•ã‚©ãƒ¼ãƒ ã«æ›¸ã込む時間を割ã„ã¦ãã ã•りã€ã‚りãŒã¨ã†ã”ã–ã„ã¾ã—ãŸï¼&lt;/p&gt;</translation>
</message>
@@ -6222,14 +6226,14 @@ p, li { white-space: pre-wrap; }
<translation>マウント</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1933"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1966"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1946"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1979"/>
<source>&lt;p&gt;The host key is currently defined as &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;</source>
<comment>additional message box paragraph</comment>
<translation>&lt;p&gt;ç¾åœ¨ãƒ›ã‚¹ãƒˆã‚­ãƒ¼ã¯&lt;b&gt;%1&lt;/b&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1940"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1953"/>
<source>Capture</source>
<comment>do input capture</comment>
<translation>キャプãƒãƒ£</translation>
@@ -6240,7 +6244,7 @@ p, li { white-space: pre-wrap; }
&lt;p&gt;&lt;b&gt;[確èª]&lt;/b&gt;ボタンをクリックã—ã¦ä»®æƒ³ãƒ‡ã‚£ã‚¹ã‚¯ãƒžãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€ã©ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„ã®ã‹ç¢ºèªã—ã¦ãã ã•ã„。ã¾ãŸã¯&lt;b&gt;[無視]&lt;/b&gt;ボタンをクリックã—ã¦ã€ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’無視ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2065"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2078"/>
<source>Check</source>
<comment>inaccessible media message box</comment>
<translation>確èª</translation>
@@ -6270,36 +6274,36 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">キャンセル</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2136"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2149"/>
<source>Switch</source>
<comment>fullscreen</comment>
<translation>切り替ãˆ</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2156"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2169"/>
<source>Switch</source>
<comment>seamless</comment>
<translation>切り替ãˆ</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2221"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2234"/>
<source>&lt;p&gt;Do you really want to reset the virtual machine?&lt;/p&gt;&lt;p&gt;This will cause any unsaved data in applications running inside it to be lost.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンを本当ã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;&lt;p&gt;仮想マシンをリセットã™ã‚‹ã¨ã€ãã®ä¸­ã§ç¨¼å‹•中ã®ã™ã¹ã¦ã®ã‚¢ãƒ—リケーションã®ä¿å­˜ã•れã¦ã„ãªã„データã¯å¤±ã‚れã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2225"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2238"/>
<source>Reset</source>
<comment>machine</comment>
<translation>リセット</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2253"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2266"/>
<source>Continue</source>
<comment>no hard disk attached</comment>
<translation>ç¶šã‘ã‚‹</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2254"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2267"/>
<source>Go Back</source>
<comment>no hard disk attached</comment>
<translation>戻る</translation>
@@ -6338,22 +6342,22 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã®ãŸã‚ã€æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報をå–å¾—ã§ãã¾ã›ã‚“:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1906"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1919"/>
<source>You are already running the most recent version of VirtualBox.</source>
<translation>最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚ 後ã§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç¢ºèªã‚’行ã£ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1918"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1931"/>
<source>&lt;p&gt;You have &lt;b&gt;clicked the mouse&lt;/b&gt; inside the Virtual Machine display or pressed the &lt;b&gt;host key&lt;/b&gt;. This will cause the Virtual Machine to &lt;b&gt;capture&lt;/b&gt; the host mouse pointer (only if the mouse pointer integration is not currently supported by the guest OS) and the keyboard, which will make them unavailable to other applications running on your host machine.&lt;/p&gt;&lt;p&gt;You can press the &lt;b&gt;host key&lt;/b&gt; at any time to &lt;b&gt;uncapture&lt;/b&gt; the keyboard and mouse (if it is captured) and return them to normal operation. The currently assigned host key is shown on the status bar at the bottom of the Virtual Machine window, next to the&amp;nbsp;&lt;img src=:/hostkey_16px.png/&gt;&amp;nbsp;icon. This icon, together with the mouse icon placed nearby, indicate the current keyboard and mouse capture state.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®ç”»é¢ã‚’&lt;b&gt;マウスクリック&lt;/b&gt;ã™ã‚‹ã‹ã€ã¾ãŸã¯&lt;b&gt;ホストキー&lt;/b&gt;を押ã™ã¨ã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯ãƒžã‚¦ã‚¹ãƒã‚¤ãƒ³ã‚¿(ãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ãŒã‚²ã‚¹ãƒˆOSã§ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ãªã„ã¨ãã ã‘)ã¨ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã‚’&lt;b&gt;キャプãƒãƒ£&lt;/b&gt;ã—ã¾ã™ã€‚仮想マシンã«ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã¨ãƒžã‚¦ã‚¹ãŒã‚­ãƒ£ãƒ—ãƒãƒ£ã•れるã¨ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã§å‹•作ã™ã‚‹ä»–ã®ã‚¢ãƒ—リケーションã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;ホストキー&lt;/b&gt;を押ã™ã¨ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã¨ãƒžã‚¦ã‚¹(キャプãƒãƒ£ã•れã¦ã„ã‚‹ã¨ã)ã¯&lt;b&gt;キャプãƒãƒ£è§£é™¤&lt;/b&gt;ã•れã€é€šå¸¸ã®æ“ä½œã«æˆ»ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ç¾åœ¨å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„るホストキーã¯ä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ä¸‹éƒ¨ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãƒãƒ¼ã«&amp;nbsp;&lt;img src=:/hostkey_16px.png/&gt;&amp;nbsp;アイコンã§è¡¨ç¤ºã•れã¾ã™ã€‚ã“ã®ã‚¢ã‚¤ã‚³ãƒ³ã¯ãƒžã‚¦ã‚¹ã‚¢ã‚¤ã‚³ãƒ³ã¨å…±ã«ç¾åœ¨ã®ã‚­ãƒ¼ãƒœâˆ’ドã¨ãƒžã‚¦ã‚¹ã®ã‚­ãƒ£ãƒ—ãƒãƒ£çŠ¶æ…‹ã‚’è¡¨ç¤ºã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1951"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1964"/>
<source>&lt;p&gt;You have the &lt;b&gt;Auto capture keyboard&lt;/b&gt; option turned on. This will cause the Virtual Machine to automatically &lt;b&gt;capture&lt;/b&gt; the keyboard every time the VM window is activated and make it unavailable to other applications running on your host machine: when the keyboard is captured, all keystrokes (including system ones like Alt-Tab) will be directed to the VM.&lt;/p&gt;&lt;p&gt;You can press the &lt;b&gt;host key&lt;/b&gt; at any time to &lt;b&gt;uncapture&lt;/b&gt; the keyboard and mouse (if it is captured) and return them to normal operation. The currently assigned host key is shown on the status bar at the bottom of the Virtual Machine window, next to the&amp;nbsp;&lt;img src=:/hostkey_16px.png/&gt;&amp;nbsp;icon. This icon, together with the mouse icon placed nearby, indicate the current keyboard and mouse capture state.&lt;/p&gt;</source>
<translation>&lt;p&gt;&lt;b&gt;キーボードã®è‡ªå‹•キャプãƒãƒ£&lt;/b&gt;æ©Ÿèƒ½ãŒæœ‰åйã§ã™ã€‚仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã®ã¨ãã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã‚’自動的ã«&lt;b&gt;キャプãƒãƒ£&lt;/b&gt;ã—ã¾ã™ã€‚キーボードãŒã‚­ãƒ£ãƒ—ãƒãƒ£ã•れるã¨ã€ã™ã¹ã¦ã®ã‚­ãƒ¼ã‚¹ãƒˆãƒ­ãƒ¼ã‚¯(Alt-Tabãªã©ã‚’å«ã‚€)ãŒä»®æƒ³ãƒžã‚·ãƒ³ã«é€ã‚‰ã‚Œã‚‹ãŸã‚ã€ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã§å‹•作ã™ã‚‹ä»–ã®ã‚¢ãƒ—リケーションã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;ホストキー&lt;/b&gt;を押ã™ã¨ã€ã‚­ãƒ¼ãƒœãƒ¼ãƒ‰ã¨ãƒžã‚¦ã‚¹(キャプãƒãƒ£ã•れã¦ã„ã‚‹ã¨ã)ã¯&lt;b&gt;キャプãƒãƒ£è§£é™¤&lt;/b&gt;ã•れã€é€šå¸¸ã®æ“ä½œã«æˆ»ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ç¾åœ¨å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„るホストキーã¯ä»®æƒ³ãƒžã‚·ãƒ³ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ä¸‹éƒ¨ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãƒãƒ¼ã«&amp;nbsp;&lt;img src=:/hostkey_16px.png/&gt;&amp;nbsp;アイコンã§è¡¨ç¤ºã•れã¾ã™ã€‚ã“ã®ã‚¢ã‚¤ã‚³ãƒ³ã¯ãƒžã‚¦ã‚¹ã‚¢ã‚¤ã‚³ãƒ³ã¨å…±ã«ç¾åœ¨ã®ã‚­ãƒ¼ãƒœâˆ’ドã¨ãƒžã‚¦ã‚¹ã®ã‚­ãƒ£ãƒ—ãƒãƒ£çŠ¶æ…‹ã‚’è¡¨ç¤ºã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1997"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2010"/>
<source>&lt;p&gt;The Virtual Machine reports that the guest OS supports &lt;b&gt;mouse pointer integration&lt;/b&gt;. This means that you do not need to &lt;i&gt;capture&lt;/i&gt; the mouse pointer to be able to use it in your guest OS -- all mouse actions you perform when the mouse pointer is over the Virtual Machine&apos;s display are directly sent to the guest OS. If the mouse is currently captured, it will be automatically uncaptured.&lt;/p&gt;&lt;p&gt;The mouse icon on the status bar will look like&amp;nbsp;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;to inform you that mouse pointer integration is supported by the guest OS and is currently turned on.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: Some applications may behave incorrectly in mouse pointer integration mode. You can always disable it for the current session (and enable it again) by selecting the corresponding action from the menu bar.&lt;/p&gt;</source>
<translation>&lt;p&gt;ゲストOSã§&lt;b&gt;マウス統åˆ&lt;/b&gt;機能ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚ゲストOSã§ãƒžã‚¦ã‚¹ãƒã‚¤ãƒ³ã‚¿ã‚’&lt;i&gt;キャプãƒãƒ£&lt;/i&gt;ã™ã‚‹ã“ã¨ãªã使用ã§ãã¾ã™ã€‚仮想マシンã®ç”»é¢ä¸Šã«ãƒžã‚¦ã‚¹ãƒã‚¤ãƒ³ã‚¿ãŒã‚ã‚‹ã¨ãã€ã™ã¹ã¦ã®ãƒžã‚¦ã‚¹ã®å‹•作ã¯ç›´æŽ¥ã‚²ã‚¹ãƒˆOSã«é€ã‚‰ã‚Œã¾ã™ã€‚ç¾åœ¨ãƒžã‚¦ã‚¹ãŒã‚­ãƒ£ãƒ—ãƒãƒ£ã•れã¦ã„ã‚‹ã¨ãã¯ã€è‡ªå‹•çš„ã«ã‚­ãƒ£ãƒ—ãƒãƒ£è§£é™¤ã•れã¾ã™ã€‚ステータスãƒãƒ¼ã®ãƒžã‚¦ã‚¹ã‚¢ã‚¤ã‚³ãƒ³ã¯ã€ãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ãŒã‚²ã‚¹ãƒˆOSã§ã‚µãƒãƒ¼ãƒˆã•れã€ç¾åœ¨æœ‰åйã§ã‚ã‚‹ã“ã¨ã‚’示ã™ãŸã‚&amp;nbsp;&lt;img src=:/mouse_seamless_16px.png/&gt;&amp;nbsp;ã®ã‚ˆã†ã«è¡¨ç¤ºã•れã¾ã™ã€‚ &lt;/p&gt;&lt;p&gt;&lt;b&gt;注&lt;/b&gt;: ãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ãŒæœ‰åйãªã¨ãã€ã„ãã¤ã‹ã®ã‚¢ãƒ—リケーションã®å‹•作ãŒä¸æ­£ã«ãªã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。メニューãƒãƒ¼ã‹ã‚‰å¯¾å¿œã™ã‚‹å‹•ä½œã‚’é¸æŠžã—ã¦ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ãƒžã‚¦ã‚¹çµ±åˆæ©Ÿèƒ½ã‚’無効化(ã¾ãŸã¯æœ‰åŠ¹åŒ–)ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
@@ -6426,7 +6430,7 @@ p, li { white-space: pre-wrap; }
<translation>è£½å“æƒ…報ダイアログを表示</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1888"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1901"/>
<source>&lt;p&gt;A new version of VirtualBox has been released! Version &lt;b&gt;%1&lt;/b&gt; is available at &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;virtualbox.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You can download this version using the link:&lt;/p&gt;&lt;p&gt;&lt;a href=%2&gt;%3&lt;/a&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBoxã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒãƒªãƒªãƒ¼ã‚¹ã•れã¾ã—ãŸï¼ ãƒãƒ¼ã‚¸ãƒ§ãƒ³ &lt;b&gt;%1&lt;/b&gt;ã¯&lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;virtualbox.org&lt;/a&gt;ã‹ã‚‰å…¥æ‰‹ã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã“ã®ãƒªãƒ³ã‚¯ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã§ãã¾ã™ã€‚: &lt;/p&gt;&lt;p&gt;&lt;a href=%2&gt;%3&lt;/a&gt;&lt;/p&gt;</translation>
</message>
@@ -6564,17 +6568,17 @@ p, li { white-space: pre-wrap; }
<translation>メディア&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;&lt;/nobr&gt;ã®ã‚¢ã‚¯ã‚»ã‚¹å¯å¦çŠ¶æ…‹ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1852"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1865"/>
<source>&lt;p&gt;Failed to connect to the VirtualBox online registration service due to the following error:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBoxã®ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ç™»éŒ²ã‚µãƒ¼ãƒ“ã‚¹ã«æŽ¥ç¶šã§ãã¾ã›ã‚“。エラー:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1898"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1911"/>
<source>&lt;p&gt;Unable to obtain the new version information due to the following error:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“。エラー:&lt;/p&gt;&lt;p&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2054"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2067"/>
<source>&lt;p&gt;One or more virtual hard disks, CD/DVD or floppy media are not currently accessible. As a result, you will not be able to operate virtual machines that use these media until they become accessible later.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;Check&lt;/b&gt; to open the Virtual Media Manager window and see what media are inaccessible, or press &lt;b&gt;Ignore&lt;/b&gt; to ignore this message.&lt;/p&gt;</source>
<translation>&lt;p&gt;一ã¤ä»¥ä¸Šã®ä»®æƒ³ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã€CD/DVDã¾ãŸã¯ãƒ•ロッピーメディアã®ã«ç¾åœ¨ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。アクセスå¯èƒ½ã«ãªã‚‹ã¾ã§ã“れらã®ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’使用ã™ã‚‹ä»®æƒ³ãƒžã‚·ãƒ³ã‚’æ“作ã§ãã¾ã›ã‚“。&lt;/p&gt;&lt;p&gt;&lt;b&gt;[確èª]&lt;/b&gt;ボタンをクリックã—ã¦ä»®æƒ³ãƒ¡ãƒ‡ã‚£ã‚¢ãƒžãƒãƒ¼ã‚¸ãƒ£ã‚’èµ·å‹•ã—ã€ã©ã®ãƒ¡ãƒ‡ã‚£ã‚¢ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ããªã„ã®ã‹ç¢ºèªã—ã¦ãã ã•ã„。ã¾ãŸã¯&lt;b&gt;[無視]&lt;/b&gt;ボタンをクリックã—ã¦ã€ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’無視ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
@@ -6606,7 +6610,7 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">上書ã(&amp;V)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2188"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2201"/>
<source>&lt;p&gt;A critical error has occurred while running the virtual machine and the machine execution has been stopped.&lt;/p&gt;&lt;p&gt;For help, please see the Community section on &lt;a href=http://www.virtualbox.org&gt;http://www.virtualbox.org&lt;/a&gt; or your support contract. Please provide the contents of the log file &lt;tt&gt;VBox.log&lt;/tt&gt; and the image file &lt;tt&gt;VBox.png&lt;/tt&gt;, which you can find in the &lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt; directory, as well as a description of what you were doing when this error happened. Note that you can also access the above files by selecting &lt;b&gt;Show Log&lt;/b&gt; from the &lt;b&gt;Machine&lt;/b&gt; menu of the main VirtualBox window.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;OK&lt;/b&gt; if you want to power off the machine or press &lt;b&gt;Ignore&lt;/b&gt; if you want to leave it as is for debugging. Please note that debugging requires special knowledge and tools, so it is recommended to press &lt;b&gt;OK&lt;/b&gt; now.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン実行中ã«é‡å¤§ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸãŸã‚ã€ä»®æƒ³ãƒžã‚·ãƒ³ã¯åœæ­¢ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;å•題ã®è§£æ±ºã®ãŸã‚ã€&lt;a href=http://www.virtualbox.org&gt;http://www.virtualbox.org&lt;/a&gt;ã®Communityセクションをå‚ç…§ã™ã‚‹ã‹ã€ã‚µãƒãƒ¼ãƒˆã«é€£çµ¡ã—ã¦ãã ã•ã„。ã‚ãªãŸãŒã‚¨ãƒ©ãƒ¼ç™ºç”Ÿæ™‚ã«è¡Œã£ãŸæ“作ã¨å…±ã«ã€&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;/nobr&gt;ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ ¼ç´ã•れã¦ã„るログファイル(&lt;tt&gt;VBox.log&lt;/tt&gt;)ã¨ã‚¤ãƒ¡ãƒ¼ã‚¸ãƒ•ァイル(&lt;tt&gt;VBox.png&lt;/tt&gt;)ã‚’æä¾›ã—ã¦ãã ã•ã„。注:VirualBoxメインウィンドウã®&lt;b&gt;[仮想マシン]&lt;/b&gt;メニューã‹ã‚‰[ログをå‚ç…§]ã‚’é¸æŠžã—ã¦ã€ä¸Šè¨˜ãƒ•ァイルã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;仮想マシンを電æºã‚ªãƒ•ã™ã‚‹ã«ã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。ã“ã®ã¾ã¾ãƒ‡ãƒãƒƒã‚°ã‚’行ã†ã«ã¯&lt;b&gt;[無視]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。デãƒãƒƒã‚°ã«ã¯ç‰¹åˆ¥ãªçŸ¥è­˜ã¨ãƒ„ールを必è¦ã¨ã™ã‚‹ãŸã‚ã€&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
@@ -6670,7 +6674,7 @@ p, li { white-space: pre-wrap; }
<location filename="../src/globals/UIMessageCenter.cpp" line="976"/>
<location filename="../src/globals/UIMessageCenter.cpp" line="989"/>
<location filename="../src/globals/UIMessageCenter.cpp" line="996"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2338"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2351"/>
<source>Continue</source>
<translation>ç¶šã‘ã‚‹</translation>
</message>
@@ -6687,7 +6691,7 @@ p, li { white-space: pre-wrap; }
<location filename="../src/globals/UIMessageCenter.cpp" line="1016"/>
<location filename="../src/globals/UIMessageCenter.cpp" line="1028"/>
<location filename="../src/globals/UIMessageCenter.cpp" line="1047"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2338"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2351"/>
<source>Cancel</source>
<translation>キャンセル</translation>
</message>
@@ -6709,13 +6713,13 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;é¸æŠžã—ãŸãƒ›ã‚¹ãƒˆ ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェース ;&lt;nobr&gt;&lt;b&gt;&quot;%1&quot;&lt;/b&gt;を除去ã—ã¾ã™ã‹ï¼Ÿ&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;注:&lt;/b&gt; ã“ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースã¯è¤‡æ•°ã®ä»®æƒ³ãƒžã‚·ãƒ³ã®1ã¤ä»¥ä¸Šã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ アタプタã§ä½¿ç”¨ä¸­ã‹ã‚‚ã—れã¾ã›ã‚“。除去ã™ã‚‹ã¨ã€ä»–ã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースåã‚’é¸ã¶ã‹ã€åˆ¥ã®å‰²ã‚Šå½“ã¦æ–¹æ³•ã‚’æ­£ã—ã設定ã™ã‚‹ã¾ã§ãれらã®ã‚¢ãƒ€ãƒ—ã‚¿ã¯å‹•作ã—ã¾ã›ã‚“。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2931"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2938"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2944"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2951"/>
<source>Failed to create the host-only network interface.</source>
<translation>ホストオンリー ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ インターフェースã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2086"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2099"/>
<source>&lt;p&gt;Your existing VirtualBox settings files will be automatically converted from the old format to a new format required by the new version of VirtualBox.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;OK&lt;/b&gt; to start VirtualBox now or press &lt;b&gt;Exit&lt;/b&gt; if you want to terminate the VirtualBox application without any further actions.&lt;/p&gt;</source>
<translation>&lt;p&gt;既存ã®VirtualBox設定ファイルã¯å¤ã„å½¢å¼ã‹ã‚‰VirtualBoxã®æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«å¿…è¦ãªå½¢å¼ã«è‡ªå‹•変æ›ã•れã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;ã™ãã«VirtualBoxã‚’èµ·å‹•ã™ã‚‹ã«ã¯&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。変æ›çµæžœã‚’ä¿å­˜ã›ãšã«VirtualBoxアプリケーションを終了ã™ã‚‹ã«ã¯&lt;b&gt;[終了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
@@ -6810,45 +6814,45 @@ p, li { white-space: pre-wrap; }
<translation type="obsolete">&lt;p&gt;VirtualBox Guest AdditionsãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ãªã„ãŸã‚ã€å…±æœ‰ãƒ•ォルダã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。共有フォルダを使用ã™ã‚‹ã«ã¯&lt;b&gt;[デãƒã‚¤ã‚¹]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«]&lt;/b&gt;ã‚’é¸ã³Guest Additionsをインストールã¾ãŸã¯å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。インストール後ã€ä»®æƒ³ãƒžã‚·ãƒ³ã‚’å†èµ·å‹•ã™ã‚‹ã¨å…±æœ‰ãƒ•ォルダãŒåˆ©ç”¨ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2272"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2285"/>
<source>Failed to open appliance.</source>
<translation>仮想アプライアンスã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2288"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2301"/>
<source>Failed to open/interpret appliance &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>仮想アプライアンス&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚ªãƒ¼ãƒ—ンã¾ãŸã¯è§£æžã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2302"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2315"/>
<source>Failed to import appliance &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>仮想アプライアンス&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message numerus="yes">
- <location filename="../src/globals/UIMessageCenter.cpp" line="2332"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2345"/>
<source>&lt;p&gt;The virtual machine(s) &lt;b&gt;%1&lt;/b&gt; are currently in a saved state.&lt;/p&gt;&lt;p&gt;If you continue the runtime state of the exported machine(s) will be discarded. Note that the existing machine(s) are not changed.&lt;/p&gt;</source>
<translation>
<numerusform>&lt;p&gt;仮想マシン&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã¯çŠ¶æ…‹ã®ä¿å­˜ä¸­ã§ã™ã€‚&lt;/p&gt;&lt;p&gt;続行ã™ã‚‹ã¨ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®ãƒ©ãƒ³ã‚¿ã‚¤ãƒ çŠ¶æ…‹ã¯ç ´æ£„ã•れã¾ã™ã€‚注:既存ã®ä»®æƒ³ãƒžã‚·ãƒ³ã¯å¤‰æ›´ã•れã¾ã›ã‚“。&lt;/p&gt;</numerusform>
</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2348"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2361"/>
<source>Failed to create appliance.</source>
<translation>仮想アプライアンスã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2356"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2375"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2369"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2388"/>
<source>Failed to prepare the export of the appliance &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>仮想アプライアンス&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã®å‰å‡¦ç†ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2370"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2383"/>
<source>Failed to create an appliance.</source>
<translation>仮想アプライアンスã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2388"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2401"/>
<source>Failed to export appliance &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>仮想アプライアンス&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
@@ -6873,22 +6877,22 @@ p, li { white-space: pre-wrap; }
<translation>&lt;p&gt;VirtualBox Guest AdditionsãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ãªã„ãŸã‚ã€å…±æœ‰ãƒ•ォルダã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。共有フォルダを使用ã™ã‚‹ã«ã¯&lt;b&gt;[デãƒã‚¤ã‚¹]&lt;/b&gt;メニューã‹ã‚‰&lt;b&gt;[Guest Additions ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«]&lt;/b&gt;ã‚’é¸ã³Guest Additionsをインストールã¾ãŸã¯å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ãã ã•ã„。インストール後ã€ä»®æƒ³ãƒžã‚·ãƒ³ã‚’å†èµ·å‹•ã™ã‚‹ã¨å…±æœ‰ãƒ•ォルダãŒåˆ©ç”¨ã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1875"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1888"/>
<source>&lt;p&gt;Invalid e-mail address or password specified.&lt;/p&gt;</source>
<translation>&lt;p&gt;無効ãªãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¾ãŸã¯ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒæŒ‡å®šã•れã¾ã—ãŸã€‚&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1878"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1891"/>
<source>&lt;p&gt;Failed to register the VirtualBox product.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBoxã®ç™»éŒ²ã«å¤±æ•—ã—ã¾ã—ãŸã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2313"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2326"/>
<source>Failed to check files.</source>
<translation>ファイルã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2324"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2337"/>
<source>Failed to remove file.</source>
<translation>ファイルã®é™¤å޻䏭ã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
@@ -7078,193 +7082,204 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../src/globals/UIMessageCenter.cpp" line="1799"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1810"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1823"/>
<source>Download</source>
<comment>extension pack</comment>
<translation type="unfinished">ダウンロード</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1806"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1805"/>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1812"/>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1819"/>
<source>&lt;p&gt;Are you sure you want to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; (size %3 bytes)?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1816"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1829"/>
<source>&lt;p&gt;The &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; has been successfully downloaded from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; and saved locally as &lt;nobr&gt;&lt;b&gt;%3&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Do you wish to install this extension pack?&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1822"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1835"/>
<source>Install</source>
<comment>extension pack</comment>
<translation type="unfinished">インストール</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1828"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1841"/>
<source>&lt;p&gt;The &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; has been successfully downloaded from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;&lt;/nobr&gt; but can&apos;t be saved locally as &lt;nobr&gt;&lt;b&gt;%3&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Please choose another location for that file.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="1838"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="1851"/>
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2097"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2115"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2110"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2128"/>
<source>E&amp;xit</source>
<comment>warnAboutSettingsAutoConversion message box</comment>
<translation>終了(&amp;X)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2103"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2116"/>
<source>&lt;p&gt;The following VirtualBox settings files will be automatically converted from the old format to a new format required by the new version of VirtualBox.&lt;/p&gt;&lt;p&gt;Press &lt;b&gt;OK&lt;/b&gt; to start VirtualBox now or press &lt;b&gt;Exit&lt;/b&gt; if you want to terminate the VirtualBox application without any further actions.&lt;/p&gt;</source>
<translation>&lt;p&gt;次ã®VirtualBox設定ファイルã¯å¤ã„å½¢å¼ã‹ã‚‰æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®VirtualBoxBoxãŒå¿…è¦ã¨ã™ã‚‹æ–°ã—ã„å½¢å¼ã«è‡ªå‹•çš„ã«å¤‰æ›´ã•れã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;&lt;b&gt;[OK]&lt;/b&gt;ボタンをクリックã—ã¦VirtualBoxã‚’èµ·å‹•ã™ã‚‹ã‹ã€è¨­å®šãƒ•ァイルã®å¤‰æ›´ã‚’行ã‚ãšã«VirtualBoxアプリケーションを終了ã•ã›ãŸã„ãªã‚‰&lt;b&gt;[終了]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2128"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2141"/>
<source>&lt;p&gt;The virtual machine window will be now switched to &lt;b&gt;fullscreen&lt;/b&gt; mode. You can go back to windowed mode at any time by pressing &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Note that the &lt;i&gt;Host&lt;/i&gt; key is currently defined as &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Note that the main menu bar is hidden in fullscreen mode. You can access it by pressing &lt;b&gt;Host+Home&lt;/b&gt;.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’&quot;フルスクリーン&quot;モードã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚&lt;b&gt;%1&lt;/b&gt;キーを押ã™ã¨ã„ã¤ã§ã‚‚ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:&lt;i&gt;ホスト&lt;/i&gt;キーã¯ç¾åœ¨&lt;b&gt;%2&lt;/b&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:フルスクリーンモードã§ã¯ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã¯è¡¨ç¤ºã•れã¾ã›ã‚“。メニューãƒãƒ¼ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ &lt;b&gt;ホスト+Home&lt;/b&gt;キーを押ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2148"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2161"/>
<source>&lt;p&gt;The virtual machine window will be now switched to &lt;b&gt;Seamless&lt;/b&gt; mode. You can go back to windowed mode at any time by pressing &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Note that the &lt;i&gt;Host&lt;/i&gt; key is currently defined as &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Note that the main menu bar is hidden in seamless mode. You can access it by pressing &lt;b&gt;Host+Home&lt;/b&gt;.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’&quot;シームレス&quot;モードã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚&lt;b&gt;%1&lt;/b&gt;キーを押ã™ã¨ã„ã¤ã§ã‚‚ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦è¡¨ç¤ºã«æˆ»ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:&lt;i&gt;ホスト&lt;/i&gt;キーã¯ç¾åœ¨&lt;b&gt;%2&lt;/b&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:シームレスモードã§ã¯ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã¯è¡¨ç¤ºã•れã¾ã›ã‚“。メニューãƒãƒ¼ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ &lt;b&gt;ホスト+Home&lt;/b&gt;キーを押ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2168"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2181"/>
<source>&lt;p&gt;The virtual machine window will be now switched to &lt;b&gt;Scale&lt;/b&gt; mode. You can go back to windowed mode at any time by pressing &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Note that the &lt;i&gt;Host&lt;/i&gt; key is currently defined as &lt;b&gt;%2&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Note that the main menu bar is hidden in scale mode. You can access it by pressing &lt;b&gt;Host+Home&lt;/b&gt;.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシンã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’&quot;スケール&quot;モードã«åˆ‡ã‚Šæ›¿ãˆã¾ã™ã€‚&lt;b&gt;%1&lt;/b&gt;キーを押ã™ã¨ã„ã¤ã§ã‚‚ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦è¡¨ç¤ºã«æˆ»ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:&lt;i&gt;ホスト&lt;/i&gt;キーã¯ç¾åœ¨&lt;b&gt;%2&lt;/b&gt;ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;注:スケールモードã§ã¯ãƒ¡ã‚¤ãƒ³ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒãƒ¼ã¯è¡¨ç¤ºã•れã¾ã›ã‚“。メニューãƒãƒ¼ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ &lt;b&gt;ホスト+Home&lt;/b&gt;キーを押ã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2176"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2189"/>
<source>Switch</source>
<comment>scale</comment>
<translation>切り替ãˆ</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2232"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2245"/>
<source>&lt;p&gt;Cannot create the machine folder &lt;b&gt;%1&lt;/b&gt; in the parent folder &lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;Please check that the parent really exists and that you have permissions to create the machine folder.&lt;/p&gt;</source>
<translation>&lt;p&gt;仮想マシン フォルダ&lt;b&gt;%1&lt;/b&gt;を親フォルダ&lt;nobr&gt;&lt;b&gt;%2&lt;/b&gt;ã«ä½œæˆã§ãã¾ã›ã‚“。&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;親フォルダã®å­˜åœ¨ã¨ã€ãƒ•ォルダ作æˆã«å¿…è¦ãªæ¨©é™ã®æœ‰ç„¡ã‚’確èªã—ã¦ãã ã•ã„。&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2409"/>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2419"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2422"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2432"/>
<source>Failed to open the Extension Pack &lt;b&gt;%1&lt;/b&gt;.</source>
<translation>機能拡張パッケージ&lt;b&gt;&quot;%1&quot;&lt;/b&gt;ã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2456"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2469"/>
<source>&lt;p&gt;You are about to install a VirtualBox extension pack. Extension packs complement the functionality of VirtualBox and can contain system level software that could be potentially harmful to your system. Please review the description below and only proceed if you have obtained the extension pack from a trusted source.&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Name:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Version:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;VirtualBox 機能拡張パッケージをインストールã—ã¾ã™ã€‚機能拡張パッケージã¯VirtualBoxã«æ©Ÿèƒ½ã‚’追加ã—ã¾ã™ãŒã€ã‚·ã‚¹ãƒ†ãƒ ã«å±å®³ã‚’与ãˆã‚‹ã‚·ã‚¹ãƒ†ãƒ ãƒ¬ãƒ™ãƒ«ã®ã‚½ãƒ•トウェアをå«ã‚€ã“ã¨ã‚‚ã§ãã¾ã™ã€‚ä¿¡é ¼ã§ãる発行元ã‹ã‚‰æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージを入手ã—ãŸå ´åˆã«é™ã‚Šã€ä»¥ä¸‹ã®å†…容を確èªã—ã¦ã€å‡¦ç†ã‚’続行ã—ã¦ãã ã•ã„。&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;åå‰:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;ãƒãƒ¼ã‚¸ãƒ§ãƒ³:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;説明:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2467"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2480"/>
<source>&amp;Install</source>
<translation>インストール(&amp;I)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2477"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2490"/>
<source>Extension packs complement the functionality of VirtualBox and can contain system level software that could be potentially harmful to your system. Please review the description below and only proceed if you have obtained the extension pack from a trusted source.</source>
<translation>機能拡張パッケージã¯VirtualBoxã«æ©Ÿèƒ½ã‚’追加ã—ã¾ã™ãŒã€ã‚·ã‚¹ãƒ†ãƒ ã«å±å®³ã‚’与ãˆã‚‹ã‚·ã‚¹ãƒ†ãƒ ãƒ¬ãƒ™ãƒ«ã®ã‚½ãƒ•トウェアをå«ã‚€ã“ã¨ã‚‚ã§ãã¾ã™ã€‚ä¿¡é ¼ã§ãる発行元ã‹ã‚‰æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージを入手ã—ãŸå ´åˆã«é™ã‚Šã€ä»¥ä¸‹ã®å†…容を確èªã—ã¦ã€å‡¦ç†ã‚’続行ã—ã¦ãã ã•ã„。</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2490"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2503"/>
<source>&lt;p&gt;An older version of the extension pack is already installed, would you like to upgrade? &lt;p&gt;%1&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Name:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;New Version:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Current Version:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚アップグレードã—ã¾ã™ã‹ï¼Ÿ&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;åå‰:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;ãƒãƒ¼ã‚¸ãƒ§ãƒ³:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;説明:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2500"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2513"/>
<source>&amp;Upgrade</source>
<translation>アップグレード(&amp;U)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2504"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2517"/>
<source>&lt;p&gt;An newer version of the extension pack is already installed, would you like to downgrade? &lt;p&gt;%1&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Name:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;New Version:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Current Version:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚ダウングレードã—ã¾ã™ã‹ï¼Ÿ&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;åå‰:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;ãƒãƒ¼ã‚¸ãƒ§ãƒ³:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;説明:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%5&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2514"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2527"/>
<source>&amp;Downgrade</source>
<translation>ダウングレード(&amp;D)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2518"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2531"/>
<source>&lt;p&gt;The extension pack is already installed with the same version, would you like reinstall it? &lt;p&gt;%1&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Name:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Version:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;åŒã˜ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®æ©Ÿèƒ½æ‹¡å¼µãƒ‘ッケージãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™ã€‚å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã‹ï¼Ÿ&lt;p&gt;%1&lt;/p&gt;&lt;p&gt;&lt;table cellpadding=0 cellspacing=0&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;åå‰:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;ãƒãƒ¼ã‚¸ãƒ§ãƒ³:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;説明:&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;&lt;td&gt;%4&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2527"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2540"/>
<source>&amp;Reinstall</source>
<translation>å†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«(&amp;R)</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2535"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2548"/>
<source>&lt;p&gt;You are about to remove the VirtualBox extension pack &lt;b&gt;%1&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Are you sure you want to proceed?&lt;/p&gt;</source>
<translation>&lt;p&gt; VirtualBox 機能拡張パッケージ&quot;&lt;b&gt;%1&lt;/b&gt;&quot;を除去ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;続行ã—ã¾ã™ã‹ï¼Ÿ&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2545"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2558"/>
<source>The extension pack &lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;nobr&gt;&lt;br&gt; was installed successfully.</source>
<translation>機能拡張パッケージ&lt;br&gt;&lt;nobr&gt;&lt;b&gt;%1&lt;/b&gt;&lt;nobr&gt;&lt;br&gt;ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«æˆåŠŸã—ã¾ã—ãŸã€‚</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2666"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2679"/>
<source>hard disk</source>
<comment>failed to mount ...</comment>
<translation>ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2668"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2681"/>
<source>CD/DVD</source>
<comment>failed to mount ... host-drive</comment>
<translation>CD/DVD</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2670"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2683"/>
<source>CD/DVD image</source>
<comment>failed to mount ...</comment>
<translation>CD/DVD イメージ</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2672"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2685"/>
<source>floppy</source>
<comment>failed to mount ... host-drive</comment>
<translation>フロッピー</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="2674"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="2687"/>
<source>floppy image</source>
<comment>failed to mount ...</comment>
<translation>フロッピー イメージ</translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3079"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3092"/>
<source>&lt;p&gt;USB 2.0 is currently enabled for this virtual machine. However, this requires the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; to be installed.&lt;/p&gt;&lt;p&gt;Please install the Extension Pack from the VirtualBox download site. After this you will be able to re-enable USB 2.0. It will be disabled in the meantime unless you cancel the current settings changes.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3135"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3148"/>
<source>Could not load the Host USB Proxy Service (VERR_FILE_NOT_FOUND). The service might not be installed on the host computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3136"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3149"/>
<source>VirtualBox is not currently allowed to access USB devices. You can change this by adding your user to the &apos;vboxusers&apos; group. Please see the user manual for a more detailed explanation</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3137"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3150"/>
<source>VirtualBox is not currently allowed to access USB devices. You can change this by allowing your user to access the &apos;usbfs&apos; folder and files. Please see the user manual for a more detailed explanation</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3138"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3151"/>
<source>The USB Proxy Service has not yet been ported to this host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../src/globals/UIMessageCenter.cpp" line="3139"/>
+ <location filename="../src/globals/UIMessageCenter.cpp" line="3152"/>
<source>Could not load the Host USB Proxy service</source>
<translation type="unfinished"></translation>
</message>
@@ -7908,12 +7923,12 @@ time depending on the image size and the write performance of your harddisk.&lt;
<context>
<name>UINewVMWzd</name>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="172"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="174"/>
<source>Create New Virtual Machine</source>
<translation>æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã®ä½œæˆ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="174"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="176"/>
<source>Create</source>
<translation type="unfinished"></translation>
</message>
@@ -8135,12 +8150,12 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>UINewVMWzdPage1</name>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="189"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="191"/>
<source>Welcome to the New Virtual Machine Wizard!</source>
<translation>よã†ã“ãæ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ä½œæˆã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¸ï¼</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="191"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="193"/>
<source>&lt;p&gt;This wizard will guide you through the steps that are necessary to create a new virtual machine for VirtualBox.&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</source>
<translation>&lt;p&gt;ã“ã®ã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã¯VirtualBoxç”¨ã®æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã‚’作æˆã™ã‚‹ãŸã‚ã«å¿…è¦ãªã‚¹ãƒ†ãƒƒãƒ—を案内ã—ã¾ã™ã€‚&lt;/p&gt;&lt;p&gt;%1&lt;/p&gt;</translation>
</message>
@@ -8163,7 +8178,7 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>OSタイプ(&amp;T)</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="249"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="251"/>
<source>VM Name and OS Type</source>
<translation>仮想マシンåã¨OSタイプ</translation>
</message>
@@ -8186,12 +8201,12 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>MB</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="355"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="357"/>
<source>Memory</source>
<translation>メモリ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="360"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="362"/>
<source>The recommended base memory size is &lt;b&gt;%1&lt;/b&gt; MB.</source>
<translation>推奨ã•れるメインメモリã®ã‚µã‚¤ã‚ºã¯&lt;b&gt;%1&lt;/b&gt;MBã§ã™ã€‚</translation>
</message>
@@ -8237,12 +8252,12 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠž...</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="449"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="451"/>
<source>Virtual Hard Disk</source>
<translation>仮想ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="454"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="456"/>
<source>The recommended size of the start-up disk is &lt;b&gt;%1&lt;/b&gt;.</source>
<translation type="unfinished">推奨ã•れる起動ディスクã®ã‚µã‚¤ã‚ºã¯&lt;b&gt;%1&lt;/b&gt;ã§ã™ã€‚</translation>
</message>
@@ -8259,24 +8274,24 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation>&lt;p&gt;æ–°è¦ä»®æƒ³ãƒžã‚·ãƒ³ã¯ä»¥ä¸‹ã®è¨­å®šã§ä½œæˆã•れã¾ã™:&lt;/p&gt;</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="650"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="652"/>
<source>Summary</source>
<translation>概è¦</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="666"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="668"/>
<source>Name</source>
<comment>summary</comment>
<translation>åå‰</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="667"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="669"/>
<source>OS Type</source>
<comment>summary</comment>
<translation>OSタイプ</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="668"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="670"/>
<source>Base Memory</source>
<comment>summary</comment>
<translation>メインメモリ</translation>
@@ -8287,13 +8302,13 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<translation type="obsolete">MB</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="678"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="680"/>
<source>Start-up Disk</source>
<comment>summary</comment>
<translation type="unfinished">èµ·å‹• ãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="685"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="687"/>
<source>&lt;p&gt;If the above is correct press the &lt;b&gt;%1&lt;/b&gt; button. Once you press it, a new virtual machine will be created. &lt;/p&gt;&lt;p&gt;Note that you can alter these and all other setting of the created virtual machine at any time using the &lt;b&gt;Settings&lt;/b&gt; dialog accessible through the menu of the main window.&lt;/p&gt;</source>
<translation>&lt;p&gt;上記ã®è¨­å®šãŒæ­£ã—ã‘れã°ã€&lt;b&gt;[%1]&lt;/b&gt;ボタンをクリックã—ã¦ãã ã•ã„。新è¦ä»®æƒ³ãƒžã‚·ãƒ³ãŒä½œæˆã•れã¾ã™ã€‚ &lt;/p&gt;&lt;p&gt;注:メインウィンドウã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ &lt;b&gt;[設定]&lt;/b&gt;ダイアログを使用ã—ã¦ã€ä½œæˆã—ãŸä»®æƒ³ãƒžã‚·ãƒ³ã®è¨­å®šã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚&lt;/p&gt;</translation>
</message>
@@ -8624,57 +8639,57 @@ step and attach hard disks later using the VM Settings dialog.&lt;/p&gt;</source
<context>
<name>UIUpdateManager</name>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="40"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="41"/>
<source>1 day</source>
<translation>1æ—¥</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="41"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="42"/>
<source>2 days</source>
<translation>2æ—¥</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="42"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="43"/>
<source>3 days</source>
<translation>3æ—¥</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="43"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="44"/>
<source>4 days</source>
<translation>4æ—¥</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="44"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="45"/>
<source>5 days</source>
<translation>5æ—¥</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="45"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="46"/>
<source>6 days</source>
<translation>6æ—¥</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="48"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="49"/>
<source>1 week</source>
<translation>1週間</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="49"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="50"/>
<source>2 weeks</source>
<translation>2週間</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="50"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="51"/>
<source>3 weeks</source>
<translation>3週間</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="53"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="54"/>
<source>1 month</source>
<translation>1月</translation>
</message>
<message>
- <location filename="../src/net/UIUpdateDefs.cpp" line="103"/>
+ <location filename="../src/net/UIUpdateDefs.cpp" line="118"/>
<source>Never</source>
<translation>確èªã—ãªã„</translation>
</message>
@@ -11665,8 +11680,8 @@ Version %1</source>
<location filename="../src/globals/VBoxGlobal.cpp" line="3663"/>
<location filename="../src/globals/VBoxGlobal.cpp" line="3716"/>
<location filename="../src/globals/VBoxGlobal.cpp" line="3774"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="363"/>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="364"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="365"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="366"/>
<location filename="../src/widgets/UIApplianceEditorWidget.cpp" line="236"/>
<location filename="../src/widgets/UIApplianceEditorWidget.cpp" line="427"/>
<source>MB</source>
@@ -11845,7 +11860,7 @@ Version %1</source>
<translation>ãƒã‚¹ãƒ†ãƒƒãƒ‰ãƒšãƒ¼ã‚¸ãƒ³ã‚°</translation>
</message>
<message>
- <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="668"/>
+ <location filename="../src/wizards/newvm/UINewVMWzd.cpp" line="670"/>
<source>MB</source>
<comment>size suffix MBytes=1024KBytes</comment>
<translation>MB</translation>
@@ -13813,12 +13828,12 @@ DOS系ゲストOSã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹å ´åˆã¯ &lt;tt&gt;net use x:¥¥vboxs
<context>
<name>VBoxSwitchMenu</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5521"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5526"/>
<source>Disable</source>
<translation>無効</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5521"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5526"/>
<source>Enable</source>
<translation>有効</translation>
</message>
@@ -14036,13 +14051,13 @@ value.&lt;/qt&gt;</source>
<context>
<name>VBoxUSBMenu</name>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5451"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5456"/>
<source>&lt;no devices available&gt;</source>
<comment>USB devices</comment>
<translation>&lt;利用ã§ãるデãƒã‚¤ã‚¹ãŒã‚りã¾ã›ã‚“&gt;</translation>
</message>
<message>
- <location filename="../src/globals/VBoxGlobal.cpp" line="5453"/>
+ <location filename="../src/globals/VBoxGlobal.cpp" line="5458"/>
<source>No supported devices connected to the host PC</source>
<comment>USB device tooltip</comment>
<translation>ãƒ›ã‚¹ãƒˆãƒžã‚·ãƒ³ã«æŽ¥ç¶šã•れãŸãƒ‡ãƒã‚¤ã‚¹ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“</translation>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts
index aca163b75..23cca3396 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_km_KH.ts
@@ -57,7 +57,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>កម្ម​វិធី​ážážºâ€‹ážŽáŸ‚ល​លីនុច​ VirtualBox (vboxdrv) មិនážáŸ’រូវ​បាន​ផ្ទុក​ ឬ​មាន​បញ្ហា​សិទ្ធិ​ជាមួយ​ /dev/vboxdrv ។ សូម​ដំឡើង​ឡើង​វិញ​ម៉ូ​​ឌុល​ážážºâ€‹ážŽáŸ‚ល​​​ដោយ​ការ​ប្រážáž·áž”ážáŸ’ážáž·â€‹â€‹ &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv ដំឡើ​ង&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;​ដូច Root ។ អ្នក​ប្រើ​យូប៊ុន​ទូ​ Fedora ឬ​ Mandriva គួរ​ážáŸ‚ដំឡើង​កញ្ចប់​ដំបូង​របស់​ DKMS ។ កញ្ចប់​នáŸáŸ‡â€‹â€‹ážáž¶áž˜â€‹ážŠáž¶áž“​​រក្សា​ទុក​​នៃ​ការ​ផ្លាស់​ប្ážáž¼ážšâ€‹ážážºâ€‹ážŽáŸ‚ល​លីនុច​ និងចង​​ក្រង​ឡើងវិញ​នៃ​​ម៉ូឌុល​ážážºážŽáŸ‚ល​របស់​ vboxdrv ប្រសិន​បើ​ចាំ​បាច់ ។</translation>
+ <translation type="obsolete">កម្ម​វិធី​ážážºâ€‹ážŽáŸ‚ល​លីនុច​ VirtualBox (vboxdrv) មិនážáŸ’រូវ​បាន​ផ្ទុក​ ឬ​មាន​បញ្ហា​សិទ្ធិ​ជាមួយ​ /dev/vboxdrv ។ សូម​ដំឡើង​ឡើង​វិញ​ម៉ូ​​ឌុល​ážážºâ€‹ážŽáŸ‚ល​​​ដោយ​ការ​ប្រážáž·áž”ážáŸ’ážáž·â€‹â€‹ &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv ដំឡើ​ង&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;​ដូច Root ។ អ្នក​ប្រើ​យូប៊ុន​ទូ​ Fedora ឬ​ Mandriva គួរ​ážáŸ‚ដំឡើង​កញ្ចប់​ដំបូង​របស់​ DKMS ។ កញ្ចប់​នáŸáŸ‡â€‹â€‹ážáž¶áž˜â€‹ážŠáž¶áž“​​រក្សា​ទុក​​នៃ​ការ​ផ្លាស់​ប្ážáž¼ážšâ€‹ážážºâ€‹ážŽáŸ‚ល​លីនុច​ និងចង​​ក្រង​ឡើងវិញ​នៃ​​ម៉ូឌុល​ážážºážŽáŸ‚ល​របស់​ vboxdrv ប្រសិន​បើ​ចាំ​បាច់ ។</translation>
</message>
<message>
<source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Please try completely uninstalling and reinstalling VirtualBox.</source>
@@ -87,6 +87,10 @@
<source>Unknown error %2 during initialization of the Runtime</source>
<translation>មិន​ស្គាល់​កំហុស​ %2 អំឡុង​ពáŸáž›â€‹ážŠáŸ‚លការ​ចាប់​ផ្ážáž¾áž˜áž–áŸáž›ážœáŸáž›áž¶â€‹ážšážáŸ‹â€‹</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5423,6 +5427,15 @@ medium</comment>
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts
index 6810dcc45..7ff4afde2 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ko.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>VirtualBox 리눅스 ì»¤ë„ ë“œë¼ì´ë²„(vboxdrv)ê°€ 불러와지지 않았거나 /dev/vobxdrvì— ì ‘ê·¼í•  수 없습니다. 루트 권한으로 ë‹¤ìŒ ëª…ë ¹ì–´ë¥¼ 실행시켜서 ì»¤ë„ ëª¨ë“ˆì„ ë‹¤ì‹œ 설정하십시오.&lt;br /&gt;&lt;br /&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;우분투, 페ë„ë¼, 맨드리바 사용ìžë“¤ê»˜ì„œëŠ” DKMS 패키지를 설치하는 ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤. ì´ íŒ¨í‚¤ì§€ë¥¼ 사용하면 리눅스 커ë„ì´ ë°”ë€Œì—ˆì„ ë•Œ ìžë™ìœ¼ë¡œ ì»¤ë„ ëª¨ë“ˆì„ ë‹¤ì‹œ 컴파ì¼í•©ë‹ˆë‹¤.</translation>
+ <translation type="obsolete">VirtualBox 리눅스 ì»¤ë„ ë“œë¼ì´ë²„(vboxdrv)ê°€ 불러와지지 않았거나 /dev/vobxdrvì— ì ‘ê·¼í•  수 없습니다. 루트 권한으로 ë‹¤ìŒ ëª…ë ¹ì–´ë¥¼ 실행시켜서 ì»¤ë„ ëª¨ë“ˆì„ ë‹¤ì‹œ 설정하십시오.&lt;br /&gt;&lt;br /&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;우분투, 페ë„ë¼, 맨드리바 사용ìžë“¤ê»˜ì„œëŠ” DKMS 패키지를 설치하는 ê²ƒì„ ì¶”ì²œí•©ë‹ˆë‹¤. ì´ íŒ¨í‚¤ì§€ë¥¼ 사용하면 리눅스 커ë„ì´ ë°”ë€Œì—ˆì„ ë•Œ ìžë™ìœ¼ë¡œ ì»¤ë„ ëª¨ë“ˆì„ ë‹¤ì‹œ 컴파ì¼í•©ë‹ˆë‹¤.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>ì´ ë²„ì „ì˜ VirtualBoxì—서는 현재 설치ë˜ì–´ 있는 ì»¤ë„ ëª¨ë“ˆì„ ì‚¬ìš©í•  수 없습니다. VirtualBox 설치 ê³¼ì •ì´ ì‹¤íŒ¨í–ˆì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; ëª…ë ¹ì„ ì‹¤í–‰ì‹œí‚¤ë©´ 문제를 í•´ê²°í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. VirtualBox OSE 버전과 PUEL ë²„ì „ì„ ê°™ì´ ì„¤ì¹˜í•˜ì§€ 마십시오..</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5862,6 +5866,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts
index 59a53e6a0..7c2502118 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts
@@ -53,7 +53,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>VirtualBox Linux branduolio modulis (vboxdrv) arba nėra įkeltas, arba nepakanka leidimų dirbti su /dev/vboxdrv. Iš naujo įdiekite branduolio modulį root teisėmis įvykdydami &lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Ubuntu, Fedora ir Mandriva platinamųjų paketų naudotojai pirma turi įsidiegti DKMS paketą. Šis paketas seka Linux branduolio pakeitimus ir, jei reikia, perkompiliuoja vboxdrv branduolio modulį.</translation>
+ <translation type="obsolete">VirtualBox Linux branduolio modulis (vboxdrv) arba nėra įkeltas, arba nepakanka leidimų dirbti su /dev/vboxdrv. Iš naujo įdiekite branduolio modulį root teisėmis įvykdydami &lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Ubuntu, Fedora ir Mandriva platinamųjų paketų naudotojai pirma turi įsidiegti DKMS paketą. Šis paketas seka Linux branduolio pakeitimus ir, jei reikia, perkompiliuoja vboxdrv branduolio modulį.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -87,6 +87,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Ši klaida reiškia, kad branduolio modulis arba negali išnaudoti pakankamai atminties, arba nepavyko atlikti kai kurių planavimo operacijų.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -4941,6 +4945,8 @@
<source>&lt;p&gt;The virtual machine(s) &lt;b&gt;%1&lt;/b&gt; are currently in a saved state.&lt;/p&gt;&lt;p&gt;If you continue the runtime state of the exported machine(s) will be discarded. Note that the existing machine(s) are not changed.&lt;/p&gt;</source>
<translation type="unfinished">
<numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -5239,6 +5245,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Nepavyko parsiųsti &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; iš &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts
index d9c3cb82b..2be7c8a1e 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>De VirtualBox Linux kernel stuurprogramma (vboxdrv) is of niet geladen of er is een probleem met de toegangsrechten van /dev/vboxdrv.Zet de kernel module opnieuw op door&lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; uit te voeren als Root. Gebruikers van Ubuntu, Fedora of Mandriva moeten het DKMS pakket als eerste installeren. Dit pakket houd de aanpassingen aan de Linux kernel bij en hercompileert de vboxdrv kernel module zo nodig.</translation>
+ <translation type="obsolete">De VirtualBox Linux kernel stuurprogramma (vboxdrv) is of niet geladen of er is een probleem met de toegangsrechten van /dev/vboxdrv.Zet de kernel module opnieuw op door&lt;br/&gt;&lt;br/&gt;&lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; uit te voeren als Root. Gebruikers van Ubuntu, Fedora of Mandriva moeten het DKMS pakket als eerste installeren. Dit pakket houd de aanpassingen aan de Linux kernel bij en hercompileert de vboxdrv kernel module zo nodig.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Deze fout betekent dat de kernel driver of teweinig geheugen kan reserveren of dat een koppeling mislukt is.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5605,6 +5609,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts
index 67f831aa5..d3fec9d85 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pl.ts
@@ -113,7 +113,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Sterownik VirtualBox dla jądra systemu Linux (vboxdrv) nie jest załadowany lub występuje problem z uprawnieniami dla /dev/vboxdrv. Należy ponownie przygotować moduł kernela, wydając polecenie&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;jako administrator. Użytkownicy systemów Ubuntu, Fedora i Mandriva powinni najpierw zainstalować pakiet DKMS. Pakiet ten śledzi zmiany kernela Linux i przekompilowuje moduł vboxdrv jeśli zachodzi taka potrzeba.</translation>
+ <translation type="obsolete">Sterownik VirtualBox dla jądra systemu Linux (vboxdrv) nie jest załadowany lub występuje problem z uprawnieniami dla /dev/vboxdrv. Należy ponownie przygotować moduł kernela, wydając polecenie&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;jako administrator. Użytkownicy systemów Ubuntu, Fedora i Mandriva powinni najpierw zainstalować pakiet DKMS. Pakiet ten śledzi zmiany kernela Linux i przekompilowuje moduł vboxdrv jeśli zachodzi taka potrzeba.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -147,6 +147,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Ten błąd oznacza, że sterownik jądra systemu nie był w stanie przydzielić odpowiedniej ilości pamięci lub nie powiodła się operacja mapowania.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6161,6 +6165,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts
index 03df661d7..72f0d43af 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt.ts
@@ -109,7 +109,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>O controlador (vboxdrv) kernel Linux do VirtualBox ou não está carregado, ou existe algum problema de permissões com /dev/vboxdrv. Por favor reinstall o módulo kernel ao executar como administrador &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Os utilizadores Ubuntu, Fedora ou Mandriva devem instalar primeiro o pacote DKMS. Este pacote mantém as alterações do kernel Linux actualizadas e recompila o módulo kernel vboxdrv se necessário.</translation>
+ <translation type="obsolete">O controlador (vboxdrv) kernel Linux do VirtualBox ou não está carregado, ou existe algum problema de permissões com /dev/vboxdrv. Por favor reinstall o módulo kernel ao executar como administrador &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. Os utilizadores Ubuntu, Fedora ou Mandriva devem instalar primeiro o pacote DKMS. Este pacote mantém as alterações do kernel Linux actualizadas e recompila o módulo kernel vboxdrv se necessário.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -143,6 +143,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Este erro significa que o controlador kernel não conseguiu alocar memória suficiente ou que falhou alfuma operação de mapeação.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5561,6 +5565,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts
index 8e64ff5ed..a31c78114 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_pt_BR.ts
@@ -113,7 +113,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>O driver de kernel para Linux do VirtualBox (vboxdrv) não está carregado, ou existe um problema de permissões no arquivo /dev/vboxdrv. Compile novamente o módulo de kernel executando o comando&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;como root. Usuários de Ubuntu, Fedora ou Mandriva devem instalar o pacote DKMS primeiro. Este pacote monitora as mudanças no kernel Linux e recompila o módulo vboxdrv automaticamente se for necessário.</translation>
+ <translation type="obsolete">O driver de kernel para Linux do VirtualBox (vboxdrv) não está carregado, ou existe um problema de permissões no arquivo /dev/vboxdrv. Compile novamente o módulo de kernel executando o comando&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;como root. Usuários de Ubuntu, Fedora ou Mandriva devem instalar o pacote DKMS primeiro. Este pacote monitora as mudanças no kernel Linux e recompila o módulo vboxdrv automaticamente se for necessário.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -147,6 +147,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Este erro indica que o driver de kernel não pode alocar memória suficiente ou que uma operação de mapeamento falhou.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6298,6 +6302,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Falha ao baixar o arquivo &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; de &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts
index 1c20abb32..be5c45ca7 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ro.ts
@@ -117,7 +117,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Fie Driverul de nucleu Linux al VirtualBox (vboxdrv) nu este încărcat fie există o problemă cu permisiunile pe /dev/vboxdrv. Vă rugăm reinstalați modulul kernel executând &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; ca root. Utilizatorii de Ubuntu, Fedora sau Mandriva ar trebui să instaleze pachetul DKMS mai întâi. Acest pachet urmărește schimbările nucleului și recompilează modulul vboxdv atunci când este cazul.</translation>
+ <translation type="obsolete">Fie Driverul de nucleu Linux al VirtualBox (vboxdrv) nu este încărcat fie există o problemă cu permisiunile pe /dev/vboxdrv. Vă rugăm reinstalați modulul kernel executând &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; ca root. Utilizatorii de Ubuntu, Fedora sau Mandriva ar trebui să instaleze pachetul DKMS mai întâi. Acest pachet urmărește schimbările nucleului și recompilează modulul vboxdv atunci când este cazul.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -151,6 +151,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5882,6 +5886,15 @@ Acest director este folosit, dacă nu este explicit specificat altfel, atunci cÃ
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts
index 6fb03660b..9c6ab5329 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ru.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Драйвер Ñдра VirtualBox ОС Linux (vboxdrv) вероÑтно не загружен, либо приÑутÑтвуют проблемы Ñ Ð¿Ñ€Ð°Ð²Ð°Ð¼Ð¸ доÑтупа к /dev/vboxdrv. Переконфигурируйте модуль Ñдра запуÑком&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;от имени админиÑтратора. ПользователÑм Ubuntu, Fedora или Mandriva Ñледует Ñперва уÑтановить пакет DKMS. Этот пакет отÑлеживает Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñдра Linux и переÑобирает модуль Ñдра vboxdrv в Ñлучае необходимоÑти.</translation>
+ <translation type="obsolete">Драйвер Ñдра VirtualBox ОС Linux (vboxdrv) вероÑтно не загружен, либо приÑутÑтвуют проблемы Ñ Ð¿Ñ€Ð°Ð²Ð°Ð¼Ð¸ доÑтупа к /dev/vboxdrv. Переконфигурируйте модуль Ñдра запуÑком&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;от имени админиÑтратора. ПользователÑм Ubuntu, Fedora или Mandriva Ñледует Ñперва уÑтановить пакет DKMS. Этот пакет отÑлеживает Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñдра Linux и переÑобирает модуль Ñдра vboxdrv в Ñлучае необходимоÑти.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Ð”Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° означает, что либо драйвер Ñдра не Ñмог выделить доÑтаточное количеÑтво памÑти, либо Ð½ÐµÐºÐ°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ Ð¿Ð°Ð¼Ñтью неудачно завершена.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5979,6 +5983,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts
index c4bdb13bd..0928c38f6 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sk.ts
@@ -109,7 +109,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>OvládaÄ Linuxového jadra pre VirtualBox (vboxdrv) buÄ nie je naÄítaný alebo je problém s právami na /dev/vboxdrv. Prosím, preinÅ¡talujte modul jadra spustením&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;ako užívateľ root. Užívatelia Ubuntu, Fedory alebo Mandrivy by mali najprv nainÅ¡talovaÅ¥ balíÄek DKMS. Tento balíÄek sleduje zmeny Linuxového jadra a prekompiluje modul jadra vboxdrv, ak je to potrebné.</translation>
+ <translation type="obsolete">OvládaÄ Linuxového jadra pre VirtualBox (vboxdrv) buÄ nie je naÄítaný alebo je problém s právami na /dev/vboxdrv. Prosím, preinÅ¡talujte modul jadra spustením&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;ako užívateľ root. Užívatelia Ubuntu, Fedory alebo Mandrivy by mali najprv nainÅ¡talovaÅ¥ balíÄek DKMS. Tento balíÄek sleduje zmeny Linuxového jadra a prekompiluje modul jadra vboxdrv, ak je to potrebné.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -143,6 +143,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Táto chyba znamená, že ovládaÄ jadra nebol schopný alokovaÅ¥ dostatok pamäte alebo zlyhala operácia mapovania.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5446,6 +5450,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts
index b12ab79b5..61f86b09a 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sr.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>VirtualBox Linux kernel driver (vboxdrv) или није учитан или нема довољно права Ñа /dev/vboxdrv. Поново инÑталирати модул Ñа&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;као root. КориÑници Ubuntu, Fedora или Mandriva требају да прво инÑталирају DKMS пакет. Пакет компилује vboxdrv ако потребно према промене језгра.</translation>
+ <translation type="obsolete">VirtualBox Linux kernel driver (vboxdrv) или није учитан или нема довољно права Ñа /dev/vboxdrv. Поново инÑталирати модул Ñа&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;као root. КориÑници Ubuntu, Fedora или Mandriva требају да прво инÑталирају DKMS пакет. Пакет компилује vboxdrv ако потребно према промене језгра.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Грешка знаћи да или кернел ноије уÑпео да алоцира довољно меморије или да је нека мапажа погрешна.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5696,6 +5700,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;ÐеуÑпешно преузимање &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; од &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts
index 8148f594e..fd5780b13 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_sv.ts
@@ -87,7 +87,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Linux-kärndrivrutinen för VirtualBox (vboxdrv) är antingen inte inläst eller så finns det ett behörighetsproblem med /dev/vboxdrv. Konfigurera om kärnmodulen genom att köra&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&quot;/etc/init.d/vboxdrv setup&quot;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; som root. Användare med Ubuntu, Fedora eller Mandriva bör installera DKMS-paketett först. Detta paket håller koll på ändringar i Linux-kärnan och kompilerar om kärnmodulen vboxdrv om det behövs.</translation>
+ <translation type="obsolete">Linux-kärndrivrutinen för VirtualBox (vboxdrv) är antingen inte inläst eller så finns det ett behörighetsproblem med /dev/vboxdrv. Konfigurera om kärnmodulen genom att köra&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&quot;/etc/init.d/vboxdrv setup&quot;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt; som root. Användare med Ubuntu, Fedora eller Mandriva bör installera DKMS-paketett först. Detta paket håller koll på ändringar i Linux-kärnan och kompilerar om kärnmodulen vboxdrv om det behövs.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -121,6 +121,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Detta fel betyder att kärndrivrutinen inte kunde allokera tillräckligt mycket minne eller att någon mappningsåtgärd misslyckades.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6199,6 +6203,15 @@ serial ports</comment>
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts
index 29f430d67..3eb486cf8 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_tr.ts
@@ -108,10 +108,6 @@
<translation>VirtualBox uygulamasının yeniden yüklenmesine yardımcı olabilir.</translation>
</message>
<message>
- <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Make sure the kernel module has been loaded successfully.</source>
<translation type="unfinished"></translation>
</message>
@@ -143,6 +139,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5395,6 +5395,15 @@ Bu Sanal Makinenin fare işaretçinizi ve klavyenizi &lt;b&gt;yakalamasına&lt;/
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts
index be67b51d1..42c7e03e2 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_uk.ts
@@ -72,7 +72,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>Драйвер Ñдра VirtualBox (vboxdrv) або не завантажений, або має проблеми з правами доÑтупу /dev/vboxdrv. ПеревÑтановіть модуль Ñдра, виконавши з-під адмініÑтратора&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. КориÑтувачі Ubuntu, Fedora або Mandriva Ñлід Ñпочатку вÑтановити DKMS. Цей пакунок утримує доріжку змін Ñ– перекомпілÑцій Ð¼Ð¾Ð´ÑƒÐ»Ñ Ñдра vboxdrv, Ñкщо це необхідно.</translation>
+ <translation type="obsolete">Драйвер Ñдра VirtualBox (vboxdrv) або не завантажений, або має проблеми з правами доÑтупу /dev/vboxdrv. ПеревÑтановіть модуль Ñдра, виконавши з-під адмініÑтратора&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;. КориÑтувачі Ubuntu, Fedora або Mandriva Ñлід Ñпочатку вÑтановити DKMS. Цей пакунок утримує доріжку змін Ñ– перекомпілÑцій Ð¼Ð¾Ð´ÑƒÐ»Ñ Ñдра vboxdrv, Ñкщо це необхідно.</translation>
</message>
<message>
<source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Please try completely uninstalling and reinstalling VirtualBox.</source>
@@ -106,6 +106,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>Ð¦Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° означає, що драйвер Ñдра не має доÑтатньо пам&apos;Ñті або помилка певної операції відображеннÑ.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -5868,6 +5872,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation>&lt;p&gt;Ðе вдалоÑÑŒ звантажити &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; з &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts
index c98d0a55e..acc1e63ed 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_xx_YY.ts
@@ -52,10 +52,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Make sure the kernel module has been loaded successfully.</source>
<translation type="unfinished"></translation>
</message>
@@ -87,6 +83,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -4406,6 +4406,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetUserManual</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts
index 7aca4a55d..35c7e7be6 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_CN.ts
@@ -121,7 +121,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</translation>
+ <translation type="obsolete">The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -155,6 +155,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>该错误æ„味ç€å½“å‰çš„å†…æ ¸é©±åŠ¨æ¨¡å—æ— æ³•分é…足够的内存或æŸäº›æ˜ å°„æ“作失败.</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -6145,6 +6149,15 @@ p, li { white-space: pre-wrap; }
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetAdditions</name>
diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts
index 0963a8da7..cd6957957 100644
--- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts
+++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_zh_TW.ts
@@ -53,7 +53,7 @@
</message>
<message>
<source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
- <translation>未載入 VirtualBox Linux æ ¸å¿ƒé©…å‹•ç¨‹å¼ (vboxdrv) 或是 /dev/vboxdrv 的權é™å•題。 請以 root 執行 &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos; 來釿–°å®‰è£æ ¸å¿ƒæ¨¡çµ„。 Ubuntu, Fedora 或 Mandriva çš„ä½¿ç”¨è€…æ‡‰å…ˆå®‰è£ DKMS 套件。 這個套件ä¿ç•™ Linux æ ¸å¿ƒè®Šæ›´çš„è¿½è¹¤ä¸¦åœ¨éœ€è¦æ™‚釿–°ç·¨è­¯ vboxdrv 核心模組。</translation>
+ <translation type="obsolete">未載入 VirtualBox Linux æ ¸å¿ƒé©…å‹•ç¨‹å¼ (vboxdrv) 或是 /dev/vboxdrv 的權é™å•題。 請以 root 執行 &lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos; 來釿–°å®‰è£æ ¸å¿ƒæ¨¡çµ„。 Ubuntu, Fedora 或 Mandriva çš„ä½¿ç”¨è€…æ‡‰å…ˆå®‰è£ DKMS 套件。 這個套件ä¿ç•™ Linux æ ¸å¿ƒè®Šæ›´çš„è¿½è¹¤ä¸¦åœ¨éœ€è¦æ™‚釿–°ç·¨è­¯ vboxdrv 核心模組。</translation>
</message>
<message>
<source>Make sure the kernel module has been loaded successfully.</source>
@@ -87,6 +87,10 @@
<source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source>
<translation>這個錯誤代表核心驅動程å¼ç„¡æ³•é…置足夠的記憶體或æŸäº›å°æ‡‰æ“作失敗。</translation>
</message>
+ <message>
+ <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing&lt;br/&gt;&lt;br/&gt; &lt;font color=blue&gt;&apos;/etc/init.d/vboxdrv setup&apos;&lt;/font&gt;&lt;br/&gt;&lt;br/&gt;as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QIArrowSplitter</name>
@@ -4406,6 +4410,15 @@
<source>&lt;p&gt;Failed to download the &lt;b&gt;&lt;nobr&gt;%1&lt;/nobr&gt;&lt;/b&gt; from &lt;nobr&gt;&lt;a href=&quot;%2&quot;&gt;%2&lt;/a&gt;.&lt;/nobr&gt;&lt;/p&gt;&lt;p&gt;%3&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>&lt;p&gt;You have version %1 of the &lt;b&gt;&lt;nobr&gt;%2&lt;/nobr&gt;&lt;/b&gt; installed.&lt;/p&gt;&lt;p&gt;You should download and install version %3 of this extension pack from Oracle!&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <comment>extension pack</comment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>UIMiniProcessWidgetUserManual</name>
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h
index f5d1a45be..f89fed96d 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.h
@@ -40,6 +40,10 @@
# define VBOXVHWA_PROFILE_FPS
#endif
+#ifdef VBOXVHWA_PROFILE_FPS
+# include <iprt/stream.h>
+#endif
+
#ifdef DEBUG
class VBoxVHWADbgTimer
{
@@ -1564,7 +1568,7 @@ public:
double fps = mFPSCounter.fps();
if(!(mFPSCounter.frames() % 31))
{
- printf("fps: %f\n", fps);
+ RTPrintf("fps: %f\n", fps);
}
mbNewFrame = false;
}
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlayCommon.h b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlayCommon.h
index 73ab04c3f..ba345f60b 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlayCommon.h
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlayCommon.h
@@ -18,7 +18,7 @@
#ifndef __VBoxFBOverlayCommon_h__
#define __VBoxFBOverlayCommon_h__
-#if defined(DEBUG_misha)
+#if 0 //defined(DEBUG_misha)
DECLINLINE(VOID) vboxDbgPrintF(LPCSTR szString, ...)
{
char szBuffer[4096] = {0};
diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp
index dfa5be24d..bd2fb4313 100644
--- a/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp
@@ -451,6 +451,7 @@ void VBoxVMInformationDlg::refreshStatistics()
/* Runtime Information */
{
CConsole console = mSession.GetConsole();
+
ULONG width = 0;
ULONG height = 0;
ULONG bpp = 0;
@@ -460,20 +461,25 @@ void VBoxVMInformationDlg::refreshStatistics()
.arg (height);
if (bpp)
resolution += QString ("x%1").arg (bpp);
- QString virtualization = console.GetDebugger().GetHWVirtExEnabled() ?
+
+ CMachineDebugger debugger = console.GetDebugger();
+ QString virtualization = debugger.GetHWVirtExEnabled() ?
VBoxGlobal::tr ("Enabled", "details report (VT-x/AMD-V)") :
VBoxGlobal::tr ("Disabled", "details report (VT-x/AMD-V)");
- QString nested = console.GetDebugger().GetHWVirtExNestedPagingEnabled() ?
+ QString nested = debugger.GetHWVirtExNestedPagingEnabled() ?
VBoxGlobal::tr ("Enabled", "details report (Nested Paging)") :
VBoxGlobal::tr ("Disabled", "details report (Nested Paging)");
- QString addVersionStr = console.GetGuest().GetAdditionsVersion();
+
+ CGuest guest = console.GetGuest();
+ QString addVersionStr = guest.GetAdditionsVersion();
if (addVersionStr.isEmpty())
- addVersionStr = tr ("Not Detected", "guest additions");
- QString osType = console.GetGuest().GetOSTypeId();
+ addVersionStr = tr("Not Detected", "guest additions");
+ QString osType = guest.GetOSTypeId();
if (osType.isEmpty())
osType = tr ("Not Detected", "guest os type");
else
osType = vboxGlobal().vmGuestOSTypeDescription (osType);
+
int vrdePort = console.GetVRDEServerInfo().GetPort();
QString vrdeInfo = (vrdePort == 0 || vrdePort == -1)?
tr ("Not Available", "details report (VRDE server port)") :
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h b/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h
index 88fa30c58..7a966b57b 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h
@@ -641,14 +641,14 @@ public:
{
clear();
mIface = that.mIface;
- addref(ptr());
+ this->addref(ptr());
}
CInterface (I *aIface)
{
clear();
setPtr (aIface);
- addref (aIface);
+ this->addref (aIface);
}
virtual ~CInterface()
@@ -701,13 +701,13 @@ public:
#endif
/* be aware of self assignment */
I* amIface = ptr();
- addref (aIface);
- release (amIface);
+ this->addref (aIface);
+ this->release (amIface);
if (aIface)
{
amIface = NULL;
B::mRC = aIface->QueryInterface (COM_IIDOF (I), (void **) &amIface);
- release (aIface);
+ this->release (aIface);
setPtr(amIface);
}
else
@@ -724,8 +724,8 @@ public:
Assert(!mDead);
#endif
/* be aware of self assignment */
- addref (aIface);
- release (ptr());
+ this->addref (aIface);
+ this->release (ptr());
setPtr(aIface);
B::mRC = S_OK;
};
@@ -736,7 +736,7 @@ public:
#ifdef DEBUG
Assert(!mDead);
#endif
- release (ptr());
+ this->release (ptr());
setPtr(NULL);
}
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
index f446d9bcd..6d05d167c 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
@@ -118,7 +118,6 @@
#include <iprt/file.h>
#include <iprt/ldr.h>
#include <iprt/system.h>
-#include <iprt/stream.h>
#ifdef VBOX_GUI_WITH_SYSTRAY
#include <iprt/process.h>
@@ -282,7 +281,8 @@ VBoxGlobal::VBoxGlobal()
, mDisableCsam(false)
, mRecompileSupervisor(false)
, mRecompileUser(false)
- , mVerString ("1.0")
+ , mVerString("1.0")
+ , m3DAvailable(false)
{
}
@@ -1656,7 +1656,7 @@ QString VBoxGlobal::detailsReport (const CMachine &aMachine, bool aWithLinks)
: tr ("Disabled", "details report (Nested Paging)");
/* VT-x/AMD-V availability: */
- bool fVTxAMDVSupported = virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+ bool fVTxAMDVSupported = host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
if (fVTxAMDVSupported)
iRowCount += 2; /* VT-x/AMD-V items. */
@@ -1711,7 +1711,7 @@ QString VBoxGlobal::detailsReport (const CMachine &aMachine, bool aWithLinks)
++rows;
}
- QString acc3d = aMachine.GetAccelerate3DEnabled()
+ QString acc3d = is3DAvailable() && aMachine.GetAccelerate3DEnabled()
? tr ("Enabled", "details report (3D Acceleration)")
: tr ("Disabled", "details report (3D Acceleration)");
@@ -2403,9 +2403,9 @@ void VBoxGlobal::startEnumeratingMedia()
mMediaList.clear();
addNullMediumToList (mMediaList, mMediaList.end());
addHardDisksToList (mVBox.GetHardDisks(), mMediaList, mMediaList.end());
- addMediumsToList (mVBox.GetHost().GetDVDDrives(), mMediaList, mMediaList.end(), VBoxDefs::MediumType_DVD);
+ addMediumsToList (mHost.GetDVDDrives(), mMediaList, mMediaList.end(), VBoxDefs::MediumType_DVD);
addMediumsToList (mVBox.GetDVDImages(), mMediaList, mMediaList.end(), VBoxDefs::MediumType_DVD);
- addMediumsToList (mVBox.GetHost().GetFloppyDrives(), mMediaList, mMediaList.end(), VBoxDefs::MediumType_Floppy);
+ addMediumsToList (mHost.GetFloppyDrives(), mMediaList, mMediaList.end(), VBoxDefs::MediumType_Floppy);
addMediumsToList (mVBox.GetFloppyImages(), mMediaList, mMediaList.end(), VBoxDefs::MediumType_Floppy);
/* enumeration thread class */
@@ -4791,6 +4791,8 @@ void VBoxGlobal::init()
msgCenter().cannotCreateVirtualBox (mVBox);
return;
}
+ mHost = virtualBox().GetHost();
+ m3DAvailable = mHost.GetAcceleration3DAvailable();
/* create default non-null global settings */
gset = VBoxGlobalSettings (false);
@@ -5289,7 +5291,8 @@ void VBoxGlobal::cleanup()
/* media list contains a lot of CUUnknown, release them */
mMediaList.clear();
- /* the last step to ensure we don't use COM any more */
+ /* the last steps to ensure we don't use COM any more */
+ mHost.detach();
mVBox.detach();
/* There may be VBoxMediaEnumEvent instances still in the message
@@ -5448,7 +5451,7 @@ void VBoxUSBMenu::processAboutToShow()
clear();
mUSBDevicesMap.clear();
- CHost host = vboxGlobal().virtualBox().GetHost();
+ CHost host = vboxGlobal().host();
bool isUSBEmpty = host.GetUSBDevices().size() == 0;
if (isUSBEmpty)
diff --git a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
index 258b4e949..3dfa4f466 100644
--- a/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
+++ b/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
@@ -134,6 +134,7 @@ public:
bool isBeta() const;
CVirtualBox virtualBox() const { return mVBox; }
+ CHost host() const { return mHost; }
VBoxGlobalSettings &settings() { return gset; }
bool setSettings (VBoxGlobalSettings &gs);
@@ -149,6 +150,8 @@ public:
void setMainWindow (QWidget *aMainWindow) { mMainWindow = aMainWindow; }
QWidget *mainWindow() const { return mMainWindow; }
+ bool is3DAvailable() const { return m3DAvailable; }
+
#ifdef VBOX_GUI_WITH_PIDFILE
void createPidfile();
void deletePidfile();
@@ -796,6 +799,7 @@ private:
bool mValid;
CVirtualBox mVBox;
+ CHost mHost;
VBoxGlobalSettings gset;
@@ -859,6 +863,8 @@ private:
QString mVerString;
QString mBrandingConfig;
+
+ int m3DAvailable;
QList <QString> mFamilyIDs;
QList <QList <CGuestOSType> > mTypes;
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp
index d61e29c3d..2e0ee4346 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.cpp
@@ -21,6 +21,7 @@
#include <QDir>
#include <QFile>
#include <QNetworkReply>
+#include <iprt/sha.h>
/* Local includes: */
#include "UIDownloaderExtensionPack.h"
@@ -60,8 +61,8 @@ void UIDownloaderExtensionPack::download(QObject *pListener)
/* Configure connections for the passed listener: */
connect(pDownloader, SIGNAL(sigToStartAcknowledging()),
pListener, SIGNAL(sigDownloaderCreatedForExtensionPack()));
- connect(pDownloader, SIGNAL(sigNotifyAboutExtensionPackDownloaded(const QString &, const QString &)),
- pListener, SLOT(sltHandleDownloadedExtensionPack(const QString &, const QString &)));
+ connect(pDownloader, SIGNAL(sigNotifyAboutExtensionPackDownloaded(const QString &, const QString &, QString)),
+ pListener, SLOT(sltHandleDownloadedExtensionPack(const QString &, const QString &, QString)));
}
UIDownloaderExtensionPack::UIDownloaderExtensionPack()
@@ -110,8 +111,9 @@ void UIDownloaderExtensionPack::handleDownloadedObject(QNetworkReply *pReply)
{
/* Read received data into buffer: */
QByteArray receivedData(pReply->readAll());
+
/* Serialize the incoming buffer into the file: */
- while (true)
+ for (;;)
{
/* Try to open file for writing: */
QFile file(target());
@@ -120,15 +122,25 @@ void UIDownloaderExtensionPack::handleDownloadedObject(QNetworkReply *pReply)
/* Write incoming buffer into the file: */
file.write(receivedData);
file.close();
+
+ /* Calc the SHA-256 on the bytes, creating a string. */
+ uint8_t abHash[RTSHA256_HASH_SIZE];
+ RTSha256(receivedData.constData(), receivedData.length(), abHash);
+ char szDigest[RTSHA256_DIGEST_LEN + 1];
+ int rc = RTSha256ToString(abHash, szDigest, sizeof(szDigest));
+ if (RT_FAILURE(rc))
+ {
+ AssertRC(rc);
+ szDigest[0] = '\0';
+ }
+
/* Notify listener about extension pack was downloaded: */
- emit sigNotifyAboutExtensionPackDownloaded(source(), target());
+ emit sigNotifyAboutExtensionPackDownloaded(source(), target(), &szDigest[0]);
break;
}
- else
- {
- /* Warn the user about extension pack was downloaded but was NOT saved, explain it: */
- msgCenter().warnAboutExtentionPackCantBeSaved(UI_ExtPackName, source(), QDir::toNativeSeparators(target()));
- }
+
+ /* Warn the user about extension pack was downloaded but was NOT saved, explain it: */
+ msgCenter().warnAboutExtentionPackCantBeSaved(UI_ExtPackName, source(), QDir::toNativeSeparators(target()));
/* Ask the user for another location for the extension pack file: */
QString strTarget = QIFileDialog::getExistingDirectory(QFileInfo(target()).absolutePath(), parentWidget(),
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.h b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.h
index 8798a5fee..35f47dc8b 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.h
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIDownloaderExtensionPack.h
@@ -54,7 +54,7 @@ public:
signals:
/* Notify listeners about extension pack downloaded: */
- void sigNotifyAboutExtensionPackDownloaded(const QString &strSource, const QString &strTarget);
+ void sigNotifyAboutExtensionPackDownloaded(const QString &strSource, const QString &strTarget, QString strHash);
private:
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp b/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp
index 6d450fef7..4d799155e 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.cpp
@@ -142,6 +142,7 @@ void UIUpdateManager::checkIfUpdateIsNecessaryForExtensionPack(bool /* fForceCal
QString strExtPackVersion(extPack.GetVersion().remove(VBOX_BUILD_PUBLISHER));
QStringList strExtPackVersionParts = strExtPackVersion.split(QRegExp("[-_]"), QString::SkipEmptyParts);
VBoxVersion extPackVersion(strExtPackVersionParts[0]);
+
/* Check if extension pack version less than required: */
if ((vboxVersion.z() % 2 != 0) /* Skip unstable VBox version */ ||
!(extPackVersion < vboxVersion) /* Ext Pack version more or equal to VBox version */)
@@ -165,11 +166,11 @@ void UIUpdateManager::checkIfUpdateIsNecessaryForExtensionPack(bool /* fForceCal
UIDownloaderExtensionPack::download(this);
}
-void UIUpdateManager::sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget)
+void UIUpdateManager::sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget, QString strDigest)
{
/* Warn the user about extension pack was downloaded and saved, propose to install it: */
if (msgCenter().proposeInstallExtentionPack(UI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget)))
- UIGlobalSettingsExtension::doInstallation(strTarget, msgCenter().mainWindowShown(), NULL);
+ UIGlobalSettingsExtension::doInstallation(strTarget, strDigest, msgCenter().mainWindowShown(), NULL);
}
/* UINewVersionChecker stuff: */
diff --git a/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h b/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h
index e7daaaa6b..3f6b03886 100644
--- a/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h
+++ b/src/VBox/Frontends/VirtualBox/src/net/UIUpdateManager.h
@@ -59,7 +59,7 @@ private slots:
void sltCheckIfUpdateIsNecessary(bool fForceCall = false);
/* Handle downloaded extension pack: */
- void sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget);
+ void sltHandleDownloadedExtensionPack(const QString &strSource, const QString &strTarget, QString strDigest);
private:
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
index 36733e1d7..d810db2d4 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
@@ -1043,11 +1043,11 @@ void UIMachineLogic::sltPrepareStorageMenu()
switch (mediumType)
{
case VBoxDefs::MediumType_DVD:
- mediums = vboxGlobal().virtualBox().GetHost().GetDVDDrives();
+ mediums = vboxGlobal().host().GetDVDDrives();
strRecentMediumAddress = VBoxDefs::GUI_RecentListCD;
break;
case VBoxDefs::MediumType_Floppy:
- mediums = vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
+ mediums = vboxGlobal().host().GetFloppyDrives();
strRecentMediumAddress = VBoxDefs::GUI_RecentListFD;
break;
default:
@@ -1330,7 +1330,7 @@ void UIMachineLogic::sltPrepareUSBMenu()
pMenu->clear();
/* Get current host: */
- CHost host = vboxGlobal().virtualBox().GetHost();
+ CHost host = vboxGlobal().host();
/* Get host USB device list: */
CHostUSBDeviceVector devices = host.GetUSBDevices();
@@ -1399,7 +1399,7 @@ void UIMachineLogic::sltAttachUSBDevice()
if (!console.isOk())
{
/* Get current host: */
- CHost host = vboxGlobal().virtualBox().GetHost();
+ CHost host = vboxGlobal().host();
/* Search the host for the corresponding USB device: */
CHostUSBDevice hostDevice = host.FindUSBDeviceById(target.id);
/* Get USB device from host USB device: */
diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
index 1a37d4ef5..0dd804a31 100644
--- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
@@ -269,7 +269,7 @@ void UISession::powerUp()
{
bool fShouldWeClose;
- bool fVTxAMDVSupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+ bool fVTxAMDVSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
QApplication::processEvents();
setPause(true);
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp b/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
index 8f1a6fb0a..2610afd73 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
@@ -168,6 +168,7 @@ private:
/* Private member vars */
CVirtualBox m_vbox;
+ CHost m_host;
CMachine m_machine;
/* Details view */
@@ -193,6 +194,7 @@ UIDetailsPagePrivate::UIDetailsPagePrivate(QWidget *aParent,
QAction *aRefreshAction /* = 0 */)
: QIWithRetranslateUI<QStackedWidget>(aParent)
, m_vbox(vboxGlobal().virtualBox())
+ , m_host(vboxGlobal().host())
, m_fChangeable(false)
, m_fUSBAvailable(true)
, m_pText(0)
@@ -632,7 +634,7 @@ void UIDetailsPagePrivate::sltUpdateSystem()
#endif /* VBOX_WITH_FULL_DETAILS_REPORT */
QStringList accel;
- if (m_vbox.GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx))
+ if (m_host.GetProcessorFeature(KProcessorFeature_HWVirtEx))
{
/* VT-x/AMD-V */
if (m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled))
diff --git a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
index b9a2185b5..2af869037 100644
--- a/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp
@@ -1030,7 +1030,7 @@ void VBoxSelectorWnd::sltOpenUrls(QList<QUrl> list /* = QList<QUrl>() */)
}
else if (VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::VBoxExtPackFileExts))
{
- UIGlobalSettingsExtension::doInstallation(strFile, this, NULL);
+ UIGlobalSettingsExtension::doInstallation(strFile, QString(), this, NULL);
}
}
}
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
index bd0d8be00..b26ac1885 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
@@ -519,7 +519,7 @@ bool UISettingsDialogGlobal::isPageAvailable(int iPageId)
{
#ifdef ENABLE_GLOBAL_USB
/* Get the host object: */
- CHost host = vboxGlobal().virtualBox().GetHost();
+ CHost host = vboxGlobal().host();
/* Show the host error message if any: */
if (!host.isReallyOk())
msgCenter().cannotAccessUSB(host);
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
index 702999050..fdf58c6cb 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
@@ -116,16 +116,26 @@ UIGlobalSettingsExtension::UIGlobalSettingsExtension()
* VBoxSelectorWnd::sltOpenUrls.
*
* @param strFilePath The path to the tarball.
+ * @param strDigest The digest of the file (SHA-256). Empty string if no
+ * digest was performed.
* @param pParent The parent widget.
* @param pstrExtPackName Where to return the extension pack name. Optional.
*/
-/*static*/ void UIGlobalSettingsExtension::doInstallation(QString const &strFilePath, QWidget *pParent, QString *pstrExtPackName)
+/*static*/ void UIGlobalSettingsExtension::doInstallation(QString const &strFilePath, QString const &strDigest,
+ QWidget *pParent, QString *pstrExtPackName)
{
/*
* Open the extpack tarball via IExtPackManager.
*/
CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
- CExtPackFile extPackFile = manager.OpenExtPackFile(strFilePath);
+ CExtPackFile extPackFile;
+ if (strDigest.isEmpty())
+ extPackFile = manager.OpenExtPackFile(strFilePath);
+ else
+ {
+ QString strFileAndHash = QString("%1::SHA-256=%2").arg(strFilePath).arg(strDigest);
+ extPackFile = manager.OpenExtPackFile(strFileAndHash);
+ }
if (!manager.isOk())
{
msgCenter().cannotOpenExtPack(strFilePath, manager, pParent);
@@ -347,7 +357,7 @@ void UIGlobalSettingsExtension::sltInstallPackage()
if (!strFilePath.isEmpty())
{
QString strExtPackName;
- doInstallation(strFilePath, this, &strExtPackName);
+ doInstallation(strFilePath, QString(), this, &strExtPackName);
/*
* Since we might be reinstalling an existing package, we have to
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.h b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.h
index b402555c3..18df82a70 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.h
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.h
@@ -50,7 +50,7 @@ public:
/* Constructor: */
UIGlobalSettingsExtension();
- static void doInstallation(QString const &strFilePath, QWidget *pParent, QString *pstrExtPackName);
+ static void doInstallation(QString const &strFilePath, QString const &strDigest, QWidget *pParent, QString *pstrExtPackName);
protected:
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp
index 7500a8874..8dbe4f274 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsNetwork.cpp
@@ -251,7 +251,7 @@ void UIGlobalSettingsNetwork::loadToCacheFrom(QVariant &data)
UISettingsPageGlobal::fetchData(data);
/* Load to cache: */
- const CHostNetworkInterfaceVector &interfaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
+ const CHostNetworkInterfaceVector &interfaces = vboxGlobal().host().GetNetworkInterfaces();
for (int iNetworkIndex = 0; iNetworkIndex < interfaces.size(); ++iNetworkIndex)
{
const CHostNetworkInterface &iface = interfaces[iNetworkIndex];
@@ -304,7 +304,7 @@ void UIGlobalSettingsNetwork::saveFromCacheTo(QVariant &data)
/* Prepare useful variables: */
CVirtualBox vbox = vboxGlobal().virtualBox();
- CHost host = vbox.GetHost();
+ CHost host = vboxGlobal().host();
/* Update all the host-only interfaces: */
for (int iNetworkIndex = 0; iNetworkIndex < m_cache.m_items.size(); ++iNetworkIndex)
@@ -410,7 +410,7 @@ void UIGlobalSettingsNetwork::sltAddInterface()
{
/* Prepare useful variables: */
CVirtualBox vbox = vboxGlobal().virtualBox();
- CHost host = vbox.GetHost();
+ CHost host = vboxGlobal().host();
/* Create new host-only interface: */
CHostNetworkInterface iface;
@@ -456,7 +456,7 @@ void UIGlobalSettingsNetwork::sltDelInterface()
/* Prepare useful variables: */
CVirtualBox vbox = vboxGlobal().virtualBox();
- CHost host = vbox.GetHost();
+ CHost host = vboxGlobal().host();
/* Find corresponding interface: */
const CHostNetworkInterface &iface = host.FindHostNetworkInterfaceByName(strInterfaceName);
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
index 8f84b7e1d..011381bf5 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp
@@ -324,6 +324,14 @@ bool UIMachineSettingsDisplay::revalidate(QString &strWarning, QString & /* strT
/* Check if video RAM requirement changed first: */
checkVRAMRequirements();
+ if (mCb3D->isChecked() && !vboxGlobal().is3DAvailable())
+ {
+ strWarning = tr("you enabled 3D acceleration. However, 3D acceleration is not "
+ "working on the current host setup so you will not be able to "
+ "start the VM.");
+ return true;
+ }
+
/* Video RAM amount test: */
if (shouldWeWarnAboutLowVideoMemory() && !m_guestOSType.isNull())
{
@@ -522,7 +530,7 @@ void UIMachineSettingsDisplay::polishPage()
mSlMonitors->setEnabled(isMachineOffline());
mLeMonitors->setEnabled(isMachineOffline());
mLbOptions->setEnabled(isMachineOffline());
- mCb3D->setEnabled(isMachineOffline() && vboxGlobal().virtualBox().GetHost().GetAcceleration3DAvailable());
+ mCb3D->setEnabled(isMachineOffline());
#ifdef VBOX_WITH_VIDEOHWACCEL
mCb2DVideo->setEnabled(isMachineOffline() && VBoxGlobal::isAcceleration2DVideoAvailable());
#endif /* VBOX_WITH_VIDEOHWACCEL */
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
index b32b2029c..a1b84df00 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsNetwork.cpp
@@ -479,7 +479,7 @@ void UIMachineSettingsNetwork::sltHandleAdvancedButtonStateChange()
void UIMachineSettingsNetwork::sltGenerateMac()
{
- m_pMACEditor->setText(vboxGlobal().virtualBox().GetHost().GenerateMACAddress());
+ m_pMACEditor->setText(vboxGlobal().host().GenerateMACAddress());
}
void UIMachineSettingsNetwork::sltOpenPortForwardingDlg()
@@ -1000,7 +1000,7 @@ void UIMachineSettingsNetworkPage::refreshBridgedAdapterList()
{
/* Reload bridged interface list: */
m_bridgedAdapterList.clear();
- const CHostNetworkInterfaceVector &ifaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
+ const CHostNetworkInterfaceVector &ifaces = vboxGlobal().host().GetNetworkInterfaces();
for (int i = 0; i < ifaces.size(); ++i)
{
const CHostNetworkInterface &iface = ifaces[i];
@@ -1033,7 +1033,7 @@ void UIMachineSettingsNetworkPage::refreshHostInterfaceList()
{
/* Reload host-only interface list: */
m_hostInterfaceList.clear();
- const CHostNetworkInterfaceVector &ifaces = vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces();
+ const CHostNetworkInterfaceVector &ifaces = vboxGlobal().host().GetNetworkInterfaces();
for (int i = 0; i < ifaces.size(); ++i)
{
const CHostNetworkInterface &iface = ifaces[i];
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp
index b088052a9..2d954120d 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSystem.cpp
@@ -38,7 +38,7 @@ UIMachineSettingsSystem::UIMachineSettingsSystem()
/* Setup constants */
CSystemProperties properties = vboxGlobal().virtualBox().GetSystemProperties();
- uint hostCPUs = vboxGlobal().virtualBox().GetHost().GetProcessorCount();
+ uint hostCPUs = vboxGlobal().host().GetProcessorCount();
mMinGuestCPU = properties.GetMinGuestCPUCount();
mMaxGuestCPU = RT_MIN (2 * hostCPUs, properties.GetMaxGuestCPUCount());
mMinGuestCPUExecCap = 1;
@@ -226,8 +226,8 @@ void UIMachineSettingsSystem::loadToCacheFrom(QVariant &data)
}
}
/* Gather other system data: */
- systemData.m_fPFHwVirtExSupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx);
- systemData.m_fPFPAESupported = vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_PAE);
+ systemData.m_fPFHwVirtExSupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_HWVirtEx);
+ systemData.m_fPFPAESupported = vboxGlobal().host().GetProcessorFeature(KProcessorFeature_PAE);
systemData.m_fIoApicEnabled = m_machine.GetBIOSSettings().GetIOAPICEnabled();
systemData.m_fEFIEnabled = m_machine.GetFirmwareType() >= KFirmwareType_EFI && m_machine.GetFirmwareType() <= KFirmwareType_EFIDUAL;
systemData.m_fUTCEnabled = m_machine.GetRTCUseUTC();
@@ -386,7 +386,7 @@ void UIMachineSettingsSystem::setValidator (QIWidgetValidator *aVal)
bool UIMachineSettingsSystem::revalidate (QString &aWarning, QString & /* aTitle */)
{
- ulong fullSize = vboxGlobal().virtualBox().GetHost().GetMemorySize();
+ ulong fullSize = vboxGlobal().host().GetMemorySize();
if (mSlMemory->value() > (int)mSlMemory->maxRAMAlw())
{
aWarning = tr (
@@ -409,7 +409,7 @@ bool UIMachineSettingsSystem::revalidate (QString &aWarning, QString & /* aTitle
}
/* VCPU amount test */
- int totalCPUs = vboxGlobal().virtualBox().GetHost().GetProcessorOnlineCount();
+ int totalCPUs = vboxGlobal().host().GetProcessorOnlineCount();
if (mSlCPU->value() > 2 * totalCPUs)
{
aWarning = tr (
diff --git a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp
index 51fc5bbdd..dc76036df 100644
--- a/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp
@@ -154,7 +154,7 @@ void UIMachineSettingsUSB::loadToCacheFrom(QVariant &data)
case UISettingsPageType_Global:
{
/* For each USB filter: */
- const CHostUSBDeviceFilterVector &filters = vboxGlobal().virtualBox().GetHost().GetUSBDeviceFilters();
+ const CHostUSBDeviceFilterVector &filters = vboxGlobal().host().GetUSBDeviceFilters();
for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
{
/* Prepare USB filter data: */
@@ -349,7 +349,7 @@ void UIMachineSettingsUSB::saveFromCacheTo(QVariant &data)
if (isMachineInValidMode())
{
/* Get host: */
- CHost host = vboxGlobal().virtualBox().GetHost();
+ CHost host = vboxGlobal().host();
/* For each USB filter data set: */
for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
{
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
index c194e4742..f023e315d 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
@@ -63,7 +63,7 @@ uint VBoxGuestRAMSlider::maxRAM() const
void VBoxGuestRAMSlider::init()
{
- ulong fullSize = vboxGlobal().virtualBox().GetHost().GetMemorySize();
+ ulong fullSize = vboxGlobal().host().GetMemorySize();
CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
mMinRAM = sys.GetMinGuestRAM();
mMaxRAM = RT_MIN (RT_ALIGN (fullSize, _1G / _1M), sys.GetMaxGuestRAM());
diff --git a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
index 7d453c8a6..cf6c38376 100644
--- a/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
@@ -53,7 +53,7 @@ VBoxOSTypeSelectorWidget::VBoxOSTypeSelectorWidget (QWidget *aParent)
mPxTypeIcon->setFixedSize (32, 32);
/* Check if host supports (AMD-V or VT-x) and long mode */
- CHost host = vboxGlobal().virtualBox().GetHost();
+ CHost host = vboxGlobal().host();
m_fSupportsHWVirtEx = host.GetProcessorFeature(KProcessorFeature_HWVirtEx);
m_fSupportsLongMode = host.GetProcessorFeature(KProcessorFeature_LongMode);
diff --git a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp
index c6f7930ec..bac16759b 100644
--- a/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp
+++ b/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UINewVMWzd.cpp
@@ -81,12 +81,12 @@ static const osTypePattern gs_OSTypePattern[] =
{ QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
/* Code names for Linux distributions */
- { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
- { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)", Qt::CaseInsensitive), "Ubuntu" },
+ { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
+ { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
{ QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)).*64", Qt::CaseInsensitive), "Debian_64" },
{ QRegExp("(sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)", Qt::CaseInsensitive), "Debian" },
- { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)).*64", Qt::CaseInsensitive), "Fedora_64" },
- { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)", Qt::CaseInsensitive), "Fedora" },
+ { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)).*64", Qt::CaseInsensitive), "Fedora_64" },
+ { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
/* Regular names of Linux distributions */
{ QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
@@ -836,6 +836,10 @@ bool UINewVMWzdPage5::constructMachine()
/* Set UTC flags */
m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
+ /* 4.1 hack for r74477 -- no API changes allowed */
+ if (typeId.startsWith("Windows8"))
+ m_Machine.SetAccelerate3DEnabled(true);
+
/* Register the VM prior to attaching hard disks */
vbox.RegisterMachine(m_Machine);
if (!vbox.isOk())
diff --git a/src/VBox/GuestHost/OpenGL/include/GL/glext.h b/src/VBox/GuestHost/OpenGL/include/GL/glext.h
index 17db4b69e..5d194243e 100644
--- a/src/VBox/GuestHost/OpenGL/include/GL/glext.h
+++ b/src/VBox/GuestHost/OpenGL/include/GL/glext.h
@@ -785,6 +785,11 @@ extern "C" {
#define GL_MIRRORED_REPEAT_ARB 0x8370
#endif
+#ifndef GL_ATI_texture_mirror_once
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#endif
+
#ifndef GL_ARB_depth_texture
#define GL_DEPTH_COMPONENT16_ARB 0x81A5
#define GL_DEPTH_COMPONENT24_ARB 0x81A6
@@ -4504,6 +4509,10 @@ typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type
#define GL_ARB_texture_mirrored_repeat 1
#endif
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+#endif
+
#ifndef GL_ARB_depth_texture
#define GL_ARB_depth_texture 1
#endif
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_error.h b/src/VBox/GuestHost/OpenGL/include/cr_error.h
index 1482770ca..dace64942 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_error.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_error.h
@@ -34,11 +34,20 @@ DECLEXPORT(void) crError(const char *format, ... ) NORETURN_PRINTF;
/* Throw more info while opengl is not stable */
#if defined(DEBUG) || 1
-#define CRASSERT( PRED ) ((PRED)?(void)0:crError( "Assertion failed: %s, file %s, line %d", #PRED, __FILE__, __LINE__))
-#define THREADASSERT( PRED ) ((PRED)?(void)0:crError( "Are you trying to run a threaded app ?\nBuild with 'make threadsafe'\nAssertion failed: %s, file %s, line %d", #PRED, __FILE__, __LINE__))
+# ifdef DEBUG_misha
+# include <iprt/assert.h>
+# define CRASSERT Assert
+//extern int g_VBoxFbgFBreakDdi;
+# define CR_DDI_PROLOGUE() do { /*if (g_VBoxFbgFBreakDdi) {Assert(0);}*/ } while (0)
+# else
+# define CRASSERT( PRED ) ((PRED)?(void)0:crError( "Assertion failed: %s, file %s, line %d", #PRED, __FILE__, __LINE__))
+# define CR_DDI_PROLOGUE() do {} while (0)
+# endif
+# define THREADASSERT( PRED ) ((PRED)?(void)0:crError( "Are you trying to run a threaded app ?\nBuild with 'make threadsafe'\nAssertion failed: %s, file %s, line %d", #PRED, __FILE__, __LINE__))
#else
-#define CRASSERT( PRED ) ((void)0)
-#define THREADASSERT( PRED ) ((void)0)
+# define CRASSERT( PRED ) ((void)0)
+# define THREADASSERT( PRED ) ((void)0)
+# define CR_DDI_PROLOGUE() do {} while (0)
#endif
#ifdef __cplusplus
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_extstring.h b/src/VBox/GuestHost/OpenGL/include/cr_extstring.h
index 9478b3a7a..f4632da3a 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_extstring.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_extstring.h
@@ -82,7 +82,10 @@ static const char *crExtensions =
"GL_ARB_texture_env_dot3 GL_EXT_texture_env_dot3 "
#endif
#ifdef CR_ARB_texture_mirrored_repeat
- "GL_ARB_texture_mirrored_repeat "
+ "GL_ARB_texture_mirrored_repeat GL_IBM_texture_mirrored_repeat "
+#endif
+#ifdef CR_ATI_texture_mirror_once
+ "GL_ATI_texture_mirror_once "
#endif
#ifdef CR_ARB_texture_non_power_of_two
"GL_ARB_texture_non_power_of_two "
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_glstate.h b/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
index 329e3eb5a..013672aad 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
@@ -206,6 +206,9 @@ DECLEXPORT(void) crStateSetCurrent(CRContext *ctx);
DECLEXPORT(CRContext *) crStateGetCurrent(void);
DECLEXPORT(void) crStateDestroyContext(CRContext *ctx);
+CRContext * crStateSwichPrepare(CRContext *toCtx);
+void crStateSwichPostprocess(CRContext *fromCtx);
+
DECLEXPORT(void) crStateFlushFunc( CRStateFlushFunc ff );
DECLEXPORT(void) crStateFlushArg( void *arg );
DECLEXPORT(void) crStateDiffAPI( SPUDispatchTable *api );
diff --git a/src/VBox/GuestHost/OpenGL/include/cr_version.h b/src/VBox/GuestHost/OpenGL/include/cr_version.h
index 8ddea1181..bc9ffdf1e 100644
--- a/src/VBox/GuestHost/OpenGL/include/cr_version.h
+++ b/src/VBox/GuestHost/OpenGL/include/cr_version.h
@@ -67,6 +67,7 @@
#define CR_ARB_texture_env_crossbar 1
#define CR_ARB_texture_env_dot3 1
#define CR_ARB_texture_mirrored_repeat 1
+#define CR_ATI_texture_mirror_once 1
#define CR_ARB_texture_non_power_of_two 1
#define CR_ARB_transpose_matrix 1
#define CR_ARB_vertex_buffer_object 1
diff --git a/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h b/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
index 2707660dd..954f211db 100644
--- a/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
+++ b/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
@@ -66,6 +66,10 @@ typedef struct {
DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectInit(CRContext *ctx);
DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectDestroy(CRContext *ctx);
DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectSwitch(CRContext *from, CRContext *to);
+
+DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectDisableHW(CRContext *ctx);
+DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectReenableHW(CRContext *fromCtx, CRContext *toCtx);
+
DECLEXPORT(GLuint) STATE_APIENTRY crStateGetFramebufferHWID(GLuint id);
DECLEXPORT(GLuint) STATE_APIENTRY crStateGetRenderbufferHWID(GLuint id);
diff --git a/src/VBox/GuestHost/OpenGL/include/state/cr_limits.h b/src/VBox/GuestHost/OpenGL/include/state/cr_limits.h
index 9f93e0c58..0378ff07f 100644
--- a/src/VBox/GuestHost/OpenGL/include/state/cr_limits.h
+++ b/src/VBox/GuestHost/OpenGL/include/state/cr_limits.h
@@ -258,6 +258,7 @@ typedef struct {
GLboolean NV_vertex_program2;
GLboolean SGIS_generate_mipmap;
GLboolean EXT_texture_from_pixmap;
+ GLboolean ATI_texture_mirror_once;
/* derived from above */
GLboolean any_vertex_program; /* NV or ARB */
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
index 60ec1ee12..dba42d4bc 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
@@ -344,3 +344,26 @@ void crStateSwitchContext( CRContext *from, CRContext *to )
crStateApplyFBImage(to);
#endif
}
+
+CRContext * crStateSwichPrepare(CRContext *toCtx)
+{
+ CRContext *fromCtx = GetCurrentContext();
+
+#ifdef CR_EXT_framebuffer_object
+ if (fromCtx)
+ crStateFramebufferObjectDisableHW(fromCtx);
+#endif
+
+ return fromCtx;
+}
+
+void crStateSwichPostprocess(CRContext *fromCtx)
+{
+ CRContext *toCtx = GetCurrentContext();;
+ if (!fromCtx || !toCtx)
+ return;
+
+#ifdef CR_EXT_framebuffer_object
+ crStateFramebufferObjectReenableHW(fromCtx, toCtx);
+#endif
+}
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
index 46ecb9e8e..73c49c3d4 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
@@ -747,11 +747,73 @@ crStateFramebufferObjectSwitch(CRContext *from, CRContext *to)
}
}
+DECLEXPORT(void) STATE_APIENTRY
+crStateFramebufferObjectDisableHW(CRContext *ctx)
+{
+ GLboolean fAdjustDrawReadBuffers = GL_FALSE;
+
+ if (ctx->framebufferobject.drawFB)
+ {
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+ fAdjustDrawReadBuffers = GL_TRUE;
+ }
+
+ if (ctx->framebufferobject.readFB)
+ {
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
+ fAdjustDrawReadBuffers = GL_TRUE;
+ }
+
+ if (fAdjustDrawReadBuffers)
+ {
+ diff_api.DrawBuffer(GL_BACK);
+ diff_api.ReadBuffer(GL_BACK);
+ }
+
+ if (ctx->framebufferobject.renderbuffer)
+ diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+}
+
+DECLEXPORT(void) STATE_APIENTRY
+crStateFramebufferObjectReenableHW(CRContext *fromCtx, CRContext *toCtx)
+{
+ GLboolean fAdjustDrawReadBuffers = GL_FALSE;
+
+ if (fromCtx->framebufferobject.drawFB /* <- the FBO state was reset in crStateFramebufferObjectDisableHW */
+ && fromCtx->framebufferobject.drawFB == toCtx->framebufferobject.drawFB) /* .. and it was NOT restored properly in crStateFramebufferObjectSwitch */
+ {
+ diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, toCtx->framebufferobject.drawFB->hwid);
+ fAdjustDrawReadBuffers = GL_TRUE;
+ }
+
+ if (fromCtx->framebufferobject.readFB /* <- the FBO state was reset in crStateFramebufferObjectDisableHW */
+ && fromCtx->framebufferobject.readFB == toCtx->framebufferobject.readFB) /* .. and it was NOT restored properly in crStateFramebufferObjectSwitch */
+ {
+ diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, toCtx->framebufferobject.readFB->hwid);
+ fAdjustDrawReadBuffers = GL_TRUE;
+ }
+
+ if (fAdjustDrawReadBuffers)
+ {
+ diff_api.DrawBuffer(toCtx->framebufferobject.drawFB?toCtx->framebufferobject.drawFB->drawbuffer[0]:toCtx->buffer.drawBuffer);
+ diff_api.ReadBuffer(toCtx->framebufferobject.readFB?toCtx->framebufferobject.readFB->readbuffer:toCtx->buffer.readBuffer);
+ }
+
+ if (fromCtx->framebufferobject.renderbuffer /* <- the FBO state was reset in crStateFramebufferObjectDisableHW */
+ && fromCtx->framebufferobject.renderbuffer==toCtx->framebufferobject.renderbuffer) /* .. and it was NOT restored properly in crStateFramebufferObjectSwitch */
+ {
+ diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, toCtx->framebufferobject.renderbuffer->hwid);
+ }
+}
+
+
DECLEXPORT(GLuint) STATE_APIENTRY crStateGetFramebufferHWID(GLuint id)
{
CRContext *g = GetCurrentContext();
CRFramebufferObject *pFBO = (CRFramebufferObject*) crHashtableSearch(g->shared->fbTable, id);
-
+#ifdef DEBUG_misha
+ crDebug("FB id(%d) hw(%d)", id, pFBO ? pFBO->hwid : 0);
+#endif
return pFBO ? pFBO->hwid : 0;
}
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_limits.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_limits.c
index 42c6c03c1..91cdd84f1 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_limits.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_limits.c
@@ -291,6 +291,9 @@ void crStateExtensionsInit( CRLimitsState *limits, CRExtensionState *extensions
if (hasExtension((const char*)limits->extensions, "GL_ARB_texture_mirrored_repeat"))
extensions->ARB_texture_mirrored_repeat = GL_TRUE;
+ if (hasExtension((const char*)limits->extensions, "GL_ATI_texture_mirror_once"))
+ extensions->ATI_texture_mirror_once = GL_TRUE;
+
if (hasExtension((const char*)limits->extensions, "GL_ARB_texture_non_power_of_two"))
extensions->ARB_texture_non_power_of_two = GL_TRUE;
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
index 8709b2a15..a0d6e2017 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c
@@ -1018,7 +1018,27 @@ int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
pContext->buffer.storedWidth = pContext->buffer.width;
pContext->buffer.storedHeight = pContext->buffer.height;
- rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
+ CRASSERT(VBoxTlsRefIsFunctional(pContext));
+
+ /* do not increment the saved state version due to VBOXTLSREFDATA addition to CRContext */
+ rc = SSMR3PutMem(pSSM, pContext, VBOXTLSREFDATA_OFFSET(CRContext));
+ AssertRCReturn(rc, rc);
+
+ /* now store bitid & neg_bitid */
+ rc = SSMR3PutMem(pSSM, pContext->bitid, sizeof (pContext->bitid) + sizeof (pContext->neg_bitid));
+ AssertRCReturn(rc, rc);
+
+ /* the pre-VBOXTLSREFDATA CRContext structure might have additional allignment bits before the CRContext::shared */
+ ui32 = VBOXTLSREFDATA_OFFSET(CRContext) + sizeof (pContext->bitid) + sizeof (pContext->neg_bitid);
+ ui32 &= (sizeof (void*) - 1);
+ if (ui32)
+ {
+ void* pTmp = NULL;
+ rc = SSMR3PutMem(pSSM, &pTmp, ui32);
+ AssertRCReturn(rc, rc);
+ }
+
+ rc = SSMR3PutMem(pSSM, &pContext->shared, sizeof (CRContext) - RT_OFFSETOF(CRContext, shared));
AssertRCReturn(rc, rc);
if (crHashtableNumElements(pContext->shared->dlistTable)>0)
@@ -1378,6 +1398,10 @@ static void crStateFindSharedCB(unsigned long key, void *data1, void *data2)
#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
+AssertCompile(VBOXTLSREFDATA_SIZE() <= CR_MAX_BITARRAY);
+AssertCompile(VBOXTLSREFDATA_STATE_INITIALIZED != 0);
+AssertCompile(RT_OFFSETOF(CRContext, shared) >= VBOXTLSREFDATA_OFFSET(CRContext) + VBOXTLSREFDATA_SIZE() + RT_SIZEOFMEMB(CRContext, bitid) + RT_SIZEOFMEMB(CRContext, neg_bitid));
+
int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PSSMHANDLE pSSM)
{
CRContext* pTmpContext;
@@ -1385,6 +1409,12 @@ int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PSSMHAN
uint32_t uiNumElems, ui, k;
unsigned long key;
GLboolean bLoadShared = GL_TRUE;
+ union {
+ CRbitvalue bitid[CR_MAX_BITARRAY];
+ struct {
+ VBOXTLSREFDATA
+ } tlsRef;
+ } bitid;
CRASSERT(pContext && pSSM);
@@ -1393,7 +1423,56 @@ int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PSSMHAN
if (!pTmpContext)
return VERR_NO_MEMORY;
- rc = SSMR3GetMem(pSSM, pTmpContext, sizeof(*pTmpContext));
+ CRASSERT(VBoxTlsRefIsFunctional(pContext));
+
+ /* do not increment the saved state version due to VBOXTLSREFDATA addition to CRContext */
+ rc = SSMR3GetMem(pSSM, pTmpContext, VBOXTLSREFDATA_OFFSET(CRContext));
+ AssertRCReturn(rc, rc);
+
+ /* VBox 4.1.8 had a bug that VBOXTLSREFDATA was also stored in the snapshot,
+ * thus the saved state data format was changed w/o changing the saved state version.
+ * here we determine whether the saved state contains VBOXTLSREFDATA, and if so, treat it accordingly */
+ rc = SSMR3GetMem(pSSM, &bitid, sizeof (bitid));
+ AssertRCReturn(rc, rc);
+
+ /* the bitid array has one bit set only. this is why if bitid.tlsRef has both cTlsRefs
+ * and enmTlsRefState non-zero - this is definitely NOT a bit id and is a VBOXTLSREFDATA */
+ if (bitid.tlsRef.enmTlsRefState == VBOXTLSREFDATA_STATE_INITIALIZED
+ && bitid.tlsRef.cTlsRefs)
+ {
+ /* VBOXTLSREFDATA is stored, skip it */
+ crMemcpy(&pTmpContext->bitid, ((uint8_t*)&bitid) + VBOXTLSREFDATA_SIZE(), sizeof (bitid) - VBOXTLSREFDATA_SIZE());
+ rc = SSMR3GetMem(pSSM, ((uint8_t*)&pTmpContext->bitid) + sizeof (pTmpContext->bitid) - VBOXTLSREFDATA_SIZE(), sizeof (pTmpContext->neg_bitid) + VBOXTLSREFDATA_SIZE());
+ AssertRCReturn(rc, rc);
+
+ ui = VBOXTLSREFDATA_OFFSET(CRContext) + VBOXTLSREFDATA_SIZE() + sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid);
+ ui = RT_OFFSETOF(CRContext, shared) - ui;
+ }
+ else
+ {
+ /* VBOXTLSREFDATA is NOT stored */
+ crMemcpy(&pTmpContext->bitid, &bitid, sizeof (bitid));
+ rc = SSMR3GetMem(pSSM, &pTmpContext->neg_bitid, sizeof (pTmpContext->neg_bitid));
+ AssertRCReturn(rc, rc);
+
+ /* the pre-VBOXTLSREFDATA CRContext structure might have additional allignment bits before the CRContext::shared */
+ ui = VBOXTLSREFDATA_OFFSET(CRContext) + sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid);
+
+ ui &= (sizeof (void*) - 1);
+ }
+
+ if (ui)
+ {
+ void* pTmp = NULL;
+ rc = SSMR3GetMem(pSSM, &pTmp, ui);
+ AssertRCReturn(rc, rc);
+ }
+
+ /* we will later do crMemcpy from entire pTmpContext to pContext,
+ * for simplicity store the VBOXTLSREFDATA from the pContext to pTmpContext */
+ VBOXTLSREFDATA_COPY(pTmpContext, pContext);
+
+ rc = SSMR3GetMem(pSSM, &pTmpContext->shared, sizeof (CRContext) - RT_OFFSETOF(CRContext, shared));
AssertRCReturn(rc, rc);
/* Deal with shared state */
@@ -1566,6 +1645,7 @@ int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PSSMHAN
/* Have to preserve original context id */
CRASSERT(pTmpContext->id == pContext->id);
+ CRASSERT(VBOXTLSREFDATA_EQUAL(pContext, pTmpContext));
/* Copy ordinary state to real context */
crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
crFree(pTmpContext);
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
index b23c7d94f..a8a3c665d 100644
--- a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
@@ -13,6 +13,10 @@
#include "cr_version.h"
#include "state_internals.h"
+#ifdef DEBUG_misha
+#include <iprt/assert.h>
+#endif
+
#define UNUSED(x) ((void) (x))
#define GET_TOBJ(tobj, state, id) \
@@ -1023,6 +1027,11 @@ crStateTexParameterfv(GLenum target, GLenum pname, const GLfloat *param)
tobj->wrapS = e;
}
#endif
+#ifdef CR_ATI_texture_mirror_once
+ else if ((e == GL_MIRROR_CLAMP_ATI || e == GL_MIRROR_CLAMP_TO_EDGE_ATI) && g->extensions.ATI_texture_mirror_once) {
+ tobj->wrapS = e;
+ }
+#endif
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"TexParameterfv: GL_TEXTURE_WRAP_S invalid param: 0x%x", e);
@@ -1053,6 +1062,11 @@ crStateTexParameterfv(GLenum target, GLenum pname, const GLfloat *param)
tobj->wrapT = e;
}
#endif
+#ifdef CR_ATI_texture_mirror_once
+ else if ((e == GL_MIRROR_CLAMP_ATI || e == GL_MIRROR_CLAMP_TO_EDGE_ATI) && g->extensions.ATI_texture_mirror_once) {
+ tobj->wrapT = e;
+ }
+#endif
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"TexParameterfv: GL_TEXTURE_WRAP_T invalid param: 0x%x", e);
@@ -1082,6 +1096,11 @@ crStateTexParameterfv(GLenum target, GLenum pname, const GLfloat *param)
tobj->wrapR = e;
}
#endif
+#ifdef CR_ATI_texture_mirror_once
+ else if ((e == GL_MIRROR_CLAMP_ATI || e == GL_MIRROR_CLAMP_TO_EDGE_ATI) && g->extensions.ATI_texture_mirror_once) {
+ tobj->wrapR = e;
+ }
+#endif
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"TexParameterfv: GL_TEXTURE_WRAP_R invalid param: 0x%x", e);
@@ -3183,6 +3202,22 @@ DECLEXPORT(GLuint) STATE_APIENTRY crStateGetTextureHWID(GLuint id)
CRContext *g = GetCurrentContext();
CRTextureObj *tobj = GET_TOBJ(tobj, g, id);
+#ifdef DEBUG_misha
+ if (id)
+ {
+ Assert(tobj);
+ }
+ else
+ {
+ Assert(!tobj);
+ }
+ if (tobj)
+ {
+ crDebug("tex id(%d), hwid(%d)", tobj->id, tobj->hwid);
+ }
+#endif
+
+
return tobj ? crStateGetTextureObjHWID(tobj) : 0;
}
@@ -3195,6 +3230,9 @@ DECLEXPORT(GLuint) STATE_APIENTRY crStateGetTextureObjHWID(CRTextureObj *tobj)
{
CRASSERT(diff_api.GenTextures);
diff_api.GenTextures(1, &tobj->hwid);
+#ifdef DEBUG_misha
+ crDebug("tex id(%d), hwid(%d)", tobj->id, tobj->hwid);
+#endif
CRASSERT(tobj->hwid);
}
#endif
diff --git a/src/VBox/GuestHost/OpenGL/util/error.c b/src/VBox/GuestHost/OpenGL/util/error.c
index fc73d755d..60d814f20 100644
--- a/src/VBox/GuestHost/OpenGL/util/error.c
+++ b/src/VBox/GuestHost/OpenGL/util/error.c
@@ -38,10 +38,20 @@ static int swedish_chef = 0;
static int australia = 0;
static int warnings_enabled = 1;
+#ifdef DEBUG_misha
+//int g_VBoxFbgFBreakDdi = 0;
+#define DebugBreak() Assert(0)
+#endif
+
void __getHostInfo( void )
{
char *temp;
+ /* on windows guests we're typically get called in a context of VBoxOGL!DllMain ( which calls VBoxOGLcrutil!crNetInit ),
+ * which may lead to deadlocks..
+ * Avoid it as it is needed for debugging purposes only */
+#if !defined(IN_GUEST) || !defined(RT_OS_WINDOWS)
if ( crGetHostname( my_hostname, sizeof( my_hostname ) ) )
+#endif
{
crStrcpy( my_hostname, "????" );
}
@@ -99,7 +109,7 @@ static void outputChromiumMessage( FILE *output, char *str )
);
fflush( output );
-#if defined(DEBUG) && defined(WINDOWS) && !defined(DEBUG_misha)
+#if defined(DEBUG) && defined(WINDOWS) /* && (!defined(DEBUG_misha) || !defined(IN_GUEST) ) */
OutputDebugString(str);
OutputDebugString("\n");
#endif
@@ -196,7 +206,7 @@ DECLEXPORT(void) crError(const char *format, ... )
va_end( args );
#ifdef WINDOWS
}
-#if !defined(DEBUG_leo) && !defined(DEBUG_ll158262) && !(defined(DEBUG_misha) && defined(IN_GUEST))
+#if !defined(DEBUG_leo) && !defined(DEBUG_ll158262) && !defined(DEBUG_misha)
if (crGetenv( "CR_DEBUG_ON_ERROR" ) != NULL)
#endif
{
@@ -240,7 +250,7 @@ DECLEXPORT(void) crWarning(const char *format, ... )
#endif
va_end( args );
-#if defined(WINDOWS) && defined(DEBUG) && !defined(IN_GUEST) && !defined(DEBUG_misha)
+#if defined(WINDOWS) && defined(DEBUG) && !defined(IN_GUEST)
DebugBreak();
#endif
}
@@ -316,12 +326,12 @@ DECLEXPORT(void) crDebug(const char *format, ... )
}
else
{
-#if defined(WINDOWS) && defined(IN_GUEST) && (defined(DEBUG_leo) || defined(DEBUG_ll158262))
+#if defined(WINDOWS) && defined(IN_GUEST) && (defined(DEBUG_leo) || defined(DEBUG_ll158262) || defined(DEBUG_misha))
crRedirectIOToConsole();
#endif
output = stderr;
}
-#if !defined(DEBUG) || defined(DEBUG_misha)
+#if !defined(DEBUG)/* || defined(DEBUG_misha)*/
/* Release mode: only emit crDebug messages if CR_DEBUG
* or CR_DEBUG_FILE is set.
*/
@@ -382,11 +392,15 @@ DECLEXPORT(void) crDebug(const char *format, ... )
# if defined(DEBUG) && (defined(DEBUG_leo) || defined(DEBUG_ll158262))
outputChromiumMessage( output, txt );
# endif
+#ifndef DEBUG_misha
if (output==stderr)
+#endif
{
LogRel(("%s\n", txt));
}
+#ifndef DEBUG_misha
else
+#endif
{
outputChromiumMessage(output, txt);
}
diff --git a/src/VBox/GuestHost/OpenGL/util/net.c b/src/VBox/GuestHost/OpenGL/util/net.c
index a460dc2d1..7af233f9c 100644
--- a/src/VBox/GuestHost/OpenGL/util/net.c
+++ b/src/VBox/GuestHost/OpenGL/util/net.c
@@ -412,6 +412,7 @@ void crNetInit( CRNetReceiveFunc recvFunc, CRNetCloseFunc closeFunc )
else
{
#ifdef WINDOWS
+ /* @todo: do we actually need that WSA stuff with VBox at all? */
WORD wVersionRequested = MAKEWORD(2, 0);
WSADATA wsaData;
int err;
diff --git a/src/VBox/GuestHost/OpenGL/util/threads.c b/src/VBox/GuestHost/OpenGL/util/threads.c
index e83894801..247c6337a 100644
--- a/src/VBox/GuestHost/OpenGL/util/threads.c
+++ b/src/VBox/GuestHost/OpenGL/util/threads.c
@@ -51,9 +51,10 @@ void crFreeTSD(CRtsd *tsd)
crError("crFreeTSD failed!");
}
#else
- if (pthread_key_delete(tsd->key) != 0) {
- perror(FREE_TSD_ERROR);
- crError("crFreeTSD failed!");
+ if (pthread_key_delete(tsd->key) != 0)
+ {
+// perror(FREE_TSD_ERROR);
+// crError("crFreeTSD failed!");
}
#endif
tsd->initMagic = 0x0;
diff --git a/src/VBox/HostDrivers/Support/Makefile.kmk b/src/VBox/HostDrivers/Support/Makefile.kmk
index b4ebf01a0..c8c7575b4 100644
--- a/src/VBox/HostDrivers/Support/Makefile.kmk
+++ b/src/VBox/HostDrivers/Support/Makefile.kmk
@@ -81,8 +81,9 @@ else
endif
SUPR3_DEFS = \
IN_SUP_R3 IN_RT_R3 \
- $(if $(VBOX_WITH_SUPSVC),VBOX_WITH_SUPSVC) \
- $(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,)
+ $(if $(VBOX_WITH_SUPSVC),VBOX_WITH_SUPSVC) \
+ $(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,) \
+ $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,)
SUPR3_INCS := $(PATH_SUB_CURRENT)
SUPR3_INCS.l4 = $(L4_INCDIR)
SUPR3_SOURCES = \
@@ -105,7 +106,8 @@ SUPR3HardenedStatic_TEMPLATE = VBOXR3HARDENEDLIB
SUPR3HardenedStatic_DEFS = IN_SUP_HARDENED_R3
SUPR3HardenedStatic_DEFS += \
$(if $(VBOX_WITH_SUPSVC),VBOX_WITH_SUPSVC,) \
- $(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,)
+ $(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,) \
+ $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,)
SUPR3HardenedStatic_INCS = .
SUPR3HardenedStatic_SOURCES = \
SUPR3HardenedMain.cpp \
diff --git a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
index de882e767..64585690d 100644
--- a/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
+++ b/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp
@@ -104,9 +104,11 @@ static SUPINSTFILE const g_aSupInstallFiles[] =
{ kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDDR0.r0" },
{ kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDD2R0.r0" },
+#ifdef VBOX_WITH_RAW_MODE
{ kSupIFT_Dll, kSupID_AppPrivArch, false, "VMMGC.gc" },
{ kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDDGC.gc" },
{ kSupIFT_Dll, kSupID_AppPrivArch, false, "VBoxDD2GC.gc" },
+#endif
{ kSupIFT_Dll, kSupID_SharedLib, false, "VBoxRT" SUPLIB_DLL_SUFF },
{ kSupIFT_Dll, kSupID_SharedLib, false, "VBoxVMM" SUPLIB_DLL_SUFF },
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
index a18d87506..179b9722b 100644
--- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
+++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
@@ -449,7 +449,9 @@ vboxNetFltSolarisProbeCtf(void)
if (pModCtl)
{
int err;
+ mutex_enter(&mod_lock);
ctf_file_t *pCtfFile = ctf_modopen(pModCtl->mod_mp, &err);
+ mutex_exit(&mod_lock);
if (pCtfFile)
{
rc = vboxNetFltSolarisCtfGetMemberOffset(pCtfFile, "file_t", "f_vnode", &s_off_vnode);
diff --git a/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp b/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp
index 635c62bda..22ca4fcd0 100644
--- a/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp
+++ b/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp
@@ -402,7 +402,7 @@ static int usbLibDevStrDriverKeyGet(HANDLE hHub, ULONG iPort, LPSTR* plpszName)
pName->ConnectionIndex = iPort;
if (DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, pName, Name.ActualLength, pName, Name.ActualLength, &cbReturned, NULL))
{
- rc = RTUtf16ToUtf8Ex((PCRTUTF16)pName->DriverKeyName, pName->ActualLength, plpszName, 0, NULL);
+ rc = RTUtf16ToUtf8Ex((PCRTUTF16)pName->DriverKeyName, pName->ActualLength / sizeof (WCHAR), plpszName, 0, NULL);
AssertRC(rc);
if (RT_SUCCESS(rc))
rc = VINF_SUCCESS;
@@ -446,7 +446,7 @@ static int usbLibDevStrHubNameGet(HANDLE hHub, ULONG iPort, LPSTR* plpszName)
pName->ConnectionIndex = iPort;
if (DeviceIoControl(hHub, IOCTL_USB_GET_NODE_CONNECTION_NAME, pName, Name.ActualLength, pName, Name.ActualLength, &cbReturned, NULL))
{
- rc = RTUtf16ToUtf8Ex((PCRTUTF16)pName->NodeName, pName->ActualLength, plpszName, 0, NULL);
+ rc = RTUtf16ToUtf8Ex((PCRTUTF16)pName->NodeName, pName->ActualLength / sizeof (WCHAR), plpszName, 0, NULL);
AssertRC(rc);
if (RT_SUCCESS(rc))
rc = VINF_SUCCESS;
@@ -476,7 +476,7 @@ static int usbLibDevStrRootHubNameGet(HANDLE hCtl, LPSTR* plpszName)
int rc = VINF_SUCCESS;
if (DeviceIoControl(hCtl, IOCTL_USB_GET_ROOT_HUB_NAME, NULL, 0, pHubName, HubName.ActualLength, &cbReturned, NULL))
{
- rc = RTUtf16ToUtf8Ex((PCRTUTF16)pHubName->RootHubName, pHubName->ActualLength, plpszName, 0, NULL);
+ rc = RTUtf16ToUtf8Ex((PCRTUTF16)pHubName->RootHubName, pHubName->ActualLength / sizeof (WCHAR), plpszName, 0, NULL);
AssertRC(rc);
if (RT_SUCCESS(rc))
rc = VINF_SUCCESS;
diff --git a/src/VBox/HostServices/GuestControl/service.cpp b/src/VBox/HostServices/GuestControl/service.cpp
index 08d8ebf4e..1b5b25520 100644
--- a/src/VBox/HostServices/GuestControl/service.cpp
+++ b/src/VBox/HostServices/GuestControl/service.cpp
@@ -26,7 +26,7 @@
* which wants to control something on the guest.
* - Client: A client (e.g. VBoxService) running inside the guest OS waiting for
* new host commands to perform. There can be multiple clients connected
- * to a service. A client is represented by its HGCM client ID.
+ * to this service. A client is represented by its unique HGCM client ID.
* - Context ID: An (almost) unique ID automatically generated on the host (Main API)
* to not only distinguish clients but individual requests. Because
* the host does not know anything about connected clients it needs
@@ -280,12 +280,13 @@ public:
private:
int paramBufferAllocate(PVBOXGUESTCTRPARAMBUFFER pBuf, uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
void paramBufferFree(PVBOXGUESTCTRPARAMBUFFER pBuf);
- int paramBufferAssign(PVBOXGUESTCTRPARAMBUFFER pBuf, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
+ int paramBufferAssign(VBOXHGCMSVCPARM paDstParms[], uint32_t cDstParms, PVBOXGUESTCTRPARAMBUFFER pSrcBuf);
int prepareExecute(uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
int clientConnect(uint32_t u32ClientID, void *pvClient);
int clientDisconnect(uint32_t u32ClientID, void *pvClient);
- int sendHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
+ int assignHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
int retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
+ int cancelHostCmd(uint32_t u32ContextID);
int cancelPendingWaits(uint32_t u32ClientID);
int notifyHost(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
int processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
@@ -406,57 +407,77 @@ void Service::paramBufferFree(PVBOXGUESTCTRPARAMBUFFER pBuf)
}
/**
- * Assigns data from a buffered HGCM request to the current HGCM request.
+ * Copies data from a buffered HGCM request to the current HGCM request.
*
* @return IPRT status code.
- * @param pBuf Parameter buffer to assign.
- * @param cParms Number of parameters the HGCM request can handle.
- * @param paParms Array of parameters of HGCM request to fill the data into.
+ * @param paDstParms Array of parameters of HGCM request to fill the data into.
+ * @param cPDstarms Number of parameters the HGCM request can handle.
+ * @param pSrcBuf Parameter buffer to assign.
*/
-int Service::paramBufferAssign(PVBOXGUESTCTRPARAMBUFFER pBuf, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
+int Service::paramBufferAssign(VBOXHGCMSVCPARM paDstParms[], uint32_t cDstParms, PVBOXGUESTCTRPARAMBUFFER pSrcBuf)
{
- AssertPtr(pBuf);
+ AssertPtr(pSrcBuf);
int rc = VINF_SUCCESS;
- if (cParms != pBuf->uParmCount)
+ if (cDstParms != pSrcBuf->uParmCount)
{
- LogFlowFunc(("Parameter count does not match: %u (host) vs. %u (guest)\n",
- pBuf->uParmCount, cParms));
+ LogFlowFunc(("Parameter count does not match (got %u, expected %u)\n",
+ cDstParms, pSrcBuf->uParmCount));
rc = VERR_INVALID_PARAMETER;
}
else
{
- /** @todo Add check to verify if the HGCM request is the same *type* as the buffered one! */
- for (uint32_t i = 0; i < pBuf->uParmCount; i++)
+ for (uint32_t i = 0; i < pSrcBuf->uParmCount; i++)
{
- paParms[i].type = pBuf->pParms[i].type;
- switch (paParms[i].type)
+ if (paDstParms[i].type != pSrcBuf->pParms[i].type)
{
- case VBOX_HGCM_SVC_PARM_32BIT:
- paParms[i].u.uint32 = pBuf->pParms[i].u.uint32;
- break;
-
- case VBOX_HGCM_SVC_PARM_64BIT:
- /* Not supported yet. */
- break;
+ LogFlowFunc(("Parameter %u type mismatch (got %u, expected %u)\n",
+ i, paDstParms[i].type, pSrcBuf->pParms[i].type));
+ rc = VERR_INVALID_PARAMETER;
+ }
+ else
+ {
+ switch (pSrcBuf->pParms[i].type)
+ {
+ case VBOX_HGCM_SVC_PARM_32BIT:
+ paDstParms[i].u.uint32 = pSrcBuf->pParms[i].u.uint32;
+ break;
- case VBOX_HGCM_SVC_PARM_PTR:
- if (paParms[i].u.pointer.size >= pBuf->pParms[i].u.pointer.size)
+ case VBOX_HGCM_SVC_PARM_PTR:
{
- /* Only copy buffer if there actually is something to copy. */
- if (pBuf->pParms[i].u.pointer.size)
+ if (!pSrcBuf->pParms[i].u.pointer.size)
+ continue; /* Only copy buffer if there actually is something to copy. */
+
+ if (!paDstParms[i].u.pointer.addr)
+ rc = VERR_INVALID_PARAMETER;
+
+ if (paDstParms[i].u.pointer.size < pSrcBuf->pParms[i].u.pointer.size)
+ rc = VERR_BUFFER_OVERFLOW;
+
+ if (RT_SUCCESS(rc))
{
- AssertPtr(pBuf->pParms[i].u.pointer.addr);
- memcpy(paParms[i].u.pointer.addr,
- pBuf->pParms[i].u.pointer.addr,
- pBuf->pParms[i].u.pointer.size);
+ memcpy(paDstParms[i].u.pointer.addr,
+ pSrcBuf->pParms[i].u.pointer.addr,
+ pSrcBuf->pParms[i].u.pointer.size);
}
+
+ break;
}
- else
- rc = VERR_BUFFER_OVERFLOW;
- break;
- default:
- break;
+ case VBOX_HGCM_SVC_PARM_64BIT:
+ /* Fall through is intentional. */
+ default:
+ LogFlowFunc(("Parameter %u of type %u is not supported yet\n",
+ i, pSrcBuf->pParms[i].type));
+ rc = VERR_NOT_SUPPORTED;
+ break;
+ }
+ }
+
+ if (RT_FAILURE(rc))
+ {
+ LogFlowFunc(("Parameter %u invalid (rc=%Rrc), refusing\n",
+ i, rc));
+ break;
}
}
}
@@ -491,10 +512,17 @@ int Service::clientConnect(uint32_t u32ClientID, void *pvClient)
*/
int Service::clientDisconnect(uint32_t u32ClientID, void *pvClient)
{
- LogFlowFunc(("Client (%ld) disconnected\n", u32ClientID));
+ LogFlowFunc(("Client (ID=%u, %u clients total) disconnected\n",
+ u32ClientID, mNumClients));
Assert(mNumClients > 0);
mNumClients--;
+ /* If this was the last connected (guest) client we need to
+ * unblock all eventually queued up (waiting) host calls. */
+ bool fAllClientsDisconnected = mNumClients == 0;
+ if (fAllClientsDisconnected)
+ LogFlowFunc(("No connected clients left, notifying all queued up callbacks\n"));
+
/*
* Throw out all stale clients.
*/
@@ -511,56 +539,87 @@ int Service::clientDisconnect(uint32_t u32ClientID, void *pvClient)
itCall++;
}
- ClientContextsListIter it = mClientContextsList.begin();
- while ( it != mClientContextsList.end()
+ ClientContextsListIter itContextList = mClientContextsList.begin();
+ while ( itContextList != mClientContextsList.end()
&& RT_SUCCESS(rc))
{
- if (it->mClientID == u32ClientID)
+ /*
+ * Unblock/call back all queued items of the specified client
+ * or for all items in case there is no waiting client around
+ * anymore.
+ */
+ if ( itContextList->mClientID == u32ClientID
+ || fAllClientsDisconnected)
{
- std::list< uint32_t >::iterator itContext = it->mContextList.begin();
- while ( itContext != it->mContextList.end()
- && RT_SUCCESS(rc))
+ std::list< uint32_t >::iterator itContext = itContextList->mContextList.begin();
+ while (itContext != itContextList->mContextList.end())
{
- LogFlowFunc(("Notifying host context %u of disconnect ...\n", (*itContext)));
+ uint32_t uContextID = (*itContext);
/*
* Notify the host that clients with u32ClientID are no longer
* around and need to be cleaned up (canceling waits etc).
*/
- if (mpfnHostCallback)
+ LogFlowFunc(("Notifying CID=%u of disconnect ...\n", uContextID));
+ rc = cancelHostCmd(uContextID);
+ if (RT_FAILURE(rc))
{
- CALLBACKDATACLIENTDISCONNECTED data;
- data.hdr.u32Magic = CALLBACKDATAMAGIC_CLIENT_DISCONNECTED;
- data.hdr.u32ContextID = (*itContext);
- rc = mpfnHostCallback(mpvHostData, GUEST_DISCONNECTED, (void *)(&data), sizeof(data));
- if (RT_FAILURE(rc))
- LogFlowFunc(("Notification of host context %u failed with %Rrc\n", rc));
+ LogFlowFunc(("Cancelling of CID=%u failed with rc=%Rrc\n",
+ uContextID, rc));
+ /* Keep going. */
}
+
itContext++;
}
- it = mClientContextsList.erase(it);
+ itContextList = mClientContextsList.erase(itContextList);
}
else
- it++;
+ itContextList++;
+ }
+
+ if (fAllClientsDisconnected)
+ {
+ /*
+ * If all clients disconnected we also need to make sure that all buffered
+ * host commands need to be notified, because Main is waiting a notification
+ * via a (multi stage) progress object.
+ */
+ HostCmdListIter itHostCmd;
+ for (itHostCmd = mHostCmds.begin(); itHostCmd != mHostCmds.end(); itHostCmd++)
+ {
+ rc = cancelHostCmd(itHostCmd->mContextID);
+ if (RT_FAILURE(rc))
+ {
+ LogFlowFunc(("Cancelling of buffered CID=%u failed with rc=%Rrc\n",
+ itHostCmd->mContextID, rc));
+ /* Keep going. */
+ }
+
+ paramBufferFree(&itHostCmd->mParmBuf);
+ }
+
+ mHostCmds.clear();
}
+
return rc;
}
/**
- * Sends a specified host command to a client.
+ * Assigns a specified host command to a client.
*
* @return IPRT status code.
- * @param pCmd Host comamnd to send.
+ * @param pCmd Host command to send.
* @param callHandle Call handle of the client to send the command to.
* @param cParms Number of parameters.
* @param paParms Array of parameters.
*/
-int Service::sendHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
+int Service::assignHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
- AssertPtr(pCmd);
+ AssertPtrReturn(pCmd, VERR_INVALID_POINTER);
int rc;
- /* Sufficient parameter space? */
+ /* Does the current host command need more parameter space which
+ * the client does not provide yet? */
if (pCmd->mParmBuf.uParmCount > cParms)
{
paParms[0].setUInt32(pCmd->mParmBuf.uMsg); /* Message ID */
@@ -575,8 +634,10 @@ int Service::sendHostCmdToGuest(HostCmd *pCmd, VBOXHGCMCALLHANDLE callHandle, ui
}
else
{
- rc = paramBufferAssign(&pCmd->mParmBuf, cParms, paParms);
+ rc = paramBufferAssign(paParms, cParms, &pCmd->mParmBuf);
}
+
+ LogFlowFunc(("Returned with rc=%Rrc\n", rc));
return rc;
}
@@ -631,7 +692,7 @@ int Service::retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHa
* Get the next unassigned host command in the list.
*/
HostCmd curCmd = mHostCmds.front();
- rc = sendHostCmdToGuest(&curCmd, callHandle, cParms, paParms);
+ rc = assignHostCmdToGuest(&curCmd, callHandle, cParms, paParms);
if (RT_SUCCESS(rc))
{
/* Remember which client processes which context (for
@@ -657,8 +718,8 @@ int Service::retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHa
}
else
{
- /* Client did not understand the message or something else weird happened. Try again one
- * more time and drop it if it didn't get handled then. */
+ /* Client did not understand the message or something else weird happened. Try again one
+ * more time and drop it if it didn't get handled then. */
if (++curCmd.mTries > 1)
{
paramBufferFree(&curCmd.mParmBuf);
@@ -670,6 +731,30 @@ int Service::retrieveNextHostCmd(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHa
}
/**
+ * Cancels a buffered host command to unblock waits on Main side
+ * (via (multi stage) progress objects.
+ *
+ * @return IPRT status code.
+ * @param u32ContextID Context ID of host command to cancel.
+ */
+int Service::cancelHostCmd(uint32_t u32ContextID)
+{
+ AssertReturn(u32ContextID, VERR_INVALID_PARAMETER);
+ Assert(mpfnHostCallback);
+
+ LogFlowFunc(("Cancelling CID=%u ...\n", u32ContextID));
+
+ CALLBACKDATACLIENTDISCONNECTED data;
+ data.hdr.u32Magic = CALLBACKDATAMAGIC_CLIENT_DISCONNECTED;
+ data.hdr.u32ContextID = u32ContextID;
+
+ AssertPtr(mpfnHostCallback);
+ AssertPtr(mpvHostData);
+
+ return mpfnHostCallback(mpvHostData, GUEST_DISCONNECTED, (void *)(&data), sizeof(data));
+}
+
+/**
* Client asks itself (in another thread) to cancel all pending waits which are blocking the client
* from shutting down / doing something else.
*
@@ -788,7 +873,8 @@ int Service::processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM
return VERR_NOT_FOUND;
HostCmd newCmd;
int rc = paramBufferAllocate(&newCmd.mParmBuf, eFunction, cParms, paParms);
- if (RT_SUCCESS(rc) && cParms)
+ if ( RT_SUCCESS(rc)
+ && cParms) /* Make sure we at least get one parameter (that is, the context ID). */
{
/*
* Assume that the context ID *always* is the first parameter,
@@ -797,17 +883,22 @@ int Service::processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM
newCmd.mParmBuf.pParms[0].getUInt32(&newCmd.mContextID);
Assert(newCmd.mContextID > 0);
}
+ else if (!cParms)
+ rc = VERR_INVALID_PARAMETER;
if (RT_SUCCESS(rc))
{
+ LogFlowFunc(("Handling host command CID = %u\n",
+ newCmd.mContextID));
+
bool fProcessed = false;
/* Can we wake up a waiting client on guest? */
if (!mClientWaiterList.empty())
{
ClientWaiter guest = mClientWaiterList.front();
- rc = sendHostCmdToGuest(&newCmd,
- guest.mHandle, guest.mNumParms, guest.mParms);
+ rc = assignHostCmdToGuest(&newCmd,
+ guest.mHandle, guest.mNumParms, guest.mParms);
/* In any case the client did something, so wake up and remove from list. */
AssertPtr(mpHelpers);
@@ -824,22 +915,23 @@ int Service::processHostCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM
}
else /* If command was understood by the client, free and remove from host commands list. */
{
+ LogFlowFunc(("Host command CID = %u processed with rc=%Rrc\n",
+ newCmd.mContextID, rc));
+
paramBufferFree(&newCmd.mParmBuf);
- fProcessed = true;
}
}
- /* If not processed, buffer it ... */
if (!fProcessed)
{
+ LogFlowFunc(("Buffering host command CID = %u (rc=%Rrc)\n",
+ newCmd.mContextID, rc));
+
mHostCmds.push_back(newCmd);
-#if 0
- /* Limit list size by deleting oldest element. */
- if (mHostCmds.size() > 256) /** @todo Use a define! */
- mHostCmds.pop_front();
-#endif
}
}
+
+ LogFlowFunc(("Returned with rc=%Rrc\n", rc));
return rc;
}
@@ -857,7 +949,7 @@ void Service::call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
VBOXHGCMSVCPARM paParms[])
{
int rc = VINF_SUCCESS;
- LogFlowFunc(("u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n",
+ LogFlowFunc(("u32ClientID = %u, fn = %u, cParms = %u, paParms = 0x%p\n",
u32ClientID, eFunction, cParms, paParms));
try
{
@@ -912,7 +1004,7 @@ void Service::call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
int Service::hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
int rc = VERR_NOT_SUPPORTED;
- LogFlowFunc(("fn = %d, cParms = %d, pparms = %d\n",
+ LogFlowFunc(("fn = %u, cParms = %u, paParms = 0x%p\n",
eFunction, cParms, paParms));
try
{
@@ -929,11 +1021,7 @@ int Service::hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paPar
int Service::uninit()
{
- /* Free allocated buffered host commands. */
- HostCmdListIter it;
- for (it = mHostCmds.begin(); it != mHostCmds.end(); it++)
- paramBufferFree(&it->mParmBuf);
- mHostCmds.clear();
+ Assert(mHostCmds.empty());
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostServices/GuestProperties/service.cpp b/src/VBox/HostServices/GuestProperties/service.cpp
index 6af52a271..a932c34be 100644
--- a/src/VBox/HostServices/GuestProperties/service.cpp
+++ b/src/VBox/HostServices/GuestProperties/service.cpp
@@ -1147,7 +1147,7 @@ void Service::doNotifications(const char *pszProperty, uint64_t u64Timestamp)
{
/* Send out a host notification */
if (RT_SUCCESS(rc))
- rc = notifyHost(pszProperty, NULL, u64Timestamp, NULL);
+ rc = notifyHost(pszProperty, "", u64Timestamp, "");
}
LogFlowThisFunc(("returning\n"));
}
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
index d6f365eb2..8e8cb4653 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
@@ -230,7 +230,7 @@ void SERVER_DISPATCH_APIENTRY
crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
{
CRMuralInfo *mural, *oldMural;
- CRContext *ctx;
+ CRContext *ctx, *oldCtx;
if (context >= 0 && window >= 0) {
mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
@@ -267,6 +267,13 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
return;
}
+ /* Ubuntu 11.04 hosts misbehave if context window switch is
+ * done with non-default framebuffer object settings.
+ * crStateSwichPrepare & crStateSwichPostprocess are supposed to work around this problem
+ * crStateSwichPrepare restores the FBO state to its default values before the context window switch,
+ * while crStateSwichPostprocess restores it back to the original values */
+ oldCtx = crStateSwichPrepare(ctx);
+
/*
crDebug("**** %s client %d curCtx=%d curWin=%d", __func__,
cr_server.curClient->number, ctxPos, window);
@@ -325,6 +332,8 @@ crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
/* This used to be earlier, after crStateUpdateColorBits() call */
crStateMakeCurrent( ctx );
+ crStateSwichPostprocess(oldCtx);
+
if (oldMural != mural && crServerSupportRedirMuralFBO())
{
if (!crStateGetCurrent()->framebufferobject.drawFB)
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c
index 3807b695b..0e6d1bb9b 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_getshaders.c
@@ -105,7 +105,7 @@ void SERVER_DISPATCH_APIENTRY crServerDispatchGetAttachedObjectsARB(GLhandleARB
GLsizei i;
GLuint *ids=(GLuint*)&pLocal[1];
- for (i=0; i<*pLocal; ++i);
+ for (i=0; i<*pLocal; ++i)
ids[i] = crStateGLSLShaderHWIDtoID(ids[i]);
}
@@ -128,7 +128,7 @@ void SERVER_DISPATCH_APIENTRY crServerDispatchGetInfoLogARB(GLhandleARB obj, GLs
hwid = crStateGetProgramHWID(obj);
if (!hwid) hwid = crStateGetShaderHWID(obj);
cr_server.head_spu->dispatch_table.GetInfoLogARB(hwid, maxLength, pLocal, (char*)&pLocal[1]);
- crServerReturnValue(pLocal, (*pLocal)+1+sizeof(GLsizei));
+ crServerReturnValue(pLocal, (*pLocal)+sizeof(GLsizei));
crFree(pLocal);
}
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
index 7b731b099..6cb42e2e2 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
@@ -156,7 +156,7 @@ static int renderspuAtiQuirk_GetICDDriverList(char *pBuf, DWORD cbBuf, DWORD *pc
static LPCSTR aValueNames[] = {"OpenGLVendorName", "OpenGLDriverName"};
char *pBufPos = pBuf;
DWORD cbBufRemain = cbBuf, cbTotal = 0;
- HKEY hKey;
+ HKEY hKey, hSubkey;
DWORD dwIndex = 0;
int i;
int rc = VINF_SUCCESS;
@@ -190,17 +190,35 @@ static int renderspuAtiQuirk_GetICDDriverList(char *pBuf, DWORD cbBuf, DWORD *pc
continue;
}
+ lRc = RegOpenKeyEx(hKey,
+ NameBuf,
+ 0, /* reserved*/
+ KEY_READ,
+ &hSubkey);
+ if (ERROR_SUCCESS != lRc)
+ {
+ crDebug("RegOpenKeyEx 2 failed, %d", lRc);
+ RegCloseKey(hKey);
+ return VERR_OPEN_FAILED;
+ }
+
for (i = 0; i < RT_ELEMENTS(aValueNames); ++i)
{
DWORD cbCur = cbBufRemain;
- lRc = RegGetValueA(hKey, NameBuf, aValueNames[i], RRF_RT_REG_MULTI_SZ,
- NULL, /* LPDWORD pdwType */
- pBufPos,
- &cbCur);
+ DWORD type;
+ lRc = RegQueryValueExA(hSubkey, aValueNames[i], NULL, /* reserved*/
+ &type,
+ (PBYTE)pBufPos, &cbCur);
/* exclude second null termination */
--cbCur;
+
if (ERROR_MORE_DATA == lRc)
{
+ if (REG_MULTI_SZ != type)
+ {
+ crWarning("unexpected data type! %d", type);
+ continue;
+ }
rc = VERR_BUFFER_OVERFLOW;
pBufPos = NULL;
cbBufRemain = 0;
@@ -210,7 +228,13 @@ static int renderspuAtiQuirk_GetICDDriverList(char *pBuf, DWORD cbBuf, DWORD *pc
}
if (ERROR_SUCCESS != lRc)
{
- crWarning("RegGetValueA failed, %d", lRc);
+ crDebug("RegQueryValueExA failed, %d", lRc);
+ continue;
+ }
+
+ if (REG_MULTI_SZ != type)
+ {
+ crWarning("unexpected data type! %d", type);
continue;
}
@@ -221,8 +245,12 @@ static int renderspuAtiQuirk_GetICDDriverList(char *pBuf, DWORD cbBuf, DWORD *pc
cbTotal += cbCur;
CRASSERT(cbBufRemain < UINT32_MAX/2);
}
+
+ RegCloseKey(hSubkey);
}
+ RegCloseKey(hKey);
+
if (cbTotal)
{
/* include second null termination */
@@ -258,7 +286,7 @@ static int renderspuAtiQuirk_ApplyForModule(LPCSTR pszAtiDll)
}
crDebug("renderspuAtiQuirk_ApplyForModule SUCCEEDED!");
- crInfo("ATI Fullscreen qwirk for SUCCEEDED!");
+ crInfo("ATI Fullscreen qwirk SUCCEEDED!");
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py
index 5fe490987..595352744 100644
--- a/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py
+++ b/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py
@@ -226,6 +226,10 @@ void crUnpack( const void *data, const void *opcodes,
for (i = 0 ; i < num_opcodes ; i++)
{
+
+ CRDBGPTR_CHECKZ(writeback_ptr);
+ CRDBGPTR_CHECKZ(return_ptr);
+
/*crDebug(\"Unpacking opcode \%d\", *unpack_opcodes);*/
switch( *unpack_opcodes )
{"""
@@ -262,6 +266,10 @@ print """
crError( "Unknown opcode: %d", *unpack_opcodes );
break;
}
+
+ CRDBGPTR_CHECKZ(writeback_ptr);
+ CRDBGPTR_CHECKZ(return_ptr);
+
unpack_opcodes--;
}
}"""
diff --git a/src/VBox/Installer/darwin/Makefile.kmk b/src/VBox/Installer/darwin/Makefile.kmk
index d11870ed1..25c52e9fe 100644
--- a/src/VBox/Installer/darwin/Makefile.kmk
+++ b/src/VBox/Installer/darwin/Makefile.kmk
@@ -588,6 +588,10 @@ if defined(VBOX_WITH_PYTHON) && !defined(VBOX_WITHOUT_VBOXPYTHON_FOR_OSX_10_6)
VBOX_DI_VBAPP_DYLIBS += \
MacOS/VBoxPython2_6.so
endif
+if defined(VBOX_WITH_PYTHON) && !defined(VBOX_WITHOUT_VBOXPYTHON_FOR_OSX_10_7)
+ VBOX_DI_VBAPP_DYLIBS += \
+ MacOS/VBoxPython2_7.so
+endif
VBOX_DI_VBAPP_DYLIBS.x86 := \
MacOS/VBoxREM32.dylib \
diff --git a/src/VBox/Installer/linux/Makefile.include.footer b/src/VBox/Installer/linux/Makefile.include.footer
index 9bf05dc3c..bcc6a3861 100644
--- a/src/VBox/Installer/linux/Makefile.include.footer
+++ b/src/VBox/Installer/linux/Makefile.include.footer
@@ -35,7 +35,7 @@ ifndef INCL
endif
KFLAGS := -D__KERNEL__ -DMODULE $(MOD_DEFS)
ifeq ($(BUILD_TYPE),debug)
- KFLAGS += -DDEBUG
+ KFLAGS += -DDEBUG -DDEBUG_$(subst $(subst _, ,_),_,$(USERNAME)) -DDEBUG_USERNAME=$(subst $(subst _, ,_),_,$(USERNAME))
endif
ifeq ($(KERN_VERSION), 24)
diff --git a/src/VBox/Installer/linux/Makefile.include.header b/src/VBox/Installer/linux/Makefile.include.header
index 21183da65..cadc09076 100644
--- a/src/VBox/Installer/linux/Makefile.include.header
+++ b/src/VBox/Installer/linux/Makefile.include.header
@@ -76,6 +76,9 @@ else
$(warning Using BUILD_TYPE='$(BUILD_TYPE)' from the $(origin BUILD_TYPE).)
endif
endif
+ifeq ($(USERNAME),)
+ USERNAME := noname
+endif
ifneq ($(MAKECMDGOALS),clean)
diff --git a/src/VBox/Installer/linux/Makefile.kmk b/src/VBox/Installer/linux/Makefile.kmk
index 73014e20c..35ee3c9bb 100644
--- a/src/VBox/Installer/linux/Makefile.kmk
+++ b/src/VBox/Installer/linux/Makefile.kmk
@@ -147,13 +147,17 @@ VBOX_LNX_STRIP_BIN = \
# Do not remove relocation information of these binaries
VBOX_LNX_STRIP_OBJ = \
- VBoxDD2GC.gc \
VBoxDD2R0.r0 \
- VBoxDDGC.gc \
VBoxDDR0.r0 \
- VMMGC.gc \
VMMR0.r0
+ifdef VBOX_WITH_RAW_MODE
+ VBOX_LNX_STRIP_OBJ += \
+ VBoxDD2GC.gc \
+ VBoxDDGC.gc \
+ VMMGC.gc
+endif
+
# Do not strip anything of these files
VBOX_LNX_NO_STRIP = \
$(if $(VBOX_OSE),,LICENSE) \
diff --git a/src/VBox/Installer/linux/distributions_deb b/src/VBox/Installer/linux/distributions_deb
index cbfe9c6e4..66848fe86 100644
--- a/src/VBox/Installer/linux/distributions_deb
+++ b/src/VBox/Installer/linux/distributions_deb
@@ -1,8 +1,10 @@
_Debian_sid = DEBIAN_7_0
+_Debian_wheezy = DEBIAN_7_0
_Debian_squeeze = DEBIAN_6_0
_Debian_lenny = DEBIAN_5_0
_Debian_etch = DEBIAN_4_0
_Debian_sarge = DEBIAN_3_1
+_Ubuntu_precise = UBUNTU_12_04
_Ubuntu_oneiric = UBUNTU_11_10
_Ubuntu_natty = UBUNTU_11_04
_Ubuntu_maverick = UBUNTU_10_10
diff --git a/src/VBox/Installer/linux/distributions_rpm b/src/VBox/Installer/linux/distributions_rpm
index f269395c4..d9d9b035e 100644
--- a/src/VBox/Installer/linux/distributions_rpm
+++ b/src/VBox/Installer/linux/distributions_rpm
@@ -1,3 +1,4 @@
+openSUSE121 = OPENSUSE_12_1
openSUSE114 = OPENSUSE_11_4
openSUSE113 = OPENSUSE_11_3
openSUSE112 = OPENSUSE_11_2
@@ -12,6 +13,7 @@ mdv2010.0 = MANDRIVA_2010_0
mdv2009.1 = MANDRIVA_2009_1
mdv2008.0 = MANDRIVA_2008_0
mdv2007.1 = MANDRIVA_2007_1
+fedora17 = FEDORA_17
fedora16 = FEDORA_16
fedora15 = FEDORA_15
fedora14 = FEDORA_14
diff --git a/src/VBox/Installer/linux/install.sh b/src/VBox/Installer/linux/install.sh
index 345d85007..5d65ce5a1 100755
--- a/src/VBox/Installer/linux/install.sh
+++ b/src/VBox/Installer/linux/install.sh
@@ -349,6 +349,7 @@ if [ "$ACTION" = "install" ]; then
chcon -t java_exec_t $INSTALLATION_DIR/VBoxExtPackHelperApp > /dev/null 2>&1
chcon -t java_exec_t $INSTALLATION_DIR/vboxwebsrv > /dev/null 2>&1
chcon -t java_exec_t $INSTALLATION_DIR/webtest > /dev/null 2>&1
+ chcon -t bin_t $INSTALLATION_DIR/src/vboxhost/*/build_in_tmp > /dev/null 2>&1
fi
# Hardened build: Mark selected binaries set-user-ID-on-execution,
@@ -453,6 +454,9 @@ if [ "$ACTION" = "install" ]; then
echo "# VirtualBox version" >> $CONFIG_DIR/$CONFIG
echo "INSTALL_VER='$VERSION'" >> $CONFIG_DIR/$CONFIG
echo "INSTALL_REV='$SVNREV'" >> $CONFIG_DIR/$CONFIG
+ echo "# Build type and user name for logging purposes" >> $CONFIG_DIR/$CONFIG
+ echo "BUILD_TYPE='$BUILD_TYPE'" >> $CONFIG_DIR/$CONFIG
+ echo "USERNAME='$USERNAME'" >> $CONFIG_DIR/$CONFIG
# Make kernel module
MODULE_FAILED="false"
diff --git a/src/VBox/Installer/linux/rpm/LocalConfig.kmk b/src/VBox/Installer/linux/rpm/LocalConfig.kmk
index 16459b603..921b63fb8 100644
--- a/src/VBox/Installer/linux/rpm/LocalConfig.kmk
+++ b/src/VBox/Installer/linux/rpm/LocalConfig.kmk
@@ -31,6 +31,3 @@ VBOX_PATH_APP_DOCS = $(VBOX_PATH_PACKAGE_DOCS)
# gcc 4.5 produces some more false positives
VBOX_WITH_WARNINGS_AS_ERRORS :=
-
-# only relevant for non-OSE builds: don't build the PUEL package
-VBOX_WITH_EXTPACK_PUEL_BUILD :=
diff --git a/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec b/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
index 72371030b..8bcc1111e 100644
--- a/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
+++ b/src/VBox/Installer/linux/rpm/VirtualBox.tmpl.spec
@@ -249,6 +249,7 @@ if [ -x /usr/bin/chcon ]; then
chcon -t java_exec_t /usr/lib/virtualbox/VBoxExtPackHelperApp > /dev/null 2>&1
chcon -t java_exec_t /usr/lib/virtualbox/VBoxBalloonCtrl > /dev/null 2>&1
chcon -t java_exec_t /usr/lib/virtualbox/vboxwebsrv > /dev/null 2>&1
+ chcon -t bin_t /usr/share/virtualbox/src/vboxhost/*/build_in_tmp > /dev/null 2>&1
fi
%endif
diff --git a/src/VBox/Installer/linux/rpm/rules b/src/VBox/Installer/linux/rpm/rules
index f6a7d22a9..97ca95288 100755
--- a/src/VBox/Installer/linux/rpm/rules
+++ b/src/VBox/Installer/linux/rpm/rules
@@ -58,10 +58,10 @@ ifneq ($(MAKECMDGOALS),clean)
$(error Cannot detect package distribution (rpmrel=$(rpmrel)))
endif
- ifeq ($(filter-out rhel4 rhel5 rhel6 ol4 ol5 ol6 centos4 centos5 centos6 fedora9 fedora11 fedora12 fedora13 fedora14 fedora15 fedora16 turbolinux11,$(rpmrel)),)
+ ifeq ($(filter-out rhel4 rhel5 rhel6 ol4 ol5 ol6 centos4 centos5 centos6 fedora9 fedora11 fedora12 fedora13 fedora14 fedora15 fedora16 fedora17 turbolinux11,$(rpmrel)),)
rpmspec := rpm_redhat
endif
- ifeq ($(filter-out openSUSE110 openSUSE111 openSUSE112 openSUSE113 openSUSE114 sles10.1 sles11.0,$(rpmrel)),)
+ ifeq ($(filter-out openSUSE110 openSUSE111 openSUSE112 openSUSE113 openSUSE114 openSUSE121 sles10.1 sles11.0,$(rpmrel)),)
rpmspec := rpm_suse
endif
ifeq ($(filter-out mdv2009.1 mdv2010.0 mdv2011.0,$(rpmrel)),)
@@ -82,7 +82,7 @@ archdir := $(current)/rpm/VirtualBox-$(ver)
rpmname := $(verpkg)-$(rpmver)_$(rpmrel)
# Fedora13/14 is bleeding edge, the other jails have outdated kernel headers
-instmod := $(if $(filter rhel4 rhel5 rhel6 ol4 ol5 ol6 centos4 centos5 centos6 sles10.1 sles11.0 fedora13 fedora14 fedora15 fedora16,$(rpmrel)),,install_rpm)
+instmod := $(if $(filter rhel4 rhel5 rhel6 ol4 ol5 ol6 centos4 centos5 centos6 sles10.1 sles11.0 fedora13 fedora14 fedora15 fedora16 fedora17,$(rpmrel)),,install_rpm)
ifneq ($(STAGEDISO),)
ifeq ($(wildcard $(STAGEDISO)/VBoxGuestAdditions.iso),)
@@ -104,14 +104,14 @@ else
endif
cfg_flags := $(if $(filter rhel4 sles10.1,$(rpmrel)),--build-libxml2,) \
- $(if $(filter rhel4 sles10.1,$(rpmrel)),--build-libxslt,) \
$(if $(filter rhel4,$(rpmrel)),--build-libssl,) \
$(if $(filter rhel4 rhel5 ol4 ol5 centos4 centos5 sles10.1,$(rpmrel)),--build-libcurl,) \
$(if $(filter rhel5 centos5 sles10.1,$(rpmrel)),--disable-sdl-ttf,) \
$(if $(filter sles10.1 turbolinux11,$(rpmrel)),--disable-pulse,) \
$(if $(filter rhel4 rhel5 ol4 ol5 centos4 centos5,$(rpmrel)),--enable-pulse,) \
$(if $(filter rhel4 rhel5 ol4 ol5 centos4 centos5 sles10.1 turbolinux11,$(rpmrel)),--with-qt4-dir=/home/vbox/Qt-4.7.4-stdc++6-$(arch)) \
- $(if $(DEBUG),--build-debug,)
+ $(if $(DEBUG),--build-debug,) \
+ --disable-extpack
bld_flags := AUTOCFG=$(current)/rpm/AutoConfig.kmk \
LOCALCFG=$(current)/rpm/LocalConfig.kmk \
diff --git a/src/VBox/Installer/linux/run-inst.sh b/src/VBox/Installer/linux/run-inst.sh
index a513fc0b7..65a628107 100755
--- a/src/VBox/Installer/linux/run-inst.sh
+++ b/src/VBox/Installer/linux/run-inst.sh
@@ -30,6 +30,9 @@ UNINSTALL="uninstall.sh"
ROUTINES="routines.sh"
ARCH="_ARCH_"
INSTALLATION_VER="_VERSION_"
+INSTALLATION_REV="_SVNREV_"
+BUILD_TYPE="_BUILDTYPE_"
+USERNAME="_USERNAME_"
UNINSTALL_SCRIPTS="_UNINSTALL_SCRIPTS_"
INSTALLATION_DIR="/opt/$PACKAGE-$INSTALLATION_VER"
@@ -272,16 +275,7 @@ link_into_fs "lib" "$lib_path"
link_into_fs "share" "/usr/share"
link_into_fs "src" "/usr/src"
-# Install, set up and start init scripts
-for i in "$INSTALLATION_DIR/init/"*; do
- if test -r "$i"; then
- install_init_script "$i" "`basename "$i"`"
- test -n "$DO_SETUP" && setup_init_script "`basename "$i"`" 1>&2
- start_init_script "`basename "$i"`"
- fi
-done
-
-# Remember our installation configuration
+# Remember our installation configuration before we call any init scripts
cat > "$CONFIG_DIR/$CONFIG" << EOF
# $PACKAGE installation record.
# Package installation directory
@@ -293,8 +287,21 @@ INSTALL_DIR=$INSTALLATION_DIR
UNINSTALLER=$UNINSTALL
# Package version
INSTALL_VER=$INSTALLATION_VER
+INSTALL_REV='$INSTALLATION_REV'
+# Build type and user name for logging purposes
+BUILD_TYPE='$BUILD_TYPE'
+USERNAME='$USERNAME'
EOF
+# Install, set up and start init scripts
+for i in "$INSTALLATION_DIR/init/"*; do
+ if test -r "$i"; then
+ install_init_script "$i" "`basename "$i"`"
+ test -n "$DO_SETUP" && setup_init_script "`basename "$i"`" 1>&2
+ start_init_script "`basename "$i"`"
+ fi
+done
+
cp $ROUTINES $INSTALLATION_DIR
echo $INSTALLATION_DIR/$ROUTINES >> "$CONFIG_DIR/$CONFIG_FILES"
cat > $INSTALLATION_DIR/$UNINSTALL << EOF
diff --git a/src/VBox/Installer/linux/vboxweb-service.sh.in b/src/VBox/Installer/linux/vboxweb-service.sh.in
index dfd9605eb..972e08dc2 100755
--- a/src/VBox/Installer/linux/vboxweb-service.sh.in
+++ b/src/VBox/Installer/linux/vboxweb-service.sh.in
@@ -2,7 +2,7 @@
#
# VirtualBox web service API daemon init script.
#
-# Copyright (C) 2006-2011 Oracle Corporation
+# 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;
@@ -292,10 +292,17 @@ start() {
PARAMS="--background"
[ -n "$VBOXWEB_HOST" ] && PARAMS="$PARAMS -H $VBOXWEB_HOST"
[ -n "$VBOXWEB_PORT" ] && PARAMS="$PARAMS -p $VBOXWEB_PORT"
+ [ -n "$VBOXWEB_SSL_KEYFILE" ] && PARAMS="$PARAMS -s -K $VBOXWEB_SSL_KEYFILE"
+ [ -n "$VBOXWEB_SSL_PASSWORDFILE" ] && PARAMS="$PARAMS -a $VBOXWEB_SSL_PASSWORDFILE"
+ [ -n "$VBOXWEB_SSL_CACERT" ] && PARAMS="$PARAMS -c $VBOXWEB_SSL_CACERT"
+ [ -n "$VBOXWEB_SSL_CAPATH" ] && PARAMS="$PARAMS -C $VBOXWEB_SSL_CAPATH"
+ [ -n "$VBOXWEB_SSL_DHFILE" ] && PARAMS="$PARAMS -D $VBOXWEB_SSL_DHFILE"
+ [ -n "$VBOXWEB_SSL_RANDFILE" ] && PARAMS="$PARAMS -r $VBOXWEB_SSL_RANDFILE"
[ -n "$VBOXWEB_TIMEOUT" ] && PARAMS="$PARAMS -t $VBOXWEB_TIMEOUT"
[ -n "$VBOXWEB_CHECK_INTERVAL" ] && PARAMS="$PARAMS -i $VBOXWEB_CHECK_INTERVAL"
[ -n "$VBOXWEB_THREADS" ] && PARAMS="$PARAMS -T $VBOXWEB_THREADS"
[ -n "$VBOXWEB_KEEPALIVE" ] && PARAMS="$PARAMS -k $VBOXWEB_KEEPALIVE"
+ [ -n "$VBOXWEB_AUTHENTICATION" ] && PARAMS="$PARAMS -A $VBOXWEB_AUTHENTICATION"
[ -n "$VBOXWEB_LOGFILE" ] && PARAMS="$PARAMS -F $VBOXWEB_LOGFILE"
[ -n "$VBOXWEB_ROTATE" ] && PARAMS="$PARAMS -R $VBOXWEB_ROTATE"
[ -n "$VBOXWEB_LOGSIZE" ] && PARAMS="$PARAMS -S $VBOXWEB_LOGSIZE"
diff --git a/src/VBox/Installer/solaris/checkinstall.sh b/src/VBox/Installer/solaris/checkinstall.sh
index 04e80d3da..e861566c4 100755
--- a/src/VBox/Installer/solaris/checkinstall.sh
+++ b/src/VBox/Installer/solaris/checkinstall.sh
@@ -69,6 +69,13 @@ if test "x${PKG_INSTALL_ROOT:=/}" != "x/"; then
REMOTE_INST=1
fi
+# nothing to check for non-global zones
+currentzone=`zonename`
+if test "$currentzone" != "global"; then
+ exit 0
+fi
+
+
infoprint "Checking package dependencies..."
PKG_MISSING_IPS=""
diff --git a/src/VBox/Installer/solaris/smf-vboxwebsrv.sh b/src/VBox/Installer/solaris/smf-vboxwebsrv.sh
index 9a5b57d8f..4202e0fc4 100755
--- a/src/VBox/Installer/solaris/smf-vboxwebsrv.sh
+++ b/src/VBox/Installer/solaris/smf-vboxwebsrv.sh
@@ -1,7 +1,7 @@
#!/sbin/sh
# $Id: smf-vboxwebsrv.sh $
-# Copyright (C) 2008-2011 Oracle Corporation
+# Copyright (C) 2008-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;
@@ -41,12 +41,30 @@ case $VW_OPT in
[ $? != 0 ] && VW_HOST=
VW_PORT=`/usr/bin/svcprop -p config/port $SMF_FMRI 2>/dev/null`
[ $? != 0 ] && VW_PORT=
+ VW_SSL_KEYFILE=`/usr/bin/svcprop -p config/ssl_keyfile $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_SSL_KEYFILE=
+ VW_SSL_PASSWORDFILE=`/usr/bin/svcprop -p config/ssl_passwordfile $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_SSL_PASSWORDFILE=
+ VW_SSL_CACERT=`/usr/bin/svcprop -p config/ssl_cacert $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_SSL_CACERT=
+ VW_SSL_CAPATH=`/usr/bin/svcprop -p config/ssl_capath $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_SSL_CAPATH=
+ VW_SSL_DHFILE=`/usr/bin/svcprop -p config/ssl_dhfile $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_SSL_DHFILE=
+ VW_SSL_RANDFILE=`/usr/bin/svcprop -p config/ssl_randfile $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_SSL_RANDFILE=
VW_TIMEOUT=`/usr/bin/svcprop -p config/timeout $SMF_FMRI 2>/dev/null`
[ $? != 0 ] && VW_TIMEOUT=
VW_CHECK_INTERVAL=`/usr/bin/svcprop -p config/checkinterval $SMF_FMRI 2>/dev/null`
[ $? != 0 ] && VW_CHECK_INTERVAL=
+ VW_THREADS=`/usr/bin/svcprop -p config/threads $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_THREADS=
VW_KEEPALIVE=`/usr/bin/svcprop -p config/keepalive $SMF_FMRI 2>/dev/null`
[ $? != 0 ] && VW_KEEPALIVE=
+ VW_AUTHENTICATION=`/usr/bin/svcprop -p config/authentication $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_AUTHENTICATION=
+ VW_LOGFILE=`/usr/bin/svcprop -p config/logfile $SMF_FMRI 2>/dev/null`
+ [ $? != 0 ] && VW_LOGFILE=
VW_ROTATE=`/usr/bin/svcprop -p config/logrotate $SMF_FMRI 2>/dev/null`
[ $? != 0 ] && VW_ROTATE=
VW_LOGSIZE=`/usr/bin/svcprop -p config/logsize $SMF_FMRI 2>/dev/null`
@@ -60,11 +78,24 @@ case $VW_OPT in
[ -z "$VW_PORT" -o "$VW_PORT" -eq 0 ] && VW_PORT=18083
[ -z "$VW_TIMEOUT" ] && VW_TIMEOUT=20
[ -z "$VW_CHECK_INTERVAL" ] && VW_CHECK_INTERVAL=5
+ [ -z "$VW_THREADS" ] && VW_THREADS=100
[ -z "$VW_KEEPALIVE" ] && VW_KEEPALIVE=100
[ -z "$VW_ROTATE" ] && VW_ROTATE=10
[ -z "$VW_LOGSIZE" ] && VW_LOGSIZE=104857600
[ -z "$VW_LOGINTERVAL" ] && VW_LOGINTERVAL=86400
- exec su - "$VW_USER" -c "/opt/VirtualBox/vboxwebsrv --background --host \"$VW_HOST\" --port \"$VW_PORT\" --timeout \"$VW_TIMEOUT\" --check-interval \"$VW_CHECK_INTERVAL\" --keepalive \"$VW_KEEPALIVE\" --logrotate \"$VW_ROTATE\" --logsize \"$VW_LOGSIZE\" --loginterval \"$VW_LOGINTERVAL\""
+
+ # Derived and optional settings
+ VW_SSL=
+ [ -n "$VW_SSL_KEYFILE" ] && VW_SSL=--ssl
+ [ -n "$VW_SSL_KEYFILE" ] && VW_SSL_KEYFILE="--keyfile $VW_SSL_KEYFILE"
+ [ -n "$VW_SSL_PASSWORDFILE" ] && VW_SSL_PASSWORDFILE="--passwordfile $VW_SSL_PASSWORDFILE"
+ [ -n "$VW_SSL_CACERT" ] && VW_SSL_CACERT="--cacert $VW_SSL_CACERT"
+ [ -n "$VW_SSL_CAPATH" ] && VW_SSL_CAPATH="--capath $VW_SSL_CAPATH"
+ [ -n "$VW_SSL_DHFILE" ] && VW_SSL_DHFILE="--dhfile $VW_SSL_DHFILE"
+ [ -n "$VW_SSL_RANDFILE" ] && VW_SSL_RANDFILE="--randfile $VW_SSL_RANDFILE"
+ [ -n "$VW_LOGFILE" ] && VW_LOGFILE="--logfile $VW_LOGFILE"
+
+ exec su - "$VW_USER" -c "/opt/VirtualBox/vboxwebsrv --background --host \"$VW_HOST\" --port \"$VW_PORT\" $VW_SSL $VW_SSL_KEYFILE $VW_SSL_PASSWORDFILE $VW_SSL_CACERT $VW_SSL_CAPATH $VW_SSL_DHFILE $VW_SSL_RANDFILE --timeout \"$VW_TIMEOUT\" --check-interval \"$VW_CHECK_INTERVAL\" --threads \"$VW_THREADS\" --keepalive \"$VW_KEEPALIVE\" --authentication \"$VW_AUTHENTICATION\" $VW_LOGFILE --logrotate \"$VW_ROTATE\" --logsize \"$VW_LOGSIZE\" --loginterval \"$VW_LOGINTERVAL\""
VW_EXIT=$?
if [ $VW_EXIT != 0 ]; then
diff --git a/src/VBox/Installer/solaris/vboxconfig.sh b/src/VBox/Installer/solaris/vboxconfig.sh
index 32c8a6a5f..5fa1b30ed 100755
--- a/src/VBox/Installer/solaris/vboxconfig.sh
+++ b/src/VBox/Installer/solaris/vboxconfig.sh
@@ -18,6 +18,10 @@
# Never use exit 2 or exit 20 etc., the return codes are used in
# SRv4 postinstall procedures which carry special meaning. Just use exit 1 for failure.
+# LC_ALL should take precedence over LC_* and LANG but whatever...
+LC_ALL=C
+export LC_ALL
+
LANG=C
export LANG
@@ -223,6 +227,16 @@ get_sysinfo()
BIN_PKG=`which pkg 2> /dev/null`
if test -x "$BIN_PKG"; then
PKGFMRI=`$BIN_PKG $BASEDIR_PKGOPT contents -H -t set -a name=pkg.fmri -o pkg.fmri pkg:/system/kernel 2> /dev/null`
+ if test -z "$PKGFMRI"; then
+ # Perhaps this is old pkg without '-a' option and/or system/kernel is missing and it's part of 'entire'
+ # Try fallback.
+ PKGFMRI=`$BIN_PKG $BASEDIR_PKGOPT contents -H -t set -o pkg.fmri entire | head -1 2> /dev/null`
+ if test -z "$PKGFMRI"; then
+ # Perhaps entire is conflicting. Try using opensolaris/entire.
+ # Last fallback try.
+ PKGFMRI=`$BIN_PKG $BASEDIR_PKGOPT contents -H -t set -o pkg.fmri opensolaris.org/entire | head -1 2> /dev/null`
+ fi
+ fi
if test ! -z "$PKGFMRI"; then
# The format is "pkg://solaris/system/kernel@0.5.11,5.11-0.161:20110315T070332Z"
# or "pkg://solaris/system/kernel@0.5.11,5.11-0.175.0.0.0.1.0:20111012T032837Z"
diff --git a/src/VBox/Installer/solaris/virtualbox-webservice.xml b/src/VBox/Installer/solaris/virtualbox-webservice.xml
index 3c217c2f7..ca70df1d9 100644
--- a/src/VBox/Installer/solaris/virtualbox-webservice.xml
+++ b/src/VBox/Installer/solaris/virtualbox-webservice.xml
@@ -4,7 +4,7 @@
# Solaris SMF service manifest for VirtualBox webservice server.
# $Id$
- Copyright (C) 2008-2011 Oracle Corporation
+ Copyright (C) 2008-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;
@@ -86,6 +86,7 @@
<propval name='user' type='astring' value='root' />
<propval name='host' type='astring' value='localhost' />
<propval name='port' type='integer' value='18083' />
+ <propval name='keyfile' type='astring' value='' />
</property_group>
<template>
diff --git a/src/VBox/Installer/win/Languages/de_DE.wxl b/src/VBox/Installer/win/Languages/de_DE.wxl
index f8cb24bdd..a7d095f1d 100644
--- a/src/VBox/Installer/win/Languages/de_DE.wxl
+++ b/src/VBox/Installer/win/Languages/de_DE.wxl
@@ -1,12 +1,18 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<WixLocalization xmlns="http://schemas.microsoft.com/wix/2003/11/localization" Codepage="1252" Culture="de_DE">
<!--
Language Definition Include for VirtualBox WiX script.
- Copyright (C) 2011 Oracle Corporation
+ Copyright (C) 2011-2012 Oracle Corporation
- All rights reserved.
+ 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.
-->
<String Id="LANG">1033</String>
diff --git a/src/VBox/Installer/win/Languages/en_US.wxl b/src/VBox/Installer/win/Languages/en_US.wxl
index 82da635a5..dd7f12839 100644
--- a/src/VBox/Installer/win/Languages/en_US.wxl
+++ b/src/VBox/Installer/win/Languages/en_US.wxl
@@ -4,9 +4,15 @@
<!--
Language Definition Include for VirtualBox WiX script.
- Copyright (C) 2011 Oracle Corporation
-
- All rights reserved.
+ Copyright (C) 2011-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.
-->
<String Id="LANG">1033</String>
diff --git a/src/VBox/Installer/win/Languages/fr_FR.wxl b/src/VBox/Installer/win/Languages/fr_FR.wxl
index 58b3ac6a4..bb726b501 100644
--- a/src/VBox/Installer/win/Languages/fr_FR.wxl
+++ b/src/VBox/Installer/win/Languages/fr_FR.wxl
@@ -4,9 +4,15 @@
<!--
Language Definition Include for VirtualBox WiX script.
- Copyright (C) 2010 Oracle Corporation
-
- All rights reserved.
+ Copyright (C) 2010-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.
-->
<String Id="LANG">1036</String>
diff --git a/src/VBox/Main/cbinding/Makefile.kmk b/src/VBox/Main/cbinding/Makefile.kmk
index 03af2602a..d2e095b02 100644
--- a/src/VBox/Main/cbinding/Makefile.kmk
+++ b/src/VBox/Main/cbinding/Makefile.kmk
@@ -4,7 +4,7 @@
#
#
-# Copyright (C) 2009 Oracle Corporation
+# Copyright (C) 2009-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;
@@ -47,9 +47,11 @@ XpComCHeaders_SOURCES = \
VBoxCAPI_v2_2.h \
VBoxCAPI_v3_0.h \
VBoxCAPI_v3_1.h \
- $(XpComCHeaders_0_OUTDIR)/VBoxCAPI_v3_2.h
+ VBoxCAPI_v3_2.h \
+ VBoxCAPI_v4_0.h \
+ $(XpComCHeaders_0_OUTDIR)/VBoxCAPI.h=>VBoxCAPI_v$(VBOX_API_VERSION).h
-$$(XpComCHeaders_0_OUTDIR)/VBoxCAPI_v3_2.h: \
+$$(XpComCHeaders_0_OUTDIR)/VBoxCAPI.h: \
$(PATH_SUB_CURRENT)/xpcidl.xsl \
$(VBOX_XIDL_FILE) \
| $$(dir $$@)
@@ -68,8 +70,10 @@ if !defined(VBOX_ONLY_SDK) && defined(VBOX_WITH_XPCOM)
VBoxXPCOMC_DEFS = IN_VBOXXPCOMC
VBoxXPCOMC_SOURCES = \
VBoxXPCOMC.cpp
+ VBoxXPCOMC_INCS = \
+ $(XpComCHeaders_0_OUTDIR)
VBoxXPCOMC_INTERMEDIATES = \
- $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v3_2.h
+ $(XpComCHeaders_0_OUTDIR)/VBoxCAPI.h
endif
#
@@ -80,8 +84,11 @@ if !defined(VBOX_ONLY_SDK) && defined(VBOX_WITH_XPCOM)
VBoxXPCOMCGlue_DEFS = IN_VBOXXPCOMC
VBoxXPCOMCGlue_SOURCES = \
VBoxXPCOMCGlue.c
+ VBoxXPCOMCGlue_INCS = \
+ $(VBOX_PATH_SDK)/bindings/xpcom/cbinding
VBoxXPCOMCGlue_INTERMEDIATES = \
- $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v3_2.h
+ $(VBOX_PATH_SDK)/bindings/xpcom/cbinding/VBoxXPCOMCGlue.h \
+ $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v$(VBOX_API_VERSION).h
if defined(VBOX_WITH_TESTCASES) && "$(KBUILD_TARGET)" != "darwin"
#
@@ -93,7 +100,8 @@ if !defined(VBOX_ONLY_SDK) && defined(VBOX_WITH_XPCOM)
tstXPCOMCGlue_INCS = \
$(VBOX_PATH_SDK)/bindings/xpcom/include
tstXPCOMCGlue_INTERMEDIATES = \
- $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v3_2.h
+ $(VBOX_PATH_SDK)/bindings/xpcom/cbinding/VBoxXPCOMCGlue.h \
+ $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v$(VBOX_API_VERSION).h
tstXPCOMCGlue_SOURCES = \
tstXPCOMCGlue.c
tstXPCOMCGlue_LIBS = \
@@ -108,7 +116,7 @@ if !defined(VBOX_ONLY_SDK) && defined(VBOX_WITH_XPCOM)
tstXPCOMCCall_INCS = \
$(VBOX_PATH_SDK)/bindings/xpcom/include
tstXPCOMCCall_INTERMEDIATES = \
- $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v3_2.h
+ $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v$(VBOX_API_VERSION).h
tstXPCOMCCall_SOURCES = \
tstXPCOMCCall.c
tstXPCOMCCall_LIBS = \
diff --git a/src/VBox/Main/cbinding/VBoxCAPI_v2_2.h b/src/VBox/Main/cbinding/VBoxCAPI_v2_2.h
index 881cd27c6..eb0367abe 100644
--- a/src/VBox/Main/cbinding/VBoxCAPI_v2_2.h
+++ b/src/VBox/Main/cbinding/VBoxCAPI_v2_2.h
@@ -14,12 +14,12 @@
* xpcom/include/nsprpub/prtypes.h
* xpcom/include/xpcom/nsISupportsBase.h
*
- * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Sun
+ * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Oracle
* elects to distribute this derived work under the LGPL2.1 only.
*/
/*
- * Copyright (C) 2008-2009 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of a free software library; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General
diff --git a/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h b/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
index 42ae75cd4..bc5c4d3db 100644
--- a/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
+++ b/src/VBox/Main/cbinding/VBoxCAPI_v3_0.h
@@ -14,12 +14,12 @@
* xpcom/include/nsprpub/prtypes.h
* xpcom/include/xpcom/nsISupportsBase.h
*
- * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Sun
+ * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Oracle
* elects to distribute this derived work under the LGPL2.1 only.
*/
/*
- * Copyright (C) 2008-2009 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of a free software library; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General
diff --git a/src/VBox/Main/cbinding/VBoxCAPI_v3_1.h b/src/VBox/Main/cbinding/VBoxCAPI_v3_1.h
index bb078072f..079bfc178 100644
--- a/src/VBox/Main/cbinding/VBoxCAPI_v3_1.h
+++ b/src/VBox/Main/cbinding/VBoxCAPI_v3_1.h
@@ -14,12 +14,12 @@
* xpcom/include/nsprpub/prtypes.h
* xpcom/include/xpcom/nsISupportsBase.h
*
- * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Sun
+ * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Oracle
* elects to distribute this derived work under the LGPL2.1 only.
*/
/*
- * Copyright (C) 2008-2009 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of a free software library; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General
diff --git a/src/VBox/Main/cbinding/VBoxCAPI_v3_2.h b/src/VBox/Main/cbinding/VBoxCAPI_v3_2.h
new file mode 100644
index 000000000..df009a639
--- /dev/null
+++ b/src/VBox/Main/cbinding/VBoxCAPI_v3_2.h
@@ -0,0 +1,5613 @@
+
+/*
+ * DO NOT EDIT! This is a generated file.
+ *
+ * XPCOM IDL (XPIDL) definition for VirtualBox Main API (COM interfaces)
+ * generated from XIDL (XML interface definition).
+ *
+ * Source : src/VBox/Main/idl/VirtualBox.xidl
+ * Generator : src/VBox/Main/idl/xpcidl.xsl
+ *
+ * This file contains portions from the following Mozilla XPCOM files:
+ * xpcom/include/xpcom/nsID.h
+ * xpcom/include/nsIException.h
+ * xpcom/include/nsprpub/prtypes.h
+ * xpcom/include/xpcom/nsISupportsBase.h
+ *
+ * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Oracle
+ * elects to distribute this derived work under the LGPL2.1 only.
+ */
+
+/*
+ * Copyright (C) 2008-2012 Oracle Corporation
+ *
+ * This file is part of a free software library; you can redistribute
+ * it and/or modify it under the terms of the GNU Lesser General
+ * Public License version 2.1 as published by the Free Software
+ * Foundation and shipped in the "COPYING" file with this library.
+ * The library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if
+ * any license choice other than GPL or LGPL is available it will
+ * apply instead, Oracle elects to use only the Lesser General Public
+ * License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the
+ * language indicating that LGPLv2 or any later version may be used,
+ * or where a choice of which version of the LGPL is applied is
+ * otherwise unspecified.
+ */
+
+#ifndef ___VirtualBox_CXPCOM_h
+#define ___VirtualBox_CXPCOM_h
+
+#ifdef __cplusplus
+# include "VirtualBox_XPCOM.h"
+#else /* !__cplusplus */
+
+#include <stddef.h>
+#include "wchar.h"
+
+#if defined(WIN32)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_BEOS)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(WIN16)
+
+#define PR_CALLBACK_DECL __cdecl
+
+#if defined(_WINDLL)
+#define PR_EXPORT(__type) extern __type _cdecl _export _loadds
+#define PR_IMPORT(__type) extern __type _cdecl _export _loadds
+#define PR_EXPORT_DATA(__type) extern __type _export
+#define PR_IMPORT_DATA(__type) extern __type _export
+
+#define PR_EXTERN(__type) extern __type _cdecl _export _loadds
+#define PR_IMPLEMENT(__type) __type _cdecl _export _loadds
+#define PR_EXTERN_DATA(__type) extern __type _export
+#define PR_IMPLEMENT_DATA(__type) __type _export
+
+#define PR_CALLBACK __cdecl __loadds
+#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+
+#else /* this must be .EXE */
+#define PR_EXPORT(__type) extern __type _cdecl _export
+#define PR_IMPORT(__type) extern __type _cdecl _export
+#define PR_EXPORT_DATA(__type) extern __type _export
+#define PR_IMPORT_DATA(__type) extern __type _export
+
+#define PR_EXTERN(__type) extern __type _cdecl _export
+#define PR_IMPLEMENT(__type) __type _cdecl _export
+#define PR_EXTERN_DATA(__type) extern __type _export
+#define PR_IMPLEMENT_DATA(__type) __type _export
+
+#define PR_CALLBACK __cdecl __loadds
+#define PR_STATIC_CALLBACK(__x) __x PR_CALLBACK
+#endif /* _WINDLL */
+
+#elif defined(XP_MAC)
+
+#define PR_EXPORT(__type) extern __declspec(export) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(export) __type
+#define PR_IMPORT(__type) extern __declspec(export) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(export) __type
+
+#define PR_EXTERN(__type) extern __declspec(export) __type
+#define PR_IMPLEMENT(__type) __declspec(export) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(export) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(export) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_OS2) && defined(__declspec)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_OS2_VACPP)
+
+#define PR_EXPORT(__type) extern __type
+#define PR_EXPORT_DATA(__type) extern __type
+#define PR_IMPORT(__type) extern __type
+#define PR_IMPORT_DATA(__type) extern __type
+
+#define PR_EXTERN(__type) extern __type
+#define PR_IMPLEMENT(__type) __type
+#define PR_EXTERN_DATA(__type) extern __type
+#define PR_IMPLEMENT_DATA(__type) __type
+#define PR_CALLBACK _Optlink
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+
+#else /* Unix */
+
+# ifdef VBOX_HAVE_VISIBILITY_HIDDEN
+# define PR_EXPORT(__type) __attribute__((visibility("default"))) extern __type
+# define PR_EXPORT_DATA(__type) __attribute__((visibility("default"))) extern __type
+# define PR_IMPORT(__type) extern __type
+# define PR_IMPORT_DATA(__type) extern __type
+# define PR_EXTERN(__type) __attribute__((visibility("default"))) extern __type
+# define PR_IMPLEMENT(__type) __attribute__((visibility("default"))) __type
+# define PR_EXTERN_DATA(__type) __attribute__((visibility("default"))) extern __type
+# define PR_IMPLEMENT_DATA(__type) __attribute__((visibility("default"))) __type
+# define PR_CALLBACK
+# define PR_CALLBACK_DECL
+# define PR_STATIC_CALLBACK(__x) static __x
+# else
+# define PR_EXPORT(__type) extern __type
+# define PR_EXPORT_DATA(__type) extern __type
+# define PR_IMPORT(__type) extern __type
+# define PR_IMPORT_DATA(__type) extern __type
+# define PR_EXTERN(__type) extern __type
+# define PR_IMPLEMENT(__type) __type
+# define PR_EXTERN_DATA(__type) extern __type
+# define PR_IMPLEMENT_DATA(__type) __type
+# define PR_CALLBACK
+# define PR_CALLBACK_DECL
+# define PR_STATIC_CALLBACK(__x) static __x
+# endif
+#endif
+
+#if defined(_NSPR_BUILD_)
+#define NSPR_API(__type) PR_EXPORT(__type)
+#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type)
+#else
+#define NSPR_API(__type) PR_IMPORT(__type)
+#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type)
+#endif
+
+typedef unsigned char PRUint8;
+#if (defined(HPUX) && defined(__cplusplus) \
+ && !defined(__GNUC__) && __cplusplus < 199707L) \
+ || (defined(SCO) && defined(__cplusplus) \
+ && !defined(__GNUC__) && __cplusplus == 1L)
+typedef char PRInt8;
+#else
+typedef signed char PRInt8;
+#endif
+
+#define PR_INT8_MAX 127
+#define PR_INT8_MIN (-128)
+#define PR_UINT8_MAX 255U
+
+typedef unsigned short PRUint16;
+typedef short PRInt16;
+
+#define PR_INT16_MAX 32767
+#define PR_INT16_MIN (-32768)
+#define PR_UINT16_MAX 65535U
+
+typedef unsigned int PRUint32;
+typedef int PRInt32;
+#define PR_INT32(x) x
+#define PR_UINT32(x) x ## U
+
+#define PR_INT32_MAX PR_INT32(2147483647)
+#define PR_INT32_MIN (-PR_INT32_MAX - 1)
+#define PR_UINT32_MAX PR_UINT32(4294967295)
+
+typedef long PRInt64;
+typedef unsigned long PRUint64;
+typedef int PRIntn;
+typedef unsigned int PRUintn;
+
+typedef double PRFloat64;
+typedef size_t PRSize;
+
+typedef ptrdiff_t PRPtrdiff;
+
+typedef unsigned long PRUptrdiff;
+
+typedef PRIntn PRBool;
+
+#define PR_TRUE 1
+#define PR_FALSE 0
+
+typedef PRUint8 PRPackedBool;
+
+/*
+** Status code used by some routines that have a single point of failure or
+** special status return.
+*/
+typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
+
+#ifndef __PRUNICHAR__
+#define __PRUNICHAR__
+#if defined(WIN32) || defined(XP_MAC)
+typedef wchar_t PRUnichar;
+#else
+typedef PRUint16 PRUnichar;
+#endif
+#endif
+
+typedef long PRWord;
+typedef unsigned long PRUword;
+
+#define nsnull 0
+typedef PRUint32 nsresult;
+
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define NS_LIKELY(x) (__builtin_expect((x), 1))
+#define NS_UNLIKELY(x) (__builtin_expect((x), 0))
+#else
+#define NS_LIKELY(x) (x)
+#define NS_UNLIKELY(x) (x)
+#endif
+
+#define NS_FAILED(_nsresult) (NS_UNLIKELY((_nsresult) & 0x80000000))
+#define NS_SUCCEEDED(_nsresult) (NS_LIKELY(!((_nsresult) & 0x80000000)))
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_IntervalNow VBoxNsprPR_IntervalNow
+# define PR_TicksPerSecond VBoxNsprPR_TicksPerSecond
+# define PR_SecondsToInterval VBoxNsprPR_SecondsToInterval
+# define PR_MillisecondsToInterval VBoxNsprPR_MillisecondsToInterval
+# define PR_MicrosecondsToInterval VBoxNsprPR_MicrosecondsToInterval
+# define PR_IntervalToSeconds VBoxNsprPR_IntervalToSeconds
+# define PR_IntervalToMilliseconds VBoxNsprPR_IntervalToMilliseconds
+# define PR_IntervalToMicroseconds VBoxNsprPR_IntervalToMicroseconds
+# define PR_EnterMonitor VBoxNsprPR_EnterMonitor
+# define PR_ExitMonitor VBoxNsprPR_ExitMonitor
+# define PR_Notify VBoxNsprPR_Notify
+# define PR_NotifyAll VBoxNsprPR_NotifyAll
+# define PR_Wait VBoxNsprPR_Wait
+# define PR_NewMonitor VBoxNsprPR_NewMonitor
+# define PR_DestroyMonitor VBoxNsprPR_DestroyMonitor
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef PRUint32 PRIntervalTime;
+
+#define PR_INTERVAL_MIN 1000UL
+#define PR_INTERVAL_MAX 100000UL
+#define PR_INTERVAL_NO_WAIT 0UL
+#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL
+
+NSPR_API(PRIntervalTime) PR_IntervalNow(void);
+NSPR_API(PRUint32) PR_TicksPerSecond(void);
+NSPR_API(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds);
+NSPR_API(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli);
+NSPR_API(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro);
+NSPR_API(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks);
+
+typedef struct PRMonitor PRMonitor;
+
+NSPR_API(PRMonitor*) PR_NewMonitor(void);
+NSPR_API(void) PR_DestroyMonitor(PRMonitor *mon);
+NSPR_API(void) PR_EnterMonitor(PRMonitor *mon);
+NSPR_API(PRStatus) PR_ExitMonitor(PRMonitor *mon);
+NSPR_API(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks);
+NSPR_API(PRStatus) PR_Notify(PRMonitor *mon);
+NSPR_API(PRStatus) PR_NotifyAll(PRMonitor *mon);
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_CreateThread VBoxNsprPR_CreateThread
+# define PR_JoinThread VBoxNsprPR_JoinThread
+# define PR_Sleep VBoxNsprPR_Sleep
+# define PR_GetCurrentThread VBoxNsprPR_GetCurrentThread
+# define PR_GetThreadState VBoxNsprPR_GetThreadState
+# define PR_SetThreadPrivate VBoxNsprPR_SetThreadPrivate
+# define PR_GetThreadPrivate VBoxNsprPR_GetThreadPrivate
+# define PR_NewThreadPrivateIndex VBoxNsprPR_NewThreadPrivateIndex
+# define PR_GetThreadPriority VBoxNsprPR_GetThreadPriority
+# define PR_SetThreadPriority VBoxNsprPR_SetThreadPriority
+# define PR_Interrupt VBoxNsprPR_Interrupt
+# define PR_ClearInterrupt VBoxNsprPR_ClearInterrupt
+# define PR_BlockInterrupt VBoxNsprPR_BlockInterrupt
+# define PR_UnblockInterrupt VBoxNsprPR_UnblockInterrupt
+# define PR_GetThreadScope VBoxNsprPR_GetThreadScope
+# define PR_GetThreadType VBoxNsprPR_GetThreadType
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PRThread PRThread;
+typedef struct PRThreadStack PRThreadStack;
+
+typedef enum PRThreadType {
+ PR_USER_THREAD,
+ PR_SYSTEM_THREAD
+} PRThreadType;
+
+typedef enum PRThreadScope {
+ PR_LOCAL_THREAD,
+ PR_GLOBAL_THREAD,
+ PR_GLOBAL_BOUND_THREAD
+} PRThreadScope;
+
+typedef enum PRThreadState {
+ PR_JOINABLE_THREAD,
+ PR_UNJOINABLE_THREAD
+} PRThreadState;
+
+typedef enum PRThreadPriority
+{
+ PR_PRIORITY_FIRST = 0, /* just a placeholder */
+ PR_PRIORITY_LOW = 0, /* the lowest possible priority */
+ PR_PRIORITY_NORMAL = 1, /* most common expected priority */
+ PR_PRIORITY_HIGH = 2, /* slightly more aggressive scheduling */
+ PR_PRIORITY_URGENT = 3, /* it does little good to have more than one */
+ PR_PRIORITY_LAST = 3 /* this is just a placeholder */
+} PRThreadPriority;
+
+NSPR_API(PRThread*) PR_CreateThread(PRThreadType type,
+ void (PR_CALLBACK *start)(void *arg),
+ void *arg,
+ PRThreadPriority priority,
+ PRThreadScope scope,
+ PRThreadState state,
+ PRUint32 stackSize);
+NSPR_API(PRStatus) PR_JoinThread(PRThread *thread);
+NSPR_API(PRThread*) PR_GetCurrentThread(void);
+#ifndef NO_NSPR_10_SUPPORT
+#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */
+#endif /* NO_NSPR_10_SUPPORT */
+NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
+NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
+
+typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
+
+NSPR_API(PRStatus) PR_NewThreadPrivateIndex(
+ PRUintn *newIndex, PRThreadPrivateDTOR destructor);
+NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv);
+NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex);
+NSPR_API(PRStatus) PR_Interrupt(PRThread *thread);
+NSPR_API(void) PR_ClearInterrupt(void);
+NSPR_API(void) PR_BlockInterrupt(void);
+NSPR_API(void) PR_UnblockInterrupt(void);
+NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks);
+NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread);
+NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread);
+NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread);
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_DestroyLock VBoxNsprPR_DestroyLock
+# define PR_Lock VBoxNsprPR_Lock
+# define PR_NewLock VBoxNsprPR_NewLock
+# define PR_Unlock VBoxNsprPR_Unlock
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PRLock PRLock;
+
+NSPR_API(PRLock*) PR_NewLock(void);
+NSPR_API(void) PR_DestroyLock(PRLock *lock);
+NSPR_API(void) PR_Lock(PRLock *lock);
+NSPR_API(PRStatus) PR_Unlock(PRLock *lock);
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_NewCondVar VBoxNsprPR_NewCondVar
+# define PR_DestroyCondVar VBoxNsprPR_DestroyCondVar
+# define PR_WaitCondVar VBoxNsprPR_WaitCondVar
+# define PR_NotifyCondVar VBoxNsprPR_NotifyCondVar
+# define PR_NotifyAllCondVar VBoxNsprPR_NotifyAllCondVar
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PRCondVar PRCondVar;
+
+NSPR_API(PRCondVar*) PR_NewCondVar(PRLock *lock);
+NSPR_API(void) PR_DestroyCondVar(PRCondVar *cvar);
+NSPR_API(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout);
+NSPR_API(PRStatus) PR_NotifyCondVar(PRCondVar *cvar);
+NSPR_API(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar);
+
+typedef struct PRCListStr PRCList;
+
+struct PRCListStr {
+ PRCList *next;
+ PRCList *prev;
+};
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PL_DestroyEvent VBoxNsplPL_DestroyEvent
+# define PL_HandleEvent VBoxNsplPL_HandleEvent
+# define PL_InitEvent VBoxNsplPL_InitEvent
+# define PL_CreateEventQueue VBoxNsplPL_CreateEventQueue
+# define PL_CreateMonitoredEventQueue VBoxNsplPL_CreateMonitoredEventQueue
+# define PL_CreateNativeEventQueue VBoxNsplPL_CreateNativeEventQueue
+# define PL_DequeueEvent VBoxNsplPL_DequeueEvent
+# define PL_DestroyEventQueue VBoxNsplPL_DestroyEventQueue
+# define PL_EventAvailable VBoxNsplPL_EventAvailable
+# define PL_EventLoop VBoxNsplPL_EventLoop
+# define PL_GetEvent VBoxNsplPL_GetEvent
+# define PL_GetEventOwner VBoxNsplPL_GetEventOwner
+# define PL_GetEventQueueMonitor VBoxNsplPL_GetEventQueueMonitor
+# define PL_GetEventQueueSelectFD VBoxNsplPL_GetEventQueueSelectFD
+# define PL_MapEvents VBoxNsplPL_MapEvents
+# define PL_PostEvent VBoxNsplPL_PostEvent
+# define PL_PostSynchronousEvent VBoxNsplPL_PostSynchronousEvent
+# define PL_ProcessEventsBeforeID VBoxNsplPL_ProcessEventsBeforeID
+# define PL_ProcessPendingEvents VBoxNsplPL_ProcessPendingEvents
+# define PL_RegisterEventIDFunc VBoxNsplPL_RegisterEventIDFunc
+# define PL_RevokeEvents VBoxNsplPL_RevokeEvents
+# define PL_UnregisterEventIDFunc VBoxNsplPL_UnregisterEventIDFunc
+# define PL_WaitForEvent VBoxNsplPL_WaitForEvent
+# define PL_IsQueueNative VBoxNsplPL_IsQueueNative
+# define PL_IsQueueOnCurrentThread VBoxNsplPL_IsQueueOnCurrentThread
+# define PL_FavorPerformanceHint VBoxNsplPL_FavorPerformanceHint
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PLEvent PLEvent;
+typedef struct PLEventQueue PLEventQueue;
+
+PR_EXTERN(PLEventQueue*)
+PL_CreateEventQueue(const char* name, PRThread* handlerThread);
+PR_EXTERN(PLEventQueue *)
+ PL_CreateNativeEventQueue(
+ const char *name,
+ PRThread *handlerThread
+ );
+PR_EXTERN(PLEventQueue *)
+ PL_CreateMonitoredEventQueue(
+ const char *name,
+ PRThread *handlerThread
+ );
+PR_EXTERN(void)
+PL_DestroyEventQueue(PLEventQueue* self);
+PR_EXTERN(PRMonitor*)
+PL_GetEventQueueMonitor(PLEventQueue* self);
+
+#define PL_ENTER_EVENT_QUEUE_MONITOR(queue) \
+ PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
+
+#define PL_EXIT_EVENT_QUEUE_MONITOR(queue) \
+ PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
+
+PR_EXTERN(PRStatus) PL_PostEvent(PLEventQueue* self, PLEvent* event);
+PR_EXTERN(void*) PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event);
+PR_EXTERN(PLEvent*) PL_GetEvent(PLEventQueue* self);
+PR_EXTERN(PRBool) PL_EventAvailable(PLEventQueue* self);
+
+typedef void (PR_CALLBACK *PLEventFunProc)(PLEvent* event, void* data, PLEventQueue* queue);
+
+PR_EXTERN(void) PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data);
+PR_EXTERN(void) PL_RevokeEvents(PLEventQueue* self, void* owner);
+PR_EXTERN(void) PL_ProcessPendingEvents(PLEventQueue* self);
+PR_EXTERN(PLEvent*) PL_WaitForEvent(PLEventQueue* self);
+PR_EXTERN(void) PL_EventLoop(PLEventQueue* self);
+PR_EXTERN(PRInt32) PL_GetEventQueueSelectFD(PLEventQueue* self);
+PR_EXTERN(PRBool) PL_IsQueueOnCurrentThread( PLEventQueue *queue );
+PR_EXTERN(PRBool) PL_IsQueueNative(PLEventQueue *queue);
+
+typedef void* (PR_CALLBACK *PLHandleEventProc)(PLEvent* self);
+typedef void (PR_CALLBACK *PLDestroyEventProc)(PLEvent* self);
+PR_EXTERN(void)
+PL_InitEvent(PLEvent* self, void* owner,
+ PLHandleEventProc handler,
+ PLDestroyEventProc destructor);
+PR_EXTERN(void*) PL_GetEventOwner(PLEvent* self);
+PR_EXTERN(void) PL_HandleEvent(PLEvent* self);
+PR_EXTERN(void) PL_DestroyEvent(PLEvent* self);
+PR_EXTERN(void) PL_DequeueEvent(PLEvent* self, PLEventQueue* queue);
+PR_EXTERN(void) PL_FavorPerformanceHint(PRBool favorPerformanceOverEventStarvation, PRUint32 starvationDelay);
+
+struct PLEvent {
+ PRCList link;
+ PLHandleEventProc handler;
+ PLDestroyEventProc destructor;
+ void* owner;
+ void* synchronousResult;
+ PRLock* lock;
+ PRCondVar* condVar;
+ PRBool handled;
+#ifdef PL_POST_TIMINGS
+ PRIntervalTime postTime;
+#endif
+#ifdef XP_UNIX
+ unsigned long id;
+#endif /* XP_UNIX */
+ /* other fields follow... */
+};
+
+#if defined(XP_WIN) || defined(XP_OS2)
+
+PR_EXTERN(HWND)
+ PL_GetNativeEventReceiverWindow(
+ PLEventQueue *eqp
+ );
+#endif /* XP_WIN || XP_OS2 */
+
+#ifdef XP_UNIX
+
+PR_EXTERN(PRInt32)
+PL_ProcessEventsBeforeID(PLEventQueue *aSelf, unsigned long aID);
+
+typedef unsigned long (PR_CALLBACK *PLGetEventIDFunc)(void *aClosure);
+
+PR_EXTERN(void)
+PL_RegisterEventIDFunc(PLEventQueue *aSelf, PLGetEventIDFunc aFunc,
+ void *aClosure);
+PR_EXTERN(void) PL_UnregisterEventIDFunc(PLEventQueue *aSelf);
+
+#endif /* XP_UNIX */
+
+/* Standard "it worked" return value */
+#define NS_OK 0
+
+#define NS_ERROR_BASE ((nsresult) 0xC1F30000)
+
+/* Returned when an instance is not initialized */
+#define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
+
+/* Returned when an instance is already initialized */
+#define NS_ERROR_ALREADY_INITIALIZED (NS_ERROR_BASE + 2)
+
+/* Returned by a not implemented function */
+#define NS_ERROR_NOT_IMPLEMENTED ((nsresult) 0x80004001L)
+
+/* Returned when a given interface is not supported. */
+#define NS_NOINTERFACE ((nsresult) 0x80004002L)
+#define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
+
+#define NS_ERROR_INVALID_POINTER ((nsresult) 0x80004003L)
+#define NS_ERROR_NULL_POINTER NS_ERROR_INVALID_POINTER
+
+/* Returned when a function aborts */
+#define NS_ERROR_ABORT ((nsresult) 0x80004004L)
+
+/* Returned when a function fails */
+#define NS_ERROR_FAILURE ((nsresult) 0x80004005L)
+
+/* Returned when an unexpected error occurs */
+#define NS_ERROR_UNEXPECTED ((nsresult) 0x8000ffffL)
+
+/* Returned when a memory allocation fails */
+#define NS_ERROR_OUT_OF_MEMORY ((nsresult) 0x8007000eL)
+
+/* Returned when an illegal value is passed */
+#define NS_ERROR_ILLEGAL_VALUE ((nsresult) 0x80070057L)
+#define NS_ERROR_INVALID_ARG NS_ERROR_ILLEGAL_VALUE
+
+/* Returned when a class doesn't allow aggregation */
+#define NS_ERROR_NO_AGGREGATION ((nsresult) 0x80040110L)
+
+/* Returned when an operation can't complete due to an unavailable resource */
+#define NS_ERROR_NOT_AVAILABLE ((nsresult) 0x80040111L)
+
+/* Returned when a class is not registered */
+#define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L)
+
+/* Returned when a class cannot be registered, but may be tried again later */
+#define NS_ERROR_FACTORY_REGISTER_AGAIN ((nsresult) 0x80040155L)
+
+/* Returned when a dynamically loaded factory couldn't be found */
+#define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L)
+
+/* Returned when a factory doesn't support signatures */
+#define NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT \
+ (NS_ERROR_BASE + 0x101)
+
+/* Returned when a factory already is registered */
+#define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
+
+
+/**
+ * An "interface id" which can be used to uniquely identify a given
+ * interface.
+ * A "unique identifier". This is modeled after OSF DCE UUIDs.
+ */
+
+struct nsID {
+ PRUint32 m0;
+ PRUint16 m1;
+ PRUint16 m2;
+ PRUint8 m3[8];
+};
+
+typedef struct nsID nsID;
+typedef nsID nsIID;
+
+struct nsISupports; /* forward declaration */
+struct nsIStackFrame; /* forward declaration */
+struct nsIException; /* forward declaration */
+typedef struct nsISupports nsISupports; /* forward declaration */
+typedef struct nsIStackFrame nsIStackFrame; /* forward declaration */
+typedef struct nsIException nsIException; /* forward declaration */
+
+/**
+ * IID for the nsISupports interface
+ * {00000000-0000-0000-c000-000000000046}
+ *
+ * To maintain binary compatibility with COM's IUnknown, we define the IID
+ * of nsISupports to be the same as that of COM's IUnknown.
+ */
+#define NS_ISUPPORTS_IID \
+ { 0x00000000, 0x0000, 0x0000, \
+ {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
+
+/**
+ * Reference count values
+ *
+ * This is the return type for AddRef() and Release() in nsISupports.
+ * IUnknown of COM returns an unsigned long from equivalent functions.
+ * The following ifdef exists to maintain binary compatibility with
+ * IUnknown.
+ */
+
+/**
+ * Basic component object model interface. Objects which implement
+ * this interface support runtime interface discovery (QueryInterface)
+ * and a reference counted memory model (AddRef/Release). This is
+ * modelled after the win32 IUnknown API.
+ */
+struct nsISupports_vtbl {
+
+ /**
+ * @name Methods
+ */
+
+ /**
+ * A run time mechanism for interface discovery.
+ * @param aIID [in] A requested interface IID
+ * @param aInstancePtr [out] A pointer to an interface pointer to
+ * receive the result.
+ * @return NS_OK if the interface is supported by the associated
+ * instance, NS_NOINTERFACE if it is not.
+ * NS_ERROR_INVALID_POINTER if aInstancePtr is NULL.
+ */
+ nsresult (*QueryInterface)(nsISupports *pThis, const nsID *iid, void **resultp);
+ /**
+ * Increases the reference count for this interface.
+ * The associated instance will not be deleted unless
+ * the reference count is returned to zero.
+ *
+ * @return The resulting reference count.
+ */
+ nsresult (*AddRef)(nsISupports *pThis);
+
+ /**
+ * Decreases the reference count for this interface.
+ * Generally, if the reference count returns to zero,
+ * the associated instance is deleted.
+ *
+ * @return The resulting reference count.
+ */
+ nsresult (*Release)(nsISupports *pThis);
+
+};
+
+struct nsISupports {
+ struct nsISupports_vtbl *vtbl;
+};
+
+/* starting interface: nsIException */
+#define NS_IEXCEPTION_IID_STR "f3a8d3b4-c424-4edc-8bf6-8974c983ba78"
+
+#define NS_IEXCEPTION_IID \
+ {0xf3a8d3b4, 0xc424, 0x4edc, \
+ { 0x8b, 0xf6, 0x89, 0x74, 0xc9, 0x83, 0xba, 0x78 }}
+
+struct nsIException_vtbl {
+
+ /* Methods from the Class nsISupports */
+ struct nsISupports_vtbl nsisupports;
+
+ /* readonly attribute string message; */
+ nsresult (*GetMessage)(nsIException *pThis, PRUnichar * *aMessage);
+
+ /* readonly attribute nsresult (*result; */
+ nsresult (*GetResult)(nsIException *pThis, nsresult *aResult);
+
+ /* readonly attribute string name; */
+ nsresult (*GetName)(nsIException *pThis, PRUnichar * *aName);
+
+ /* readonly attribute string filename; */
+ nsresult (*GetFilename)(nsIException *pThis, PRUnichar * *aFilename);
+
+ /* readonly attribute PRUint32 lineNumber; */
+ nsresult (*GetLineNumber)(nsIException *pThis, PRUint32 *aLineNumber);
+
+ /* readonly attribute PRUint32 columnNumber; */
+ nsresult (*GetColumnNumber)(nsIException *pThis, PRUint32 *aColumnNumber);
+
+ /* readonly attribute nsIStackFrame location; */
+ nsresult (*GetLocation)(nsIException *pThis, nsIStackFrame * *aLocation);
+
+ /* readonly attribute nsIException inner; */
+ nsresult (*GetInner)(nsIException *pThis, nsIException * *aInner);
+
+ /* readonly attribute nsISupports data; */
+ nsresult (*GetData)(nsIException *pThis, nsISupports * *aData);
+
+ /* string toString (); */
+ nsresult (*ToString)(nsIException *pThis, PRUnichar **_retval);
+};
+
+struct nsIException {
+ struct nsIException_vtbl *vtbl;
+};
+
+/* starting interface: nsIStackFrame */
+#define NS_ISTACKFRAME_IID_STR "91d82105-7c62-4f8b-9779-154277c0ee90"
+
+#define NS_ISTACKFRAME_IID \
+ {0x91d82105, 0x7c62, 0x4f8b, \
+ { 0x97, 0x79, 0x15, 0x42, 0x77, 0xc0, 0xee, 0x90 }}
+
+struct nsIStackFrame_vtbl {
+
+ /* Methods from the Class nsISupports */
+ struct nsISupports_vtbl nsisupports;
+
+ /* readonly attribute PRUint32 language; */
+ nsresult (*GetLanguage)(nsIStackFrame *pThis, PRUint32 *aLanguage);
+
+ /* readonly attribute string languageName; */
+ nsresult (*GetLanguageName)(nsIStackFrame *pThis, PRUnichar * *aLanguageName);
+
+ /* readonly attribute string filename; */
+ nsresult (*GetFilename)(nsIStackFrame *pThis, PRUnichar * *aFilename);
+
+ /* readonly attribute string name; */
+ nsresult (*GetName)(nsIStackFrame *pThis, PRUnichar * *aName);
+
+ /* readonly attribute PRInt32 lineNumber; */
+ nsresult (*GetLineNumber)(nsIStackFrame *pThis, PRInt32 *aLineNumber);
+
+ /* readonly attribute string sourceLine; */
+ nsresult (*GetSourceLine)(nsIStackFrame *pThis, PRUnichar * *aSourceLine);
+
+ /* readonly attribute nsIStackFrame caller; */
+ nsresult (*GetCaller)(nsIStackFrame *pThis, nsIStackFrame * *aCaller);
+
+ /* string toString (); */
+ nsresult (*ToString)(nsIStackFrame *pThis, PRUnichar **_retval);
+};
+
+struct nsIStackFrame {
+ struct nsIStackFrame_vtbl *vtbl;
+};
+
+/* starting interface: nsIEventTarget */
+#define NS_IEVENTTARGET_IID_STR "ea99ad5b-cc67-4efb-97c9-2ef620a59f2a"
+
+#define NS_IEVENTTARGET_IID \
+ {0xea99ad5b, 0xcc67, 0x4efb, \
+ { 0x97, 0xc9, 0x2e, 0xf6, 0x20, 0xa5, 0x9f, 0x2a }}
+
+struct nsIEventTarget;
+typedef struct nsIEventTarget nsIEventTarget;
+
+struct nsIEventTarget_vtbl {
+
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*PostEvent)(nsIEventTarget *pThis, PLEvent * aEvent);
+
+ nsresult (*IsOnCurrentThread)(nsIEventTarget *pThis, PRBool *_retval);
+
+};
+
+struct nsIEventTarget {
+ struct nsIEventTarget_vtbl *vtbl;
+};
+
+/* starting interface: nsIEventQueue */
+#define NS_IEVENTQUEUE_IID_STR "176afb41-00a4-11d3-9f2a-00400553eef0"
+
+#define NS_IEVENTQUEUE_IID \
+ {0x176afb41, 0x00a4, 0x11d3, \
+ { 0x9f, 0x2a, 0x00, 0x40, 0x05, 0x53, 0xee, 0xf0 }}
+
+struct nsIEventQueue;
+typedef struct nsIEventQueue nsIEventQueue;
+
+struct nsIEventQueue_vtbl {
+
+ struct nsIEventTarget_vtbl nsieventtarget;
+
+ nsresult (*InitEvent)(nsIEventQueue *pThis, PLEvent * aEvent, void * owner, PLHandleEventProc handler, PLDestroyEventProc destructor);
+
+ nsresult (*PostSynchronousEvent)(nsIEventQueue *pThis, PLEvent * aEvent, void * *aResult);
+
+ nsresult (*PendingEvents)(nsIEventQueue *pThis, PRBool *_retval);
+
+ nsresult (*ProcessPendingEvents)(nsIEventQueue *pThis);
+
+ nsresult (*EventLoop)(nsIEventQueue *pThis);
+
+ nsresult (*EventAvailable)(nsIEventQueue *pThis, PRBool *aResult);
+
+ nsresult (*GetEvent)(nsIEventQueue *pThis, PLEvent * *_retval);
+
+ nsresult (*HandleEvent)(nsIEventQueue *pThis, PLEvent * aEvent);
+
+ nsresult (*WaitForEvent)(nsIEventQueue *pThis, PLEvent * *_retval);
+
+ PRInt32 (*GetEventQueueSelectFD)(nsIEventQueue *pThis);
+
+ nsresult (*Init)(nsIEventQueue *pThis, PRBool aNative);
+
+ nsresult (*InitFromPRThread)(nsIEventQueue *pThis, PRThread * thread, PRBool aNative);
+
+ nsresult (*InitFromPLQueue)(nsIEventQueue *pThis, PLEventQueue * aQueue);
+
+ nsresult (*EnterMonitor)(nsIEventQueue *pThis);
+
+ nsresult (*ExitMonitor)(nsIEventQueue *pThis);
+
+ nsresult (*RevokeEvents)(nsIEventQueue *pThis, void * owner);
+
+ nsresult (*GetPLEventQueue)(nsIEventQueue *pThis, PLEventQueue * *_retval);
+
+ nsresult (*IsQueueNative)(nsIEventQueue *pThis, PRBool *_retval);
+
+ nsresult (*StopAcceptingEvents)(nsIEventQueue *pThis);
+
+};
+
+struct nsIEventQueue {
+ struct nsIEventQueue_vtbl *vtbl;
+};
+
+
+#define VBOX_E_OBJECT_NOT_FOUND 0x80BB0001
+#define VBOX_E_INVALID_VM_STATE 0x80BB0002
+#define VBOX_E_VM_ERROR 0x80BB0003
+#define VBOX_E_FILE_ERROR 0x80BB0004
+#define VBOX_E_IPRT_ERROR 0x80BB0005
+#define VBOX_E_PDM_ERROR 0x80BB0006
+#define VBOX_E_INVALID_OBJECT_STATE 0x80BB0007
+#define VBOX_E_HOST_ERROR 0x80BB0008
+#define VBOX_E_NOT_SUPPORTED 0x80BB0009
+#define VBOX_E_XML_ERROR 0x80BB000A
+#define VBOX_E_INVALID_SESSION_STATE 0x80BB000B
+#define VBOX_E_OBJECT_IN_USE 0x80BB000C
+#define VBOX_E_DONT_CALL_AGAIN 0x80BB000D
+
+
+struct IVirtualBoxErrorInfo;
+struct ILocalOwner;
+struct IVirtualBoxCallback;
+struct IDHCPServer;
+struct IVirtualBox;
+struct IVFSExplorer;
+struct IAppliance;
+struct IVirtualSystemDescription;
+struct IInternalMachineControl;
+struct IBIOSSettings;
+struct IMachine;
+struct IConsoleCallback;
+struct IRemoteDisplayInfo;
+struct IConsole;
+struct IHostNetworkInterface;
+struct IHost;
+struct ISystemProperties;
+struct IGuestOSType;
+struct IGuest;
+struct IProgress;
+struct ISnapshot;
+struct IMediumAttachment;
+struct IMedium;
+struct IMediumFormat;
+struct IKeyboard;
+struct IMouse;
+struct IFramebuffer;
+struct IFramebufferOverlay;
+struct IDisplay;
+struct INetworkAdapter;
+struct ISerialPort;
+struct IParallelPort;
+struct IMachineDebugger;
+struct IUSBController;
+struct IUSBDevice;
+struct IUSBDeviceFilter;
+struct IHostUSBDevice;
+struct IHostUSBDeviceFilter;
+struct IAudioAdapter;
+struct IVRDPServer;
+struct ISharedFolder;
+struct IInternalSessionControl;
+struct ISession;
+struct IStorageController;
+struct IManagedObjectRef;
+struct IWebsessionManager;
+struct IPerformanceMetric;
+struct IPerformanceCollector;
+struct INATEngine;
+
+typedef struct IVirtualBoxErrorInfo IVirtualBoxErrorInfo;
+typedef struct ILocalOwner ILocalOwner;
+typedef struct IVirtualBoxCallback IVirtualBoxCallback;
+typedef struct IDHCPServer IDHCPServer;
+typedef struct IVirtualBox IVirtualBox;
+typedef struct IVFSExplorer IVFSExplorer;
+typedef struct IAppliance IAppliance;
+typedef struct IVirtualSystemDescription IVirtualSystemDescription;
+typedef struct IInternalMachineControl IInternalMachineControl;
+typedef struct IBIOSSettings IBIOSSettings;
+typedef struct IMachine IMachine;
+typedef struct IConsoleCallback IConsoleCallback;
+typedef struct IRemoteDisplayInfo IRemoteDisplayInfo;
+typedef struct IConsole IConsole;
+typedef struct IHostNetworkInterface IHostNetworkInterface;
+typedef struct IHost IHost;
+typedef struct ISystemProperties ISystemProperties;
+typedef struct IGuestOSType IGuestOSType;
+typedef struct IGuest IGuest;
+typedef struct IProgress IProgress;
+typedef struct ISnapshot ISnapshot;
+typedef struct IMediumAttachment IMediumAttachment;
+typedef struct IMedium IMedium;
+typedef struct IMediumFormat IMediumFormat;
+typedef struct IKeyboard IKeyboard;
+typedef struct IMouse IMouse;
+typedef struct IFramebuffer IFramebuffer;
+typedef struct IFramebufferOverlay IFramebufferOverlay;
+typedef struct IDisplay IDisplay;
+typedef struct INetworkAdapter INetworkAdapter;
+typedef struct ISerialPort ISerialPort;
+typedef struct IParallelPort IParallelPort;
+typedef struct IMachineDebugger IMachineDebugger;
+typedef struct IUSBController IUSBController;
+typedef struct IUSBDevice IUSBDevice;
+typedef struct IUSBDeviceFilter IUSBDeviceFilter;
+typedef struct IHostUSBDevice IHostUSBDevice;
+typedef struct IHostUSBDeviceFilter IHostUSBDeviceFilter;
+typedef struct IAudioAdapter IAudioAdapter;
+typedef struct IVRDPServer IVRDPServer;
+typedef struct ISharedFolder ISharedFolder;
+typedef struct IInternalSessionControl IInternalSessionControl;
+typedef struct ISession ISession;
+typedef struct IStorageController IStorageController;
+typedef struct IManagedObjectRef IManagedObjectRef;
+typedef struct IWebsessionManager IWebsessionManager;
+typedef struct IPerformanceMetric IPerformanceMetric;
+typedef struct IPerformanceCollector IPerformanceCollector;
+typedef struct INATEngine INATEngine;
+
+/* Start of enum SettingsVersion Declaration */
+#define SETTINGSVERSION_IID_STR "52bd6f5f-1adb-4493-975d-581a9c4b803f"
+#define SETTINGSVERSION_IID { \
+ 0x52bd6f5f, 0x1adb, 0x4493, \
+ { 0x97, 0x5d, 0x58, 0x1a, 0x9c, 0x4b, 0x80, 0x3f } \
+}
+enum SettingsVersion
+{
+ SettingsVersion_Null = 0,
+ SettingsVersion_v1_0 = 1,
+ SettingsVersion_v1_1 = 2,
+ SettingsVersion_v1_2 = 3,
+ SettingsVersion_v1_3pre = 4,
+ SettingsVersion_v1_3 = 5,
+ SettingsVersion_v1_4 = 6,
+ SettingsVersion_v1_5 = 7,
+ SettingsVersion_v1_6 = 8,
+ SettingsVersion_v1_7 = 9,
+ SettingsVersion_v1_8 = 10,
+ SettingsVersion_v1_9 = 11,
+ SettingsVersion_v1_10 = 12,
+ SettingsVersion_Future = 13
+};
+/* End of enum SettingsVersion Declaration */
+
+
+/* Start of enum AccessMode Declaration */
+#define ACCESSMODE_IID_STR "1da0007c-ddf7-4be8-bcac-d84a1558785f"
+#define ACCESSMODE_IID { \
+ 0x1da0007c, 0xddf7, 0x4be8, \
+ { 0xbc, 0xac, 0xd8, 0x4a, 0x15, 0x58, 0x78, 0x5f } \
+}
+enum AccessMode
+{
+ AccessMode_ReadOnly = 1,
+ AccessMode_ReadWrite = 2
+};
+/* End of enum AccessMode Declaration */
+
+
+/* Start of enum MachineState Declaration */
+#define MACHINESTATE_IID_STR "e998d075-543a-41fc-8aa9-5ca3e92393fd"
+#define MACHINESTATE_IID { \
+ 0xe998d075, 0x543a, 0x41fc, \
+ { 0x8a, 0xa9, 0x5c, 0xa3, 0xe9, 0x23, 0x93, 0xfd } \
+}
+enum MachineState
+{
+ MachineState_Null = 0,
+ MachineState_PoweredOff = 1,
+ MachineState_Saved = 2,
+ MachineState_Teleported = 3,
+ MachineState_Aborted = 4,
+ MachineState_Running = 5,
+ MachineState_Paused = 6,
+ MachineState_Stuck = 7,
+ MachineState_Teleporting = 8,
+ MachineState_LiveSnapshotting = 9,
+ MachineState_Starting = 10,
+ MachineState_Stopping = 11,
+ MachineState_Saving = 12,
+ MachineState_Restoring = 13,
+ MachineState_TeleportingPausedVM = 14,
+ MachineState_TeleportingIn = 15,
+ MachineState_DeletingSnapshotOnline = 16,
+ MachineState_DeletingSnapshotPaused = 17,
+ MachineState_RestoringSnapshot = 18,
+ MachineState_DeletingSnapshot = 19,
+ MachineState_SettingUp = 20,
+ MachineState_FirstOnline = 5,
+ MachineState_LastOnline = 17,
+ MachineState_FirstTransient = 8,
+ MachineState_LastTransient = 20
+};
+/* End of enum MachineState Declaration */
+
+
+/* Start of enum SessionState Declaration */
+#define SESSIONSTATE_IID_STR "cf2700c0-ea4b-47ae-9725-7810114b94d8"
+#define SESSIONSTATE_IID { \
+ 0xcf2700c0, 0xea4b, 0x47ae, \
+ { 0x97, 0x25, 0x78, 0x10, 0x11, 0x4b, 0x94, 0xd8 } \
+}
+enum SessionState
+{
+ SessionState_Null = 0,
+ SessionState_Closed = 1,
+ SessionState_Open = 2,
+ SessionState_Spawning = 3,
+ SessionState_Closing = 4
+};
+/* End of enum SessionState Declaration */
+
+
+/* Start of enum CPUPropertyType Declaration */
+#define CPUPROPERTYTYPE_IID_STR "24d356a6-2f45-4abd-b977-1cbe9c4701f5"
+#define CPUPROPERTYTYPE_IID { \
+ 0x24d356a6, 0x2f45, 0x4abd, \
+ { 0xb9, 0x77, 0x1c, 0xbe, 0x9c, 0x47, 0x01, 0xf5 } \
+}
+enum CPUPropertyType
+{
+ CPUPropertyType_Null = 0,
+ CPUPropertyType_PAE = 1,
+ CPUPropertyType_Synthetic = 2
+};
+/* End of enum CPUPropertyType Declaration */
+
+
+/* Start of enum HWVirtExPropertyType Declaration */
+#define HWVIRTEXPROPERTYTYPE_IID_STR "ce81dfdd-d2b8-4a90-bbea-40ee8b7ffcee"
+#define HWVIRTEXPROPERTYTYPE_IID { \
+ 0xce81dfdd, 0xd2b8, 0x4a90, \
+ { 0xbb, 0xea, 0x40, 0xee, 0x8b, 0x7f, 0xfc, 0xee } \
+}
+enum HWVirtExPropertyType
+{
+ HWVirtExPropertyType_Null = 0,
+ HWVirtExPropertyType_Enabled = 1,
+ HWVirtExPropertyType_Exclusive = 2,
+ HWVirtExPropertyType_VPID = 3,
+ HWVirtExPropertyType_NestedPaging = 4,
+ HWVirtExPropertyType_LargePages = 5,
+ HWVirtExPropertyType_Force = 6
+};
+/* End of enum HWVirtExPropertyType Declaration */
+
+
+/* Start of enum SessionType Declaration */
+#define SESSIONTYPE_IID_STR "A13C02CB-0C2C-421E-8317-AC0E8AAA153A"
+#define SESSIONTYPE_IID { \
+ 0xA13C02CB, 0x0C2C, 0x421E, \
+ { 0x83, 0x17, 0xAC, 0x0E, 0x8A, 0xAA, 0x15, 0x3A } \
+}
+enum SessionType
+{
+ SessionType_Null = 0,
+ SessionType_Direct = 1,
+ SessionType_Remote = 2,
+ SessionType_Existing = 3
+};
+/* End of enum SessionType Declaration */
+
+
+/* Start of enum DeviceType Declaration */
+#define DEVICETYPE_IID_STR "6d9420f7-0b56-4636-99f9-7346f1b01e57"
+#define DEVICETYPE_IID { \
+ 0x6d9420f7, 0x0b56, 0x4636, \
+ { 0x99, 0xf9, 0x73, 0x46, 0xf1, 0xb0, 0x1e, 0x57 } \
+}
+enum DeviceType
+{
+ DeviceType_Null = 0,
+ DeviceType_Floppy = 1,
+ DeviceType_DVD = 2,
+ DeviceType_HardDisk = 3,
+ DeviceType_Network = 4,
+ DeviceType_USB = 5,
+ DeviceType_SharedFolder = 6
+};
+/* End of enum DeviceType Declaration */
+
+
+/* Start of enum DeviceActivity Declaration */
+#define DEVICEACTIVITY_IID_STR "6FC8AEAA-130A-4eb5-8954-3F921422D707"
+#define DEVICEACTIVITY_IID { \
+ 0x6FC8AEAA, 0x130A, 0x4eb5, \
+ { 0x89, 0x54, 0x3F, 0x92, 0x14, 0x22, 0xD7, 0x07 } \
+}
+enum DeviceActivity
+{
+ DeviceActivity_Null = 0,
+ DeviceActivity_Idle = 1,
+ DeviceActivity_Reading = 2,
+ DeviceActivity_Writing = 3
+};
+/* End of enum DeviceActivity Declaration */
+
+
+/* Start of enum ClipboardMode Declaration */
+#define CLIPBOARDMODE_IID_STR "33364716-4008-4701-8f14-be0fa3d62950"
+#define CLIPBOARDMODE_IID { \
+ 0x33364716, 0x4008, 0x4701, \
+ { 0x8f, 0x14, 0xbe, 0x0f, 0xa3, 0xd6, 0x29, 0x50 } \
+}
+enum ClipboardMode
+{
+ ClipboardMode_Disabled = 0,
+ ClipboardMode_HostToGuest = 1,
+ ClipboardMode_GuestToHost = 2,
+ ClipboardMode_Bidirectional = 3
+};
+/* End of enum ClipboardMode Declaration */
+
+
+/* Start of enum Scope Declaration */
+#define SCOPE_IID_STR "7c91096e-499e-4eca-9f9b-9001438d7855"
+#define SCOPE_IID { \
+ 0x7c91096e, 0x499e, 0x4eca, \
+ { 0x9f, 0x9b, 0x90, 0x01, 0x43, 0x8d, 0x78, 0x55 } \
+}
+enum Scope
+{
+ Scope_Global = 0,
+ Scope_Machine = 1,
+ Scope_Session = 2
+};
+/* End of enum Scope Declaration */
+
+
+/* Start of enum BIOSBootMenuMode Declaration */
+#define BIOSBOOTMENUMODE_IID_STR "ae4fb9f7-29d2-45b4-b2c7-d579603135d5"
+#define BIOSBOOTMENUMODE_IID { \
+ 0xae4fb9f7, 0x29d2, 0x45b4, \
+ { 0xb2, 0xc7, 0xd5, 0x79, 0x60, 0x31, 0x35, 0xd5 } \
+}
+enum BIOSBootMenuMode
+{
+ BIOSBootMenuMode_Disabled = 0,
+ BIOSBootMenuMode_MenuOnly = 1,
+ BIOSBootMenuMode_MessageAndMenu = 2
+};
+/* End of enum BIOSBootMenuMode Declaration */
+
+
+/* Start of enum ProcessorFeature Declaration */
+#define PROCESSORFEATURE_IID_STR "64c38e6b-8bcf-45ad-ac03-9b406287c5bf"
+#define PROCESSORFEATURE_IID { \
+ 0x64c38e6b, 0x8bcf, 0x45ad, \
+ { 0xac, 0x03, 0x9b, 0x40, 0x62, 0x87, 0xc5, 0xbf } \
+}
+enum ProcessorFeature
+{
+ ProcessorFeature_HWVirtEx = 0,
+ ProcessorFeature_PAE = 1,
+ ProcessorFeature_LongMode = 2,
+ ProcessorFeature_NestedPaging = 3
+};
+/* End of enum ProcessorFeature Declaration */
+
+
+/* Start of enum FirmwareType Declaration */
+#define FIRMWARETYPE_IID_STR "b903f264-c230-483e-ac74-2b37ce60d371"
+#define FIRMWARETYPE_IID { \
+ 0xb903f264, 0xc230, 0x483e, \
+ { 0xac, 0x74, 0x2b, 0x37, 0xce, 0x60, 0xd3, 0x71 } \
+}
+enum FirmwareType
+{
+ FirmwareType_BIOS = 1,
+ FirmwareType_EFI = 2,
+ FirmwareType_EFI32 = 3,
+ FirmwareType_EFI64 = 4,
+ FirmwareType_EFIDUAL = 5
+};
+/* End of enum FirmwareType Declaration */
+
+
+/* Start of enum PointingHidType Declaration */
+#define POINTINGHIDTYPE_IID_STR "0d3c17a2-821a-4b2e-ae41-890c6c60aa97"
+#define POINTINGHIDTYPE_IID { \
+ 0x0d3c17a2, 0x821a, 0x4b2e, \
+ { 0xae, 0x41, 0x89, 0x0c, 0x6c, 0x60, 0xaa, 0x97 } \
+}
+enum PointingHidType
+{
+ PointingHidType_None = 1,
+ PointingHidType_PS2Mouse = 2,
+ PointingHidType_USBMouse = 3,
+ PointingHidType_USBTablet = 4,
+ PointingHidType_ComboMouse = 5
+};
+/* End of enum PointingHidType Declaration */
+
+
+/* Start of enum KeyboardHidType Declaration */
+#define KEYBOARDHIDTYPE_IID_STR "5a5b0996-3a3e-44bb-9019-56979812cbcc"
+#define KEYBOARDHIDTYPE_IID { \
+ 0x5a5b0996, 0x3a3e, 0x44bb, \
+ { 0x90, 0x19, 0x56, 0x97, 0x98, 0x12, 0xcb, 0xcc } \
+}
+enum KeyboardHidType
+{
+ KeyboardHidType_None = 1,
+ KeyboardHidType_PS2Keyboard = 2,
+ KeyboardHidType_USBKeyboard = 3,
+ KeyboardHidType_ComboKeyboard = 4
+};
+/* End of enum KeyboardHidType Declaration */
+
+
+/* Start of enum VFSType Declaration */
+#define VFSTYPE_IID_STR "813999ba-b949-48a8-9230-aadc6285e2f2"
+#define VFSTYPE_IID { \
+ 0x813999ba, 0xb949, 0x48a8, \
+ { 0x92, 0x30, 0xaa, 0xdc, 0x62, 0x85, 0xe2, 0xf2 } \
+}
+enum VFSType
+{
+ VFSType_File = 1,
+ VFSType_Cloud = 2,
+ VFSType_S3 = 3,
+ VFSType_WebDav = 4
+};
+/* End of enum VFSType Declaration */
+
+
+/* Start of enum VFSFileType Declaration */
+#define VFSFILETYPE_IID_STR "714333cd-44e2-415f-a245-d378fa9b1242"
+#define VFSFILETYPE_IID { \
+ 0x714333cd, 0x44e2, 0x415f, \
+ { 0xa2, 0x45, 0xd3, 0x78, 0xfa, 0x9b, 0x12, 0x42 } \
+}
+enum VFSFileType
+{
+ VFSFileType_Unknown = 1,
+ VFSFileType_Fifo = 2,
+ VFSFileType_DevChar = 3,
+ VFSFileType_Directory = 4,
+ VFSFileType_DevBlock = 5,
+ VFSFileType_File = 6,
+ VFSFileType_SymLink = 7,
+ VFSFileType_Socket = 8,
+ VFSFileType_WhiteOut = 9
+};
+/* End of enum VFSFileType Declaration */
+
+
+/* Start of enum VirtualSystemDescriptionType Declaration */
+#define VIRTUALSYSTEMDESCRIPTIONTYPE_IID_STR "c0f8f135-3a1d-417d-afa6-b38b95a91f90"
+#define VIRTUALSYSTEMDESCRIPTIONTYPE_IID { \
+ 0xc0f8f135, 0x3a1d, 0x417d, \
+ { 0xaf, 0xa6, 0xb3, 0x8b, 0x95, 0xa9, 0x1f, 0x90 } \
+}
+enum VirtualSystemDescriptionType
+{
+ VirtualSystemDescriptionType_Ignore = 1,
+ VirtualSystemDescriptionType_OS = 2,
+ VirtualSystemDescriptionType_Name = 3,
+ VirtualSystemDescriptionType_Product = 4,
+ VirtualSystemDescriptionType_Vendor = 5,
+ VirtualSystemDescriptionType_Version = 6,
+ VirtualSystemDescriptionType_ProductUrl = 7,
+ VirtualSystemDescriptionType_VendorUrl = 8,
+ VirtualSystemDescriptionType_Description = 9,
+ VirtualSystemDescriptionType_License = 10,
+ VirtualSystemDescriptionType_Miscellaneous = 11,
+ VirtualSystemDescriptionType_CPU = 12,
+ VirtualSystemDescriptionType_Memory = 13,
+ VirtualSystemDescriptionType_HardDiskControllerIDE = 14,
+ VirtualSystemDescriptionType_HardDiskControllerSATA = 15,
+ VirtualSystemDescriptionType_HardDiskControllerSCSI = 16,
+ VirtualSystemDescriptionType_HardDiskControllerSAS = 17,
+ VirtualSystemDescriptionType_HardDiskImage = 18,
+ VirtualSystemDescriptionType_Floppy = 19,
+ VirtualSystemDescriptionType_CDROM = 20,
+ VirtualSystemDescriptionType_NetworkAdapter = 21,
+ VirtualSystemDescriptionType_USBController = 22,
+ VirtualSystemDescriptionType_SoundCard = 23
+};
+/* End of enum VirtualSystemDescriptionType Declaration */
+
+
+/* Start of enum VirtualSystemDescriptionValueType Declaration */
+#define VIRTUALSYSTEMDESCRIPTIONVALUETYPE_IID_STR "56d9403f-3425-4118-9919-36f2a9b8c77c"
+#define VIRTUALSYSTEMDESCRIPTIONVALUETYPE_IID { \
+ 0x56d9403f, 0x3425, 0x4118, \
+ { 0x99, 0x19, 0x36, 0xf2, 0xa9, 0xb8, 0xc7, 0x7c } \
+}
+enum VirtualSystemDescriptionValueType
+{
+ VirtualSystemDescriptionValueType_Reference = 1,
+ VirtualSystemDescriptionValueType_Original = 2,
+ VirtualSystemDescriptionValueType_Auto = 3,
+ VirtualSystemDescriptionValueType_ExtraConfig = 4
+};
+/* End of enum VirtualSystemDescriptionValueType Declaration */
+
+
+/* Start of enum HostNetworkInterfaceMediumType Declaration */
+#define HOSTNETWORKINTERFACEMEDIUMTYPE_IID_STR "1aa54aaf-2497-45a2-bfb1-8eb225e93d5b"
+#define HOSTNETWORKINTERFACEMEDIUMTYPE_IID { \
+ 0x1aa54aaf, 0x2497, 0x45a2, \
+ { 0xbf, 0xb1, 0x8e, 0xb2, 0x25, 0xe9, 0x3d, 0x5b } \
+}
+enum HostNetworkInterfaceMediumType
+{
+ HostNetworkInterfaceMediumType_Unknown = 0,
+ HostNetworkInterfaceMediumType_Ethernet = 1,
+ HostNetworkInterfaceMediumType_PPP = 2,
+ HostNetworkInterfaceMediumType_SLIP = 3
+};
+/* End of enum HostNetworkInterfaceMediumType Declaration */
+
+
+/* Start of enum HostNetworkInterfaceStatus Declaration */
+#define HOSTNETWORKINTERFACESTATUS_IID_STR "CC474A69-2710-434B-8D99-C38E5D5A6F41"
+#define HOSTNETWORKINTERFACESTATUS_IID { \
+ 0xCC474A69, 0x2710, 0x434B, \
+ { 0x8D, 0x99, 0xC3, 0x8E, 0x5D, 0x5A, 0x6F, 0x41 } \
+}
+enum HostNetworkInterfaceStatus
+{
+ HostNetworkInterfaceStatus_Unknown = 0,
+ HostNetworkInterfaceStatus_Up = 1,
+ HostNetworkInterfaceStatus_Down = 2
+};
+/* End of enum HostNetworkInterfaceStatus Declaration */
+
+
+/* Start of enum HostNetworkInterfaceType Declaration */
+#define HOSTNETWORKINTERFACETYPE_IID_STR "67431b00-9946-48a2-bc02-b25c5919f4f3"
+#define HOSTNETWORKINTERFACETYPE_IID { \
+ 0x67431b00, 0x9946, 0x48a2, \
+ { 0xbc, 0x02, 0xb2, 0x5c, 0x59, 0x19, 0xf4, 0xf3 } \
+}
+enum HostNetworkInterfaceType
+{
+ HostNetworkInterfaceType_Bridged = 1,
+ HostNetworkInterfaceType_HostOnly = 2
+};
+/* End of enum HostNetworkInterfaceType Declaration */
+
+
+/* Start of enum MediumState Declaration */
+#define MEDIUMSTATE_IID_STR "ef41e980-e012-43cd-9dea-479d4ef14d13"
+#define MEDIUMSTATE_IID { \
+ 0xef41e980, 0xe012, 0x43cd, \
+ { 0x9d, 0xea, 0x47, 0x9d, 0x4e, 0xf1, 0x4d, 0x13 } \
+}
+enum MediumState
+{
+ MediumState_NotCreated = 0,
+ MediumState_Created = 1,
+ MediumState_LockedRead = 2,
+ MediumState_LockedWrite = 3,
+ MediumState_Inaccessible = 4,
+ MediumState_Creating = 5,
+ MediumState_Deleting = 6
+};
+/* End of enum MediumState Declaration */
+
+
+/* Start of enum MediumType Declaration */
+#define MEDIUMTYPE_IID_STR "46bf1fd4-ad86-4ded-8c49-28bd2d148e5a"
+#define MEDIUMTYPE_IID { \
+ 0x46bf1fd4, 0xad86, 0x4ded, \
+ { 0x8c, 0x49, 0x28, 0xbd, 0x2d, 0x14, 0x8e, 0x5a } \
+}
+enum MediumType
+{
+ MediumType_Normal = 0,
+ MediumType_Immutable = 1,
+ MediumType_Writethrough = 2,
+ MediumType_Shareable = 3
+};
+/* End of enum MediumType Declaration */
+
+
+/* Start of enum MediumVariant Declaration */
+#define MEDIUMVARIANT_IID_STR "584ea502-143b-4ab0-ad14-d1028fdf0316"
+#define MEDIUMVARIANT_IID { \
+ 0x584ea502, 0x143b, 0x4ab0, \
+ { 0xad, 0x14, 0xd1, 0x02, 0x8f, 0xdf, 0x03, 0x16 } \
+}
+enum MediumVariant
+{
+ MediumVariant_Standard = 0,
+ MediumVariant_VmdkSplit2G = 0x01,
+ MediumVariant_VmdkStreamOptimized = 0x04,
+ MediumVariant_VmdkESX = 0x08,
+ MediumVariant_Fixed = 0x10000,
+ MediumVariant_Diff = 0x20000
+};
+/* End of enum MediumVariant Declaration */
+
+
+/* Start of enum DataType Declaration */
+#define DATATYPE_IID_STR "d90ea51e-a3f1-4a01-beb1-c1723c0d3ba7"
+#define DATATYPE_IID { \
+ 0xd90ea51e, 0xa3f1, 0x4a01, \
+ { 0xbe, 0xb1, 0xc1, 0x72, 0x3c, 0x0d, 0x3b, 0xa7 } \
+}
+enum DataType
+{
+ DataType_Int32 = 0,
+ DataType_Int8 = 1,
+ DataType_String = 2
+};
+/* End of enum DataType Declaration */
+
+
+/* Start of enum DataFlags Declaration */
+#define DATAFLAGS_IID_STR "86884dcf-1d6b-4f1b-b4bf-f5aa44959d60"
+#define DATAFLAGS_IID { \
+ 0x86884dcf, 0x1d6b, 0x4f1b, \
+ { 0xb4, 0xbf, 0xf5, 0xaa, 0x44, 0x95, 0x9d, 0x60 } \
+}
+enum DataFlags
+{
+ DataFlags_None = 0x00,
+ DataFlags_Mandatory = 0x01,
+ DataFlags_Expert = 0x02,
+ DataFlags_Array = 0x04,
+ DataFlags_FlagMask = 0x07
+};
+/* End of enum DataFlags Declaration */
+
+
+/* Start of enum MediumFormatCapabilities Declaration */
+#define MEDIUMFORMATCAPABILITIES_IID_STR "70fcf810-99e8-4edc-aee4-7f51d489e657"
+#define MEDIUMFORMATCAPABILITIES_IID { \
+ 0x70fcf810, 0x99e8, 0x4edc, \
+ { 0xae, 0xe4, 0x7f, 0x51, 0xd4, 0x89, 0xe6, 0x57 } \
+}
+enum MediumFormatCapabilities
+{
+ MediumFormatCapabilities_Uuid = 0x01,
+ MediumFormatCapabilities_CreateFixed = 0x02,
+ MediumFormatCapabilities_CreateDynamic = 0x04,
+ MediumFormatCapabilities_CreateSplit2G = 0x08,
+ MediumFormatCapabilities_Differencing = 0x10,
+ MediumFormatCapabilities_Asynchronous = 0x20,
+ MediumFormatCapabilities_File = 0x40,
+ MediumFormatCapabilities_Properties = 0x80,
+ MediumFormatCapabilities_CapabilityMask = 0xFF
+};
+/* End of enum MediumFormatCapabilities Declaration */
+
+
+/* Start of enum MouseButtonState Declaration */
+#define MOUSEBUTTONSTATE_IID_STR "9ee094b8-b28a-4d56-a166-973cb588d7f8"
+#define MOUSEBUTTONSTATE_IID { \
+ 0x9ee094b8, 0xb28a, 0x4d56, \
+ { 0xa1, 0x66, 0x97, 0x3c, 0xb5, 0x88, 0xd7, 0xf8 } \
+}
+enum MouseButtonState
+{
+ MouseButtonState_LeftButton = 0x01,
+ MouseButtonState_RightButton = 0x02,
+ MouseButtonState_MiddleButton = 0x04,
+ MouseButtonState_WheelUp = 0x08,
+ MouseButtonState_WheelDown = 0x10,
+ MouseButtonState_XButton1 = 0x20,
+ MouseButtonState_XButton2 = 0x40,
+ MouseButtonState_MouseStateMask = 0x7F
+};
+/* End of enum MouseButtonState Declaration */
+
+
+/* Start of enum FramebufferPixelFormat Declaration */
+#define FRAMEBUFFERPIXELFORMAT_IID_STR "7acfd5ed-29e3-45e3-8136-73c9224f3d2d"
+#define FRAMEBUFFERPIXELFORMAT_IID { \
+ 0x7acfd5ed, 0x29e3, 0x45e3, \
+ { 0x81, 0x36, 0x73, 0xc9, 0x22, 0x4f, 0x3d, 0x2d } \
+}
+enum FramebufferPixelFormat
+{
+ FramebufferPixelFormat_Opaque = 0,
+ FramebufferPixelFormat_FOURCC_RGB = 0x32424752
+};
+/* End of enum FramebufferPixelFormat Declaration */
+
+
+/* Start of enum NetworkAttachmentType Declaration */
+#define NETWORKATTACHMENTTYPE_IID_STR "44bce1ee-99f7-4e8e-89fc-80597fd9eeaf"
+#define NETWORKATTACHMENTTYPE_IID { \
+ 0x44bce1ee, 0x99f7, 0x4e8e, \
+ { 0x89, 0xfc, 0x80, 0x59, 0x7f, 0xd9, 0xee, 0xaf } \
+}
+enum NetworkAttachmentType
+{
+ NetworkAttachmentType_Null = 0,
+ NetworkAttachmentType_NAT = 1,
+ NetworkAttachmentType_Bridged = 2,
+ NetworkAttachmentType_Internal = 3,
+ NetworkAttachmentType_HostOnly = 4,
+ NetworkAttachmentType_VDE = 5
+};
+/* End of enum NetworkAttachmentType Declaration */
+
+
+/* Start of enum NetworkAdapterType Declaration */
+#define NETWORKADAPTERTYPE_IID_STR "3c2281e4-d952-4e87-8c7d-24379cb6a81c"
+#define NETWORKADAPTERTYPE_IID { \
+ 0x3c2281e4, 0xd952, 0x4e87, \
+ { 0x8c, 0x7d, 0x24, 0x37, 0x9c, 0xb6, 0xa8, 0x1c } \
+}
+enum NetworkAdapterType
+{
+ NetworkAdapterType_Null = 0,
+ NetworkAdapterType_Am79C970A = 1,
+ NetworkAdapterType_Am79C973 = 2,
+ NetworkAdapterType_I82540EM = 3,
+ NetworkAdapterType_I82543GC = 4,
+ NetworkAdapterType_I82545EM = 5,
+ NetworkAdapterType_Virtio = 6
+};
+/* End of enum NetworkAdapterType Declaration */
+
+
+/* Start of enum PortMode Declaration */
+#define PORTMODE_IID_STR "533b5fe3-0185-4197-86a7-17e37dd39d76"
+#define PORTMODE_IID { \
+ 0x533b5fe3, 0x0185, 0x4197, \
+ { 0x86, 0xa7, 0x17, 0xe3, 0x7d, 0xd3, 0x9d, 0x76 } \
+}
+enum PortMode
+{
+ PortMode_Disconnected = 0,
+ PortMode_HostPipe = 1,
+ PortMode_HostDevice = 2,
+ PortMode_RawFile = 3
+};
+/* End of enum PortMode Declaration */
+
+
+/* Start of enum USBDeviceState Declaration */
+#define USBDEVICESTATE_IID_STR "b99a2e65-67fb-4882-82fd-f3e5e8193ab4"
+#define USBDEVICESTATE_IID { \
+ 0xb99a2e65, 0x67fb, 0x4882, \
+ { 0x82, 0xfd, 0xf3, 0xe5, 0xe8, 0x19, 0x3a, 0xb4 } \
+}
+enum USBDeviceState
+{
+ USBDeviceState_NotSupported = 0,
+ USBDeviceState_Unavailable = 1,
+ USBDeviceState_Busy = 2,
+ USBDeviceState_Available = 3,
+ USBDeviceState_Held = 4,
+ USBDeviceState_Captured = 5
+};
+/* End of enum USBDeviceState Declaration */
+
+
+/* Start of enum USBDeviceFilterAction Declaration */
+#define USBDEVICEFILTERACTION_IID_STR "cbc30a49-2f4e-43b5-9da6-121320475933"
+#define USBDEVICEFILTERACTION_IID { \
+ 0xcbc30a49, 0x2f4e, 0x43b5, \
+ { 0x9d, 0xa6, 0x12, 0x13, 0x20, 0x47, 0x59, 0x33 } \
+}
+enum USBDeviceFilterAction
+{
+ USBDeviceFilterAction_Null = 0,
+ USBDeviceFilterAction_Ignore = 1,
+ USBDeviceFilterAction_Hold = 2
+};
+/* End of enum USBDeviceFilterAction Declaration */
+
+
+/* Start of enum AudioDriverType Declaration */
+#define AUDIODRIVERTYPE_IID_STR "4bcc3d73-c2fe-40db-b72f-0c2ca9d68496"
+#define AUDIODRIVERTYPE_IID { \
+ 0x4bcc3d73, 0xc2fe, 0x40db, \
+ { 0xb7, 0x2f, 0x0c, 0x2c, 0xa9, 0xd6, 0x84, 0x96 } \
+}
+enum AudioDriverType
+{
+ AudioDriverType_Null = 0,
+ AudioDriverType_WinMM = 1,
+ AudioDriverType_OSS = 2,
+ AudioDriverType_ALSA = 3,
+ AudioDriverType_DirectSound = 4,
+ AudioDriverType_CoreAudio = 5,
+ AudioDriverType_MMPM = 6,
+ AudioDriverType_Pulse = 7,
+ AudioDriverType_SolAudio = 8
+};
+/* End of enum AudioDriverType Declaration */
+
+
+/* Start of enum AudioControllerType Declaration */
+#define AUDIOCONTROLLERTYPE_IID_STR "7afd395c-42c3-444e-8788-3ce80292f36c"
+#define AUDIOCONTROLLERTYPE_IID { \
+ 0x7afd395c, 0x42c3, 0x444e, \
+ { 0x87, 0x88, 0x3c, 0xe8, 0x02, 0x92, 0xf3, 0x6c } \
+}
+enum AudioControllerType
+{
+ AudioControllerType_AC97 = 0,
+ AudioControllerType_SB16 = 1
+};
+/* End of enum AudioControllerType Declaration */
+
+
+/* Start of enum VRDPAuthType Declaration */
+#define VRDPAUTHTYPE_IID_STR "3d91887a-b67f-4b33-85bf-2da7ab1ea83a"
+#define VRDPAUTHTYPE_IID { \
+ 0x3d91887a, 0xb67f, 0x4b33, \
+ { 0x85, 0xbf, 0x2d, 0xa7, 0xab, 0x1e, 0xa8, 0x3a } \
+}
+enum VRDPAuthType
+{
+ VRDPAuthType_Null = 0,
+ VRDPAuthType_External = 1,
+ VRDPAuthType_Guest = 2
+};
+/* End of enum VRDPAuthType Declaration */
+
+
+/* Start of enum StorageBus Declaration */
+#define STORAGEBUS_IID_STR "eee67ab3-668d-4ef5-91e0-7025fe4a0d7a"
+#define STORAGEBUS_IID { \
+ 0xeee67ab3, 0x668d, 0x4ef5, \
+ { 0x91, 0xe0, 0x70, 0x25, 0xfe, 0x4a, 0x0d, 0x7a } \
+}
+enum StorageBus
+{
+ StorageBus_Null = 0,
+ StorageBus_IDE = 1,
+ StorageBus_SATA = 2,
+ StorageBus_SCSI = 3,
+ StorageBus_Floppy = 4,
+ StorageBus_SAS = 5
+};
+/* End of enum StorageBus Declaration */
+
+
+/* Start of enum StorageControllerType Declaration */
+#define STORAGECONTROLLERTYPE_IID_STR "8a412b8a-f43e-4456-bd37-b474f0879a58"
+#define STORAGECONTROLLERTYPE_IID { \
+ 0x8a412b8a, 0xf43e, 0x4456, \
+ { 0xbd, 0x37, 0xb4, 0x74, 0xf0, 0x87, 0x9a, 0x58 } \
+}
+enum StorageControllerType
+{
+ StorageControllerType_Null = 0,
+ StorageControllerType_LsiLogic = 1,
+ StorageControllerType_BusLogic = 2,
+ StorageControllerType_IntelAhci = 3,
+ StorageControllerType_PIIX3 = 4,
+ StorageControllerType_PIIX4 = 5,
+ StorageControllerType_ICH6 = 6,
+ StorageControllerType_I82078 = 7,
+ StorageControllerType_LsiLogicSas = 8
+};
+/* End of enum StorageControllerType Declaration */
+
+
+/* Start of enum NATAliasMode Declaration */
+#define NATALIASMODE_IID_STR "67772168-50d9-11df-9669-7fb714ee4fa1"
+#define NATALIASMODE_IID { \
+ 0x67772168, 0x50d9, 0x11df, \
+ { 0x96, 0x69, 0x7f, 0xb7, 0x14, 0xee, 0x4f, 0xa1 } \
+}
+enum NATAliasMode
+{
+ NATAliasMode_AliasLog = 0x1,
+ NATAliasMode_AliasProxyOnly = 0x02,
+ NATAliasMode_AliasUseSamePorts = 0x04
+};
+/* End of enum NATAliasMode Declaration */
+
+
+/* Start of enum NATProtocol Declaration */
+#define NATPROTOCOL_IID_STR "e90164be-eb03-11de-94af-fff9b1c1b19f"
+#define NATPROTOCOL_IID { \
+ 0xe90164be, 0xeb03, 0x11de, \
+ { 0x94, 0xaf, 0xff, 0xf9, 0xb1, 0xc1, 0xb1, 0x9f } \
+}
+enum NATProtocol
+{
+ NATProtocol_UDP = 0,
+ NATProtocol_TCP = 1
+};
+/* End of enum NATProtocol Declaration */
+
+
+/* Start of struct IVirtualBoxErrorInfo Declaration */
+#define IVIRTUALBOXERRORINFO_IID_STR "4b86d186-407e-4f9e-8be8-e50061be8725"
+#define IVIRTUALBOXERRORINFO_IID { \
+ 0x4b86d186, 0x407e, 0x4f9e, \
+ { 0x8b, 0xe8, 0xe5, 0x00, 0x61, 0xbe, 0x87, 0x25 } \
+}
+struct IVirtualBoxErrorInfo_vtbl
+{
+ struct nsIException_vtbl nsiexception;
+
+ nsresult (*GetResultCode)(IVirtualBoxErrorInfo *pThis, PRInt32 *resultCode);
+
+ nsresult (*GetInterfaceID)(IVirtualBoxErrorInfo *pThis, PRUnichar * *interfaceID);
+
+ nsresult (*GetComponent)(IVirtualBoxErrorInfo *pThis, PRUnichar * *component);
+
+ nsresult (*GetText)(IVirtualBoxErrorInfo *pThis, PRUnichar * *text);
+
+ nsresult (*GetNext)(IVirtualBoxErrorInfo *pThis, IVirtualBoxErrorInfo * *next);
+
+};
+
+struct IVirtualBoxErrorInfo
+{
+ struct IVirtualBoxErrorInfo_vtbl *vtbl;
+};
+/* End of struct IVirtualBoxErrorInfo Declaration */
+
+
+/* Start of struct ILocalOwner Declaration */
+#define ILOCALOWNER_IID_STR "308FF42A-DC45-49D4-A950-B1EEE5E00BB5"
+#define ILOCALOWNER_IID { \
+ 0x308FF42A, 0xDC45, 0x49D4, \
+ { 0xA9, 0x50, 0xB1, 0xEE, 0xE5, 0xE0, 0x0B, 0xB5 } \
+}
+struct ILocalOwner_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*SetLocalObject)(
+ ILocalOwner *pThis,
+ nsISupports * object
+ );
+
+};
+
+struct ILocalOwner
+{
+ struct ILocalOwner_vtbl *vtbl;
+};
+/* End of struct ILocalOwner Declaration */
+
+
+/* Start of struct IVirtualBoxCallback Declaration */
+#define IVIRTUALBOXCALLBACK_IID_STR "7f6a65b6-ad5d-4a67-8872-0b11cb7ea95c"
+#define IVIRTUALBOXCALLBACK_IID { \
+ 0x7f6a65b6, 0xad5d, 0x4a67, \
+ { 0x88, 0x72, 0x0b, 0x11, 0xcb, 0x7e, 0xa9, 0x5c } \
+}
+struct IVirtualBoxCallback_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*OnMachineStateChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUint32 state
+ );
+
+ nsresult (*OnMachineDataChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId
+ );
+
+ nsresult (*OnExtraDataCanChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUnichar * key,
+ PRUnichar * value,
+ PRUnichar * * error,
+ PRBool * allowChange
+ );
+
+ nsresult (*OnExtraDataChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUnichar * key,
+ PRUnichar * value
+ );
+
+ nsresult (*OnMediumRegistered)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * mediumId,
+ PRUint32 mediumType,
+ PRBool registered
+ );
+
+ nsresult (*OnMachineRegistered)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRBool registered
+ );
+
+ nsresult (*OnSessionStateChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUint32 state
+ );
+
+ nsresult (*OnSnapshotTaken)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUnichar * snapshotId
+ );
+
+ nsresult (*OnSnapshotDeleted)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUnichar * snapshotId
+ );
+
+ nsresult (*OnSnapshotChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUnichar * snapshotId
+ );
+
+ nsresult (*OnGuestPropertyChange)(
+ IVirtualBoxCallback *pThis,
+ PRUnichar * machineId,
+ PRUnichar * name,
+ PRUnichar * value,
+ PRUnichar * flags
+ );
+
+};
+
+struct IVirtualBoxCallback
+{
+ struct IVirtualBoxCallback_vtbl *vtbl;
+};
+/* End of struct IVirtualBoxCallback Declaration */
+
+
+/* Start of struct IDHCPServer Declaration */
+#define IDHCPSERVER_IID_STR "6cfe387c-74fb-4ca7-bff6-973bec8af7a3"
+#define IDHCPSERVER_IID { \
+ 0x6cfe387c, 0x74fb, 0x4ca7, \
+ { 0xbf, 0xf6, 0x97, 0x3b, 0xec, 0x8a, 0xf7, 0xa3 } \
+}
+struct IDHCPServer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IDHCPServer *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IDHCPServer *pThis, PRBool enabled);
+
+ nsresult (*GetIPAddress)(IDHCPServer *pThis, PRUnichar * *IPAddress);
+
+ nsresult (*GetNetworkMask)(IDHCPServer *pThis, PRUnichar * *networkMask);
+
+ nsresult (*GetNetworkName)(IDHCPServer *pThis, PRUnichar * *networkName);
+
+ nsresult (*GetLowerIP)(IDHCPServer *pThis, PRUnichar * *lowerIP);
+
+ nsresult (*GetUpperIP)(IDHCPServer *pThis, PRUnichar * *upperIP);
+
+ nsresult (*SetConfiguration)(
+ IDHCPServer *pThis,
+ PRUnichar * IPAddress,
+ PRUnichar * networkMask,
+ PRUnichar * FromIPAddress,
+ PRUnichar * ToIPAddress
+ );
+
+ nsresult (*Start)(
+ IDHCPServer *pThis,
+ PRUnichar * networkName,
+ PRUnichar * trunkName,
+ PRUnichar * trunkType
+ );
+
+ nsresult (*Stop)(IDHCPServer *pThis );
+
+};
+
+struct IDHCPServer
+{
+ struct IDHCPServer_vtbl *vtbl;
+};
+/* End of struct IDHCPServer Declaration */
+
+
+/* Start of struct IVirtualBox Declaration */
+#define IVIRTUALBOX_IID_STR "3f36e024-7fed-4f20-a02c-9158a82b44e6"
+#define IVIRTUALBOX_IID { \
+ 0x3f36e024, 0x7fed, 0x4f20, \
+ { 0xa0, 0x2c, 0x91, 0x58, 0xa8, 0x2b, 0x44, 0xe6 } \
+}
+struct IVirtualBox_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetVersion)(IVirtualBox *pThis, PRUnichar * *version);
+
+ nsresult (*GetRevision)(IVirtualBox *pThis, PRUint32 *revision);
+
+ nsresult (*GetPackageType)(IVirtualBox *pThis, PRUnichar * *packageType);
+
+ nsresult (*GetHomeFolder)(IVirtualBox *pThis, PRUnichar * *homeFolder);
+
+ nsresult (*GetSettingsFilePath)(IVirtualBox *pThis, PRUnichar * *settingsFilePath);
+
+ nsresult (*GetHost)(IVirtualBox *pThis, IHost * *host);
+
+ nsresult (*GetSystemProperties)(IVirtualBox *pThis, ISystemProperties * *systemProperties);
+
+ nsresult (*GetMachines)(IVirtualBox *pThis, PRUint32 *machinesSize, IMachine * **machines);
+
+ nsresult (*GetHardDisks)(IVirtualBox *pThis, PRUint32 *hardDisksSize, IMedium * **hardDisks);
+
+ nsresult (*GetDVDImages)(IVirtualBox *pThis, PRUint32 *DVDImagesSize, IMedium * **DVDImages);
+
+ nsresult (*GetFloppyImages)(IVirtualBox *pThis, PRUint32 *floppyImagesSize, IMedium * **floppyImages);
+
+ nsresult (*GetProgressOperations)(IVirtualBox *pThis, PRUint32 *progressOperationsSize, IProgress * **progressOperations);
+
+ nsresult (*GetGuestOSTypes)(IVirtualBox *pThis, PRUint32 *guestOSTypesSize, IGuestOSType * **guestOSTypes);
+
+ nsresult (*GetSharedFolders)(IVirtualBox *pThis, PRUint32 *sharedFoldersSize, ISharedFolder * **sharedFolders);
+
+ nsresult (*GetPerformanceCollector)(IVirtualBox *pThis, IPerformanceCollector * *performanceCollector);
+
+ nsresult (*GetDHCPServers)(IVirtualBox *pThis, PRUint32 *DHCPServersSize, IDHCPServer * **DHCPServers);
+
+ nsresult (*CreateMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ PRUnichar * osTypeId,
+ PRUnichar * baseFolder,
+ PRUnichar * id,
+ PRBool override,
+ IMachine * * machine
+ );
+
+ nsresult (*CreateLegacyMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ PRUnichar * osTypeId,
+ PRUnichar * settingsFile,
+ PRUnichar * id,
+ IMachine * * machine
+ );
+
+ nsresult (*OpenMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * settingsFile,
+ IMachine * * machine
+ );
+
+ nsresult (*RegisterMachine)(
+ IVirtualBox *pThis,
+ IMachine * machine
+ );
+
+ nsresult (*GetMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IMachine * * machine
+ );
+
+ nsresult (*FindMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ IMachine * * machine
+ );
+
+ nsresult (*UnregisterMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IMachine * * machine
+ );
+
+ nsresult (*CreateAppliance)(
+ IVirtualBox *pThis,
+ IAppliance * * appliance
+ );
+
+ nsresult (*CreateHardDisk)(
+ IVirtualBox *pThis,
+ PRUnichar * format,
+ PRUnichar * location,
+ IMedium * * medium
+ );
+
+ nsresult (*OpenHardDisk)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ PRUint32 accessMode,
+ PRBool setImageId,
+ PRUnichar * imageId,
+ PRBool setParentId,
+ PRUnichar * parentId,
+ IMedium * * medium
+ );
+
+ nsresult (*GetHardDisk)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IMedium * * medium
+ );
+
+ nsresult (*FindHardDisk)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ IMedium * * medium
+ );
+
+ nsresult (*OpenDVDImage)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ PRUnichar * id,
+ IMedium * * image
+ );
+
+ nsresult (*GetDVDImage)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IMedium * * image
+ );
+
+ nsresult (*FindDVDImage)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ IMedium * * image
+ );
+
+ nsresult (*OpenFloppyImage)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ PRUnichar * id,
+ IMedium * * image
+ );
+
+ nsresult (*GetFloppyImage)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IMedium * * image
+ );
+
+ nsresult (*FindFloppyImage)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ IMedium * * image
+ );
+
+ nsresult (*GetGuestOSType)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IGuestOSType * * type
+ );
+
+ nsresult (*CreateSharedFolder)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ PRUnichar * hostPath,
+ PRBool writable
+ );
+
+ nsresult (*RemoveSharedFolder)(
+ IVirtualBox *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*GetExtraDataKeys)(
+ IVirtualBox *pThis,
+ PRUint32 *valueSize,
+ PRUnichar *** value
+ );
+
+ nsresult (*GetExtraData)(
+ IVirtualBox *pThis,
+ PRUnichar * key,
+ PRUnichar * * value
+ );
+
+ nsresult (*SetExtraData)(
+ IVirtualBox *pThis,
+ PRUnichar * key,
+ PRUnichar * value
+ );
+
+ nsresult (*OpenSession)(
+ IVirtualBox *pThis,
+ ISession * session,
+ PRUnichar * machineId
+ );
+
+ nsresult (*OpenRemoteSession)(
+ IVirtualBox *pThis,
+ ISession * session,
+ PRUnichar * machineId,
+ PRUnichar * type,
+ PRUnichar * environment,
+ IProgress * * progress
+ );
+
+ nsresult (*OpenExistingSession)(
+ IVirtualBox *pThis,
+ ISession * session,
+ PRUnichar * machineId
+ );
+
+ nsresult (*RegisterCallback)(
+ IVirtualBox *pThis,
+ IVirtualBoxCallback * callback
+ );
+
+ nsresult (*UnregisterCallback)(
+ IVirtualBox *pThis,
+ IVirtualBoxCallback * callback
+ );
+
+ nsresult (*WaitForPropertyChange)(
+ IVirtualBox *pThis,
+ PRUnichar * what,
+ PRUint32 timeout,
+ PRUnichar * * changed,
+ PRUnichar * * values
+ );
+
+ nsresult (*CreateDHCPServer)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ IDHCPServer * * server
+ );
+
+ nsresult (*FindDHCPServerByNetworkName)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ IDHCPServer * * server
+ );
+
+ nsresult (*RemoveDHCPServer)(
+ IVirtualBox *pThis,
+ IDHCPServer * server
+ );
+
+ nsresult (*CheckFirmwarePresent)(
+ IVirtualBox *pThis,
+ PRUint32 firmwareType,
+ PRUnichar * version,
+ PRUnichar * * url,
+ PRUnichar * * file,
+ PRBool * result
+ );
+
+};
+
+struct IVirtualBox
+{
+ struct IVirtualBox_vtbl *vtbl;
+};
+/* End of struct IVirtualBox Declaration */
+
+
+/* Start of struct IVFSExplorer Declaration */
+#define IVFSEXPLORER_IID_STR "2bb864a1-02a3-4474-a1d4-fb5f23b742e1"
+#define IVFSEXPLORER_IID { \
+ 0x2bb864a1, 0x02a3, 0x4474, \
+ { 0xa1, 0xd4, 0xfb, 0x5f, 0x23, 0xb7, 0x42, 0xe1 } \
+}
+struct IVFSExplorer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetPath)(IVFSExplorer *pThis, PRUnichar * *path);
+
+ nsresult (*GetType)(IVFSExplorer *pThis, PRUint32 *type);
+
+ nsresult (*Update)(
+ IVFSExplorer *pThis,
+ IProgress * * aProgress
+ );
+
+ nsresult (*Cd)(
+ IVFSExplorer *pThis,
+ PRUnichar * aDir,
+ IProgress * * aProgress
+ );
+
+ nsresult (*CdUp)(
+ IVFSExplorer *pThis,
+ IProgress * * aProgress
+ );
+
+ nsresult (*EntryList)(
+ IVFSExplorer *pThis,
+ PRUint32 *aNamesSize,
+ PRUnichar *** aNames,
+ PRUint32 *aTypesSize,
+ PRUint32* aTypes
+ );
+
+ nsresult (*Exists)(
+ IVFSExplorer *pThis,
+ PRUint32 aNamesSize,
+ PRUnichar ** aNames,
+ PRUint32 *aExistsSize,
+ PRUnichar *** aExists
+ );
+
+ nsresult (*Remove)(
+ IVFSExplorer *pThis,
+ PRUint32 aNamesSize,
+ PRUnichar ** aNames,
+ IProgress * * aProgress
+ );
+
+};
+
+struct IVFSExplorer
+{
+ struct IVFSExplorer_vtbl *vtbl;
+};
+/* End of struct IVFSExplorer Declaration */
+
+
+/* Start of struct IAppliance Declaration */
+#define IAPPLIANCE_IID_STR "e3ba9ab9-ac2c-4266-8bd2-91c4bf721ceb"
+#define IAPPLIANCE_IID { \
+ 0xe3ba9ab9, 0xac2c, 0x4266, \
+ { 0x8b, 0xd2, 0x91, 0xc4, 0xbf, 0x72, 0x1c, 0xeb } \
+}
+struct IAppliance_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetPath)(IAppliance *pThis, PRUnichar * *path);
+
+ nsresult (*GetDisks)(IAppliance *pThis, PRUint32 *disksSize, PRUnichar * **disks);
+
+ nsresult (*GetVirtualSystemDescriptions)(IAppliance *pThis, PRUint32 *virtualSystemDescriptionsSize, IVirtualSystemDescription * **virtualSystemDescriptions);
+
+ nsresult (*Read)(
+ IAppliance *pThis,
+ PRUnichar * file,
+ IProgress * * aProgress
+ );
+
+ nsresult (*Interpret)(IAppliance *pThis );
+
+ nsresult (*ImportMachines)(
+ IAppliance *pThis,
+ IProgress * * aProgress
+ );
+
+ nsresult (*CreateVFSExplorer)(
+ IAppliance *pThis,
+ PRUnichar * aUri,
+ IVFSExplorer * * aExplorer
+ );
+
+ nsresult (*Write)(
+ IAppliance *pThis,
+ PRUnichar * format,
+ PRUnichar * path,
+ IProgress * * aProgress
+ );
+
+ nsresult (*GetWarnings)(
+ IAppliance *pThis,
+ PRUint32 *aWarningsSize,
+ PRUnichar *** aWarnings
+ );
+
+};
+
+struct IAppliance
+{
+ struct IAppliance_vtbl *vtbl;
+};
+/* End of struct IAppliance Declaration */
+
+
+/* Start of struct IVirtualSystemDescription Declaration */
+#define IVIRTUALSYSTEMDESCRIPTION_IID_STR "d7525e6c-531a-4c51-8e04-41235083a3d8"
+#define IVIRTUALSYSTEMDESCRIPTION_IID { \
+ 0xd7525e6c, 0x531a, 0x4c51, \
+ { 0x8e, 0x04, 0x41, 0x23, 0x50, 0x83, 0xa3, 0xd8 } \
+}
+struct IVirtualSystemDescription_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetCount)(IVirtualSystemDescription *pThis, PRUint32 *count);
+
+ nsresult (*GetDescription)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 *aTypesSize,
+ PRUint32* aTypes,
+ PRUint32 *aRefsSize,
+ PRUnichar *** aRefs,
+ PRUint32 *aOvfValuesSize,
+ PRUnichar *** aOvfValues,
+ PRUint32 *aVBoxValuesSize,
+ PRUnichar *** aVBoxValues,
+ PRUint32 *aExtraConfigValuesSize,
+ PRUnichar *** aExtraConfigValues
+ );
+
+ nsresult (*GetDescriptionByType)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aType,
+ PRUint32 *aTypesSize,
+ PRUint32* aTypes,
+ PRUint32 *aRefsSize,
+ PRUnichar *** aRefs,
+ PRUint32 *aOvfValuesSize,
+ PRUnichar *** aOvfValues,
+ PRUint32 *aVBoxValuesSize,
+ PRUnichar *** aVBoxValues,
+ PRUint32 *aExtraConfigValuesSize,
+ PRUnichar *** aExtraConfigValues
+ );
+
+ nsresult (*GetValuesByType)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aType,
+ PRUint32 aWhich,
+ PRUint32 *aValuesSize,
+ PRUnichar *** aValues
+ );
+
+ nsresult (*SetFinalValues)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aEnabledSize,
+ PRBool* aEnabled,
+ PRUint32 aVBoxValuesSize,
+ PRUnichar ** aVBoxValues,
+ PRUint32 aExtraConfigValuesSize,
+ PRUnichar ** aExtraConfigValues
+ );
+
+ nsresult (*AddDescription)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aType,
+ PRUnichar * aVBoxValue,
+ PRUnichar * aExtraConfigValue
+ );
+
+};
+
+struct IVirtualSystemDescription
+{
+ struct IVirtualSystemDescription_vtbl *vtbl;
+};
+/* End of struct IVirtualSystemDescription Declaration */
+
+
+/* Start of struct IInternalMachineControl Declaration */
+#define IINTERNALMACHINECONTROL_IID_STR "26604a54-8628-491b-a0ea-e1392a16d13b"
+#define IINTERNALMACHINECONTROL_IID { \
+ 0x26604a54, 0x8628, 0x491b, \
+ { 0xa0, 0xea, 0xe1, 0x39, 0x2a, 0x16, 0xd1, 0x3b } \
+}
+struct IInternalMachineControl_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*SetRemoveSavedState)(
+ IInternalMachineControl *pThis,
+ PRBool aRemove
+ );
+
+ nsresult (*UpdateState)(
+ IInternalMachineControl *pThis,
+ PRUint32 state
+ );
+
+ nsresult (*GetIPCId)(
+ IInternalMachineControl *pThis,
+ PRUnichar * * id
+ );
+
+ nsresult (*BeginPowerUp)(
+ IInternalMachineControl *pThis,
+ IProgress * progress
+ );
+
+ nsresult (*EndPowerUp)(
+ IInternalMachineControl *pThis,
+ PRInt32 result
+ );
+
+ nsresult (*RunUSBDeviceFilters)(
+ IInternalMachineControl *pThis,
+ IUSBDevice * device,
+ PRBool * matched,
+ PRUint32 * maskedInterfaces
+ );
+
+ nsresult (*CaptureUSBDevice)(
+ IInternalMachineControl *pThis,
+ PRUnichar * id
+ );
+
+ nsresult (*DetachUSBDevice)(
+ IInternalMachineControl *pThis,
+ PRUnichar * id,
+ PRBool done
+ );
+
+ nsresult (*AutoCaptureUSBDevices)(IInternalMachineControl *pThis );
+
+ nsresult (*DetachAllUSBDevices)(
+ IInternalMachineControl *pThis,
+ PRBool done
+ );
+
+ nsresult (*OnSessionEnd)(
+ IInternalMachineControl *pThis,
+ ISession * session,
+ IProgress * * progress
+ );
+
+ nsresult (*BeginSavingState)(
+ IInternalMachineControl *pThis,
+ IProgress * progress,
+ PRUnichar * * stateFilePath
+ );
+
+ nsresult (*EndSavingState)(
+ IInternalMachineControl *pThis,
+ PRBool success
+ );
+
+ nsresult (*AdoptSavedState)(
+ IInternalMachineControl *pThis,
+ PRUnichar * savedStateFile
+ );
+
+ nsresult (*BeginTakingSnapshot)(
+ IInternalMachineControl *pThis,
+ IConsole * initiator,
+ PRUnichar * name,
+ PRUnichar * description,
+ IProgress * consoleProgress,
+ PRBool fTakingSnapshotOnline,
+ PRUnichar * * stateFilePath
+ );
+
+ nsresult (*EndTakingSnapshot)(
+ IInternalMachineControl *pThis,
+ PRBool success
+ );
+
+ nsresult (*DeleteSnapshot)(
+ IInternalMachineControl *pThis,
+ IConsole * initiator,
+ PRUnichar * id,
+ PRUint32 * machineState,
+ IProgress * * progress
+ );
+
+ nsresult (*FinishOnlineMergeMedium)(
+ IInternalMachineControl *pThis,
+ IMediumAttachment * mediumAttachment,
+ IMedium * source,
+ IMedium * target,
+ PRBool mergeForward,
+ IMedium * parentForTarget,
+ PRUint32 childrenToReparentSize,
+ IMedium ** childrenToReparent
+ );
+
+ nsresult (*RestoreSnapshot)(
+ IInternalMachineControl *pThis,
+ IConsole * initiator,
+ ISnapshot * snapshot,
+ PRUint32 * machineState,
+ IProgress * * progress
+ );
+
+ nsresult (*PullGuestProperties)(
+ IInternalMachineControl *pThis,
+ PRUint32 *nameSize,
+ PRUnichar *** name,
+ PRUint32 *valueSize,
+ PRUnichar *** value,
+ PRUint32 *timestampSize,
+ PRUint64* timestamp,
+ PRUint32 *flagsSize,
+ PRUnichar *** flags
+ );
+
+ nsresult (*PushGuestProperty)(
+ IInternalMachineControl *pThis,
+ PRUnichar * name,
+ PRUnichar * value,
+ PRUint64 timestamp,
+ PRUnichar * flags
+ );
+
+ nsresult (*LockMedia)(IInternalMachineControl *pThis );
+
+ nsresult (*UnlockMedia)(IInternalMachineControl *pThis );
+
+};
+
+struct IInternalMachineControl
+{
+ struct IInternalMachineControl_vtbl *vtbl;
+};
+/* End of struct IInternalMachineControl Declaration */
+
+
+/* Start of struct IBIOSSettings Declaration */
+#define IBIOSSETTINGS_IID_STR "38b54279-dc35-4f5e-a431-835b867c6b5e"
+#define IBIOSSETTINGS_IID { \
+ 0x38b54279, 0xdc35, 0x4f5e, \
+ { 0xa4, 0x31, 0x83, 0x5b, 0x86, 0x7c, 0x6b, 0x5e } \
+}
+struct IBIOSSettings_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetLogoFadeIn)(IBIOSSettings *pThis, PRBool *logoFadeIn);
+ nsresult (*SetLogoFadeIn)(IBIOSSettings *pThis, PRBool logoFadeIn);
+
+ nsresult (*GetLogoFadeOut)(IBIOSSettings *pThis, PRBool *logoFadeOut);
+ nsresult (*SetLogoFadeOut)(IBIOSSettings *pThis, PRBool logoFadeOut);
+
+ nsresult (*GetLogoDisplayTime)(IBIOSSettings *pThis, PRUint32 *logoDisplayTime);
+ nsresult (*SetLogoDisplayTime)(IBIOSSettings *pThis, PRUint32 logoDisplayTime);
+
+ nsresult (*GetLogoImagePath)(IBIOSSettings *pThis, PRUnichar * *logoImagePath);
+ nsresult (*SetLogoImagePath)(IBIOSSettings *pThis, PRUnichar * logoImagePath);
+
+ nsresult (*GetBootMenuMode)(IBIOSSettings *pThis, PRUint32 *bootMenuMode);
+ nsresult (*SetBootMenuMode)(IBIOSSettings *pThis, PRUint32 bootMenuMode);
+
+ nsresult (*GetACPIEnabled)(IBIOSSettings *pThis, PRBool *ACPIEnabled);
+ nsresult (*SetACPIEnabled)(IBIOSSettings *pThis, PRBool ACPIEnabled);
+
+ nsresult (*GetIOAPICEnabled)(IBIOSSettings *pThis, PRBool *IOAPICEnabled);
+ nsresult (*SetIOAPICEnabled)(IBIOSSettings *pThis, PRBool IOAPICEnabled);
+
+ nsresult (*GetTimeOffset)(IBIOSSettings *pThis, PRInt64 *timeOffset);
+ nsresult (*SetTimeOffset)(IBIOSSettings *pThis, PRInt64 timeOffset);
+
+ nsresult (*GetPXEDebugEnabled)(IBIOSSettings *pThis, PRBool *PXEDebugEnabled);
+ nsresult (*SetPXEDebugEnabled)(IBIOSSettings *pThis, PRBool PXEDebugEnabled);
+
+};
+
+struct IBIOSSettings
+{
+ struct IBIOSSettings_vtbl *vtbl;
+};
+/* End of struct IBIOSSettings Declaration */
+
+
+/* Start of struct IMachine Declaration */
+#define IMACHINE_IID_STR "6d9212cb-a5c0-48b7-bbc1-3fa2ba2ee6d2"
+#define IMACHINE_IID { \
+ 0x6d9212cb, 0xa5c0, 0x48b7, \
+ { 0xbb, 0xc1, 0x3f, 0xa2, 0xba, 0x2e, 0xe6, 0xd2 } \
+}
+struct IMachine_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetParent)(IMachine *pThis, IVirtualBox * *parent);
+
+ nsresult (*GetAccessible)(IMachine *pThis, PRBool *accessible);
+
+ nsresult (*GetAccessError)(IMachine *pThis, IVirtualBoxErrorInfo * *accessError);
+
+ nsresult (*GetName)(IMachine *pThis, PRUnichar * *name);
+ nsresult (*SetName)(IMachine *pThis, PRUnichar * name);
+
+ nsresult (*GetDescription)(IMachine *pThis, PRUnichar * *description);
+ nsresult (*SetDescription)(IMachine *pThis, PRUnichar * description);
+
+ nsresult (*GetId)(IMachine *pThis, PRUnichar * *id);
+
+ nsresult (*GetOSTypeId)(IMachine *pThis, PRUnichar * *OSTypeId);
+ nsresult (*SetOSTypeId)(IMachine *pThis, PRUnichar * OSTypeId);
+
+ nsresult (*GetHardwareVersion)(IMachine *pThis, PRUnichar * *HardwareVersion);
+ nsresult (*SetHardwareVersion)(IMachine *pThis, PRUnichar * HardwareVersion);
+
+ nsresult (*GetHardwareUUID)(IMachine *pThis, PRUnichar * *hardwareUUID);
+ nsresult (*SetHardwareUUID)(IMachine *pThis, PRUnichar * hardwareUUID);
+
+ nsresult (*GetCPUCount)(IMachine *pThis, PRUint32 *CPUCount);
+ nsresult (*SetCPUCount)(IMachine *pThis, PRUint32 CPUCount);
+
+ nsresult (*GetCPUHotPlugEnabled)(IMachine *pThis, PRBool *CPUHotPlugEnabled);
+ nsresult (*SetCPUHotPlugEnabled)(IMachine *pThis, PRBool CPUHotPlugEnabled);
+
+ nsresult (*GetMemorySize)(IMachine *pThis, PRUint32 *memorySize);
+ nsresult (*SetMemorySize)(IMachine *pThis, PRUint32 memorySize);
+
+ nsresult (*GetMemoryBalloonSize)(IMachine *pThis, PRUint32 *memoryBalloonSize);
+ nsresult (*SetMemoryBalloonSize)(IMachine *pThis, PRUint32 memoryBalloonSize);
+
+ nsresult (*GetPageFusionEnabled)(IMachine *pThis, PRBool *PageFusionEnabled);
+ nsresult (*SetPageFusionEnabled)(IMachine *pThis, PRBool PageFusionEnabled);
+
+ nsresult (*GetVRAMSize)(IMachine *pThis, PRUint32 *VRAMSize);
+ nsresult (*SetVRAMSize)(IMachine *pThis, PRUint32 VRAMSize);
+
+ nsresult (*GetAccelerate3DEnabled)(IMachine *pThis, PRBool *accelerate3DEnabled);
+ nsresult (*SetAccelerate3DEnabled)(IMachine *pThis, PRBool accelerate3DEnabled);
+
+ nsresult (*GetAccelerate2DVideoEnabled)(IMachine *pThis, PRBool *accelerate2DVideoEnabled);
+ nsresult (*SetAccelerate2DVideoEnabled)(IMachine *pThis, PRBool accelerate2DVideoEnabled);
+
+ nsresult (*GetMonitorCount)(IMachine *pThis, PRUint32 *monitorCount);
+ nsresult (*SetMonitorCount)(IMachine *pThis, PRUint32 monitorCount);
+
+ nsresult (*GetBIOSSettings)(IMachine *pThis, IBIOSSettings * *BIOSSettings);
+
+ nsresult (*GetFirmwareType)(IMachine *pThis, PRUint32 *firmwareType);
+ nsresult (*SetFirmwareType)(IMachine *pThis, PRUint32 firmwareType);
+
+ nsresult (*GetPointingHidType)(IMachine *pThis, PRUint32 *pointingHidType);
+ nsresult (*SetPointingHidType)(IMachine *pThis, PRUint32 pointingHidType);
+
+ nsresult (*GetKeyboardHidType)(IMachine *pThis, PRUint32 *keyboardHidType);
+ nsresult (*SetKeyboardHidType)(IMachine *pThis, PRUint32 keyboardHidType);
+
+ nsresult (*GetHpetEnabled)(IMachine *pThis, PRBool *hpetEnabled);
+ nsresult (*SetHpetEnabled)(IMachine *pThis, PRBool hpetEnabled);
+
+ nsresult (*GetSnapshotFolder)(IMachine *pThis, PRUnichar * *snapshotFolder);
+ nsresult (*SetSnapshotFolder)(IMachine *pThis, PRUnichar * snapshotFolder);
+
+ nsresult (*GetVRDPServer)(IMachine *pThis, IVRDPServer * *VRDPServer);
+
+ nsresult (*GetMediumAttachments)(IMachine *pThis, PRUint32 *mediumAttachmentsSize, IMediumAttachment * **mediumAttachments);
+
+ nsresult (*GetUSBController)(IMachine *pThis, IUSBController * *USBController);
+
+ nsresult (*GetAudioAdapter)(IMachine *pThis, IAudioAdapter * *audioAdapter);
+
+ nsresult (*GetStorageControllers)(IMachine *pThis, PRUint32 *storageControllersSize, IStorageController * **storageControllers);
+
+ nsresult (*GetSettingsFilePath)(IMachine *pThis, PRUnichar * *settingsFilePath);
+
+ nsresult (*GetSettingsModified)(IMachine *pThis, PRBool *settingsModified);
+
+ nsresult (*GetSessionState)(IMachine *pThis, PRUint32 *sessionState);
+
+ nsresult (*GetSessionType)(IMachine *pThis, PRUnichar * *sessionType);
+
+ nsresult (*GetSessionPid)(IMachine *pThis, PRUint32 *sessionPid);
+
+ nsresult (*GetState)(IMachine *pThis, PRUint32 *state);
+
+ nsresult (*GetLastStateChange)(IMachine *pThis, PRInt64 *lastStateChange);
+
+ nsresult (*GetStateFilePath)(IMachine *pThis, PRUnichar * *stateFilePath);
+
+ nsresult (*GetLogFolder)(IMachine *pThis, PRUnichar * *logFolder);
+
+ nsresult (*GetCurrentSnapshot)(IMachine *pThis, ISnapshot * *currentSnapshot);
+
+ nsresult (*GetSnapshotCount)(IMachine *pThis, PRUint32 *snapshotCount);
+
+ nsresult (*GetCurrentStateModified)(IMachine *pThis, PRBool *currentStateModified);
+
+ nsresult (*GetSharedFolders)(IMachine *pThis, PRUint32 *sharedFoldersSize, ISharedFolder * **sharedFolders);
+
+ nsresult (*GetClipboardMode)(IMachine *pThis, PRUint32 *clipboardMode);
+ nsresult (*SetClipboardMode)(IMachine *pThis, PRUint32 clipboardMode);
+
+ nsresult (*GetGuestPropertyNotificationPatterns)(IMachine *pThis, PRUnichar * *guestPropertyNotificationPatterns);
+ nsresult (*SetGuestPropertyNotificationPatterns)(IMachine *pThis, PRUnichar * guestPropertyNotificationPatterns);
+
+ nsresult (*GetTeleporterEnabled)(IMachine *pThis, PRBool *teleporterEnabled);
+ nsresult (*SetTeleporterEnabled)(IMachine *pThis, PRBool teleporterEnabled);
+
+ nsresult (*GetTeleporterPort)(IMachine *pThis, PRUint32 *teleporterPort);
+ nsresult (*SetTeleporterPort)(IMachine *pThis, PRUint32 teleporterPort);
+
+ nsresult (*GetTeleporterAddress)(IMachine *pThis, PRUnichar * *teleporterAddress);
+ nsresult (*SetTeleporterAddress)(IMachine *pThis, PRUnichar * teleporterAddress);
+
+ nsresult (*GetTeleporterPassword)(IMachine *pThis, PRUnichar * *teleporterPassword);
+ nsresult (*SetTeleporterPassword)(IMachine *pThis, PRUnichar * teleporterPassword);
+
+ nsresult (*GetRTCUseUTC)(IMachine *pThis, PRBool *RTCUseUTC);
+ nsresult (*SetRTCUseUTC)(IMachine *pThis, PRBool RTCUseUTC);
+
+ nsresult (*GetIoCacheEnabled)(IMachine *pThis, PRBool *ioCacheEnabled);
+ nsresult (*SetIoCacheEnabled)(IMachine *pThis, PRBool ioCacheEnabled);
+
+ nsresult (*GetIoCacheSize)(IMachine *pThis, PRUint32 *ioCacheSize);
+ nsresult (*SetIoCacheSize)(IMachine *pThis, PRUint32 ioCacheSize);
+
+ nsresult (*GetIoBandwidthMax)(IMachine *pThis, PRUint32 *ioBandwidthMax);
+ nsresult (*SetIoBandwidthMax)(IMachine *pThis, PRUint32 ioBandwidthMax);
+
+ nsresult (*SetBootOrder)(
+ IMachine *pThis,
+ PRUint32 position,
+ PRUint32 device
+ );
+
+ nsresult (*GetBootOrder)(
+ IMachine *pThis,
+ PRUint32 position,
+ PRUint32 * device
+ );
+
+ nsresult (*AttachDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ PRUint32 type,
+ PRUnichar * id
+ );
+
+ nsresult (*DetachDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device
+ );
+
+ nsresult (*PassthroughDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ PRBool passthrough
+ );
+
+ nsresult (*MountMedium)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ PRUnichar * medium,
+ PRBool force
+ );
+
+ nsresult (*GetMedium)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ IMedium * * medium
+ );
+
+ nsresult (*GetMediumAttachmentsOfController)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUint32 *mediumAttachmentsSize,
+ IMediumAttachment *** mediumAttachments
+ );
+
+ nsresult (*GetMediumAttachment)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ IMediumAttachment * * attachment
+ );
+
+ nsresult (*GetNetworkAdapter)(
+ IMachine *pThis,
+ PRUint32 slot,
+ INetworkAdapter * * adapter
+ );
+
+ nsresult (*AddStorageController)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUint32 connectionType,
+ IStorageController * * controller
+ );
+
+ nsresult (*GetStorageControllerByName)(
+ IMachine *pThis,
+ PRUnichar * name,
+ IStorageController * * storageController
+ );
+
+ nsresult (*GetStorageControllerByInstance)(
+ IMachine *pThis,
+ PRUint32 instance,
+ IStorageController * * storageController
+ );
+
+ nsresult (*RemoveStorageController)(
+ IMachine *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*GetSerialPort)(
+ IMachine *pThis,
+ PRUint32 slot,
+ ISerialPort * * port
+ );
+
+ nsresult (*GetParallelPort)(
+ IMachine *pThis,
+ PRUint32 slot,
+ IParallelPort * * port
+ );
+
+ nsresult (*GetExtraDataKeys)(
+ IMachine *pThis,
+ PRUint32 *valueSize,
+ PRUnichar *** value
+ );
+
+ nsresult (*GetExtraData)(
+ IMachine *pThis,
+ PRUnichar * key,
+ PRUnichar * * value
+ );
+
+ nsresult (*SetExtraData)(
+ IMachine *pThis,
+ PRUnichar * key,
+ PRUnichar * value
+ );
+
+ nsresult (*GetCPUProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool * value
+ );
+
+ nsresult (*SetCPUProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool value
+ );
+
+ nsresult (*GetCPUIDLeaf)(
+ IMachine *pThis,
+ PRUint32 id,
+ PRUint32 * valEax,
+ PRUint32 * valEbx,
+ PRUint32 * valEcx,
+ PRUint32 * valEdx
+ );
+
+ nsresult (*SetCPUIDLeaf)(
+ IMachine *pThis,
+ PRUint32 id,
+ PRUint32 valEax,
+ PRUint32 valEbx,
+ PRUint32 valEcx,
+ PRUint32 valEdx
+ );
+
+ nsresult (*RemoveCPUIDLeaf)(
+ IMachine *pThis,
+ PRUint32 id
+ );
+
+ nsresult (*RemoveAllCPUIDLeaves)(IMachine *pThis );
+
+ nsresult (*GetHWVirtExProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool * value
+ );
+
+ nsresult (*SetHWVirtExProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool value
+ );
+
+ nsresult (*SaveSettings)(IMachine *pThis );
+
+ nsresult (*DiscardSettings)(IMachine *pThis );
+
+ nsresult (*DeleteSettings)(IMachine *pThis );
+
+ nsresult (*Export)(
+ IMachine *pThis,
+ IAppliance * aAppliance,
+ IVirtualSystemDescription * * aDescription
+ );
+
+ nsresult (*GetSnapshot)(
+ IMachine *pThis,
+ PRUnichar * id,
+ ISnapshot * * snapshot
+ );
+
+ nsresult (*FindSnapshot)(
+ IMachine *pThis,
+ PRUnichar * name,
+ ISnapshot * * snapshot
+ );
+
+ nsresult (*SetCurrentSnapshot)(
+ IMachine *pThis,
+ PRUnichar * id
+ );
+
+ nsresult (*CreateSharedFolder)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUnichar * hostPath,
+ PRBool writable
+ );
+
+ nsresult (*RemoveSharedFolder)(
+ IMachine *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*CanShowConsoleWindow)(
+ IMachine *pThis,
+ PRBool * canShow
+ );
+
+ nsresult (*ShowConsoleWindow)(
+ IMachine *pThis,
+ PRUint64 * winId
+ );
+
+ nsresult (*GetGuestProperty)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUnichar * * value,
+ PRUint64 * timestamp,
+ PRUnichar * * flags
+ );
+
+ nsresult (*GetGuestPropertyValue)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUnichar * * value
+ );
+
+ nsresult (*GetGuestPropertyTimestamp)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUint64 * value
+ );
+
+ nsresult (*SetGuestProperty)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUnichar * value,
+ PRUnichar * flags
+ );
+
+ nsresult (*SetGuestPropertyValue)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUnichar * value
+ );
+
+ nsresult (*EnumerateGuestProperties)(
+ IMachine *pThis,
+ PRUnichar * patterns,
+ PRUint32 *nameSize,
+ PRUnichar *** name,
+ PRUint32 *valueSize,
+ PRUnichar *** value,
+ PRUint32 *timestampSize,
+ PRUint64* timestamp,
+ PRUint32 *flagsSize,
+ PRUnichar *** flags
+ );
+
+ nsresult (*QuerySavedThumbnailSize)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * size,
+ PRUint32 * width,
+ PRUint32 * height
+ );
+
+ nsresult (*ReadSavedThumbnailToArray)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRBool BGR,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*QuerySavedScreenshotPNGSize)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * size,
+ PRUint32 * width,
+ PRUint32 * height
+ );
+
+ nsresult (*ReadSavedScreenshotPNGToArray)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*HotPlugCPU)(
+ IMachine *pThis,
+ PRUint32 cpu
+ );
+
+ nsresult (*HotUnplugCPU)(
+ IMachine *pThis,
+ PRUint32 cpu
+ );
+
+ nsresult (*GetCPUStatus)(
+ IMachine *pThis,
+ PRUint32 cpu,
+ PRBool * attached
+ );
+
+ nsresult (*QueryLogFilename)(
+ IMachine *pThis,
+ PRUint32 idx,
+ PRUnichar * * filename
+ );
+
+ nsresult (*ReadLog)(
+ IMachine *pThis,
+ PRUint32 idx,
+ PRUint64 offset,
+ PRUint64 size,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+};
+
+struct IMachine
+{
+ struct IMachine_vtbl *vtbl;
+};
+/* End of struct IMachine Declaration */
+
+
+/* Start of struct IConsoleCallback Declaration */
+#define ICONSOLECALLBACK_IID_STR "60703f8d-81e4-4b45-a147-dcfd07692b19"
+#define ICONSOLECALLBACK_IID { \
+ 0x60703f8d, 0x81e4, 0x4b45, \
+ { 0xa1, 0x47, 0xdc, 0xfd, 0x07, 0x69, 0x2b, 0x19 } \
+}
+struct IConsoleCallback_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*OnMousePointerShapeChange)(
+ IConsoleCallback *pThis,
+ PRBool visible,
+ PRBool alpha,
+ PRUint32 xHot,
+ PRUint32 yHot,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 shapeSize,
+ PRUint8* shape
+ );
+
+ nsresult (*OnMouseCapabilityChange)(
+ IConsoleCallback *pThis,
+ PRBool supportsAbsolute,
+ PRBool supportsRelative,
+ PRBool needsHostCursor
+ );
+
+ nsresult (*OnKeyboardLedsChange)(
+ IConsoleCallback *pThis,
+ PRBool numLock,
+ PRBool capsLock,
+ PRBool scrollLock
+ );
+
+ nsresult (*OnStateChange)(
+ IConsoleCallback *pThis,
+ PRUint32 state
+ );
+
+ nsresult (*OnAdditionsStateChange)(IConsoleCallback *pThis );
+
+ nsresult (*OnNetworkAdapterChange)(
+ IConsoleCallback *pThis,
+ INetworkAdapter * networkAdapter
+ );
+
+ nsresult (*OnSerialPortChange)(
+ IConsoleCallback *pThis,
+ ISerialPort * serialPort
+ );
+
+ nsresult (*OnParallelPortChange)(
+ IConsoleCallback *pThis,
+ IParallelPort * parallelPort
+ );
+
+ nsresult (*OnStorageControllerChange)(IConsoleCallback *pThis );
+
+ nsresult (*OnMediumChange)(
+ IConsoleCallback *pThis,
+ IMediumAttachment * mediumAttachment
+ );
+
+ nsresult (*OnCPUChange)(
+ IConsoleCallback *pThis,
+ PRUint32 cpu,
+ PRBool add
+ );
+
+ nsresult (*OnVRDPServerChange)(IConsoleCallback *pThis );
+
+ nsresult (*OnRemoteDisplayInfoChange)(IConsoleCallback *pThis );
+
+ nsresult (*OnUSBControllerChange)(IConsoleCallback *pThis );
+
+ nsresult (*OnUSBDeviceStateChange)(
+ IConsoleCallback *pThis,
+ IUSBDevice * device,
+ PRBool attached,
+ IVirtualBoxErrorInfo * error
+ );
+
+ nsresult (*OnSharedFolderChange)(
+ IConsoleCallback *pThis,
+ PRUint32 scope
+ );
+
+ nsresult (*OnRuntimeError)(
+ IConsoleCallback *pThis,
+ PRBool fatal,
+ PRUnichar * id,
+ PRUnichar * message
+ );
+
+ nsresult (*OnCanShowWindow)(
+ IConsoleCallback *pThis,
+ PRBool * canShow
+ );
+
+ nsresult (*OnShowWindow)(
+ IConsoleCallback *pThis,
+ PRUint64 * winId
+ );
+
+};
+
+struct IConsoleCallback
+{
+ struct IConsoleCallback_vtbl *vtbl;
+};
+/* End of struct IConsoleCallback Declaration */
+
+
+/* Start of struct IRemoteDisplayInfo Declaration */
+#define IREMOTEDISPLAYINFO_IID_STR "b3741084-806f-4c3b-8c42-ebad1a81e45a"
+#define IREMOTEDISPLAYINFO_IID { \
+ 0xb3741084, 0x806f, 0x4c3b, \
+ { 0x8c, 0x42, 0xeb, 0xad, 0x1a, 0x81, 0xe4, 0x5a } \
+}
+struct IRemoteDisplayInfo_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetActive)(IRemoteDisplayInfo *pThis, PRBool *active);
+
+ nsresult (*GetPort)(IRemoteDisplayInfo *pThis, PRInt32 *port);
+
+ nsresult (*GetNumberOfClients)(IRemoteDisplayInfo *pThis, PRUint32 *numberOfClients);
+
+ nsresult (*GetBeginTime)(IRemoteDisplayInfo *pThis, PRInt64 *beginTime);
+
+ nsresult (*GetEndTime)(IRemoteDisplayInfo *pThis, PRInt64 *endTime);
+
+ nsresult (*GetBytesSent)(IRemoteDisplayInfo *pThis, PRUint64 *bytesSent);
+
+ nsresult (*GetBytesSentTotal)(IRemoteDisplayInfo *pThis, PRUint64 *bytesSentTotal);
+
+ nsresult (*GetBytesReceived)(IRemoteDisplayInfo *pThis, PRUint64 *bytesReceived);
+
+ nsresult (*GetBytesReceivedTotal)(IRemoteDisplayInfo *pThis, PRUint64 *bytesReceivedTotal);
+
+ nsresult (*GetUser)(IRemoteDisplayInfo *pThis, PRUnichar * *user);
+
+ nsresult (*GetDomain)(IRemoteDisplayInfo *pThis, PRUnichar * *domain);
+
+ nsresult (*GetClientName)(IRemoteDisplayInfo *pThis, PRUnichar * *clientName);
+
+ nsresult (*GetClientIP)(IRemoteDisplayInfo *pThis, PRUnichar * *clientIP);
+
+ nsresult (*GetClientVersion)(IRemoteDisplayInfo *pThis, PRUint32 *clientVersion);
+
+ nsresult (*GetEncryptionStyle)(IRemoteDisplayInfo *pThis, PRUint32 *encryptionStyle);
+
+};
+
+struct IRemoteDisplayInfo
+{
+ struct IRemoteDisplayInfo_vtbl *vtbl;
+};
+/* End of struct IRemoteDisplayInfo Declaration */
+
+
+/* Start of struct IConsole Declaration */
+#define ICONSOLE_IID_STR "6375231a-c17c-464b-92cb-ae9e128d71c3"
+#define ICONSOLE_IID { \
+ 0x6375231a, 0xc17c, 0x464b, \
+ { 0x92, 0xcb, 0xae, 0x9e, 0x12, 0x8d, 0x71, 0xc3 } \
+}
+struct IConsole_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMachine)(IConsole *pThis, IMachine * *machine);
+
+ nsresult (*GetState)(IConsole *pThis, PRUint32 *state);
+
+ nsresult (*GetGuest)(IConsole *pThis, IGuest * *guest);
+
+ nsresult (*GetKeyboard)(IConsole *pThis, IKeyboard * *keyboard);
+
+ nsresult (*GetMouse)(IConsole *pThis, IMouse * *mouse);
+
+ nsresult (*GetDisplay)(IConsole *pThis, IDisplay * *display);
+
+ nsresult (*GetDebugger)(IConsole *pThis, IMachineDebugger * *debugger);
+
+ nsresult (*GetUSBDevices)(IConsole *pThis, PRUint32 *USBDevicesSize, IUSBDevice * **USBDevices);
+
+ nsresult (*GetRemoteUSBDevices)(IConsole *pThis, PRUint32 *remoteUSBDevicesSize, IHostUSBDevice * **remoteUSBDevices);
+
+ nsresult (*GetSharedFolders)(IConsole *pThis, PRUint32 *sharedFoldersSize, ISharedFolder * **sharedFolders);
+
+ nsresult (*GetRemoteDisplayInfo)(IConsole *pThis, IRemoteDisplayInfo * *remoteDisplayInfo);
+
+ nsresult (*PowerUp)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*PowerUpPaused)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*PowerDown)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*Reset)(IConsole *pThis );
+
+ nsresult (*Pause)(IConsole *pThis );
+
+ nsresult (*Resume)(IConsole *pThis );
+
+ nsresult (*PowerButton)(IConsole *pThis );
+
+ nsresult (*SleepButton)(IConsole *pThis );
+
+ nsresult (*GetPowerButtonHandled)(
+ IConsole *pThis,
+ PRBool * handled
+ );
+
+ nsresult (*GetGuestEnteredACPIMode)(
+ IConsole *pThis,
+ PRBool * entered
+ );
+
+ nsresult (*SaveState)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*AdoptSavedState)(
+ IConsole *pThis,
+ PRUnichar * savedStateFile
+ );
+
+ nsresult (*ForgetSavedState)(
+ IConsole *pThis,
+ PRBool remove
+ );
+
+ nsresult (*GetDeviceActivity)(
+ IConsole *pThis,
+ PRUint32 type,
+ PRUint32 * activity
+ );
+
+ nsresult (*AttachUSBDevice)(
+ IConsole *pThis,
+ PRUnichar * id
+ );
+
+ nsresult (*DetachUSBDevice)(
+ IConsole *pThis,
+ PRUnichar * id,
+ IUSBDevice * * device
+ );
+
+ nsresult (*FindUSBDeviceByAddress)(
+ IConsole *pThis,
+ PRUnichar * name,
+ IUSBDevice * * device
+ );
+
+ nsresult (*FindUSBDeviceById)(
+ IConsole *pThis,
+ PRUnichar * id,
+ IUSBDevice * * device
+ );
+
+ nsresult (*CreateSharedFolder)(
+ IConsole *pThis,
+ PRUnichar * name,
+ PRUnichar * hostPath,
+ PRBool writable
+ );
+
+ nsresult (*RemoveSharedFolder)(
+ IConsole *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*TakeSnapshot)(
+ IConsole *pThis,
+ PRUnichar * name,
+ PRUnichar * description,
+ IProgress * * progress
+ );
+
+ nsresult (*DeleteSnapshot)(
+ IConsole *pThis,
+ PRUnichar * id,
+ IProgress * * progress
+ );
+
+ nsresult (*RestoreSnapshot)(
+ IConsole *pThis,
+ ISnapshot * snapshot,
+ IProgress * * progress
+ );
+
+ nsresult (*Teleport)(
+ IConsole *pThis,
+ PRUnichar * hostname,
+ PRUint32 tcpport,
+ PRUnichar * password,
+ PRUint32 maxDowntime,
+ IProgress * * progress
+ );
+
+ nsresult (*RegisterCallback)(
+ IConsole *pThis,
+ IConsoleCallback * callback
+ );
+
+ nsresult (*UnregisterCallback)(
+ IConsole *pThis,
+ IConsoleCallback * callback
+ );
+
+};
+
+struct IConsole
+{
+ struct IConsole_vtbl *vtbl;
+};
+/* End of struct IConsole Declaration */
+
+
+/* Start of struct IHostNetworkInterface Declaration */
+#define IHOSTNETWORKINTERFACE_IID_STR "ce6fae58-7642-4102-b5db-c9005c2320a8"
+#define IHOSTNETWORKINTERFACE_IID { \
+ 0xce6fae58, 0x7642, 0x4102, \
+ { 0xb5, 0xdb, 0xc9, 0x00, 0x5c, 0x23, 0x20, 0xa8 } \
+}
+struct IHostNetworkInterface_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IHostNetworkInterface *pThis, PRUnichar * *name);
+
+ nsresult (*GetId)(IHostNetworkInterface *pThis, PRUnichar * *id);
+
+ nsresult (*GetNetworkName)(IHostNetworkInterface *pThis, PRUnichar * *networkName);
+
+ nsresult (*GetDhcpEnabled)(IHostNetworkInterface *pThis, PRBool *dhcpEnabled);
+
+ nsresult (*GetIPAddress)(IHostNetworkInterface *pThis, PRUnichar * *IPAddress);
+
+ nsresult (*GetNetworkMask)(IHostNetworkInterface *pThis, PRUnichar * *networkMask);
+
+ nsresult (*GetIPV6Supported)(IHostNetworkInterface *pThis, PRBool *IPV6Supported);
+
+ nsresult (*GetIPV6Address)(IHostNetworkInterface *pThis, PRUnichar * *IPV6Address);
+
+ nsresult (*GetIPV6NetworkMaskPrefixLength)(IHostNetworkInterface *pThis, PRUint32 *IPV6NetworkMaskPrefixLength);
+
+ nsresult (*GetHardwareAddress)(IHostNetworkInterface *pThis, PRUnichar * *hardwareAddress);
+
+ nsresult (*GetMediumType)(IHostNetworkInterface *pThis, PRUint32 *mediumType);
+
+ nsresult (*GetStatus)(IHostNetworkInterface *pThis, PRUint32 *status);
+
+ nsresult (*GetInterfaceType)(IHostNetworkInterface *pThis, PRUint32 *interfaceType);
+
+ nsresult (*EnableStaticIpConfig)(
+ IHostNetworkInterface *pThis,
+ PRUnichar * IPAddress,
+ PRUnichar * networkMask
+ );
+
+ nsresult (*EnableStaticIpConfigV6)(
+ IHostNetworkInterface *pThis,
+ PRUnichar * IPV6Address,
+ PRUint32 IPV6NetworkMaskPrefixLength
+ );
+
+ nsresult (*EnableDynamicIpConfig)(IHostNetworkInterface *pThis );
+
+ nsresult (*DhcpRediscover)(IHostNetworkInterface *pThis );
+
+};
+
+struct IHostNetworkInterface
+{
+ struct IHostNetworkInterface_vtbl *vtbl;
+};
+/* End of struct IHostNetworkInterface Declaration */
+
+
+/* Start of struct IHost Declaration */
+#define IHOST_IID_STR "35b004f4-7806-4009-bfa8-d1308adba7e5"
+#define IHOST_IID { \
+ 0x35b004f4, 0x7806, 0x4009, \
+ { 0xbf, 0xa8, 0xd1, 0x30, 0x8a, 0xdb, 0xa7, 0xe5 } \
+}
+struct IHost_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetDVDDrives)(IHost *pThis, PRUint32 *DVDDrivesSize, IMedium * **DVDDrives);
+
+ nsresult (*GetFloppyDrives)(IHost *pThis, PRUint32 *floppyDrivesSize, IMedium * **floppyDrives);
+
+ nsresult (*GetUSBDevices)(IHost *pThis, PRUint32 *USBDevicesSize, IHostUSBDevice * **USBDevices);
+
+ nsresult (*GetUSBDeviceFilters)(IHost *pThis, PRUint32 *USBDeviceFiltersSize, IHostUSBDeviceFilter * **USBDeviceFilters);
+
+ nsresult (*GetNetworkInterfaces)(IHost *pThis, PRUint32 *networkInterfacesSize, IHostNetworkInterface * **networkInterfaces);
+
+ nsresult (*GetProcessorCount)(IHost *pThis, PRUint32 *processorCount);
+
+ nsresult (*GetProcessorOnlineCount)(IHost *pThis, PRUint32 *processorOnlineCount);
+
+ nsresult (*GetProcessorCoreCount)(IHost *pThis, PRUint32 *processorCoreCount);
+
+ nsresult (*GetMemorySize)(IHost *pThis, PRUint32 *memorySize);
+
+ nsresult (*GetMemoryAvailable)(IHost *pThis, PRUint32 *memoryAvailable);
+
+ nsresult (*GetOperatingSystem)(IHost *pThis, PRUnichar * *operatingSystem);
+
+ nsresult (*GetOSVersion)(IHost *pThis, PRUnichar * *OSVersion);
+
+ nsresult (*GetUTCTime)(IHost *pThis, PRInt64 *UTCTime);
+
+ nsresult (*GetAcceleration3DAvailable)(IHost *pThis, PRBool *Acceleration3DAvailable);
+
+ nsresult (*GetProcessorSpeed)(
+ IHost *pThis,
+ PRUint32 cpuId,
+ PRUint32 * speed
+ );
+
+ nsresult (*GetProcessorFeature)(
+ IHost *pThis,
+ PRUint32 feature,
+ PRBool * supported
+ );
+
+ nsresult (*GetProcessorDescription)(
+ IHost *pThis,
+ PRUint32 cpuId,
+ PRUnichar * * description
+ );
+
+ nsresult (*GetProcessorCPUIDLeaf)(
+ IHost *pThis,
+ PRUint32 cpuId,
+ PRUint32 leaf,
+ PRUint32 subLeaf,
+ PRUint32 * valEax,
+ PRUint32 * valEbx,
+ PRUint32 * valEcx,
+ PRUint32 * valEdx
+ );
+
+ nsresult (*CreateHostOnlyNetworkInterface)(
+ IHost *pThis,
+ IHostNetworkInterface * * hostInterface,
+ IProgress * * progress
+ );
+
+ nsresult (*RemoveHostOnlyNetworkInterface)(
+ IHost *pThis,
+ PRUnichar * id,
+ IProgress * * progress
+ );
+
+ nsresult (*CreateUSBDeviceFilter)(
+ IHost *pThis,
+ PRUnichar * name,
+ IHostUSBDeviceFilter * * filter
+ );
+
+ nsresult (*InsertUSBDeviceFilter)(
+ IHost *pThis,
+ PRUint32 position,
+ IHostUSBDeviceFilter * filter
+ );
+
+ nsresult (*RemoveUSBDeviceFilter)(
+ IHost *pThis,
+ PRUint32 position
+ );
+
+ nsresult (*FindHostDVDDrive)(
+ IHost *pThis,
+ PRUnichar * name,
+ IMedium * * drive
+ );
+
+ nsresult (*FindHostFloppyDrive)(
+ IHost *pThis,
+ PRUnichar * name,
+ IMedium * * drive
+ );
+
+ nsresult (*FindHostNetworkInterfaceByName)(
+ IHost *pThis,
+ PRUnichar * name,
+ IHostNetworkInterface * * networkInterface
+ );
+
+ nsresult (*FindHostNetworkInterfaceById)(
+ IHost *pThis,
+ PRUnichar * id,
+ IHostNetworkInterface * * networkInterface
+ );
+
+ nsresult (*FindHostNetworkInterfacesOfType)(
+ IHost *pThis,
+ PRUint32 type,
+ PRUint32 *networkInterfacesSize,
+ IHostNetworkInterface *** networkInterfaces
+ );
+
+ nsresult (*FindUSBDeviceById)(
+ IHost *pThis,
+ PRUnichar * id,
+ IHostUSBDevice * * device
+ );
+
+ nsresult (*FindUSBDeviceByAddress)(
+ IHost *pThis,
+ PRUnichar * name,
+ IHostUSBDevice * * device
+ );
+
+};
+
+struct IHost
+{
+ struct IHost_vtbl *vtbl;
+};
+/* End of struct IHost Declaration */
+
+
+/* Start of struct ISystemProperties Declaration */
+#define ISYSTEMPROPERTIES_IID_STR "07c3ffd8-8f59-49cc-b608-53a332e85cc3"
+#define ISYSTEMPROPERTIES_IID { \
+ 0x07c3ffd8, 0x8f59, 0x49cc, \
+ { 0xb6, 0x08, 0x53, 0xa3, 0x32, 0xe8, 0x5c, 0xc3 } \
+}
+struct ISystemProperties_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMinGuestRAM)(ISystemProperties *pThis, PRUint32 *minGuestRAM);
+
+ nsresult (*GetMaxGuestRAM)(ISystemProperties *pThis, PRUint32 *maxGuestRAM);
+
+ nsresult (*GetMinGuestVRAM)(ISystemProperties *pThis, PRUint32 *minGuestVRAM);
+
+ nsresult (*GetMaxGuestVRAM)(ISystemProperties *pThis, PRUint32 *maxGuestVRAM);
+
+ nsresult (*GetMinGuestCPUCount)(ISystemProperties *pThis, PRUint32 *minGuestCPUCount);
+
+ nsresult (*GetMaxGuestCPUCount)(ISystemProperties *pThis, PRUint32 *maxGuestCPUCount);
+
+ nsresult (*GetMaxGuestMonitors)(ISystemProperties *pThis, PRUint32 *maxGuestMonitors);
+
+ nsresult (*GetMaxVDISize)(ISystemProperties *pThis, PRUint64 *maxVDISize);
+
+ nsresult (*GetNetworkAdapterCount)(ISystemProperties *pThis, PRUint32 *networkAdapterCount);
+
+ nsresult (*GetSerialPortCount)(ISystemProperties *pThis, PRUint32 *serialPortCount);
+
+ nsresult (*GetParallelPortCount)(ISystemProperties *pThis, PRUint32 *parallelPortCount);
+
+ nsresult (*GetMaxBootPosition)(ISystemProperties *pThis, PRUint32 *maxBootPosition);
+
+ nsresult (*GetDefaultMachineFolder)(ISystemProperties *pThis, PRUnichar * *defaultMachineFolder);
+ nsresult (*SetDefaultMachineFolder)(ISystemProperties *pThis, PRUnichar * defaultMachineFolder);
+
+ nsresult (*GetDefaultHardDiskFolder)(ISystemProperties *pThis, PRUnichar * *defaultHardDiskFolder);
+ nsresult (*SetDefaultHardDiskFolder)(ISystemProperties *pThis, PRUnichar * defaultHardDiskFolder);
+
+ nsresult (*GetMediumFormats)(ISystemProperties *pThis, PRUint32 *mediumFormatsSize, IMediumFormat * **mediumFormats);
+
+ nsresult (*GetDefaultHardDiskFormat)(ISystemProperties *pThis, PRUnichar * *defaultHardDiskFormat);
+ nsresult (*SetDefaultHardDiskFormat)(ISystemProperties *pThis, PRUnichar * defaultHardDiskFormat);
+
+ nsresult (*GetFreeDiskSpaceWarning)(ISystemProperties *pThis, PRUint64 *freeDiskSpaceWarning);
+ nsresult (*SetFreeDiskSpaceWarning)(ISystemProperties *pThis, PRUint64 freeDiskSpaceWarning);
+
+ nsresult (*GetFreeDiskSpacePercentWarning)(ISystemProperties *pThis, PRUint32 *freeDiskSpacePercentWarning);
+ nsresult (*SetFreeDiskSpacePercentWarning)(ISystemProperties *pThis, PRUint32 freeDiskSpacePercentWarning);
+
+ nsresult (*GetFreeDiskSpaceError)(ISystemProperties *pThis, PRUint64 *freeDiskSpaceError);
+ nsresult (*SetFreeDiskSpaceError)(ISystemProperties *pThis, PRUint64 freeDiskSpaceError);
+
+ nsresult (*GetFreeDiskSpacePercentError)(ISystemProperties *pThis, PRUint32 *freeDiskSpacePercentError);
+ nsresult (*SetFreeDiskSpacePercentError)(ISystemProperties *pThis, PRUint32 freeDiskSpacePercentError);
+
+ nsresult (*GetRemoteDisplayAuthLibrary)(ISystemProperties *pThis, PRUnichar * *remoteDisplayAuthLibrary);
+ nsresult (*SetRemoteDisplayAuthLibrary)(ISystemProperties *pThis, PRUnichar * remoteDisplayAuthLibrary);
+
+ nsresult (*GetWebServiceAuthLibrary)(ISystemProperties *pThis, PRUnichar * *webServiceAuthLibrary);
+ nsresult (*SetWebServiceAuthLibrary)(ISystemProperties *pThis, PRUnichar * webServiceAuthLibrary);
+
+ nsresult (*GetLogHistoryCount)(ISystemProperties *pThis, PRUint32 *LogHistoryCount);
+ nsresult (*SetLogHistoryCount)(ISystemProperties *pThis, PRUint32 LogHistoryCount);
+
+ nsresult (*GetDefaultAudioDriver)(ISystemProperties *pThis, PRUint32 *defaultAudioDriver);
+
+ nsresult (*GetMaxDevicesPerPortForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * maxDevicesPerPort
+ );
+
+ nsresult (*GetMinPortCountForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * minPortCount
+ );
+
+ nsresult (*GetMaxPortCountForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * maxPortCount
+ );
+
+ nsresult (*GetMaxInstancesOfStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * maxInstances
+ );
+
+ nsresult (*GetDeviceTypesForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 *deviceTypesSize,
+ PRUint32** deviceTypes
+ );
+
+};
+
+struct ISystemProperties
+{
+ struct ISystemProperties_vtbl *vtbl;
+};
+/* End of struct ISystemProperties Declaration */
+
+
+/* Start of struct IGuestOSType Declaration */
+#define IGUESTOSTYPE_IID_STR "e3f6727e-a09b-41ea-a824-864a176472f3"
+#define IGUESTOSTYPE_IID { \
+ 0xe3f6727e, 0xa09b, 0x41ea, \
+ { 0xa8, 0x24, 0x86, 0x4a, 0x17, 0x64, 0x72, 0xf3 } \
+}
+struct IGuestOSType_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetFamilyId)(IGuestOSType *pThis, PRUnichar * *familyId);
+
+ nsresult (*GetFamilyDescription)(IGuestOSType *pThis, PRUnichar * *familyDescription);
+
+ nsresult (*GetId)(IGuestOSType *pThis, PRUnichar * *id);
+
+ nsresult (*GetDescription)(IGuestOSType *pThis, PRUnichar * *description);
+
+ nsresult (*GetIs64Bit)(IGuestOSType *pThis, PRBool *is64Bit);
+
+ nsresult (*GetRecommendedIOAPIC)(IGuestOSType *pThis, PRBool *recommendedIOAPIC);
+
+ nsresult (*GetRecommendedVirtEx)(IGuestOSType *pThis, PRBool *recommendedVirtEx);
+
+ nsresult (*GetRecommendedRAM)(IGuestOSType *pThis, PRUint32 *recommendedRAM);
+
+ nsresult (*GetRecommendedVRAM)(IGuestOSType *pThis, PRUint32 *recommendedVRAM);
+
+ nsresult (*GetRecommendedHDD)(IGuestOSType *pThis, PRUint32 *recommendedHDD);
+
+ nsresult (*GetAdapterType)(IGuestOSType *pThis, PRUint32 *adapterType);
+
+ nsresult (*GetRecommendedPae)(IGuestOSType *pThis, PRBool *recommendedPae);
+
+ nsresult (*GetRecommendedDvdStorageController)(IGuestOSType *pThis, PRUint32 *recommendedDvdStorageController);
+
+ nsresult (*GetRecommendedDvdStorageBus)(IGuestOSType *pThis, PRUint32 *recommendedDvdStorageBus);
+
+ nsresult (*GetRecommendedHdStorageController)(IGuestOSType *pThis, PRUint32 *recommendedHdStorageController);
+
+ nsresult (*GetRecommendedHdStorageBus)(IGuestOSType *pThis, PRUint32 *recommendedHdStorageBus);
+
+ nsresult (*GetRecommendedFirmware)(IGuestOSType *pThis, PRUint32 *recommendedFirmware);
+
+ nsresult (*GetRecommendedUsbHid)(IGuestOSType *pThis, PRBool *recommendedUsbHid);
+
+ nsresult (*GetRecommendedHpet)(IGuestOSType *pThis, PRBool *recommendedHpet);
+
+ nsresult (*GetRecommendedUsbTablet)(IGuestOSType *pThis, PRBool *recommendedUsbTablet);
+
+ nsresult (*GetRecommendedRtcUseUtc)(IGuestOSType *pThis, PRBool *recommendedRtcUseUtc);
+
+};
+
+struct IGuestOSType
+{
+ struct IGuestOSType_vtbl *vtbl;
+};
+/* End of struct IGuestOSType Declaration */
+
+
+/* Start of struct IGuest Declaration */
+#define IGUEST_IID_STR "d915dff1-ed38-495a-91f1-ab6c53932468"
+#define IGUEST_IID { \
+ 0xd915dff1, 0xed38, 0x495a, \
+ { 0x91, 0xf1, 0xab, 0x6c, 0x53, 0x93, 0x24, 0x68 } \
+}
+struct IGuest_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetOSTypeId)(IGuest *pThis, PRUnichar * *OSTypeId);
+
+ nsresult (*GetAdditionsActive)(IGuest *pThis, PRBool *additionsActive);
+
+ nsresult (*GetAdditionsVersion)(IGuest *pThis, PRUnichar * *additionsVersion);
+
+ nsresult (*GetSupportsSeamless)(IGuest *pThis, PRBool *supportsSeamless);
+
+ nsresult (*GetSupportsGraphics)(IGuest *pThis, PRBool *supportsGraphics);
+
+ nsresult (*GetMemoryBalloonSize)(IGuest *pThis, PRUint32 *memoryBalloonSize);
+ nsresult (*SetMemoryBalloonSize)(IGuest *pThis, PRUint32 memoryBalloonSize);
+
+ nsresult (*GetPageFusionEnabled)(IGuest *pThis, PRBool *pageFusionEnabled);
+ nsresult (*SetPageFusionEnabled)(IGuest *pThis, PRBool pageFusionEnabled);
+
+ nsresult (*GetStatisticsUpdateInterval)(IGuest *pThis, PRUint32 *statisticsUpdateInterval);
+ nsresult (*SetStatisticsUpdateInterval)(IGuest *pThis, PRUint32 statisticsUpdateInterval);
+
+ nsresult (*InternalGetStatistics)(
+ IGuest *pThis,
+ PRUint32 * cpuUser,
+ PRUint32 * cpuKernel,
+ PRUint32 * cpuIdle,
+ PRUint32 * memTotal,
+ PRUint32 * memFree,
+ PRUint32 * memBalloon,
+ PRUint32 * memShared,
+ PRUint32 * memCache,
+ PRUint32 * pagedTotal,
+ PRUint32 * memAllocTotal,
+ PRUint32 * memFreeTotal,
+ PRUint32 * memBalloonTotal,
+ PRUint32 * memSharedTotal
+ );
+
+ nsresult (*SetCredentials)(
+ IGuest *pThis,
+ PRUnichar * userName,
+ PRUnichar * password,
+ PRUnichar * domain,
+ PRBool allowInteractiveLogon
+ );
+
+ nsresult (*ExecuteProcess)(
+ IGuest *pThis,
+ PRUnichar * execName,
+ PRUint32 flags,
+ PRUint32 argumentsSize,
+ PRUnichar ** arguments,
+ PRUint32 environmentSize,
+ PRUnichar ** environment,
+ PRUnichar * userName,
+ PRUnichar * password,
+ PRUint32 timeoutMS,
+ PRUint32 * pid,
+ IProgress * * progress
+ );
+
+ nsresult (*GetProcessOutput)(
+ IGuest *pThis,
+ PRUint32 pid,
+ PRUint32 flags,
+ PRUint32 timeoutMS,
+ PRUint64 size,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*GetProcessStatus)(
+ IGuest *pThis,
+ PRUint32 pid,
+ PRUint32 * exitcode,
+ PRUint32 * flags,
+ PRUint32 * reason
+ );
+
+};
+
+struct IGuest
+{
+ struct IGuest_vtbl *vtbl;
+};
+/* End of struct IGuest Declaration */
+
+
+/* Start of struct IProgress Declaration */
+#define IPROGRESS_IID_STR "856aa038-853f-42e2-acf7-6e7b02dbe294"
+#define IPROGRESS_IID { \
+ 0x856aa038, 0x853f, 0x42e2, \
+ { 0xac, 0xf7, 0x6e, 0x7b, 0x02, 0xdb, 0xe2, 0x94 } \
+}
+struct IProgress_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IProgress *pThis, PRUnichar * *id);
+
+ nsresult (*GetDescription)(IProgress *pThis, PRUnichar * *description);
+
+ nsresult (*GetInitiator)(IProgress *pThis, nsISupports * *initiator);
+
+ nsresult (*GetCancelable)(IProgress *pThis, PRBool *cancelable);
+
+ nsresult (*GetPercent)(IProgress *pThis, PRUint32 *percent);
+
+ nsresult (*GetTimeRemaining)(IProgress *pThis, PRInt32 *timeRemaining);
+
+ nsresult (*GetCompleted)(IProgress *pThis, PRBool *completed);
+
+ nsresult (*GetCanceled)(IProgress *pThis, PRBool *canceled);
+
+ nsresult (*GetResultCode)(IProgress *pThis, PRInt32 *resultCode);
+
+ nsresult (*GetErrorInfo)(IProgress *pThis, IVirtualBoxErrorInfo * *errorInfo);
+
+ nsresult (*GetOperationCount)(IProgress *pThis, PRUint32 *operationCount);
+
+ nsresult (*GetOperation)(IProgress *pThis, PRUint32 *operation);
+
+ nsresult (*GetOperationDescription)(IProgress *pThis, PRUnichar * *operationDescription);
+
+ nsresult (*GetOperationPercent)(IProgress *pThis, PRUint32 *operationPercent);
+
+ nsresult (*GetTimeout)(IProgress *pThis, PRUint32 *timeout);
+ nsresult (*SetTimeout)(IProgress *pThis, PRUint32 timeout);
+
+ nsresult (*SetCurrentOperationProgress)(
+ IProgress *pThis,
+ PRUint32 percent
+ );
+
+ nsresult (*SetNextOperation)(
+ IProgress *pThis,
+ PRUnichar * nextOperationDescription,
+ PRUint32 nextOperationsWeight
+ );
+
+ nsresult (*WaitForCompletion)(
+ IProgress *pThis,
+ PRInt32 timeout
+ );
+
+ nsresult (*WaitForOperationCompletion)(
+ IProgress *pThis,
+ PRUint32 operation,
+ PRInt32 timeout
+ );
+
+ nsresult (*Cancel)(IProgress *pThis );
+
+};
+
+struct IProgress
+{
+ struct IProgress_vtbl *vtbl;
+};
+/* End of struct IProgress Declaration */
+
+
+/* Start of struct ISnapshot Declaration */
+#define ISNAPSHOT_IID_STR "1a2d0551-58a4-4107-857e-ef414fc42ffc"
+#define ISNAPSHOT_IID { \
+ 0x1a2d0551, 0x58a4, 0x4107, \
+ { 0x85, 0x7e, 0xef, 0x41, 0x4f, 0xc4, 0x2f, 0xfc } \
+}
+struct ISnapshot_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(ISnapshot *pThis, PRUnichar * *id);
+
+ nsresult (*GetName)(ISnapshot *pThis, PRUnichar * *name);
+ nsresult (*SetName)(ISnapshot *pThis, PRUnichar * name);
+
+ nsresult (*GetDescription)(ISnapshot *pThis, PRUnichar * *description);
+ nsresult (*SetDescription)(ISnapshot *pThis, PRUnichar * description);
+
+ nsresult (*GetTimeStamp)(ISnapshot *pThis, PRInt64 *timeStamp);
+
+ nsresult (*GetOnline)(ISnapshot *pThis, PRBool *online);
+
+ nsresult (*GetMachine)(ISnapshot *pThis, IMachine * *machine);
+
+ nsresult (*GetParent)(ISnapshot *pThis, ISnapshot * *parent);
+
+ nsresult (*GetChildren)(ISnapshot *pThis, PRUint32 *childrenSize, ISnapshot * **children);
+
+};
+
+struct ISnapshot
+{
+ struct ISnapshot_vtbl *vtbl;
+};
+/* End of struct ISnapshot Declaration */
+
+
+/* Start of struct IMediumAttachment Declaration */
+#define IMEDIUMATTACHMENT_IID_STR "e58eb3eb-8627-428b-bdf8-34487c848de5"
+#define IMEDIUMATTACHMENT_IID { \
+ 0xe58eb3eb, 0x8627, 0x428b, \
+ { 0xbd, 0xf8, 0x34, 0x48, 0x7c, 0x84, 0x8d, 0xe5 } \
+}
+struct IMediumAttachment_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMedium)(IMediumAttachment *pThis, IMedium * *medium);
+
+ nsresult (*GetController)(IMediumAttachment *pThis, PRUnichar * *controller);
+
+ nsresult (*GetPort)(IMediumAttachment *pThis, PRInt32 *port);
+
+ nsresult (*GetDevice)(IMediumAttachment *pThis, PRInt32 *device);
+
+ nsresult (*GetType)(IMediumAttachment *pThis, PRUint32 *type);
+
+ nsresult (*GetPassthrough)(IMediumAttachment *pThis, PRBool *passthrough);
+
+};
+
+struct IMediumAttachment
+{
+ struct IMediumAttachment_vtbl *vtbl;
+};
+/* End of struct IMediumAttachment Declaration */
+
+
+/* Start of struct IMedium Declaration */
+#define IMEDIUM_IID_STR "1d578f43-5ef1-4415-b556-7592d3ccdc8f"
+#define IMEDIUM_IID { \
+ 0x1d578f43, 0x5ef1, 0x4415, \
+ { 0xb5, 0x56, 0x75, 0x92, 0xd3, 0xcc, 0xdc, 0x8f } \
+}
+struct IMedium_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IMedium *pThis, PRUnichar * *id);
+
+ nsresult (*GetDescription)(IMedium *pThis, PRUnichar * *description);
+ nsresult (*SetDescription)(IMedium *pThis, PRUnichar * description);
+
+ nsresult (*GetState)(IMedium *pThis, PRUint32 *state);
+
+ nsresult (*GetLocation)(IMedium *pThis, PRUnichar * *location);
+ nsresult (*SetLocation)(IMedium *pThis, PRUnichar * location);
+
+ nsresult (*GetName)(IMedium *pThis, PRUnichar * *name);
+
+ nsresult (*GetDeviceType)(IMedium *pThis, PRUint32 *deviceType);
+
+ nsresult (*GetHostDrive)(IMedium *pThis, PRBool *hostDrive);
+
+ nsresult (*GetSize)(IMedium *pThis, PRUint64 *size);
+
+ nsresult (*GetFormat)(IMedium *pThis, PRUnichar * *format);
+
+ nsresult (*GetMediumFormat)(IMedium *pThis, IMediumFormat * *mediumFormat);
+
+ nsresult (*GetType)(IMedium *pThis, PRUint32 *type);
+ nsresult (*SetType)(IMedium *pThis, PRUint32 type);
+
+ nsresult (*GetParent)(IMedium *pThis, IMedium * *parent);
+
+ nsresult (*GetChildren)(IMedium *pThis, PRUint32 *childrenSize, IMedium * **children);
+
+ nsresult (*GetBase)(IMedium *pThis, IMedium * *base);
+
+ nsresult (*GetReadOnly)(IMedium *pThis, PRBool *readOnly);
+
+ nsresult (*GetLogicalSize)(IMedium *pThis, PRUint64 *logicalSize);
+
+ nsresult (*GetAutoReset)(IMedium *pThis, PRBool *autoReset);
+ nsresult (*SetAutoReset)(IMedium *pThis, PRBool autoReset);
+
+ nsresult (*GetLastAccessError)(IMedium *pThis, PRUnichar * *lastAccessError);
+
+ nsresult (*GetMachineIds)(IMedium *pThis, PRUint32 *machineIdsSize, PRUnichar * **machineIds);
+
+ nsresult (*RefreshState)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*GetSnapshotIds)(
+ IMedium *pThis,
+ PRUnichar * machineId,
+ PRUint32 *snapshotIdsSize,
+ PRUnichar *** snapshotIds
+ );
+
+ nsresult (*LockRead)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*UnlockRead)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*LockWrite)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*UnlockWrite)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*Close)(IMedium *pThis );
+
+ nsresult (*GetProperty)(
+ IMedium *pThis,
+ PRUnichar * name,
+ PRUnichar * * value
+ );
+
+ nsresult (*SetProperty)(
+ IMedium *pThis,
+ PRUnichar * name,
+ PRUnichar * value
+ );
+
+ nsresult (*GetProperties)(
+ IMedium *pThis,
+ PRUnichar * names,
+ PRUint32 *returnNamesSize,
+ PRUnichar *** returnNames,
+ PRUint32 *returnValuesSize,
+ PRUnichar *** returnValues
+ );
+
+ nsresult (*SetProperties)(
+ IMedium *pThis,
+ PRUint32 namesSize,
+ PRUnichar ** names,
+ PRUint32 valuesSize,
+ PRUnichar ** values
+ );
+
+ nsresult (*CreateBaseStorage)(
+ IMedium *pThis,
+ PRUint64 logicalSize,
+ PRUint32 variant,
+ IProgress * * progress
+ );
+
+ nsresult (*DeleteStorage)(
+ IMedium *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*CreateDiffStorage)(
+ IMedium *pThis,
+ IMedium * target,
+ PRUint32 variant,
+ IProgress * * progress
+ );
+
+ nsresult (*MergeTo)(
+ IMedium *pThis,
+ IMedium * target,
+ IProgress * * progress
+ );
+
+ nsresult (*CloneTo)(
+ IMedium *pThis,
+ IMedium * target,
+ PRUint32 variant,
+ IMedium * parent,
+ IProgress * * progress
+ );
+
+ nsresult (*Compact)(
+ IMedium *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*Resize)(
+ IMedium *pThis,
+ PRUint64 logicalSize,
+ IProgress * * progress
+ );
+
+ nsresult (*Reset)(
+ IMedium *pThis,
+ IProgress * * progress
+ );
+
+};
+
+struct IMedium
+{
+ struct IMedium_vtbl *vtbl;
+};
+/* End of struct IMedium Declaration */
+
+
+/* Start of struct IMediumFormat Declaration */
+#define IMEDIUMFORMAT_IID_STR "89f52554-d469-4799-9fad-1705e86a08b1"
+#define IMEDIUMFORMAT_IID { \
+ 0x89f52554, 0xd469, 0x4799, \
+ { 0x9f, 0xad, 0x17, 0x05, 0xe8, 0x6a, 0x08, 0xb1 } \
+}
+struct IMediumFormat_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IMediumFormat *pThis, PRUnichar * *id);
+
+ nsresult (*GetName)(IMediumFormat *pThis, PRUnichar * *name);
+
+ nsresult (*GetFileExtensions)(IMediumFormat *pThis, PRUint32 *fileExtensionsSize, PRUnichar * **fileExtensions);
+
+ nsresult (*GetCapabilities)(IMediumFormat *pThis, PRUint32 *capabilities);
+
+ nsresult (*DescribeProperties)(
+ IMediumFormat *pThis,
+ PRUint32 *namesSize,
+ PRUnichar *** names,
+ PRUint32 *descriptionSize,
+ PRUnichar *** description,
+ PRUint32 *typesSize,
+ PRUint32* types,
+ PRUint32 *flagsSize,
+ PRUint32* flags,
+ PRUint32 *defaultsSize,
+ PRUnichar *** defaults
+ );
+
+};
+
+struct IMediumFormat
+{
+ struct IMediumFormat_vtbl *vtbl;
+};
+/* End of struct IMediumFormat Declaration */
+
+
+/* Start of struct IKeyboard Declaration */
+#define IKEYBOARD_IID_STR "2d1a531b-4c6e-49cc-8af6-5c857b78b5d7"
+#define IKEYBOARD_IID { \
+ 0x2d1a531b, 0x4c6e, 0x49cc, \
+ { 0x8a, 0xf6, 0x5c, 0x85, 0x7b, 0x78, 0xb5, 0xd7 } \
+}
+struct IKeyboard_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*PutScancode)(
+ IKeyboard *pThis,
+ PRInt32 scancode
+ );
+
+ nsresult (*PutScancodes)(
+ IKeyboard *pThis,
+ PRUint32 scancodesSize,
+ PRInt32* scancodes,
+ PRUint32 * codesStored
+ );
+
+ nsresult (*PutCAD)(IKeyboard *pThis );
+
+};
+
+struct IKeyboard
+{
+ struct IKeyboard_vtbl *vtbl;
+};
+/* End of struct IKeyboard Declaration */
+
+
+/* Start of struct IMouse Declaration */
+#define IMOUSE_IID_STR "7c0f2eae-f92d-498c-b802-e1a3763774dc"
+#define IMOUSE_IID { \
+ 0x7c0f2eae, 0xf92d, 0x498c, \
+ { 0xb8, 0x02, 0xe1, 0xa3, 0x76, 0x37, 0x74, 0xdc } \
+}
+struct IMouse_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetAbsoluteSupported)(IMouse *pThis, PRBool *absoluteSupported);
+
+ nsresult (*GetRelativeSupported)(IMouse *pThis, PRBool *relativeSupported);
+
+ nsresult (*GetNeedsHostCursor)(IMouse *pThis, PRBool *needsHostCursor);
+
+ nsresult (*PutMouseEvent)(
+ IMouse *pThis,
+ PRInt32 dx,
+ PRInt32 dy,
+ PRInt32 dz,
+ PRInt32 dw,
+ PRInt32 buttonState
+ );
+
+ nsresult (*PutMouseEventAbsolute)(
+ IMouse *pThis,
+ PRInt32 x,
+ PRInt32 y,
+ PRInt32 dz,
+ PRInt32 dw,
+ PRInt32 buttonState
+ );
+
+};
+
+struct IMouse
+{
+ struct IMouse_vtbl *vtbl;
+};
+/* End of struct IMouse Declaration */
+
+
+/* Start of struct IFramebuffer Declaration */
+#define IFRAMEBUFFER_IID_STR "b7ed347a-5765-40a0-ae1c-f543eb4ddeaf"
+#define IFRAMEBUFFER_IID { \
+ 0xb7ed347a, 0x5765, 0x40a0, \
+ { 0xae, 0x1c, 0xf5, 0x43, 0xeb, 0x4d, 0xde, 0xaf } \
+}
+struct IFramebuffer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetAddress)(IFramebuffer *pThis, PRUint8 * *address);
+
+ nsresult (*GetWidth)(IFramebuffer *pThis, PRUint32 *width);
+
+ nsresult (*GetHeight)(IFramebuffer *pThis, PRUint32 *height);
+
+ nsresult (*GetBitsPerPixel)(IFramebuffer *pThis, PRUint32 *bitsPerPixel);
+
+ nsresult (*GetBytesPerLine)(IFramebuffer *pThis, PRUint32 *bytesPerLine);
+
+ nsresult (*GetPixelFormat)(IFramebuffer *pThis, PRUint32 *pixelFormat);
+
+ nsresult (*GetUsesGuestVRAM)(IFramebuffer *pThis, PRBool *usesGuestVRAM);
+
+ nsresult (*GetHeightReduction)(IFramebuffer *pThis, PRUint32 *heightReduction);
+
+ nsresult (*GetOverlay)(IFramebuffer *pThis, IFramebufferOverlay * *overlay);
+
+ nsresult (*GetWinId)(IFramebuffer *pThis, PRUint64 *winId);
+
+ nsresult (*Lock)(IFramebuffer *pThis );
+
+ nsresult (*Unlock)(IFramebuffer *pThis );
+
+ nsresult (*NotifyUpdate)(
+ IFramebuffer *pThis,
+ PRUint32 x,
+ PRUint32 y,
+ PRUint32 width,
+ PRUint32 height
+ );
+
+ nsresult (*RequestResize)(
+ IFramebuffer *pThis,
+ PRUint32 screenId,
+ PRUint32 pixelFormat,
+ PRUint8 * VRAM,
+ PRUint32 bitsPerPixel,
+ PRUint32 bytesPerLine,
+ PRUint32 width,
+ PRUint32 height,
+ PRBool * finished
+ );
+
+ nsresult (*VideoModeSupported)(
+ IFramebuffer *pThis,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 bpp,
+ PRBool * supported
+ );
+
+ nsresult (*GetVisibleRegion)(
+ IFramebuffer *pThis,
+ PRUint8 * rectangles,
+ PRUint32 count,
+ PRUint32 * countCopied
+ );
+
+ nsresult (*SetVisibleRegion)(
+ IFramebuffer *pThis,
+ PRUint8 * rectangles,
+ PRUint32 count
+ );
+
+ nsresult (*ProcessVHWACommand)(
+ IFramebuffer *pThis,
+ PRUint8 * command
+ );
+
+};
+
+struct IFramebuffer
+{
+ struct IFramebuffer_vtbl *vtbl;
+};
+/* End of struct IFramebuffer Declaration */
+
+
+/* Start of struct IFramebufferOverlay Declaration */
+#define IFRAMEBUFFEROVERLAY_IID_STR "0bcc1c7e-e415-47d2-bfdb-e4c705fb0f47"
+#define IFRAMEBUFFEROVERLAY_IID { \
+ 0x0bcc1c7e, 0xe415, 0x47d2, \
+ { 0xbf, 0xdb, 0xe4, 0xc7, 0x05, 0xfb, 0x0f, 0x47 } \
+}
+struct IFramebufferOverlay_vtbl
+{
+ struct IFramebuffer_vtbl iframebuffer;
+
+ nsresult (*GetX)(IFramebufferOverlay *pThis, PRUint32 *x);
+
+ nsresult (*GetY)(IFramebufferOverlay *pThis, PRUint32 *y);
+
+ nsresult (*GetVisible)(IFramebufferOverlay *pThis, PRBool *visible);
+ nsresult (*SetVisible)(IFramebufferOverlay *pThis, PRBool visible);
+
+ nsresult (*GetAlpha)(IFramebufferOverlay *pThis, PRUint32 *alpha);
+ nsresult (*SetAlpha)(IFramebufferOverlay *pThis, PRUint32 alpha);
+
+ nsresult (*Move)(
+ IFramebufferOverlay *pThis,
+ PRUint32 x,
+ PRUint32 y
+ );
+
+};
+
+struct IFramebufferOverlay
+{
+ struct IFramebufferOverlay_vtbl *vtbl;
+};
+/* End of struct IFramebufferOverlay Declaration */
+
+
+/* Start of struct IDisplay Declaration */
+#define IDISPLAY_IID_STR "1fa79e39-0cc9-4ab3-9df3-ed3e96b42496"
+#define IDISPLAY_IID { \
+ 0x1fa79e39, 0x0cc9, 0x4ab3, \
+ { 0x9d, 0xf3, 0xed, 0x3e, 0x96, 0xb4, 0x24, 0x96 } \
+}
+struct IDisplay_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetScreenResolution)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 * bitsPerPixel
+ );
+
+ nsresult (*SetFramebuffer)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ IFramebuffer * framebuffer
+ );
+
+ nsresult (*GetFramebuffer)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ IFramebuffer * * framebuffer,
+ PRInt32 * xOrigin,
+ PRInt32 * yOrigin
+ );
+
+ nsresult (*SetVideoModeHint)(
+ IDisplay *pThis,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 bitsPerPixel,
+ PRUint32 display
+ );
+
+ nsresult (*SetSeamlessMode)(
+ IDisplay *pThis,
+ PRBool enabled
+ );
+
+ nsresult (*TakeScreenShot)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint8 * address,
+ PRUint32 width,
+ PRUint32 height
+ );
+
+ nsresult (*TakeScreenShotToArray)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 *screenDataSize,
+ PRUint8** screenData
+ );
+
+ nsresult (*DrawToScreen)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint8 * address,
+ PRUint32 x,
+ PRUint32 y,
+ PRUint32 width,
+ PRUint32 height
+ );
+
+ nsresult (*InvalidateAndUpdate)(IDisplay *pThis );
+
+ nsresult (*ResizeCompleted)(
+ IDisplay *pThis,
+ PRUint32 screenId
+ );
+
+ nsresult (*CompleteVHWACommand)(
+ IDisplay *pThis,
+ PRUint8 * command
+ );
+
+};
+
+struct IDisplay
+{
+ struct IDisplay_vtbl *vtbl;
+};
+/* End of struct IDisplay Declaration */
+
+
+/* Start of struct INetworkAdapter Declaration */
+#define INETWORKADAPTER_IID_STR "5bdb9df8-a5e1-4322-a139-b7a4a734c790"
+#define INETWORKADAPTER_IID { \
+ 0x5bdb9df8, 0xa5e1, 0x4322, \
+ { 0xa1, 0x39, 0xb7, 0xa4, 0xa7, 0x34, 0xc7, 0x90 } \
+}
+struct INetworkAdapter_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetAdapterType)(INetworkAdapter *pThis, PRUint32 *adapterType);
+ nsresult (*SetAdapterType)(INetworkAdapter *pThis, PRUint32 adapterType);
+
+ nsresult (*GetSlot)(INetworkAdapter *pThis, PRUint32 *slot);
+
+ nsresult (*GetEnabled)(INetworkAdapter *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(INetworkAdapter *pThis, PRBool enabled);
+
+ nsresult (*GetMACAddress)(INetworkAdapter *pThis, PRUnichar * *MACAddress);
+ nsresult (*SetMACAddress)(INetworkAdapter *pThis, PRUnichar * MACAddress);
+
+ nsresult (*GetAttachmentType)(INetworkAdapter *pThis, PRUint32 *attachmentType);
+
+ nsresult (*GetHostInterface)(INetworkAdapter *pThis, PRUnichar * *hostInterface);
+ nsresult (*SetHostInterface)(INetworkAdapter *pThis, PRUnichar * hostInterface);
+
+ nsresult (*GetInternalNetwork)(INetworkAdapter *pThis, PRUnichar * *internalNetwork);
+ nsresult (*SetInternalNetwork)(INetworkAdapter *pThis, PRUnichar * internalNetwork);
+
+ nsresult (*GetNATNetwork)(INetworkAdapter *pThis, PRUnichar * *NATNetwork);
+ nsresult (*SetNATNetwork)(INetworkAdapter *pThis, PRUnichar * NATNetwork);
+
+ nsresult (*GetVDENetwork)(INetworkAdapter *pThis, PRUnichar * *VDENetwork);
+ nsresult (*SetVDENetwork)(INetworkAdapter *pThis, PRUnichar * VDENetwork);
+
+ nsresult (*GetCableConnected)(INetworkAdapter *pThis, PRBool *cableConnected);
+ nsresult (*SetCableConnected)(INetworkAdapter *pThis, PRBool cableConnected);
+
+ nsresult (*GetLineSpeed)(INetworkAdapter *pThis, PRUint32 *lineSpeed);
+ nsresult (*SetLineSpeed)(INetworkAdapter *pThis, PRUint32 lineSpeed);
+
+ nsresult (*GetTraceEnabled)(INetworkAdapter *pThis, PRBool *traceEnabled);
+ nsresult (*SetTraceEnabled)(INetworkAdapter *pThis, PRBool traceEnabled);
+
+ nsresult (*GetTraceFile)(INetworkAdapter *pThis, PRUnichar * *traceFile);
+ nsresult (*SetTraceFile)(INetworkAdapter *pThis, PRUnichar * traceFile);
+
+ nsresult (*GetNatDriver)(INetworkAdapter *pThis, INATEngine * *natDriver);
+
+ nsresult (*GetBootPriority)(INetworkAdapter *pThis, PRUint32 *bootPriority);
+ nsresult (*SetBootPriority)(INetworkAdapter *pThis, PRUint32 bootPriority);
+
+ nsresult (*AttachToNAT)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToBridgedInterface)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToInternalNetwork)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToHostOnlyInterface)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToVDE)(INetworkAdapter *pThis );
+
+ nsresult (*Detach)(INetworkAdapter *pThis );
+
+};
+
+struct INetworkAdapter
+{
+ struct INetworkAdapter_vtbl *vtbl;
+};
+/* End of struct INetworkAdapter Declaration */
+
+
+/* Start of struct ISerialPort Declaration */
+#define ISERIALPORT_IID_STR "937f6970-5103-4745-b78e-d28dcf1479a8"
+#define ISERIALPORT_IID { \
+ 0x937f6970, 0x5103, 0x4745, \
+ { 0xb7, 0x8e, 0xd2, 0x8d, 0xcf, 0x14, 0x79, 0xa8 } \
+}
+struct ISerialPort_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetSlot)(ISerialPort *pThis, PRUint32 *slot);
+
+ nsresult (*GetEnabled)(ISerialPort *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(ISerialPort *pThis, PRBool enabled);
+
+ nsresult (*GetIOBase)(ISerialPort *pThis, PRUint32 *IOBase);
+ nsresult (*SetIOBase)(ISerialPort *pThis, PRUint32 IOBase);
+
+ nsresult (*GetIRQ)(ISerialPort *pThis, PRUint32 *IRQ);
+ nsresult (*SetIRQ)(ISerialPort *pThis, PRUint32 IRQ);
+
+ nsresult (*GetHostMode)(ISerialPort *pThis, PRUint32 *hostMode);
+ nsresult (*SetHostMode)(ISerialPort *pThis, PRUint32 hostMode);
+
+ nsresult (*GetServer)(ISerialPort *pThis, PRBool *server);
+ nsresult (*SetServer)(ISerialPort *pThis, PRBool server);
+
+ nsresult (*GetPath)(ISerialPort *pThis, PRUnichar * *path);
+ nsresult (*SetPath)(ISerialPort *pThis, PRUnichar * path);
+
+};
+
+struct ISerialPort
+{
+ struct ISerialPort_vtbl *vtbl;
+};
+/* End of struct ISerialPort Declaration */
+
+
+/* Start of struct IParallelPort Declaration */
+#define IPARALLELPORT_IID_STR "0c925f06-dd10-4b77-8de8-294d738c3214"
+#define IPARALLELPORT_IID { \
+ 0x0c925f06, 0xdd10, 0x4b77, \
+ { 0x8d, 0xe8, 0x29, 0x4d, 0x73, 0x8c, 0x32, 0x14 } \
+}
+struct IParallelPort_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetSlot)(IParallelPort *pThis, PRUint32 *slot);
+
+ nsresult (*GetEnabled)(IParallelPort *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IParallelPort *pThis, PRBool enabled);
+
+ nsresult (*GetIOBase)(IParallelPort *pThis, PRUint32 *IOBase);
+ nsresult (*SetIOBase)(IParallelPort *pThis, PRUint32 IOBase);
+
+ nsresult (*GetIRQ)(IParallelPort *pThis, PRUint32 *IRQ);
+ nsresult (*SetIRQ)(IParallelPort *pThis, PRUint32 IRQ);
+
+ nsresult (*GetPath)(IParallelPort *pThis, PRUnichar * *path);
+ nsresult (*SetPath)(IParallelPort *pThis, PRUnichar * path);
+
+};
+
+struct IParallelPort
+{
+ struct IParallelPort_vtbl *vtbl;
+};
+/* End of struct IParallelPort Declaration */
+
+
+/* Start of struct IMachineDebugger Declaration */
+#define IMACHINEDEBUGGER_IID_STR "b0b2a2dd-0627-4502-91c2-ddc5e77609e0"
+#define IMACHINEDEBUGGER_IID { \
+ 0xb0b2a2dd, 0x0627, 0x4502, \
+ { 0x91, 0xc2, 0xdd, 0xc5, 0xe7, 0x76, 0x09, 0xe0 } \
+}
+struct IMachineDebugger_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetSinglestep)(IMachineDebugger *pThis, PRBool *singlestep);
+ nsresult (*SetSinglestep)(IMachineDebugger *pThis, PRBool singlestep);
+
+ nsresult (*GetRecompileUser)(IMachineDebugger *pThis, PRBool *recompileUser);
+ nsresult (*SetRecompileUser)(IMachineDebugger *pThis, PRBool recompileUser);
+
+ nsresult (*GetRecompileSupervisor)(IMachineDebugger *pThis, PRBool *recompileSupervisor);
+ nsresult (*SetRecompileSupervisor)(IMachineDebugger *pThis, PRBool recompileSupervisor);
+
+ nsresult (*GetPATMEnabled)(IMachineDebugger *pThis, PRBool *PATMEnabled);
+ nsresult (*SetPATMEnabled)(IMachineDebugger *pThis, PRBool PATMEnabled);
+
+ nsresult (*GetCSAMEnabled)(IMachineDebugger *pThis, PRBool *CSAMEnabled);
+ nsresult (*SetCSAMEnabled)(IMachineDebugger *pThis, PRBool CSAMEnabled);
+
+ nsresult (*GetLogEnabled)(IMachineDebugger *pThis, PRBool *logEnabled);
+ nsresult (*SetLogEnabled)(IMachineDebugger *pThis, PRBool logEnabled);
+
+ nsresult (*GetHWVirtExEnabled)(IMachineDebugger *pThis, PRBool *HWVirtExEnabled);
+
+ nsresult (*GetHWVirtExNestedPagingEnabled)(IMachineDebugger *pThis, PRBool *HWVirtExNestedPagingEnabled);
+
+ nsresult (*GetHWVirtExVPIDEnabled)(IMachineDebugger *pThis, PRBool *HWVirtExVPIDEnabled);
+
+ nsresult (*GetPAEEnabled)(IMachineDebugger *pThis, PRBool *PAEEnabled);
+
+ nsresult (*GetVirtualTimeRate)(IMachineDebugger *pThis, PRUint32 *virtualTimeRate);
+ nsresult (*SetVirtualTimeRate)(IMachineDebugger *pThis, PRUint32 virtualTimeRate);
+
+ nsresult (*GetVM)(IMachineDebugger *pThis, PRUint64 *VM);
+
+ nsresult (*ResetStats)(
+ IMachineDebugger *pThis,
+ PRUnichar * pattern
+ );
+
+ nsresult (*DumpStats)(
+ IMachineDebugger *pThis,
+ PRUnichar * pattern
+ );
+
+ nsresult (*GetStats)(
+ IMachineDebugger *pThis,
+ PRUnichar * pattern,
+ PRBool withDescriptions,
+ PRUnichar * * stats
+ );
+
+ nsresult (*InjectNMI)(IMachineDebugger *pThis );
+
+};
+
+struct IMachineDebugger
+{
+ struct IMachineDebugger_vtbl *vtbl;
+};
+/* End of struct IMachineDebugger Declaration */
+
+
+/* Start of struct IUSBController Declaration */
+#define IUSBCONTROLLER_IID_STR "6fdcccc5-abd3-4fec-9387-2ad3914fc4a8"
+#define IUSBCONTROLLER_IID { \
+ 0x6fdcccc5, 0xabd3, 0x4fec, \
+ { 0x93, 0x87, 0x2a, 0xd3, 0x91, 0x4f, 0xc4, 0xa8 } \
+}
+struct IUSBController_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IUSBController *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IUSBController *pThis, PRBool enabled);
+
+ nsresult (*GetEnabledEhci)(IUSBController *pThis, PRBool *enabledEhci);
+ nsresult (*SetEnabledEhci)(IUSBController *pThis, PRBool enabledEhci);
+
+ nsresult (*GetProxyAvailable)(IUSBController *pThis, PRBool *proxyAvailable);
+
+ nsresult (*GetUSBStandard)(IUSBController *pThis, PRUint16 *USBStandard);
+
+ nsresult (*GetDeviceFilters)(IUSBController *pThis, PRUint32 *deviceFiltersSize, IUSBDeviceFilter * **deviceFilters);
+
+ nsresult (*CreateDeviceFilter)(
+ IUSBController *pThis,
+ PRUnichar * name,
+ IUSBDeviceFilter * * filter
+ );
+
+ nsresult (*InsertDeviceFilter)(
+ IUSBController *pThis,
+ PRUint32 position,
+ IUSBDeviceFilter * filter
+ );
+
+ nsresult (*RemoveDeviceFilter)(
+ IUSBController *pThis,
+ PRUint32 position,
+ IUSBDeviceFilter * * filter
+ );
+
+};
+
+struct IUSBController
+{
+ struct IUSBController_vtbl *vtbl;
+};
+/* End of struct IUSBController Declaration */
+
+
+/* Start of struct IUSBDevice Declaration */
+#define IUSBDEVICE_IID_STR "f8967b0b-4483-400f-92b5-8b675d98a85b"
+#define IUSBDEVICE_IID { \
+ 0xf8967b0b, 0x4483, 0x400f, \
+ { 0x92, 0xb5, 0x8b, 0x67, 0x5d, 0x98, 0xa8, 0x5b } \
+}
+struct IUSBDevice_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IUSBDevice *pThis, PRUnichar * *id);
+
+ nsresult (*GetVendorId)(IUSBDevice *pThis, PRUint16 *vendorId);
+
+ nsresult (*GetProductId)(IUSBDevice *pThis, PRUint16 *productId);
+
+ nsresult (*GetRevision)(IUSBDevice *pThis, PRUint16 *revision);
+
+ nsresult (*GetManufacturer)(IUSBDevice *pThis, PRUnichar * *manufacturer);
+
+ nsresult (*GetProduct)(IUSBDevice *pThis, PRUnichar * *product);
+
+ nsresult (*GetSerialNumber)(IUSBDevice *pThis, PRUnichar * *serialNumber);
+
+ nsresult (*GetAddress)(IUSBDevice *pThis, PRUnichar * *address);
+
+ nsresult (*GetPort)(IUSBDevice *pThis, PRUint16 *port);
+
+ nsresult (*GetVersion)(IUSBDevice *pThis, PRUint16 *version);
+
+ nsresult (*GetPortVersion)(IUSBDevice *pThis, PRUint16 *portVersion);
+
+ nsresult (*GetRemote)(IUSBDevice *pThis, PRBool *remote);
+
+};
+
+struct IUSBDevice
+{
+ struct IUSBDevice_vtbl *vtbl;
+};
+/* End of struct IUSBDevice Declaration */
+
+
+/* Start of struct IUSBDeviceFilter Declaration */
+#define IUSBDEVICEFILTER_IID_STR "d6831fb4-1a94-4c2c-96ef-8d0d6192066d"
+#define IUSBDEVICEFILTER_IID { \
+ 0xd6831fb4, 0x1a94, 0x4c2c, \
+ { 0x96, 0xef, 0x8d, 0x0d, 0x61, 0x92, 0x06, 0x6d } \
+}
+struct IUSBDeviceFilter_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IUSBDeviceFilter *pThis, PRUnichar * *name);
+ nsresult (*SetName)(IUSBDeviceFilter *pThis, PRUnichar * name);
+
+ nsresult (*GetActive)(IUSBDeviceFilter *pThis, PRBool *active);
+ nsresult (*SetActive)(IUSBDeviceFilter *pThis, PRBool active);
+
+ nsresult (*GetVendorId)(IUSBDeviceFilter *pThis, PRUnichar * *vendorId);
+ nsresult (*SetVendorId)(IUSBDeviceFilter *pThis, PRUnichar * vendorId);
+
+ nsresult (*GetProductId)(IUSBDeviceFilter *pThis, PRUnichar * *productId);
+ nsresult (*SetProductId)(IUSBDeviceFilter *pThis, PRUnichar * productId);
+
+ nsresult (*GetRevision)(IUSBDeviceFilter *pThis, PRUnichar * *revision);
+ nsresult (*SetRevision)(IUSBDeviceFilter *pThis, PRUnichar * revision);
+
+ nsresult (*GetManufacturer)(IUSBDeviceFilter *pThis, PRUnichar * *manufacturer);
+ nsresult (*SetManufacturer)(IUSBDeviceFilter *pThis, PRUnichar * manufacturer);
+
+ nsresult (*GetProduct)(IUSBDeviceFilter *pThis, PRUnichar * *product);
+ nsresult (*SetProduct)(IUSBDeviceFilter *pThis, PRUnichar * product);
+
+ nsresult (*GetSerialNumber)(IUSBDeviceFilter *pThis, PRUnichar * *serialNumber);
+ nsresult (*SetSerialNumber)(IUSBDeviceFilter *pThis, PRUnichar * serialNumber);
+
+ nsresult (*GetPort)(IUSBDeviceFilter *pThis, PRUnichar * *port);
+ nsresult (*SetPort)(IUSBDeviceFilter *pThis, PRUnichar * port);
+
+ nsresult (*GetRemote)(IUSBDeviceFilter *pThis, PRUnichar * *remote);
+ nsresult (*SetRemote)(IUSBDeviceFilter *pThis, PRUnichar * remote);
+
+ nsresult (*GetMaskedInterfaces)(IUSBDeviceFilter *pThis, PRUint32 *maskedInterfaces);
+ nsresult (*SetMaskedInterfaces)(IUSBDeviceFilter *pThis, PRUint32 maskedInterfaces);
+
+};
+
+struct IUSBDeviceFilter
+{
+ struct IUSBDeviceFilter_vtbl *vtbl;
+};
+/* End of struct IUSBDeviceFilter Declaration */
+
+
+/* Start of struct IHostUSBDevice Declaration */
+#define IHOSTUSBDEVICE_IID_STR "173b4b44-d268-4334-a00d-b6521c9a740a"
+#define IHOSTUSBDEVICE_IID { \
+ 0x173b4b44, 0xd268, 0x4334, \
+ { 0xa0, 0x0d, 0xb6, 0x52, 0x1c, 0x9a, 0x74, 0x0a } \
+}
+struct IHostUSBDevice_vtbl
+{
+ struct IUSBDevice_vtbl iusbdevice;
+
+ nsresult (*GetState)(IHostUSBDevice *pThis, PRUint32 *state);
+
+};
+
+struct IHostUSBDevice
+{
+ struct IHostUSBDevice_vtbl *vtbl;
+};
+/* End of struct IHostUSBDevice Declaration */
+
+
+/* Start of struct IHostUSBDeviceFilter Declaration */
+#define IHOSTUSBDEVICEFILTER_IID_STR "4cc70246-d74a-400f-8222-3900489c0374"
+#define IHOSTUSBDEVICEFILTER_IID { \
+ 0x4cc70246, 0xd74a, 0x400f, \
+ { 0x82, 0x22, 0x39, 0x00, 0x48, 0x9c, 0x03, 0x74 } \
+}
+struct IHostUSBDeviceFilter_vtbl
+{
+ struct IUSBDeviceFilter_vtbl iusbdevicefilter;
+
+ nsresult (*GetAction)(IHostUSBDeviceFilter *pThis, PRUint32 *action);
+ nsresult (*SetAction)(IHostUSBDeviceFilter *pThis, PRUint32 action);
+
+};
+
+struct IHostUSBDeviceFilter
+{
+ struct IHostUSBDeviceFilter_vtbl *vtbl;
+};
+/* End of struct IHostUSBDeviceFilter Declaration */
+
+
+/* Start of struct IAudioAdapter Declaration */
+#define IAUDIOADAPTER_IID_STR "921873db-5f3f-4b69-91f9-7be9e535a2cb"
+#define IAUDIOADAPTER_IID { \
+ 0x921873db, 0x5f3f, 0x4b69, \
+ { 0x91, 0xf9, 0x7b, 0xe9, 0xe5, 0x35, 0xa2, 0xcb } \
+}
+struct IAudioAdapter_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IAudioAdapter *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IAudioAdapter *pThis, PRBool enabled);
+
+ nsresult (*GetAudioController)(IAudioAdapter *pThis, PRUint32 *audioController);
+ nsresult (*SetAudioController)(IAudioAdapter *pThis, PRUint32 audioController);
+
+ nsresult (*GetAudioDriver)(IAudioAdapter *pThis, PRUint32 *audioDriver);
+ nsresult (*SetAudioDriver)(IAudioAdapter *pThis, PRUint32 audioDriver);
+
+};
+
+struct IAudioAdapter
+{
+ struct IAudioAdapter_vtbl *vtbl;
+};
+/* End of struct IAudioAdapter Declaration */
+
+
+/* Start of struct IVRDPServer Declaration */
+#define IVRDPSERVER_IID_STR "7aeeb530-0b08-41fe-835d-9be9ec1dbe5c"
+#define IVRDPSERVER_IID { \
+ 0x7aeeb530, 0x0b08, 0x41fe, \
+ { 0x83, 0x5d, 0x9b, 0xe9, 0xec, 0x1d, 0xbe, 0x5c } \
+}
+struct IVRDPServer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IVRDPServer *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IVRDPServer *pThis, PRBool enabled);
+
+ nsresult (*GetPorts)(IVRDPServer *pThis, PRUnichar * *ports);
+ nsresult (*SetPorts)(IVRDPServer *pThis, PRUnichar * ports);
+
+ nsresult (*GetNetAddress)(IVRDPServer *pThis, PRUnichar * *netAddress);
+ nsresult (*SetNetAddress)(IVRDPServer *pThis, PRUnichar * netAddress);
+
+ nsresult (*GetAuthType)(IVRDPServer *pThis, PRUint32 *authType);
+ nsresult (*SetAuthType)(IVRDPServer *pThis, PRUint32 authType);
+
+ nsresult (*GetAuthTimeout)(IVRDPServer *pThis, PRUint32 *authTimeout);
+ nsresult (*SetAuthTimeout)(IVRDPServer *pThis, PRUint32 authTimeout);
+
+ nsresult (*GetAllowMultiConnection)(IVRDPServer *pThis, PRBool *allowMultiConnection);
+ nsresult (*SetAllowMultiConnection)(IVRDPServer *pThis, PRBool allowMultiConnection);
+
+ nsresult (*GetReuseSingleConnection)(IVRDPServer *pThis, PRBool *reuseSingleConnection);
+ nsresult (*SetReuseSingleConnection)(IVRDPServer *pThis, PRBool reuseSingleConnection);
+
+ nsresult (*GetVideoChannel)(IVRDPServer *pThis, PRBool *videoChannel);
+ nsresult (*SetVideoChannel)(IVRDPServer *pThis, PRBool videoChannel);
+
+ nsresult (*GetVideoChannelQuality)(IVRDPServer *pThis, PRUint32 *videoChannelQuality);
+ nsresult (*SetVideoChannelQuality)(IVRDPServer *pThis, PRUint32 videoChannelQuality);
+
+};
+
+struct IVRDPServer
+{
+ struct IVRDPServer_vtbl *vtbl;
+};
+/* End of struct IVRDPServer Declaration */
+
+
+/* Start of struct ISharedFolder Declaration */
+#define ISHAREDFOLDER_IID_STR "64637bb2-9e17-471c-b8f3-f8968dd9884e"
+#define ISHAREDFOLDER_IID { \
+ 0x64637bb2, 0x9e17, 0x471c, \
+ { 0xb8, 0xf3, 0xf8, 0x96, 0x8d, 0xd9, 0x88, 0x4e } \
+}
+struct ISharedFolder_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(ISharedFolder *pThis, PRUnichar * *name);
+
+ nsresult (*GetHostPath)(ISharedFolder *pThis, PRUnichar * *hostPath);
+
+ nsresult (*GetAccessible)(ISharedFolder *pThis, PRBool *accessible);
+
+ nsresult (*GetWritable)(ISharedFolder *pThis, PRBool *writable);
+
+ nsresult (*GetLastAccessError)(ISharedFolder *pThis, PRUnichar * *lastAccessError);
+
+};
+
+struct ISharedFolder
+{
+ struct ISharedFolder_vtbl *vtbl;
+};
+/* End of struct ISharedFolder Declaration */
+
+
+/* Start of struct IInternalSessionControl Declaration */
+#define IINTERNALSESSIONCONTROL_IID_STR "ab161f72-e4b3-44e6-a919-2256474bda66"
+#define IINTERNALSESSIONCONTROL_IID { \
+ 0xab161f72, 0xe4b3, 0x44e6, \
+ { 0xa9, 0x19, 0x22, 0x56, 0x47, 0x4b, 0xda, 0x66 } \
+}
+struct IInternalSessionControl_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetPID)(
+ IInternalSessionControl *pThis,
+ PRUint32 * pid
+ );
+
+ nsresult (*GetRemoteConsole)(
+ IInternalSessionControl *pThis,
+ IConsole * * console
+ );
+
+ nsresult (*AssignMachine)(
+ IInternalSessionControl *pThis,
+ IMachine * machine
+ );
+
+ nsresult (*AssignRemoteMachine)(
+ IInternalSessionControl *pThis,
+ IMachine * machine,
+ IConsole * console
+ );
+
+ nsresult (*UpdateMachineState)(
+ IInternalSessionControl *pThis,
+ PRUint32 aMachineState
+ );
+
+ nsresult (*Uninitialize)(IInternalSessionControl *pThis );
+
+ nsresult (*OnNetworkAdapterChange)(
+ IInternalSessionControl *pThis,
+ INetworkAdapter * networkAdapter,
+ PRBool changeAdapter
+ );
+
+ nsresult (*OnSerialPortChange)(
+ IInternalSessionControl *pThis,
+ ISerialPort * serialPort
+ );
+
+ nsresult (*OnParallelPortChange)(
+ IInternalSessionControl *pThis,
+ IParallelPort * parallelPort
+ );
+
+ nsresult (*OnStorageControllerChange)(IInternalSessionControl *pThis );
+
+ nsresult (*OnMediumChange)(
+ IInternalSessionControl *pThis,
+ IMediumAttachment * mediumAttachment,
+ PRBool force
+ );
+
+ nsresult (*OnCPUChange)(
+ IInternalSessionControl *pThis,
+ PRUint32 cpu,
+ PRBool add
+ );
+
+ nsresult (*OnVRDPServerChange)(
+ IInternalSessionControl *pThis,
+ PRBool restart
+ );
+
+ nsresult (*OnUSBControllerChange)(IInternalSessionControl *pThis );
+
+ nsresult (*OnSharedFolderChange)(
+ IInternalSessionControl *pThis,
+ PRBool global
+ );
+
+ nsresult (*OnUSBDeviceAttach)(
+ IInternalSessionControl *pThis,
+ IUSBDevice * device,
+ IVirtualBoxErrorInfo * error,
+ PRUint32 maskedInterfaces
+ );
+
+ nsresult (*OnUSBDeviceDetach)(
+ IInternalSessionControl *pThis,
+ PRUnichar * id,
+ IVirtualBoxErrorInfo * error
+ );
+
+ nsresult (*OnShowWindow)(
+ IInternalSessionControl *pThis,
+ PRBool check,
+ PRBool * canShow,
+ PRUint64 * winId
+ );
+
+ nsresult (*AccessGuestProperty)(
+ IInternalSessionControl *pThis,
+ PRUnichar * name,
+ PRUnichar * value,
+ PRUnichar * flags,
+ PRBool isSetter,
+ PRUnichar * * retValue,
+ PRUint64 * retTimestamp,
+ PRUnichar * * retFlags
+ );
+
+ nsresult (*EnumerateGuestProperties)(
+ IInternalSessionControl *pThis,
+ PRUnichar * patterns,
+ PRUint32 *keySize,
+ PRUnichar *** key,
+ PRUint32 *valueSize,
+ PRUnichar *** value,
+ PRUint32 *timestampSize,
+ PRUint64* timestamp,
+ PRUint32 *flagsSize,
+ PRUnichar *** flags
+ );
+
+ nsresult (*OnlineMergeMedium)(
+ IInternalSessionControl *pThis,
+ IMediumAttachment * mediumAttachment,
+ PRUint32 sourceIdx,
+ PRUint32 targetIdx,
+ IMedium * source,
+ IMedium * target,
+ PRBool mergeForward,
+ IMedium * parentForTarget,
+ PRUint32 childrenToReparentSize,
+ IMedium ** childrenToReparent,
+ IProgress * progress
+ );
+
+};
+
+struct IInternalSessionControl
+{
+ struct IInternalSessionControl_vtbl *vtbl;
+};
+/* End of struct IInternalSessionControl Declaration */
+
+
+/* Start of struct ISession Declaration */
+#define ISESSION_IID_STR "12F4DCDB-12B2-4EC1-B7CD-DDD9F6C5BF4D"
+#define ISESSION_IID { \
+ 0x12F4DCDB, 0x12B2, 0x4EC1, \
+ { 0xB7, 0xCD, 0xDD, 0xD9, 0xF6, 0xC5, 0xBF, 0x4D } \
+}
+struct ISession_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetState)(ISession *pThis, PRUint32 *state);
+
+ nsresult (*GetType)(ISession *pThis, PRUint32 *type);
+
+ nsresult (*GetMachine)(ISession *pThis, IMachine * *machine);
+
+ nsresult (*GetConsole)(ISession *pThis, IConsole * *console);
+
+ nsresult (*Close)(ISession *pThis );
+
+};
+
+struct ISession
+{
+ struct ISession_vtbl *vtbl;
+};
+/* End of struct ISession Declaration */
+
+
+/* Start of struct IStorageController Declaration */
+#define ISTORAGECONTROLLER_IID_STR "fd93adc0-bbaa-4256-9e6e-00e29f9151c9"
+#define ISTORAGECONTROLLER_IID { \
+ 0xfd93adc0, 0xbbaa, 0x4256, \
+ { 0x9e, 0x6e, 0x00, 0xe2, 0x9f, 0x91, 0x51, 0xc9 } \
+}
+struct IStorageController_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IStorageController *pThis, PRUnichar * *name);
+
+ nsresult (*GetMaxDevicesPerPortCount)(IStorageController *pThis, PRUint32 *maxDevicesPerPortCount);
+
+ nsresult (*GetMinPortCount)(IStorageController *pThis, PRUint32 *minPortCount);
+
+ nsresult (*GetMaxPortCount)(IStorageController *pThis, PRUint32 *maxPortCount);
+
+ nsresult (*GetInstance)(IStorageController *pThis, PRUint32 *instance);
+ nsresult (*SetInstance)(IStorageController *pThis, PRUint32 instance);
+
+ nsresult (*GetPortCount)(IStorageController *pThis, PRUint32 *portCount);
+ nsresult (*SetPortCount)(IStorageController *pThis, PRUint32 portCount);
+
+ nsresult (*GetBus)(IStorageController *pThis, PRUint32 *bus);
+
+ nsresult (*GetControllerType)(IStorageController *pThis, PRUint32 *controllerType);
+ nsresult (*SetControllerType)(IStorageController *pThis, PRUint32 controllerType);
+
+ nsresult (*GetUseHostIOCache)(IStorageController *pThis, PRBool *useHostIOCache);
+ nsresult (*SetUseHostIOCache)(IStorageController *pThis, PRBool useHostIOCache);
+
+ nsresult (*GetIDEEmulationPort)(
+ IStorageController *pThis,
+ PRInt32 devicePosition,
+ PRInt32 * portNumber
+ );
+
+ nsresult (*SetIDEEmulationPort)(
+ IStorageController *pThis,
+ PRInt32 devicePosition,
+ PRInt32 portNumber
+ );
+
+};
+
+struct IStorageController
+{
+ struct IStorageController_vtbl *vtbl;
+};
+/* End of struct IStorageController Declaration */
+
+
+/* Start of struct IPerformanceMetric Declaration */
+#define IPERFORMANCEMETRIC_IID_STR "2a1a60ae-9345-4019-ad53-d34ba41cbfe9"
+#define IPERFORMANCEMETRIC_IID { \
+ 0x2a1a60ae, 0x9345, 0x4019, \
+ { 0xad, 0x53, 0xd3, 0x4b, 0xa4, 0x1c, 0xbf, 0xe9 } \
+}
+struct IPerformanceMetric_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMetricName)(IPerformanceMetric *pThis, PRUnichar * *metricName);
+
+ nsresult (*GetObject)(IPerformanceMetric *pThis, nsISupports * *object);
+
+ nsresult (*GetDescription)(IPerformanceMetric *pThis, PRUnichar * *description);
+
+ nsresult (*GetPeriod)(IPerformanceMetric *pThis, PRUint32 *period);
+
+ nsresult (*GetCount)(IPerformanceMetric *pThis, PRUint32 *count);
+
+ nsresult (*GetUnit)(IPerformanceMetric *pThis, PRUnichar * *unit);
+
+ nsresult (*GetMinimumValue)(IPerformanceMetric *pThis, PRInt32 *minimumValue);
+
+ nsresult (*GetMaximumValue)(IPerformanceMetric *pThis, PRInt32 *maximumValue);
+
+};
+
+struct IPerformanceMetric
+{
+ struct IPerformanceMetric_vtbl *vtbl;
+};
+/* End of struct IPerformanceMetric Declaration */
+
+
+/* Start of struct IPerformanceCollector Declaration */
+#define IPERFORMANCECOLLECTOR_IID_STR "e22e1acb-ac4a-43bb-a31c-17321659b0c6"
+#define IPERFORMANCECOLLECTOR_IID { \
+ 0xe22e1acb, 0xac4a, 0x43bb, \
+ { 0xa3, 0x1c, 0x17, 0x32, 0x16, 0x59, 0xb0, 0xc6 } \
+}
+struct IPerformanceCollector_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMetricNames)(IPerformanceCollector *pThis, PRUint32 *metricNamesSize, PRUnichar * **metricNames);
+
+ nsresult (*GetMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *metricsSize,
+ IPerformanceMetric *** metrics
+ );
+
+ nsresult (*SetupMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 period,
+ PRUint32 count,
+ PRUint32 *affectedMetricsSize,
+ IPerformanceMetric *** affectedMetrics
+ );
+
+ nsresult (*EnableMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *affectedMetricsSize,
+ IPerformanceMetric *** affectedMetrics
+ );
+
+ nsresult (*DisableMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *affectedMetricsSize,
+ IPerformanceMetric *** affectedMetrics
+ );
+
+ nsresult (*QueryMetricsData)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *returnMetricNamesSize,
+ PRUnichar *** returnMetricNames,
+ PRUint32 *returnObjectsSize,
+ nsISupports ** returnObjects,
+ PRUint32 *returnUnitsSize,
+ PRUnichar *** returnUnits,
+ PRUint32 *returnScalesSize,
+ PRUint32* returnScales,
+ PRUint32 *returnSequenceNumbersSize,
+ PRUint32* returnSequenceNumbers,
+ PRUint32 *returnDataIndicesSize,
+ PRUint32* returnDataIndices,
+ PRUint32 *returnDataLengthsSize,
+ PRUint32* returnDataLengths,
+ PRUint32 *returnDataSize,
+ PRInt32** returnData
+ );
+
+};
+
+struct IPerformanceCollector
+{
+ struct IPerformanceCollector_vtbl *vtbl;
+};
+/* End of struct IPerformanceCollector Declaration */
+
+
+/* Start of struct INATEngine Declaration */
+#define INATENGINE_IID_STR "4b286616-eb03-11de-b0fb-1701eca42246"
+#define INATENGINE_IID { \
+ 0x4b286616, 0xeb03, 0x11de, \
+ { 0xb0, 0xfb, 0x17, 0x01, 0xec, 0xa4, 0x22, 0x46 } \
+}
+struct INATEngine_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetNetwork)(INATEngine *pThis, PRUnichar * *network);
+ nsresult (*SetNetwork)(INATEngine *pThis, PRUnichar * network);
+
+ nsresult (*GetHostIP)(INATEngine *pThis, PRUnichar * *hostIP);
+ nsresult (*SetHostIP)(INATEngine *pThis, PRUnichar * hostIP);
+
+ nsresult (*GetTftpPrefix)(INATEngine *pThis, PRUnichar * *tftpPrefix);
+ nsresult (*SetTftpPrefix)(INATEngine *pThis, PRUnichar * tftpPrefix);
+
+ nsresult (*GetTftpBootFile)(INATEngine *pThis, PRUnichar * *tftpBootFile);
+ nsresult (*SetTftpBootFile)(INATEngine *pThis, PRUnichar * tftpBootFile);
+
+ nsresult (*GetTftpNextServer)(INATEngine *pThis, PRUnichar * *tftpNextServer);
+ nsresult (*SetTftpNextServer)(INATEngine *pThis, PRUnichar * tftpNextServer);
+
+ nsresult (*GetAliasMode)(INATEngine *pThis, PRUint32 *aliasMode);
+ nsresult (*SetAliasMode)(INATEngine *pThis, PRUint32 aliasMode);
+
+ nsresult (*GetDnsPassDomain)(INATEngine *pThis, PRBool *dnsPassDomain);
+ nsresult (*SetDnsPassDomain)(INATEngine *pThis, PRBool dnsPassDomain);
+
+ nsresult (*GetDnsProxy)(INATEngine *pThis, PRBool *dnsProxy);
+ nsresult (*SetDnsProxy)(INATEngine *pThis, PRBool dnsProxy);
+
+ nsresult (*GetDnsUseHostResolver)(INATEngine *pThis, PRBool *dnsUseHostResolver);
+ nsresult (*SetDnsUseHostResolver)(INATEngine *pThis, PRBool dnsUseHostResolver);
+
+ nsresult (*GetRedirects)(INATEngine *pThis, PRUint32 *redirectsSize, PRUnichar * **redirects);
+
+ nsresult (*SetNetworkSettings)(
+ INATEngine *pThis,
+ PRUint32 mtu,
+ PRUint32 sockSnd,
+ PRUint32 sockRcv,
+ PRUint32 TcpWndSnd,
+ PRUint32 TcpWndRcv
+ );
+
+ nsresult (*GetNetworkSettings)(
+ INATEngine *pThis,
+ PRUint32 * mtu,
+ PRUint32 * sockSnd,
+ PRUint32 * sockRcv,
+ PRUint32 * TcpWndSnd,
+ PRUint32 * TcpWndRcv
+ );
+
+ nsresult (*AddRedirect)(
+ INATEngine *pThis,
+ PRUnichar * name,
+ PRUint32 proto,
+ PRUnichar * hostIp,
+ PRUint16 hostPort,
+ PRUnichar * guestIp,
+ PRUint16 guestPort
+ );
+
+ nsresult (*RemoveRedirect)(
+ INATEngine *pThis,
+ PRUnichar * name
+ );
+
+};
+
+struct INATEngine
+{
+ struct INATEngine_vtbl *vtbl;
+};
+/* End of struct INATEngine Declaration */
+
+
+
+#define NS_VIRTUALBOX_CID { \
+ 0xB1A7A4F2, 0x47B9, 0x4A1E, \
+ { 0x82, 0xB2, 0x07, 0xCC, 0xD5, 0x32, 0x3C, 0x3F } \
+}
+#define NS_VIRTUALBOX_CONTRACTID "@virtualbox.org/VirtualBox;1"
+/* for compatibility with Win32 */
+#define CLSID_VirtualBox (nsCID) NS_VIRTUALBOX_CID
+
+
+
+#define NS_SESSION_CID { \
+ 0x3C02F46D, 0xC9D2, 0x4F11, \
+ { 0xA3, 0x84, 0x53, 0xF0, 0xCF, 0x91, 0x72, 0x14 } \
+}
+#define NS_SESSION_CONTRACTID "@virtualbox.org/Session;1"
+/* for compatibility with Win32 */
+#define CLSID_Session (nsCID) NS_SESSION_CID
+
+
+
+#define NS_CALLBACKWRAPPER_CID { \
+ 0x49EE8561, 0x5563, 0x4715, \
+ { 0xB1, 0x8C, 0xA4, 0xB1, 0xA4, 0x90, 0xDA, 0xFE } \
+}
+#define NS_CALLBACKWRAPPER_CONTRACTID "@virtualbox.org/CallbackWrapper;1"
+/* for compatibility with Win32 */
+#define CLSID_CallbackWrapper (nsCID) NS_CALLBACKWRAPPER_CID
+
+
+
+#endif /* !__cplusplus */
+
+#ifdef IN_VBOXXPCOMC
+# define VBOXXPCOMC_DECL(type) PR_EXPORT(type)
+#else
+# define VBOXXPCOMC_DECL(type) PR_IMPORT(type)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Function table for dynamic linking.
+ * Use VBoxGetFunctions() to obtain the pointer to it.
+ */
+typedef struct VBOXXPCOMC
+{
+ /** The size of the structure. */
+ unsigned cb;
+ /** The structure version. */
+ unsigned uVersion;
+
+ unsigned int (*pfnGetVersion)(void);
+
+ void (*pfnComInitialize)(const char *pszVirtualBoxIID,
+ IVirtualBox **ppVirtualBox,
+ const char *pszSessionIID,
+ ISession **ppSession);
+ void (*pfnComUninitialize)(void);
+
+ void (*pfnComUnallocMem)(void *pv);
+ void (*pfnUtf16Free)(PRUnichar *pwszString);
+ void (*pfnUtf8Free)(char *pszString);
+
+ int (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
+ int (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
+
+ void (*pfnGetEventQueue)(nsIEventQueue **eventQueue);
+
+ /** Tail version, same as uVersion. */
+ unsigned uEndVersion;
+} VBOXXPCOMC;
+/** Pointer to a const VBoxXPCOMC function table. */
+typedef VBOXXPCOMC const *PCVBOXXPCOM;
+
+/** The current interface version.
+ * For use with VBoxGetXPCOMCFunctions and to be found in
+ * VBOXXPCOMC::uVersion. */
+#define VBOX_XPCOMC_VERSION 0x00020000U
+
+VBOXXPCOMC_DECL(PCVBOXXPCOM) VBoxGetXPCOMCFunctions(unsigned uVersion);
+/** Typedef for VBoxGetXPCOMCFunctions. */
+typedef PCVBOXXPCOM (*PFNVBOXGETXPCOMCFUNCTIONS)(unsigned uVersion);
+
+/** The symbol name of VBoxGetXPCOMCFunctions. */
+#if defined(__OS2__)
+# define VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME "_VBoxGetXPCOMCFunctions"
+#else
+# define VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME "VBoxGetXPCOMCFunctions"
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !___VirtualBox_CXPCOM_h */
diff --git a/src/VBox/Main/cbinding/VBoxCAPI_v4_0.h b/src/VBox/Main/cbinding/VBoxCAPI_v4_0.h
new file mode 100644
index 000000000..bb621d0c9
--- /dev/null
+++ b/src/VBox/Main/cbinding/VBoxCAPI_v4_0.h
@@ -0,0 +1,7445 @@
+
+/*
+ * DO NOT EDIT! This is a generated file.
+ *
+ * XPCOM IDL (XPIDL) definition for VirtualBox Main API (COM interfaces)
+ * generated from XIDL (XML interface definition).
+ *
+ * Source : src/VBox/Main/idl/VirtualBox.xidl
+ * Generator : src/VBox/Main/idl/xpcidl.xsl
+ *
+ * This file contains portions from the following Mozilla XPCOM files:
+ * xpcom/include/xpcom/nsID.h
+ * xpcom/include/nsIException.h
+ * xpcom/include/nsprpub/prtypes.h
+ * xpcom/include/xpcom/nsISupportsBase.h
+ *
+ * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Oracle
+ * elects to distribute this derived work under the LGPL2.1 only.
+ */
+
+/*
+ * Copyright (C) 2008-2012 Oracle Corporation
+ *
+ * This file is part of a free software library; you can redistribute
+ * it and/or modify it under the terms of the GNU Lesser General
+ * Public License version 2.1 as published by the Free Software
+ * Foundation and shipped in the "COPYING" file with this library.
+ * The library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if
+ * any license choice other than GPL or LGPL is available it will
+ * apply instead, Oracle elects to use only the Lesser General Public
+ * License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the
+ * language indicating that LGPLv2 or any later version may be used,
+ * or where a choice of which version of the LGPL is applied is
+ * otherwise unspecified.
+ */
+
+#ifndef ___VirtualBox_CXPCOM_h
+#define ___VirtualBox_CXPCOM_h
+
+#ifdef __cplusplus
+# include "VirtualBox_XPCOM.h"
+#else /* !__cplusplus */
+
+#include <stddef.h>
+#include "wchar.h"
+
+#if defined(WIN32)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_BEOS)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(WIN16)
+
+#define PR_CALLBACK_DECL __cdecl
+
+#if defined(_WINDLL)
+#define PR_EXPORT(__type) extern __type _cdecl _export _loadds
+#define PR_IMPORT(__type) extern __type _cdecl _export _loadds
+#define PR_EXPORT_DATA(__type) extern __type _export
+#define PR_IMPORT_DATA(__type) extern __type _export
+
+#define PR_EXTERN(__type) extern __type _cdecl _export _loadds
+#define PR_IMPLEMENT(__type) __type _cdecl _export _loadds
+#define PR_EXTERN_DATA(__type) extern __type _export
+#define PR_IMPLEMENT_DATA(__type) __type _export
+
+#define PR_CALLBACK __cdecl __loadds
+#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+
+#else /* this must be .EXE */
+#define PR_EXPORT(__type) extern __type _cdecl _export
+#define PR_IMPORT(__type) extern __type _cdecl _export
+#define PR_EXPORT_DATA(__type) extern __type _export
+#define PR_IMPORT_DATA(__type) extern __type _export
+
+#define PR_EXTERN(__type) extern __type _cdecl _export
+#define PR_IMPLEMENT(__type) __type _cdecl _export
+#define PR_EXTERN_DATA(__type) extern __type _export
+#define PR_IMPLEMENT_DATA(__type) __type _export
+
+#define PR_CALLBACK __cdecl __loadds
+#define PR_STATIC_CALLBACK(__x) __x PR_CALLBACK
+#endif /* _WINDLL */
+
+#elif defined(XP_MAC)
+
+#define PR_EXPORT(__type) extern __declspec(export) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(export) __type
+#define PR_IMPORT(__type) extern __declspec(export) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(export) __type
+
+#define PR_EXTERN(__type) extern __declspec(export) __type
+#define PR_IMPLEMENT(__type) __declspec(export) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(export) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(export) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_OS2) && defined(__declspec)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_OS2_VACPP)
+
+#define PR_EXPORT(__type) extern __type
+#define PR_EXPORT_DATA(__type) extern __type
+#define PR_IMPORT(__type) extern __type
+#define PR_IMPORT_DATA(__type) extern __type
+
+#define PR_EXTERN(__type) extern __type
+#define PR_IMPLEMENT(__type) __type
+#define PR_EXTERN_DATA(__type) extern __type
+#define PR_IMPLEMENT_DATA(__type) __type
+#define PR_CALLBACK _Optlink
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+
+#else /* Unix */
+
+# ifdef VBOX_HAVE_VISIBILITY_HIDDEN
+# define PR_EXPORT(__type) __attribute__((visibility("default"))) extern __type
+# define PR_EXPORT_DATA(__type) __attribute__((visibility("default"))) extern __type
+# define PR_IMPORT(__type) extern __type
+# define PR_IMPORT_DATA(__type) extern __type
+# define PR_EXTERN(__type) __attribute__((visibility("default"))) extern __type
+# define PR_IMPLEMENT(__type) __attribute__((visibility("default"))) __type
+# define PR_EXTERN_DATA(__type) __attribute__((visibility("default"))) extern __type
+# define PR_IMPLEMENT_DATA(__type) __attribute__((visibility("default"))) __type
+# define PR_CALLBACK
+# define PR_CALLBACK_DECL
+# define PR_STATIC_CALLBACK(__x) static __x
+# else
+# define PR_EXPORT(__type) extern __type
+# define PR_EXPORT_DATA(__type) extern __type
+# define PR_IMPORT(__type) extern __type
+# define PR_IMPORT_DATA(__type) extern __type
+# define PR_EXTERN(__type) extern __type
+# define PR_IMPLEMENT(__type) __type
+# define PR_EXTERN_DATA(__type) extern __type
+# define PR_IMPLEMENT_DATA(__type) __type
+# define PR_CALLBACK
+# define PR_CALLBACK_DECL
+# define PR_STATIC_CALLBACK(__x) static __x
+# endif
+#endif
+
+#if defined(_NSPR_BUILD_)
+#define NSPR_API(__type) PR_EXPORT(__type)
+#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type)
+#else
+#define NSPR_API(__type) PR_IMPORT(__type)
+#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type)
+#endif
+
+typedef unsigned char PRUint8;
+#if (defined(HPUX) && defined(__cplusplus) \
+ && !defined(__GNUC__) && __cplusplus < 199707L) \
+ || (defined(SCO) && defined(__cplusplus) \
+ && !defined(__GNUC__) && __cplusplus == 1L)
+typedef char PRInt8;
+#else
+typedef signed char PRInt8;
+#endif
+
+#define PR_INT8_MAX 127
+#define PR_INT8_MIN (-128)
+#define PR_UINT8_MAX 255U
+
+typedef unsigned short PRUint16;
+typedef short PRInt16;
+
+#define PR_INT16_MAX 32767
+#define PR_INT16_MIN (-32768)
+#define PR_UINT16_MAX 65535U
+
+typedef unsigned int PRUint32;
+typedef int PRInt32;
+#define PR_INT32(x) x
+#define PR_UINT32(x) x ## U
+
+#define PR_INT32_MAX PR_INT32(2147483647)
+#define PR_INT32_MIN (-PR_INT32_MAX - 1)
+#define PR_UINT32_MAX PR_UINT32(4294967295)
+
+typedef long PRInt64;
+typedef unsigned long PRUint64;
+typedef int PRIntn;
+typedef unsigned int PRUintn;
+
+typedef double PRFloat64;
+typedef size_t PRSize;
+
+typedef ptrdiff_t PRPtrdiff;
+
+typedef unsigned long PRUptrdiff;
+
+typedef PRIntn PRBool;
+
+#define PR_TRUE 1
+#define PR_FALSE 0
+
+typedef PRUint8 PRPackedBool;
+
+/*
+** Status code used by some routines that have a single point of failure or
+** special status return.
+*/
+typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
+
+#ifndef __PRUNICHAR__
+#define __PRUNICHAR__
+#if defined(WIN32) || defined(XP_MAC)
+typedef wchar_t PRUnichar;
+#else
+typedef PRUint16 PRUnichar;
+#endif
+#endif
+
+typedef long PRWord;
+typedef unsigned long PRUword;
+
+#define nsnull 0
+typedef PRUint32 nsresult;
+
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define NS_LIKELY(x) (__builtin_expect((x), 1))
+#define NS_UNLIKELY(x) (__builtin_expect((x), 0))
+#else
+#define NS_LIKELY(x) (x)
+#define NS_UNLIKELY(x) (x)
+#endif
+
+#define NS_FAILED(_nsresult) (NS_UNLIKELY((_nsresult) & 0x80000000))
+#define NS_SUCCEEDED(_nsresult) (NS_LIKELY(!((_nsresult) & 0x80000000)))
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_IntervalNow VBoxNsprPR_IntervalNow
+# define PR_TicksPerSecond VBoxNsprPR_TicksPerSecond
+# define PR_SecondsToInterval VBoxNsprPR_SecondsToInterval
+# define PR_MillisecondsToInterval VBoxNsprPR_MillisecondsToInterval
+# define PR_MicrosecondsToInterval VBoxNsprPR_MicrosecondsToInterval
+# define PR_IntervalToSeconds VBoxNsprPR_IntervalToSeconds
+# define PR_IntervalToMilliseconds VBoxNsprPR_IntervalToMilliseconds
+# define PR_IntervalToMicroseconds VBoxNsprPR_IntervalToMicroseconds
+# define PR_EnterMonitor VBoxNsprPR_EnterMonitor
+# define PR_ExitMonitor VBoxNsprPR_ExitMonitor
+# define PR_Notify VBoxNsprPR_Notify
+# define PR_NotifyAll VBoxNsprPR_NotifyAll
+# define PR_Wait VBoxNsprPR_Wait
+# define PR_NewMonitor VBoxNsprPR_NewMonitor
+# define PR_DestroyMonitor VBoxNsprPR_DestroyMonitor
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef PRUint32 PRIntervalTime;
+
+#define PR_INTERVAL_MIN 1000UL
+#define PR_INTERVAL_MAX 100000UL
+#define PR_INTERVAL_NO_WAIT 0UL
+#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL
+
+NSPR_API(PRIntervalTime) PR_IntervalNow(void);
+NSPR_API(PRUint32) PR_TicksPerSecond(void);
+NSPR_API(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds);
+NSPR_API(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli);
+NSPR_API(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro);
+NSPR_API(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks);
+
+typedef struct PRMonitor PRMonitor;
+
+NSPR_API(PRMonitor*) PR_NewMonitor(void);
+NSPR_API(void) PR_DestroyMonitor(PRMonitor *mon);
+NSPR_API(void) PR_EnterMonitor(PRMonitor *mon);
+NSPR_API(PRStatus) PR_ExitMonitor(PRMonitor *mon);
+NSPR_API(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks);
+NSPR_API(PRStatus) PR_Notify(PRMonitor *mon);
+NSPR_API(PRStatus) PR_NotifyAll(PRMonitor *mon);
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_CreateThread VBoxNsprPR_CreateThread
+# define PR_JoinThread VBoxNsprPR_JoinThread
+# define PR_Sleep VBoxNsprPR_Sleep
+# define PR_GetCurrentThread VBoxNsprPR_GetCurrentThread
+# define PR_GetThreadState VBoxNsprPR_GetThreadState
+# define PR_SetThreadPrivate VBoxNsprPR_SetThreadPrivate
+# define PR_GetThreadPrivate VBoxNsprPR_GetThreadPrivate
+# define PR_NewThreadPrivateIndex VBoxNsprPR_NewThreadPrivateIndex
+# define PR_GetThreadPriority VBoxNsprPR_GetThreadPriority
+# define PR_SetThreadPriority VBoxNsprPR_SetThreadPriority
+# define PR_Interrupt VBoxNsprPR_Interrupt
+# define PR_ClearInterrupt VBoxNsprPR_ClearInterrupt
+# define PR_BlockInterrupt VBoxNsprPR_BlockInterrupt
+# define PR_UnblockInterrupt VBoxNsprPR_UnblockInterrupt
+# define PR_GetThreadScope VBoxNsprPR_GetThreadScope
+# define PR_GetThreadType VBoxNsprPR_GetThreadType
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PRThread PRThread;
+typedef struct PRThreadStack PRThreadStack;
+
+typedef enum PRThreadType {
+ PR_USER_THREAD,
+ PR_SYSTEM_THREAD
+} PRThreadType;
+
+typedef enum PRThreadScope {
+ PR_LOCAL_THREAD,
+ PR_GLOBAL_THREAD,
+ PR_GLOBAL_BOUND_THREAD
+} PRThreadScope;
+
+typedef enum PRThreadState {
+ PR_JOINABLE_THREAD,
+ PR_UNJOINABLE_THREAD
+} PRThreadState;
+
+typedef enum PRThreadPriority
+{
+ PR_PRIORITY_FIRST = 0, /* just a placeholder */
+ PR_PRIORITY_LOW = 0, /* the lowest possible priority */
+ PR_PRIORITY_NORMAL = 1, /* most common expected priority */
+ PR_PRIORITY_HIGH = 2, /* slightly more aggressive scheduling */
+ PR_PRIORITY_URGENT = 3, /* it does little good to have more than one */
+ PR_PRIORITY_LAST = 3 /* this is just a placeholder */
+} PRThreadPriority;
+
+NSPR_API(PRThread*) PR_CreateThread(PRThreadType type,
+ void (PR_CALLBACK *start)(void *arg),
+ void *arg,
+ PRThreadPriority priority,
+ PRThreadScope scope,
+ PRThreadState state,
+ PRUint32 stackSize);
+NSPR_API(PRStatus) PR_JoinThread(PRThread *thread);
+NSPR_API(PRThread*) PR_GetCurrentThread(void);
+#ifndef NO_NSPR_10_SUPPORT
+#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */
+#endif /* NO_NSPR_10_SUPPORT */
+NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
+NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
+
+typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
+
+NSPR_API(PRStatus) PR_NewThreadPrivateIndex(
+ PRUintn *newIndex, PRThreadPrivateDTOR destructor);
+NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv);
+NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex);
+NSPR_API(PRStatus) PR_Interrupt(PRThread *thread);
+NSPR_API(void) PR_ClearInterrupt(void);
+NSPR_API(void) PR_BlockInterrupt(void);
+NSPR_API(void) PR_UnblockInterrupt(void);
+NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks);
+NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread);
+NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread);
+NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread);
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_DestroyLock VBoxNsprPR_DestroyLock
+# define PR_Lock VBoxNsprPR_Lock
+# define PR_NewLock VBoxNsprPR_NewLock
+# define PR_Unlock VBoxNsprPR_Unlock
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PRLock PRLock;
+
+NSPR_API(PRLock*) PR_NewLock(void);
+NSPR_API(void) PR_DestroyLock(PRLock *lock);
+NSPR_API(void) PR_Lock(PRLock *lock);
+NSPR_API(PRStatus) PR_Unlock(PRLock *lock);
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PR_NewCondVar VBoxNsprPR_NewCondVar
+# define PR_DestroyCondVar VBoxNsprPR_DestroyCondVar
+# define PR_WaitCondVar VBoxNsprPR_WaitCondVar
+# define PR_NotifyCondVar VBoxNsprPR_NotifyCondVar
+# define PR_NotifyAllCondVar VBoxNsprPR_NotifyAllCondVar
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PRCondVar PRCondVar;
+
+NSPR_API(PRCondVar*) PR_NewCondVar(PRLock *lock);
+NSPR_API(void) PR_DestroyCondVar(PRCondVar *cvar);
+NSPR_API(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout);
+NSPR_API(PRStatus) PR_NotifyCondVar(PRCondVar *cvar);
+NSPR_API(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar);
+
+typedef struct PRCListStr PRCList;
+
+struct PRCListStr {
+ PRCList *next;
+ PRCList *prev;
+};
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+# define PL_DestroyEvent VBoxNsplPL_DestroyEvent
+# define PL_HandleEvent VBoxNsplPL_HandleEvent
+# define PL_InitEvent VBoxNsplPL_InitEvent
+# define PL_CreateEventQueue VBoxNsplPL_CreateEventQueue
+# define PL_CreateMonitoredEventQueue VBoxNsplPL_CreateMonitoredEventQueue
+# define PL_CreateNativeEventQueue VBoxNsplPL_CreateNativeEventQueue
+# define PL_DequeueEvent VBoxNsplPL_DequeueEvent
+# define PL_DestroyEventQueue VBoxNsplPL_DestroyEventQueue
+# define PL_EventAvailable VBoxNsplPL_EventAvailable
+# define PL_EventLoop VBoxNsplPL_EventLoop
+# define PL_GetEvent VBoxNsplPL_GetEvent
+# define PL_GetEventOwner VBoxNsplPL_GetEventOwner
+# define PL_GetEventQueueMonitor VBoxNsplPL_GetEventQueueMonitor
+# define PL_GetEventQueueSelectFD VBoxNsplPL_GetEventQueueSelectFD
+# define PL_MapEvents VBoxNsplPL_MapEvents
+# define PL_PostEvent VBoxNsplPL_PostEvent
+# define PL_PostSynchronousEvent VBoxNsplPL_PostSynchronousEvent
+# define PL_ProcessEventsBeforeID VBoxNsplPL_ProcessEventsBeforeID
+# define PL_ProcessPendingEvents VBoxNsplPL_ProcessPendingEvents
+# define PL_RegisterEventIDFunc VBoxNsplPL_RegisterEventIDFunc
+# define PL_RevokeEvents VBoxNsplPL_RevokeEvents
+# define PL_UnregisterEventIDFunc VBoxNsplPL_UnregisterEventIDFunc
+# define PL_WaitForEvent VBoxNsplPL_WaitForEvent
+# define PL_IsQueueNative VBoxNsplPL_IsQueueNative
+# define PL_IsQueueOnCurrentThread VBoxNsplPL_IsQueueOnCurrentThread
+# define PL_FavorPerformanceHint VBoxNsplPL_FavorPerformanceHint
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+typedef struct PLEvent PLEvent;
+typedef struct PLEventQueue PLEventQueue;
+
+PR_EXTERN(PLEventQueue*)
+PL_CreateEventQueue(const char* name, PRThread* handlerThread);
+PR_EXTERN(PLEventQueue *)
+ PL_CreateNativeEventQueue(
+ const char *name,
+ PRThread *handlerThread
+ );
+PR_EXTERN(PLEventQueue *)
+ PL_CreateMonitoredEventQueue(
+ const char *name,
+ PRThread *handlerThread
+ );
+PR_EXTERN(void)
+PL_DestroyEventQueue(PLEventQueue* self);
+PR_EXTERN(PRMonitor*)
+PL_GetEventQueueMonitor(PLEventQueue* self);
+
+#define PL_ENTER_EVENT_QUEUE_MONITOR(queue) \
+ PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
+
+#define PL_EXIT_EVENT_QUEUE_MONITOR(queue) \
+ PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
+
+PR_EXTERN(PRStatus) PL_PostEvent(PLEventQueue* self, PLEvent* event);
+PR_EXTERN(void*) PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event);
+PR_EXTERN(PLEvent*) PL_GetEvent(PLEventQueue* self);
+PR_EXTERN(PRBool) PL_EventAvailable(PLEventQueue* self);
+
+typedef void (PR_CALLBACK *PLEventFunProc)(PLEvent* event, void* data, PLEventQueue* queue);
+
+PR_EXTERN(void) PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data);
+PR_EXTERN(void) PL_RevokeEvents(PLEventQueue* self, void* owner);
+PR_EXTERN(void) PL_ProcessPendingEvents(PLEventQueue* self);
+PR_EXTERN(PLEvent*) PL_WaitForEvent(PLEventQueue* self);
+PR_EXTERN(void) PL_EventLoop(PLEventQueue* self);
+PR_EXTERN(PRInt32) PL_GetEventQueueSelectFD(PLEventQueue* self);
+PR_EXTERN(PRBool) PL_IsQueueOnCurrentThread( PLEventQueue *queue );
+PR_EXTERN(PRBool) PL_IsQueueNative(PLEventQueue *queue);
+
+typedef void* (PR_CALLBACK *PLHandleEventProc)(PLEvent* self);
+typedef void (PR_CALLBACK *PLDestroyEventProc)(PLEvent* self);
+PR_EXTERN(void)
+PL_InitEvent(PLEvent* self, void* owner,
+ PLHandleEventProc handler,
+ PLDestroyEventProc destructor);
+PR_EXTERN(void*) PL_GetEventOwner(PLEvent* self);
+PR_EXTERN(void) PL_HandleEvent(PLEvent* self);
+PR_EXTERN(void) PL_DestroyEvent(PLEvent* self);
+PR_EXTERN(void) PL_DequeueEvent(PLEvent* self, PLEventQueue* queue);
+PR_EXTERN(void) PL_FavorPerformanceHint(PRBool favorPerformanceOverEventStarvation, PRUint32 starvationDelay);
+
+struct PLEvent {
+ PRCList link;
+ PLHandleEventProc handler;
+ PLDestroyEventProc destructor;
+ void* owner;
+ void* synchronousResult;
+ PRLock* lock;
+ PRCondVar* condVar;
+ PRBool handled;
+#ifdef PL_POST_TIMINGS
+ PRIntervalTime postTime;
+#endif
+#ifdef XP_UNIX
+ unsigned long id;
+#endif /* XP_UNIX */
+ /* other fields follow... */
+};
+
+#if defined(XP_WIN) || defined(XP_OS2)
+
+PR_EXTERN(HWND)
+ PL_GetNativeEventReceiverWindow(
+ PLEventQueue *eqp
+ );
+#endif /* XP_WIN || XP_OS2 */
+
+#ifdef XP_UNIX
+
+PR_EXTERN(PRInt32)
+PL_ProcessEventsBeforeID(PLEventQueue *aSelf, unsigned long aID);
+
+typedef unsigned long (PR_CALLBACK *PLGetEventIDFunc)(void *aClosure);
+
+PR_EXTERN(void)
+PL_RegisterEventIDFunc(PLEventQueue *aSelf, PLGetEventIDFunc aFunc,
+ void *aClosure);
+PR_EXTERN(void) PL_UnregisterEventIDFunc(PLEventQueue *aSelf);
+
+#endif /* XP_UNIX */
+
+/* Standard "it worked" return value */
+#define NS_OK 0
+
+#define NS_ERROR_BASE ((nsresult) 0xC1F30000)
+
+/* Returned when an instance is not initialized */
+#define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
+
+/* Returned when an instance is already initialized */
+#define NS_ERROR_ALREADY_INITIALIZED (NS_ERROR_BASE + 2)
+
+/* Returned by a not implemented function */
+#define NS_ERROR_NOT_IMPLEMENTED ((nsresult) 0x80004001L)
+
+/* Returned when a given interface is not supported. */
+#define NS_NOINTERFACE ((nsresult) 0x80004002L)
+#define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
+
+#define NS_ERROR_INVALID_POINTER ((nsresult) 0x80004003L)
+#define NS_ERROR_NULL_POINTER NS_ERROR_INVALID_POINTER
+
+/* Returned when a function aborts */
+#define NS_ERROR_ABORT ((nsresult) 0x80004004L)
+
+/* Returned when a function fails */
+#define NS_ERROR_FAILURE ((nsresult) 0x80004005L)
+
+/* Returned when an unexpected error occurs */
+#define NS_ERROR_UNEXPECTED ((nsresult) 0x8000ffffL)
+
+/* Returned when a memory allocation fails */
+#define NS_ERROR_OUT_OF_MEMORY ((nsresult) 0x8007000eL)
+
+/* Returned when an illegal value is passed */
+#define NS_ERROR_ILLEGAL_VALUE ((nsresult) 0x80070057L)
+#define NS_ERROR_INVALID_ARG NS_ERROR_ILLEGAL_VALUE
+
+/* Returned when a class doesn't allow aggregation */
+#define NS_ERROR_NO_AGGREGATION ((nsresult) 0x80040110L)
+
+/* Returned when an operation can't complete due to an unavailable resource */
+#define NS_ERROR_NOT_AVAILABLE ((nsresult) 0x80040111L)
+
+/* Returned when a class is not registered */
+#define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L)
+
+/* Returned when a class cannot be registered, but may be tried again later */
+#define NS_ERROR_FACTORY_REGISTER_AGAIN ((nsresult) 0x80040155L)
+
+/* Returned when a dynamically loaded factory couldn't be found */
+#define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L)
+
+/* Returned when a factory doesn't support signatures */
+#define NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT \
+ (NS_ERROR_BASE + 0x101)
+
+/* Returned when a factory already is registered */
+#define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
+
+
+/**
+ * An "interface id" which can be used to uniquely identify a given
+ * interface.
+ * A "unique identifier". This is modeled after OSF DCE UUIDs.
+ */
+
+struct nsID {
+ PRUint32 m0;
+ PRUint16 m1;
+ PRUint16 m2;
+ PRUint8 m3[8];
+};
+
+typedef struct nsID nsID;
+typedef nsID nsIID;
+
+struct nsISupports; /* forward declaration */
+struct nsIStackFrame; /* forward declaration */
+struct nsIException; /* forward declaration */
+typedef struct nsISupports nsISupports; /* forward declaration */
+typedef struct nsIStackFrame nsIStackFrame; /* forward declaration */
+typedef struct nsIException nsIException; /* forward declaration */
+
+/**
+ * IID for the nsISupports interface
+ * {00000000-0000-0000-c000-000000000046}
+ *
+ * To maintain binary compatibility with COM's IUnknown, we define the IID
+ * of nsISupports to be the same as that of COM's IUnknown.
+ */
+#define NS_ISUPPORTS_IID \
+ { 0x00000000, 0x0000, 0x0000, \
+ {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
+
+/**
+ * Reference count values
+ *
+ * This is the return type for AddRef() and Release() in nsISupports.
+ * IUnknown of COM returns an unsigned long from equivalent functions.
+ * The following ifdef exists to maintain binary compatibility with
+ * IUnknown.
+ */
+
+/**
+ * Basic component object model interface. Objects which implement
+ * this interface support runtime interface discovery (QueryInterface)
+ * and a reference counted memory model (AddRef/Release). This is
+ * modelled after the win32 IUnknown API.
+ */
+struct nsISupports_vtbl {
+
+ /**
+ * @name Methods
+ */
+
+ /**
+ * A run time mechanism for interface discovery.
+ * @param aIID [in] A requested interface IID
+ * @param aInstancePtr [out] A pointer to an interface pointer to
+ * receive the result.
+ * @return NS_OK if the interface is supported by the associated
+ * instance, NS_NOINTERFACE if it is not.
+ * NS_ERROR_INVALID_POINTER if aInstancePtr is NULL.
+ */
+ nsresult (*QueryInterface)(nsISupports *pThis, const nsID *iid, void **resultp);
+ /**
+ * Increases the reference count for this interface.
+ * The associated instance will not be deleted unless
+ * the reference count is returned to zero.
+ *
+ * @return The resulting reference count.
+ */
+ nsresult (*AddRef)(nsISupports *pThis);
+
+ /**
+ * Decreases the reference count for this interface.
+ * Generally, if the reference count returns to zero,
+ * the associated instance is deleted.
+ *
+ * @return The resulting reference count.
+ */
+ nsresult (*Release)(nsISupports *pThis);
+
+};
+
+struct nsISupports {
+ struct nsISupports_vtbl *vtbl;
+};
+
+/* starting interface: nsIException */
+#define NS_IEXCEPTION_IID_STR "f3a8d3b4-c424-4edc-8bf6-8974c983ba78"
+
+#define NS_IEXCEPTION_IID \
+ {0xf3a8d3b4, 0xc424, 0x4edc, \
+ { 0x8b, 0xf6, 0x89, 0x74, 0xc9, 0x83, 0xba, 0x78 }}
+
+struct nsIException_vtbl {
+
+ /* Methods from the Class nsISupports */
+ struct nsISupports_vtbl nsisupports;
+
+ /* readonly attribute string message; */
+ nsresult (*GetMessage)(nsIException *pThis, PRUnichar * *aMessage);
+
+ /* readonly attribute nsresult (*result; */
+ nsresult (*GetResult)(nsIException *pThis, nsresult *aResult);
+
+ /* readonly attribute string name; */
+ nsresult (*GetName)(nsIException *pThis, PRUnichar * *aName);
+
+ /* readonly attribute string filename; */
+ nsresult (*GetFilename)(nsIException *pThis, PRUnichar * *aFilename);
+
+ /* readonly attribute PRUint32 lineNumber; */
+ nsresult (*GetLineNumber)(nsIException *pThis, PRUint32 *aLineNumber);
+
+ /* readonly attribute PRUint32 columnNumber; */
+ nsresult (*GetColumnNumber)(nsIException *pThis, PRUint32 *aColumnNumber);
+
+ /* readonly attribute nsIStackFrame location; */
+ nsresult (*GetLocation)(nsIException *pThis, nsIStackFrame * *aLocation);
+
+ /* readonly attribute nsIException inner; */
+ nsresult (*GetInner)(nsIException *pThis, nsIException * *aInner);
+
+ /* readonly attribute nsISupports data; */
+ nsresult (*GetData)(nsIException *pThis, nsISupports * *aData);
+
+ /* string toString (); */
+ nsresult (*ToString)(nsIException *pThis, PRUnichar **_retval);
+};
+
+struct nsIException {
+ struct nsIException_vtbl *vtbl;
+};
+
+/* starting interface: nsIStackFrame */
+#define NS_ISTACKFRAME_IID_STR "91d82105-7c62-4f8b-9779-154277c0ee90"
+
+#define NS_ISTACKFRAME_IID \
+ {0x91d82105, 0x7c62, 0x4f8b, \
+ { 0x97, 0x79, 0x15, 0x42, 0x77, 0xc0, 0xee, 0x90 }}
+
+struct nsIStackFrame_vtbl {
+
+ /* Methods from the Class nsISupports */
+ struct nsISupports_vtbl nsisupports;
+
+ /* readonly attribute PRUint32 language; */
+ nsresult (*GetLanguage)(nsIStackFrame *pThis, PRUint32 *aLanguage);
+
+ /* readonly attribute string languageName; */
+ nsresult (*GetLanguageName)(nsIStackFrame *pThis, PRUnichar * *aLanguageName);
+
+ /* readonly attribute string filename; */
+ nsresult (*GetFilename)(nsIStackFrame *pThis, PRUnichar * *aFilename);
+
+ /* readonly attribute string name; */
+ nsresult (*GetName)(nsIStackFrame *pThis, PRUnichar * *aName);
+
+ /* readonly attribute PRInt32 lineNumber; */
+ nsresult (*GetLineNumber)(nsIStackFrame *pThis, PRInt32 *aLineNumber);
+
+ /* readonly attribute string sourceLine; */
+ nsresult (*GetSourceLine)(nsIStackFrame *pThis, PRUnichar * *aSourceLine);
+
+ /* readonly attribute nsIStackFrame caller; */
+ nsresult (*GetCaller)(nsIStackFrame *pThis, nsIStackFrame * *aCaller);
+
+ /* string toString (); */
+ nsresult (*ToString)(nsIStackFrame *pThis, PRUnichar **_retval);
+};
+
+struct nsIStackFrame {
+ struct nsIStackFrame_vtbl *vtbl;
+};
+
+/* starting interface: nsIEventTarget */
+#define NS_IEVENTTARGET_IID_STR "ea99ad5b-cc67-4efb-97c9-2ef620a59f2a"
+
+#define NS_IEVENTTARGET_IID \
+ {0xea99ad5b, 0xcc67, 0x4efb, \
+ { 0x97, 0xc9, 0x2e, 0xf6, 0x20, 0xa5, 0x9f, 0x2a }}
+
+struct nsIEventTarget;
+typedef struct nsIEventTarget nsIEventTarget;
+
+struct nsIEventTarget_vtbl {
+
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*PostEvent)(nsIEventTarget *pThis, PLEvent * aEvent);
+
+ nsresult (*IsOnCurrentThread)(nsIEventTarget *pThis, PRBool *_retval);
+
+};
+
+struct nsIEventTarget {
+ struct nsIEventTarget_vtbl *vtbl;
+};
+
+/* starting interface: nsIEventQueue */
+#define NS_IEVENTQUEUE_IID_STR "176afb41-00a4-11d3-9f2a-00400553eef0"
+
+#define NS_IEVENTQUEUE_IID \
+ {0x176afb41, 0x00a4, 0x11d3, \
+ { 0x9f, 0x2a, 0x00, 0x40, 0x05, 0x53, 0xee, 0xf0 }}
+
+struct nsIEventQueue;
+typedef struct nsIEventQueue nsIEventQueue;
+
+struct nsIEventQueue_vtbl {
+
+ struct nsIEventTarget_vtbl nsieventtarget;
+
+ nsresult (*InitEvent)(nsIEventQueue *pThis, PLEvent * aEvent, void * owner, PLHandleEventProc handler, PLDestroyEventProc destructor);
+
+ nsresult (*PostSynchronousEvent)(nsIEventQueue *pThis, PLEvent * aEvent, void * *aResult);
+
+ nsresult (*PendingEvents)(nsIEventQueue *pThis, PRBool *_retval);
+
+ nsresult (*ProcessPendingEvents)(nsIEventQueue *pThis);
+
+ nsresult (*EventLoop)(nsIEventQueue *pThis);
+
+ nsresult (*EventAvailable)(nsIEventQueue *pThis, PRBool *aResult);
+
+ nsresult (*GetEvent)(nsIEventQueue *pThis, PLEvent * *_retval);
+
+ nsresult (*HandleEvent)(nsIEventQueue *pThis, PLEvent * aEvent);
+
+ nsresult (*WaitForEvent)(nsIEventQueue *pThis, PLEvent * *_retval);
+
+ PRInt32 (*GetEventQueueSelectFD)(nsIEventQueue *pThis);
+
+ nsresult (*Init)(nsIEventQueue *pThis, PRBool aNative);
+
+ nsresult (*InitFromPRThread)(nsIEventQueue *pThis, PRThread * thread, PRBool aNative);
+
+ nsresult (*InitFromPLQueue)(nsIEventQueue *pThis, PLEventQueue * aQueue);
+
+ nsresult (*EnterMonitor)(nsIEventQueue *pThis);
+
+ nsresult (*ExitMonitor)(nsIEventQueue *pThis);
+
+ nsresult (*RevokeEvents)(nsIEventQueue *pThis, void * owner);
+
+ nsresult (*GetPLEventQueue)(nsIEventQueue *pThis, PLEventQueue * *_retval);
+
+ nsresult (*IsQueueNative)(nsIEventQueue *pThis, PRBool *_retval);
+
+ nsresult (*StopAcceptingEvents)(nsIEventQueue *pThis);
+
+};
+
+struct nsIEventQueue {
+ struct nsIEventQueue_vtbl *vtbl;
+};
+
+
+#define VBOX_E_OBJECT_NOT_FOUND 0x80BB0001
+#define VBOX_E_INVALID_VM_STATE 0x80BB0002
+#define VBOX_E_VM_ERROR 0x80BB0003
+#define VBOX_E_FILE_ERROR 0x80BB0004
+#define VBOX_E_IPRT_ERROR 0x80BB0005
+#define VBOX_E_PDM_ERROR 0x80BB0006
+#define VBOX_E_INVALID_OBJECT_STATE 0x80BB0007
+#define VBOX_E_HOST_ERROR 0x80BB0008
+#define VBOX_E_NOT_SUPPORTED 0x80BB0009
+#define VBOX_E_XML_ERROR 0x80BB000A
+#define VBOX_E_INVALID_SESSION_STATE 0x80BB000B
+#define VBOX_E_OBJECT_IN_USE 0x80BB000C
+
+
+struct IVirtualBoxErrorInfo;
+struct IDHCPServer;
+struct IVirtualBox;
+struct IVFSExplorer;
+struct IAppliance;
+struct IVirtualSystemDescription;
+struct IInternalMachineControl;
+struct IBIOSSettings;
+struct IEventContext;
+struct IPciAddress;
+struct IPciDeviceAttachment;
+struct IMachine;
+struct IVRDEServerInfo;
+struct IConsole;
+struct IHostNetworkInterface;
+struct IHost;
+struct ISystemProperties;
+struct IGuestOSType;
+struct IGuest;
+struct IProgress;
+struct ISnapshot;
+struct IMediumAttachment;
+struct IMedium;
+struct IMediumFormat;
+struct IKeyboard;
+struct IMouse;
+struct IFramebuffer;
+struct IFramebufferOverlay;
+struct IDisplay;
+struct INetworkAdapter;
+struct ISerialPort;
+struct IParallelPort;
+struct IMachineDebugger;
+struct IUSBController;
+struct IUSBDevice;
+struct IUSBDeviceFilter;
+struct IHostUSBDevice;
+struct IHostUSBDeviceFilter;
+struct IAudioAdapter;
+struct IVRDEServer;
+struct ISharedFolder;
+struct IInternalSessionControl;
+struct ISession;
+struct IStorageController;
+struct IManagedObjectRef;
+struct IWebsessionManager;
+struct IPerformanceMetric;
+struct IPerformanceCollector;
+struct INATEngine;
+struct IExtPackPlugIn;
+struct IExtPackBase;
+struct IExtPack;
+struct IExtPackFile;
+struct IExtPackManager;
+struct IBandwidthGroup;
+struct IBandwidthControl;
+struct IVirtualBoxClient;
+struct IEventSource;
+struct IEventListener;
+struct IEvent;
+struct IReusableEvent;
+struct IMachineEvent;
+struct IMachineStateChangedEvent;
+struct IMachineDataChangedEvent;
+struct IMediumRegisteredEvent;
+struct IMachineRegisteredEvent;
+struct ISessionStateChangedEvent;
+struct IGuestPropertyChangedEvent;
+struct ISnapshotEvent;
+struct ISnapshotTakenEvent;
+struct ISnapshotDeletedEvent;
+struct ISnapshotChangedEvent;
+struct IMousePointerShapeChangedEvent;
+struct IMouseCapabilityChangedEvent;
+struct IKeyboardLedsChangedEvent;
+struct IStateChangedEvent;
+struct IAdditionsStateChangedEvent;
+struct INetworkAdapterChangedEvent;
+struct ISerialPortChangedEvent;
+struct IParallelPortChangedEvent;
+struct IStorageControllerChangedEvent;
+struct IMediumChangedEvent;
+struct ICPUChangedEvent;
+struct ICPUExecutionCapChangedEvent;
+struct IGuestKeyboardEvent;
+struct IGuestMouseEvent;
+struct IVRDEServerChangedEvent;
+struct IVRDEServerInfoChangedEvent;
+struct IUSBControllerChangedEvent;
+struct IUSBDeviceStateChangedEvent;
+struct ISharedFolderChangedEvent;
+struct IRuntimeErrorEvent;
+struct IEventSourceChangedEvent;
+struct IExtraDataChangedEvent;
+struct IVetoEvent;
+struct IExtraDataCanChangeEvent;
+struct ICanShowWindowEvent;
+struct IShowWindowEvent;
+struct INATRedirectEvent;
+struct IHostPciDevicePlugEvent;
+struct IVBoxSVCAvailabilityChangedEvent;
+struct IBandwidthGroupChangedEvent;
+struct IGuestMonitorChangedEvent;
+
+typedef struct IVirtualBoxErrorInfo IVirtualBoxErrorInfo;
+typedef struct IDHCPServer IDHCPServer;
+typedef struct IVirtualBox IVirtualBox;
+typedef struct IVFSExplorer IVFSExplorer;
+typedef struct IAppliance IAppliance;
+typedef struct IVirtualSystemDescription IVirtualSystemDescription;
+typedef struct IInternalMachineControl IInternalMachineControl;
+typedef struct IBIOSSettings IBIOSSettings;
+typedef struct IEventContext IEventContext;
+typedef struct IPciAddress IPciAddress;
+typedef struct IPciDeviceAttachment IPciDeviceAttachment;
+typedef struct IMachine IMachine;
+typedef struct IVRDEServerInfo IVRDEServerInfo;
+typedef struct IConsole IConsole;
+typedef struct IHostNetworkInterface IHostNetworkInterface;
+typedef struct IHost IHost;
+typedef struct ISystemProperties ISystemProperties;
+typedef struct IGuestOSType IGuestOSType;
+typedef struct IGuest IGuest;
+typedef struct IProgress IProgress;
+typedef struct ISnapshot ISnapshot;
+typedef struct IMediumAttachment IMediumAttachment;
+typedef struct IMedium IMedium;
+typedef struct IMediumFormat IMediumFormat;
+typedef struct IKeyboard IKeyboard;
+typedef struct IMouse IMouse;
+typedef struct IFramebuffer IFramebuffer;
+typedef struct IFramebufferOverlay IFramebufferOverlay;
+typedef struct IDisplay IDisplay;
+typedef struct INetworkAdapter INetworkAdapter;
+typedef struct ISerialPort ISerialPort;
+typedef struct IParallelPort IParallelPort;
+typedef struct IMachineDebugger IMachineDebugger;
+typedef struct IUSBController IUSBController;
+typedef struct IUSBDevice IUSBDevice;
+typedef struct IUSBDeviceFilter IUSBDeviceFilter;
+typedef struct IHostUSBDevice IHostUSBDevice;
+typedef struct IHostUSBDeviceFilter IHostUSBDeviceFilter;
+typedef struct IAudioAdapter IAudioAdapter;
+typedef struct IVRDEServer IVRDEServer;
+typedef struct ISharedFolder ISharedFolder;
+typedef struct IInternalSessionControl IInternalSessionControl;
+typedef struct ISession ISession;
+typedef struct IStorageController IStorageController;
+typedef struct IManagedObjectRef IManagedObjectRef;
+typedef struct IWebsessionManager IWebsessionManager;
+typedef struct IPerformanceMetric IPerformanceMetric;
+typedef struct IPerformanceCollector IPerformanceCollector;
+typedef struct INATEngine INATEngine;
+typedef struct IExtPackPlugIn IExtPackPlugIn;
+typedef struct IExtPackBase IExtPackBase;
+typedef struct IExtPack IExtPack;
+typedef struct IExtPackFile IExtPackFile;
+typedef struct IExtPackManager IExtPackManager;
+typedef struct IBandwidthGroup IBandwidthGroup;
+typedef struct IBandwidthControl IBandwidthControl;
+typedef struct IVirtualBoxClient IVirtualBoxClient;
+typedef struct IEventSource IEventSource;
+typedef struct IEventListener IEventListener;
+typedef struct IEvent IEvent;
+typedef struct IReusableEvent IReusableEvent;
+typedef struct IMachineEvent IMachineEvent;
+typedef struct IMachineStateChangedEvent IMachineStateChangedEvent;
+typedef struct IMachineDataChangedEvent IMachineDataChangedEvent;
+typedef struct IMediumRegisteredEvent IMediumRegisteredEvent;
+typedef struct IMachineRegisteredEvent IMachineRegisteredEvent;
+typedef struct ISessionStateChangedEvent ISessionStateChangedEvent;
+typedef struct IGuestPropertyChangedEvent IGuestPropertyChangedEvent;
+typedef struct ISnapshotEvent ISnapshotEvent;
+typedef struct ISnapshotTakenEvent ISnapshotTakenEvent;
+typedef struct ISnapshotDeletedEvent ISnapshotDeletedEvent;
+typedef struct ISnapshotChangedEvent ISnapshotChangedEvent;
+typedef struct IMousePointerShapeChangedEvent IMousePointerShapeChangedEvent;
+typedef struct IMouseCapabilityChangedEvent IMouseCapabilityChangedEvent;
+typedef struct IKeyboardLedsChangedEvent IKeyboardLedsChangedEvent;
+typedef struct IStateChangedEvent IStateChangedEvent;
+typedef struct IAdditionsStateChangedEvent IAdditionsStateChangedEvent;
+typedef struct INetworkAdapterChangedEvent INetworkAdapterChangedEvent;
+typedef struct ISerialPortChangedEvent ISerialPortChangedEvent;
+typedef struct IParallelPortChangedEvent IParallelPortChangedEvent;
+typedef struct IStorageControllerChangedEvent IStorageControllerChangedEvent;
+typedef struct IMediumChangedEvent IMediumChangedEvent;
+typedef struct ICPUChangedEvent ICPUChangedEvent;
+typedef struct ICPUExecutionCapChangedEvent ICPUExecutionCapChangedEvent;
+typedef struct IGuestKeyboardEvent IGuestKeyboardEvent;
+typedef struct IGuestMouseEvent IGuestMouseEvent;
+typedef struct IVRDEServerChangedEvent IVRDEServerChangedEvent;
+typedef struct IVRDEServerInfoChangedEvent IVRDEServerInfoChangedEvent;
+typedef struct IUSBControllerChangedEvent IUSBControllerChangedEvent;
+typedef struct IUSBDeviceStateChangedEvent IUSBDeviceStateChangedEvent;
+typedef struct ISharedFolderChangedEvent ISharedFolderChangedEvent;
+typedef struct IRuntimeErrorEvent IRuntimeErrorEvent;
+typedef struct IEventSourceChangedEvent IEventSourceChangedEvent;
+typedef struct IExtraDataChangedEvent IExtraDataChangedEvent;
+typedef struct IVetoEvent IVetoEvent;
+typedef struct IExtraDataCanChangeEvent IExtraDataCanChangeEvent;
+typedef struct ICanShowWindowEvent ICanShowWindowEvent;
+typedef struct IShowWindowEvent IShowWindowEvent;
+typedef struct INATRedirectEvent INATRedirectEvent;
+typedef struct IHostPciDevicePlugEvent IHostPciDevicePlugEvent;
+typedef struct IVBoxSVCAvailabilityChangedEvent IVBoxSVCAvailabilityChangedEvent;
+typedef struct IBandwidthGroupChangedEvent IBandwidthGroupChangedEvent;
+typedef struct IGuestMonitorChangedEvent IGuestMonitorChangedEvent;
+
+/* Start of enum SettingsVersion Declaration */
+#define SETTINGSVERSION_IID_STR "52bd6f5f-1adb-4493-975d-581a9c4b803f"
+#define SETTINGSVERSION_IID { \
+ 0x52bd6f5f, 0x1adb, 0x4493, \
+ { 0x97, 0x5d, 0x58, 0x1a, 0x9c, 0x4b, 0x80, 0x3f } \
+}
+enum SettingsVersion
+{
+ SettingsVersion_Null = 0,
+ SettingsVersion_v1_0 = 1,
+ SettingsVersion_v1_1 = 2,
+ SettingsVersion_v1_2 = 3,
+ SettingsVersion_v1_3pre = 4,
+ SettingsVersion_v1_3 = 5,
+ SettingsVersion_v1_4 = 6,
+ SettingsVersion_v1_5 = 7,
+ SettingsVersion_v1_6 = 8,
+ SettingsVersion_v1_7 = 9,
+ SettingsVersion_v1_8 = 10,
+ SettingsVersion_v1_9 = 11,
+ SettingsVersion_v1_10 = 12,
+ SettingsVersion_v1_11 = 13,
+ SettingsVersion_Future = 99999
+};
+/* End of enum SettingsVersion Declaration */
+
+
+/* Start of enum AccessMode Declaration */
+#define ACCESSMODE_IID_STR "1da0007c-ddf7-4be8-bcac-d84a1558785f"
+#define ACCESSMODE_IID { \
+ 0x1da0007c, 0xddf7, 0x4be8, \
+ { 0xbc, 0xac, 0xd8, 0x4a, 0x15, 0x58, 0x78, 0x5f } \
+}
+enum AccessMode
+{
+ AccessMode_ReadOnly = 1,
+ AccessMode_ReadWrite = 2
+};
+/* End of enum AccessMode Declaration */
+
+
+/* Start of enum MachineState Declaration */
+#define MACHINESTATE_IID_STR "ec6c6a9e-113d-4ff4-b44f-0b69f21c97fe"
+#define MACHINESTATE_IID { \
+ 0xec6c6a9e, 0x113d, 0x4ff4, \
+ { 0xb4, 0x4f, 0x0b, 0x69, 0xf2, 0x1c, 0x97, 0xfe } \
+}
+enum MachineState
+{
+ MachineState_Null = 0,
+ MachineState_PoweredOff = 1,
+ MachineState_Saved = 2,
+ MachineState_Teleported = 3,
+ MachineState_Aborted = 4,
+ MachineState_Running = 5,
+ MachineState_Paused = 6,
+ MachineState_Stuck = 7,
+ MachineState_Teleporting = 8,
+ MachineState_LiveSnapshotting = 9,
+ MachineState_Starting = 10,
+ MachineState_Stopping = 11,
+ MachineState_Saving = 12,
+ MachineState_Restoring = 13,
+ MachineState_TeleportingPausedVM = 14,
+ MachineState_TeleportingIn = 15,
+ MachineState_FaultTolerantSyncing = 16,
+ MachineState_DeletingSnapshotOnline = 17,
+ MachineState_DeletingSnapshotPaused = 18,
+ MachineState_RestoringSnapshot = 19,
+ MachineState_DeletingSnapshot = 20,
+ MachineState_SettingUp = 21,
+ MachineState_FirstOnline = 5,
+ MachineState_LastOnline = 18,
+ MachineState_FirstTransient = 8,
+ MachineState_LastTransient = 21
+};
+/* End of enum MachineState Declaration */
+
+
+/* Start of enum SessionState Declaration */
+#define SESSIONSTATE_IID_STR "cf2700c0-ea4b-47ae-9725-7810114b94d8"
+#define SESSIONSTATE_IID { \
+ 0xcf2700c0, 0xea4b, 0x47ae, \
+ { 0x97, 0x25, 0x78, 0x10, 0x11, 0x4b, 0x94, 0xd8 } \
+}
+enum SessionState
+{
+ SessionState_Null = 0,
+ SessionState_Unlocked = 1,
+ SessionState_Locked = 2,
+ SessionState_Spawning = 3,
+ SessionState_Unlocking = 4
+};
+/* End of enum SessionState Declaration */
+
+
+/* Start of enum CPUPropertyType Declaration */
+#define CPUPROPERTYTYPE_IID_STR "24d356a6-2f45-4abd-b977-1cbe9c4701f5"
+#define CPUPROPERTYTYPE_IID { \
+ 0x24d356a6, 0x2f45, 0x4abd, \
+ { 0xb9, 0x77, 0x1c, 0xbe, 0x9c, 0x47, 0x01, 0xf5 } \
+}
+enum CPUPropertyType
+{
+ CPUPropertyType_Null = 0,
+ CPUPropertyType_PAE = 1,
+ CPUPropertyType_Synthetic = 2
+};
+/* End of enum CPUPropertyType Declaration */
+
+
+/* Start of enum HWVirtExPropertyType Declaration */
+#define HWVIRTEXPROPERTYTYPE_IID_STR "ce81dfdd-d2b8-4a90-bbea-40ee8b7ffcee"
+#define HWVIRTEXPROPERTYTYPE_IID { \
+ 0xce81dfdd, 0xd2b8, 0x4a90, \
+ { 0xbb, 0xea, 0x40, 0xee, 0x8b, 0x7f, 0xfc, 0xee } \
+}
+enum HWVirtExPropertyType
+{
+ HWVirtExPropertyType_Null = 0,
+ HWVirtExPropertyType_Enabled = 1,
+ HWVirtExPropertyType_Exclusive = 2,
+ HWVirtExPropertyType_VPID = 3,
+ HWVirtExPropertyType_NestedPaging = 4,
+ HWVirtExPropertyType_LargePages = 5,
+ HWVirtExPropertyType_Force = 6
+};
+/* End of enum HWVirtExPropertyType Declaration */
+
+
+/* Start of enum FaultToleranceState Declaration */
+#define FAULTTOLERANCESTATE_IID_STR "5124f7ec-6b67-493c-9dee-ee45a44114e1"
+#define FAULTTOLERANCESTATE_IID { \
+ 0x5124f7ec, 0x6b67, 0x493c, \
+ { 0x9d, 0xee, 0xee, 0x45, 0xa4, 0x41, 0x14, 0xe1 } \
+}
+enum FaultToleranceState
+{
+ FaultToleranceState_Inactive = 1,
+ FaultToleranceState_Master = 2,
+ FaultToleranceState_Standby = 3
+};
+/* End of enum FaultToleranceState Declaration */
+
+
+/* Start of enum LockType Declaration */
+#define LOCKTYPE_IID_STR "138b53f8-db4b-47c5-b32b-4ef52f769413"
+#define LOCKTYPE_IID { \
+ 0x138b53f8, 0xdb4b, 0x47c5, \
+ { 0xb3, 0x2b, 0x4e, 0xf5, 0x2f, 0x76, 0x94, 0x13 } \
+}
+enum LockType
+{
+ LockType_Write = 2,
+ LockType_Shared = 1
+};
+/* End of enum LockType Declaration */
+
+
+/* Start of enum SessionType Declaration */
+#define SESSIONTYPE_IID_STR "A13C02CB-0C2C-421E-8317-AC0E8AAA153A"
+#define SESSIONTYPE_IID { \
+ 0xA13C02CB, 0x0C2C, 0x421E, \
+ { 0x83, 0x17, 0xAC, 0x0E, 0x8A, 0xAA, 0x15, 0x3A } \
+}
+enum SessionType
+{
+ SessionType_Null = 0,
+ SessionType_WriteLock = 1,
+ SessionType_Remote = 2,
+ SessionType_Shared = 3
+};
+/* End of enum SessionType Declaration */
+
+
+/* Start of enum DeviceType Declaration */
+#define DEVICETYPE_IID_STR "6d9420f7-0b56-4636-99f9-7346f1b01e57"
+#define DEVICETYPE_IID { \
+ 0x6d9420f7, 0x0b56, 0x4636, \
+ { 0x99, 0xf9, 0x73, 0x46, 0xf1, 0xb0, 0x1e, 0x57 } \
+}
+enum DeviceType
+{
+ DeviceType_Null = 0,
+ DeviceType_Floppy = 1,
+ DeviceType_DVD = 2,
+ DeviceType_HardDisk = 3,
+ DeviceType_Network = 4,
+ DeviceType_USB = 5,
+ DeviceType_SharedFolder = 6
+};
+/* End of enum DeviceType Declaration */
+
+
+/* Start of enum DeviceActivity Declaration */
+#define DEVICEACTIVITY_IID_STR "6FC8AEAA-130A-4eb5-8954-3F921422D707"
+#define DEVICEACTIVITY_IID { \
+ 0x6FC8AEAA, 0x130A, 0x4eb5, \
+ { 0x89, 0x54, 0x3F, 0x92, 0x14, 0x22, 0xD7, 0x07 } \
+}
+enum DeviceActivity
+{
+ DeviceActivity_Null = 0,
+ DeviceActivity_Idle = 1,
+ DeviceActivity_Reading = 2,
+ DeviceActivity_Writing = 3
+};
+/* End of enum DeviceActivity Declaration */
+
+
+/* Start of enum ClipboardMode Declaration */
+#define CLIPBOARDMODE_IID_STR "33364716-4008-4701-8f14-be0fa3d62950"
+#define CLIPBOARDMODE_IID { \
+ 0x33364716, 0x4008, 0x4701, \
+ { 0x8f, 0x14, 0xbe, 0x0f, 0xa3, 0xd6, 0x29, 0x50 } \
+}
+enum ClipboardMode
+{
+ ClipboardMode_Disabled = 0,
+ ClipboardMode_HostToGuest = 1,
+ ClipboardMode_GuestToHost = 2,
+ ClipboardMode_Bidirectional = 3
+};
+/* End of enum ClipboardMode Declaration */
+
+
+/* Start of enum Scope Declaration */
+#define SCOPE_IID_STR "7c91096e-499e-4eca-9f9b-9001438d7855"
+#define SCOPE_IID { \
+ 0x7c91096e, 0x499e, 0x4eca, \
+ { 0x9f, 0x9b, 0x90, 0x01, 0x43, 0x8d, 0x78, 0x55 } \
+}
+enum Scope
+{
+ Scope_Global = 0,
+ Scope_Machine = 1,
+ Scope_Session = 2
+};
+/* End of enum Scope Declaration */
+
+
+/* Start of enum BIOSBootMenuMode Declaration */
+#define BIOSBOOTMENUMODE_IID_STR "ae4fb9f7-29d2-45b4-b2c7-d579603135d5"
+#define BIOSBOOTMENUMODE_IID { \
+ 0xae4fb9f7, 0x29d2, 0x45b4, \
+ { 0xb2, 0xc7, 0xd5, 0x79, 0x60, 0x31, 0x35, 0xd5 } \
+}
+enum BIOSBootMenuMode
+{
+ BIOSBootMenuMode_Disabled = 0,
+ BIOSBootMenuMode_MenuOnly = 1,
+ BIOSBootMenuMode_MessageAndMenu = 2
+};
+/* End of enum BIOSBootMenuMode Declaration */
+
+
+/* Start of enum ProcessorFeature Declaration */
+#define PROCESSORFEATURE_IID_STR "64c38e6b-8bcf-45ad-ac03-9b406287c5bf"
+#define PROCESSORFEATURE_IID { \
+ 0x64c38e6b, 0x8bcf, 0x45ad, \
+ { 0xac, 0x03, 0x9b, 0x40, 0x62, 0x87, 0xc5, 0xbf } \
+}
+enum ProcessorFeature
+{
+ ProcessorFeature_HWVirtEx = 0,
+ ProcessorFeature_PAE = 1,
+ ProcessorFeature_LongMode = 2,
+ ProcessorFeature_NestedPaging = 3
+};
+/* End of enum ProcessorFeature Declaration */
+
+
+/* Start of enum FirmwareType Declaration */
+#define FIRMWARETYPE_IID_STR "b903f264-c230-483e-ac74-2b37ce60d371"
+#define FIRMWARETYPE_IID { \
+ 0xb903f264, 0xc230, 0x483e, \
+ { 0xac, 0x74, 0x2b, 0x37, 0xce, 0x60, 0xd3, 0x71 } \
+}
+enum FirmwareType
+{
+ FirmwareType_BIOS = 1,
+ FirmwareType_EFI = 2,
+ FirmwareType_EFI32 = 3,
+ FirmwareType_EFI64 = 4,
+ FirmwareType_EFIDUAL = 5
+};
+/* End of enum FirmwareType Declaration */
+
+
+/* Start of enum PointingHidType Declaration */
+#define POINTINGHIDTYPE_IID_STR "0d3c17a2-821a-4b2e-ae41-890c6c60aa97"
+#define POINTINGHIDTYPE_IID { \
+ 0x0d3c17a2, 0x821a, 0x4b2e, \
+ { 0xae, 0x41, 0x89, 0x0c, 0x6c, 0x60, 0xaa, 0x97 } \
+}
+enum PointingHidType
+{
+ PointingHidType_None = 1,
+ PointingHidType_PS2Mouse = 2,
+ PointingHidType_USBMouse = 3,
+ PointingHidType_USBTablet = 4,
+ PointingHidType_ComboMouse = 5
+};
+/* End of enum PointingHidType Declaration */
+
+
+/* Start of enum KeyboardHidType Declaration */
+#define KEYBOARDHIDTYPE_IID_STR "5a5b0996-3a3e-44bb-9019-56979812cbcc"
+#define KEYBOARDHIDTYPE_IID { \
+ 0x5a5b0996, 0x3a3e, 0x44bb, \
+ { 0x90, 0x19, 0x56, 0x97, 0x98, 0x12, 0xcb, 0xcc } \
+}
+enum KeyboardHidType
+{
+ KeyboardHidType_None = 1,
+ KeyboardHidType_PS2Keyboard = 2,
+ KeyboardHidType_USBKeyboard = 3,
+ KeyboardHidType_ComboKeyboard = 4
+};
+/* End of enum KeyboardHidType Declaration */
+
+
+/* Start of enum VFSType Declaration */
+#define VFSTYPE_IID_STR "813999ba-b949-48a8-9230-aadc6285e2f2"
+#define VFSTYPE_IID { \
+ 0x813999ba, 0xb949, 0x48a8, \
+ { 0x92, 0x30, 0xaa, 0xdc, 0x62, 0x85, 0xe2, 0xf2 } \
+}
+enum VFSType
+{
+ VFSType_File = 1,
+ VFSType_Cloud = 2,
+ VFSType_S3 = 3,
+ VFSType_WebDav = 4
+};
+/* End of enum VFSType Declaration */
+
+
+/* Start of enum VFSFileType Declaration */
+#define VFSFILETYPE_IID_STR "714333cd-44e2-415f-a245-d378fa9b1242"
+#define VFSFILETYPE_IID { \
+ 0x714333cd, 0x44e2, 0x415f, \
+ { 0xa2, 0x45, 0xd3, 0x78, 0xfa, 0x9b, 0x12, 0x42 } \
+}
+enum VFSFileType
+{
+ VFSFileType_Unknown = 1,
+ VFSFileType_Fifo = 2,
+ VFSFileType_DevChar = 3,
+ VFSFileType_Directory = 4,
+ VFSFileType_DevBlock = 5,
+ VFSFileType_File = 6,
+ VFSFileType_SymLink = 7,
+ VFSFileType_Socket = 8,
+ VFSFileType_WhiteOut = 9
+};
+/* End of enum VFSFileType Declaration */
+
+
+/* Start of enum VirtualSystemDescriptionType Declaration */
+#define VIRTUALSYSTEMDESCRIPTIONTYPE_IID_STR "c0f8f135-3a1d-417d-afa6-b38b95a91f90"
+#define VIRTUALSYSTEMDESCRIPTIONTYPE_IID { \
+ 0xc0f8f135, 0x3a1d, 0x417d, \
+ { 0xaf, 0xa6, 0xb3, 0x8b, 0x95, 0xa9, 0x1f, 0x90 } \
+}
+enum VirtualSystemDescriptionType
+{
+ VirtualSystemDescriptionType_Ignore = 1,
+ VirtualSystemDescriptionType_OS = 2,
+ VirtualSystemDescriptionType_Name = 3,
+ VirtualSystemDescriptionType_Product = 4,
+ VirtualSystemDescriptionType_Vendor = 5,
+ VirtualSystemDescriptionType_Version = 6,
+ VirtualSystemDescriptionType_ProductUrl = 7,
+ VirtualSystemDescriptionType_VendorUrl = 8,
+ VirtualSystemDescriptionType_Description = 9,
+ VirtualSystemDescriptionType_License = 10,
+ VirtualSystemDescriptionType_Miscellaneous = 11,
+ VirtualSystemDescriptionType_CPU = 12,
+ VirtualSystemDescriptionType_Memory = 13,
+ VirtualSystemDescriptionType_HardDiskControllerIDE = 14,
+ VirtualSystemDescriptionType_HardDiskControllerSATA = 15,
+ VirtualSystemDescriptionType_HardDiskControllerSCSI = 16,
+ VirtualSystemDescriptionType_HardDiskControllerSAS = 17,
+ VirtualSystemDescriptionType_HardDiskImage = 18,
+ VirtualSystemDescriptionType_Floppy = 19,
+ VirtualSystemDescriptionType_CDROM = 20,
+ VirtualSystemDescriptionType_NetworkAdapter = 21,
+ VirtualSystemDescriptionType_USBController = 22,
+ VirtualSystemDescriptionType_SoundCard = 23
+};
+/* End of enum VirtualSystemDescriptionType Declaration */
+
+
+/* Start of enum VirtualSystemDescriptionValueType Declaration */
+#define VIRTUALSYSTEMDESCRIPTIONVALUETYPE_IID_STR "56d9403f-3425-4118-9919-36f2a9b8c77c"
+#define VIRTUALSYSTEMDESCRIPTIONVALUETYPE_IID { \
+ 0x56d9403f, 0x3425, 0x4118, \
+ { 0x99, 0x19, 0x36, 0xf2, 0xa9, 0xb8, 0xc7, 0x7c } \
+}
+enum VirtualSystemDescriptionValueType
+{
+ VirtualSystemDescriptionValueType_Reference = 1,
+ VirtualSystemDescriptionValueType_Original = 2,
+ VirtualSystemDescriptionValueType_Auto = 3,
+ VirtualSystemDescriptionValueType_ExtraConfig = 4
+};
+/* End of enum VirtualSystemDescriptionValueType Declaration */
+
+
+/* Start of enum CleanupMode Declaration */
+#define CLEANUPMODE_IID_STR "67897c50-7cca-47a9-83f6-ce8fd8eb5441"
+#define CLEANUPMODE_IID { \
+ 0x67897c50, 0x7cca, 0x47a9, \
+ { 0x83, 0xf6, 0xce, 0x8f, 0xd8, 0xeb, 0x54, 0x41 } \
+}
+enum CleanupMode
+{
+ CleanupMode_UnregisterOnly = 1,
+ CleanupMode_DetachAllReturnNone = 2,
+ CleanupMode_DetachAllReturnHardDisksOnly = 3,
+ CleanupMode_Full = 4
+};
+/* End of enum CleanupMode Declaration */
+
+
+/* Start of enum HostNetworkInterfaceMediumType Declaration */
+#define HOSTNETWORKINTERFACEMEDIUMTYPE_IID_STR "1aa54aaf-2497-45a2-bfb1-8eb225e93d5b"
+#define HOSTNETWORKINTERFACEMEDIUMTYPE_IID { \
+ 0x1aa54aaf, 0x2497, 0x45a2, \
+ { 0xbf, 0xb1, 0x8e, 0xb2, 0x25, 0xe9, 0x3d, 0x5b } \
+}
+enum HostNetworkInterfaceMediumType
+{
+ HostNetworkInterfaceMediumType_Unknown = 0,
+ HostNetworkInterfaceMediumType_Ethernet = 1,
+ HostNetworkInterfaceMediumType_PPP = 2,
+ HostNetworkInterfaceMediumType_SLIP = 3
+};
+/* End of enum HostNetworkInterfaceMediumType Declaration */
+
+
+/* Start of enum HostNetworkInterfaceStatus Declaration */
+#define HOSTNETWORKINTERFACESTATUS_IID_STR "CC474A69-2710-434B-8D99-C38E5D5A6F41"
+#define HOSTNETWORKINTERFACESTATUS_IID { \
+ 0xCC474A69, 0x2710, 0x434B, \
+ { 0x8D, 0x99, 0xC3, 0x8E, 0x5D, 0x5A, 0x6F, 0x41 } \
+}
+enum HostNetworkInterfaceStatus
+{
+ HostNetworkInterfaceStatus_Unknown = 0,
+ HostNetworkInterfaceStatus_Up = 1,
+ HostNetworkInterfaceStatus_Down = 2
+};
+/* End of enum HostNetworkInterfaceStatus Declaration */
+
+
+/* Start of enum HostNetworkInterfaceType Declaration */
+#define HOSTNETWORKINTERFACETYPE_IID_STR "67431b00-9946-48a2-bc02-b25c5919f4f3"
+#define HOSTNETWORKINTERFACETYPE_IID { \
+ 0x67431b00, 0x9946, 0x48a2, \
+ { 0xbc, 0x02, 0xb2, 0x5c, 0x59, 0x19, 0xf4, 0xf3 } \
+}
+enum HostNetworkInterfaceType
+{
+ HostNetworkInterfaceType_Bridged = 1,
+ HostNetworkInterfaceType_HostOnly = 2
+};
+/* End of enum HostNetworkInterfaceType Declaration */
+
+
+/* Start of enum AdditionsRunLevelType Declaration */
+#define ADDITIONSRUNLEVELTYPE_IID_STR "a25417ee-a9dd-4f5b-b0dc-377860087754"
+#define ADDITIONSRUNLEVELTYPE_IID { \
+ 0xa25417ee, 0xa9dd, 0x4f5b, \
+ { 0xb0, 0xdc, 0x37, 0x78, 0x60, 0x08, 0x77, 0x54 } \
+}
+enum AdditionsRunLevelType
+{
+ AdditionsRunLevelType_None = 0,
+ AdditionsRunLevelType_System = 1,
+ AdditionsRunLevelType_Userland = 2,
+ AdditionsRunLevelType_Desktop = 3
+};
+/* End of enum AdditionsRunLevelType Declaration */
+
+
+/* Start of enum AdditionsUpdateFlag Declaration */
+#define ADDITIONSUPDATEFLAG_IID_STR "726a818d-18d6-4389-94e8-3e9e6826171a"
+#define ADDITIONSUPDATEFLAG_IID { \
+ 0x726a818d, 0x18d6, 0x4389, \
+ { 0x94, 0xe8, 0x3e, 0x9e, 0x68, 0x26, 0x17, 0x1a } \
+}
+enum AdditionsUpdateFlag
+{
+ AdditionsUpdateFlag_None = 0,
+ AdditionsUpdateFlag_WaitForUpdateStartOnly = 1
+};
+/* End of enum AdditionsUpdateFlag Declaration */
+
+
+/* Start of enum ExecuteProcessFlag Declaration */
+#define EXECUTEPROCESSFLAG_IID_STR "3258e8a5-ba0c-43d5-86b5-cf91405fddc0"
+#define EXECUTEPROCESSFLAG_IID { \
+ 0x3258e8a5, 0xba0c, 0x43d5, \
+ { 0x86, 0xb5, 0xcf, 0x91, 0x40, 0x5f, 0xdd, 0xc0 } \
+}
+enum ExecuteProcessFlag
+{
+ ExecuteProcessFlag_None = 0,
+ ExecuteProcessFlag_WaitForProcessStartOnly = 1,
+ ExecuteProcessFlag_IgnoreOrphanedProcesses = 2,
+ ExecuteProcessFlag_Hidden = 4,
+ ExecuteProcessFlag_NoProfile = 8
+};
+/* End of enum ExecuteProcessFlag Declaration */
+
+
+/* Start of enum ProcessInputFlag Declaration */
+#define PROCESSINPUTFLAG_IID_STR "5d38c1dd-2604-4ddf-92e5-0c0cdd3bdbd5"
+#define PROCESSINPUTFLAG_IID { \
+ 0x5d38c1dd, 0x2604, 0x4ddf, \
+ { 0x92, 0xe5, 0x0c, 0x0c, 0xdd, 0x3b, 0xdb, 0xd5 } \
+}
+enum ProcessInputFlag
+{
+ ProcessInputFlag_None = 0,
+ ProcessInputFlag_EndOfFile = 1
+};
+/* End of enum ProcessInputFlag Declaration */
+
+
+/* Start of enum CopyFileFlag Declaration */
+#define COPYFILEFLAG_IID_STR "23f79fdf-738a-493d-b80b-42d607c9b916"
+#define COPYFILEFLAG_IID { \
+ 0x23f79fdf, 0x738a, 0x493d, \
+ { 0xb8, 0x0b, 0x42, 0xd6, 0x07, 0xc9, 0xb9, 0x16 } \
+}
+enum CopyFileFlag
+{
+ CopyFileFlag_None = 0,
+ CopyFileFlag_Recursive = 1,
+ CopyFileFlag_Update = 2,
+ CopyFileFlag_FollowLinks = 4
+};
+/* End of enum CopyFileFlag Declaration */
+
+
+/* Start of enum CreateDirectoryFlag Declaration */
+#define CREATEDIRECTORYFLAG_IID_STR "26ff5bdd-c81f-4304-857b-b8be5e3f9cd6"
+#define CREATEDIRECTORYFLAG_IID { \
+ 0x26ff5bdd, 0xc81f, 0x4304, \
+ { 0x85, 0x7b, 0xb8, 0xbe, 0x5e, 0x3f, 0x9c, 0xd6 } \
+}
+enum CreateDirectoryFlag
+{
+ CreateDirectoryFlag_None = 0,
+ CreateDirectoryFlag_Parents = 1
+};
+/* End of enum CreateDirectoryFlag Declaration */
+
+
+/* Start of enum MediumState Declaration */
+#define MEDIUMSTATE_IID_STR "ef41e980-e012-43cd-9dea-479d4ef14d13"
+#define MEDIUMSTATE_IID { \
+ 0xef41e980, 0xe012, 0x43cd, \
+ { 0x9d, 0xea, 0x47, 0x9d, 0x4e, 0xf1, 0x4d, 0x13 } \
+}
+enum MediumState
+{
+ MediumState_NotCreated = 0,
+ MediumState_Created = 1,
+ MediumState_LockedRead = 2,
+ MediumState_LockedWrite = 3,
+ MediumState_Inaccessible = 4,
+ MediumState_Creating = 5,
+ MediumState_Deleting = 6
+};
+/* End of enum MediumState Declaration */
+
+
+/* Start of enum MediumType Declaration */
+#define MEDIUMTYPE_IID_STR "fe663fb5-c244-4e1b-9d81-c628b417dd04"
+#define MEDIUMTYPE_IID { \
+ 0xfe663fb5, 0xc244, 0x4e1b, \
+ { 0x9d, 0x81, 0xc6, 0x28, 0xb4, 0x17, 0xdd, 0x04 } \
+}
+enum MediumType
+{
+ MediumType_Normal = 0,
+ MediumType_Immutable = 1,
+ MediumType_Writethrough = 2,
+ MediumType_Shareable = 3,
+ MediumType_Readonly = 4,
+ MediumType_MultiAttach = 5
+};
+/* End of enum MediumType Declaration */
+
+
+/* Start of enum MediumVariant Declaration */
+#define MEDIUMVARIANT_IID_STR "584ea502-143b-4ab0-ad14-d1028fdf0316"
+#define MEDIUMVARIANT_IID { \
+ 0x584ea502, 0x143b, 0x4ab0, \
+ { 0xad, 0x14, 0xd1, 0x02, 0x8f, 0xdf, 0x03, 0x16 } \
+}
+enum MediumVariant
+{
+ MediumVariant_Standard = 0,
+ MediumVariant_VmdkSplit2G = 0x01,
+ MediumVariant_VmdkStreamOptimized = 0x04,
+ MediumVariant_VmdkESX = 0x08,
+ MediumVariant_Fixed = 0x10000,
+ MediumVariant_Diff = 0x20000
+};
+/* End of enum MediumVariant Declaration */
+
+
+/* Start of enum DataType Declaration */
+#define DATATYPE_IID_STR "d90ea51e-a3f1-4a01-beb1-c1723c0d3ba7"
+#define DATATYPE_IID { \
+ 0xd90ea51e, 0xa3f1, 0x4a01, \
+ { 0xbe, 0xb1, 0xc1, 0x72, 0x3c, 0x0d, 0x3b, 0xa7 } \
+}
+enum DataType
+{
+ DataType_Int32 = 0,
+ DataType_Int8 = 1,
+ DataType_String = 2
+};
+/* End of enum DataType Declaration */
+
+
+/* Start of enum DataFlags Declaration */
+#define DATAFLAGS_IID_STR "86884dcf-1d6b-4f1b-b4bf-f5aa44959d60"
+#define DATAFLAGS_IID { \
+ 0x86884dcf, 0x1d6b, 0x4f1b, \
+ { 0xb4, 0xbf, 0xf5, 0xaa, 0x44, 0x95, 0x9d, 0x60 } \
+}
+enum DataFlags
+{
+ DataFlags_None = 0x00,
+ DataFlags_Mandatory = 0x01,
+ DataFlags_Expert = 0x02,
+ DataFlags_Array = 0x04,
+ DataFlags_FlagMask = 0x07
+};
+/* End of enum DataFlags Declaration */
+
+
+/* Start of enum MediumFormatCapabilities Declaration */
+#define MEDIUMFORMATCAPABILITIES_IID_STR "7342ba79-7ce0-4d94-8f86-5ed5a185d9bd"
+#define MEDIUMFORMATCAPABILITIES_IID { \
+ 0x7342ba79, 0x7ce0, 0x4d94, \
+ { 0x8f, 0x86, 0x5e, 0xd5, 0xa1, 0x85, 0xd9, 0xbd } \
+}
+enum MediumFormatCapabilities
+{
+ MediumFormatCapabilities_Uuid = 0x01,
+ MediumFormatCapabilities_CreateFixed = 0x02,
+ MediumFormatCapabilities_CreateDynamic = 0x04,
+ MediumFormatCapabilities_CreateSplit2G = 0x08,
+ MediumFormatCapabilities_Differencing = 0x10,
+ MediumFormatCapabilities_Asynchronous = 0x20,
+ MediumFormatCapabilities_File = 0x40,
+ MediumFormatCapabilities_Properties = 0x80,
+ MediumFormatCapabilities_TcpNetworking = 0x100,
+ MediumFormatCapabilities_VFS = 0x200,
+ MediumFormatCapabilities_CapabilityMask = 0x3FF
+};
+/* End of enum MediumFormatCapabilities Declaration */
+
+
+/* Start of enum MouseButtonState Declaration */
+#define MOUSEBUTTONSTATE_IID_STR "9ee094b8-b28a-4d56-a166-973cb588d7f8"
+#define MOUSEBUTTONSTATE_IID { \
+ 0x9ee094b8, 0xb28a, 0x4d56, \
+ { 0xa1, 0x66, 0x97, 0x3c, 0xb5, 0x88, 0xd7, 0xf8 } \
+}
+enum MouseButtonState
+{
+ MouseButtonState_LeftButton = 0x01,
+ MouseButtonState_RightButton = 0x02,
+ MouseButtonState_MiddleButton = 0x04,
+ MouseButtonState_WheelUp = 0x08,
+ MouseButtonState_WheelDown = 0x10,
+ MouseButtonState_XButton1 = 0x20,
+ MouseButtonState_XButton2 = 0x40,
+ MouseButtonState_MouseStateMask = 0x7F
+};
+/* End of enum MouseButtonState Declaration */
+
+
+/* Start of enum FramebufferPixelFormat Declaration */
+#define FRAMEBUFFERPIXELFORMAT_IID_STR "7acfd5ed-29e3-45e3-8136-73c9224f3d2d"
+#define FRAMEBUFFERPIXELFORMAT_IID { \
+ 0x7acfd5ed, 0x29e3, 0x45e3, \
+ { 0x81, 0x36, 0x73, 0xc9, 0x22, 0x4f, 0x3d, 0x2d } \
+}
+enum FramebufferPixelFormat
+{
+ FramebufferPixelFormat_Opaque = 0,
+ FramebufferPixelFormat_FOURCC_RGB = 0x32424752
+};
+/* End of enum FramebufferPixelFormat Declaration */
+
+
+/* Start of enum NetworkAttachmentType Declaration */
+#define NETWORKATTACHMENTTYPE_IID_STR "44bce1ee-99f7-4e8e-89fc-80597fd9eeaf"
+#define NETWORKATTACHMENTTYPE_IID { \
+ 0x44bce1ee, 0x99f7, 0x4e8e, \
+ { 0x89, 0xfc, 0x80, 0x59, 0x7f, 0xd9, 0xee, 0xaf } \
+}
+enum NetworkAttachmentType
+{
+ NetworkAttachmentType_Null = 0,
+ NetworkAttachmentType_NAT = 1,
+ NetworkAttachmentType_Bridged = 2,
+ NetworkAttachmentType_Internal = 3,
+ NetworkAttachmentType_HostOnly = 4,
+ NetworkAttachmentType_VDE = 5
+};
+/* End of enum NetworkAttachmentType Declaration */
+
+
+/* Start of enum NetworkAdapterType Declaration */
+#define NETWORKADAPTERTYPE_IID_STR "3c2281e4-d952-4e87-8c7d-24379cb6a81c"
+#define NETWORKADAPTERTYPE_IID { \
+ 0x3c2281e4, 0xd952, 0x4e87, \
+ { 0x8c, 0x7d, 0x24, 0x37, 0x9c, 0xb6, 0xa8, 0x1c } \
+}
+enum NetworkAdapterType
+{
+ NetworkAdapterType_Null = 0,
+ NetworkAdapterType_Am79C970A = 1,
+ NetworkAdapterType_Am79C973 = 2,
+ NetworkAdapterType_I82540EM = 3,
+ NetworkAdapterType_I82543GC = 4,
+ NetworkAdapterType_I82545EM = 5,
+ NetworkAdapterType_Virtio = 6
+};
+/* End of enum NetworkAdapterType Declaration */
+
+
+/* Start of enum PortMode Declaration */
+#define PORTMODE_IID_STR "533b5fe3-0185-4197-86a7-17e37dd39d76"
+#define PORTMODE_IID { \
+ 0x533b5fe3, 0x0185, 0x4197, \
+ { 0x86, 0xa7, 0x17, 0xe3, 0x7d, 0xd3, 0x9d, 0x76 } \
+}
+enum PortMode
+{
+ PortMode_Disconnected = 0,
+ PortMode_HostPipe = 1,
+ PortMode_HostDevice = 2,
+ PortMode_RawFile = 3
+};
+/* End of enum PortMode Declaration */
+
+
+/* Start of enum USBDeviceState Declaration */
+#define USBDEVICESTATE_IID_STR "b99a2e65-67fb-4882-82fd-f3e5e8193ab4"
+#define USBDEVICESTATE_IID { \
+ 0xb99a2e65, 0x67fb, 0x4882, \
+ { 0x82, 0xfd, 0xf3, 0xe5, 0xe8, 0x19, 0x3a, 0xb4 } \
+}
+enum USBDeviceState
+{
+ USBDeviceState_NotSupported = 0,
+ USBDeviceState_Unavailable = 1,
+ USBDeviceState_Busy = 2,
+ USBDeviceState_Available = 3,
+ USBDeviceState_Held = 4,
+ USBDeviceState_Captured = 5
+};
+/* End of enum USBDeviceState Declaration */
+
+
+/* Start of enum USBDeviceFilterAction Declaration */
+#define USBDEVICEFILTERACTION_IID_STR "cbc30a49-2f4e-43b5-9da6-121320475933"
+#define USBDEVICEFILTERACTION_IID { \
+ 0xcbc30a49, 0x2f4e, 0x43b5, \
+ { 0x9d, 0xa6, 0x12, 0x13, 0x20, 0x47, 0x59, 0x33 } \
+}
+enum USBDeviceFilterAction
+{
+ USBDeviceFilterAction_Null = 0,
+ USBDeviceFilterAction_Ignore = 1,
+ USBDeviceFilterAction_Hold = 2
+};
+/* End of enum USBDeviceFilterAction Declaration */
+
+
+/* Start of enum AudioDriverType Declaration */
+#define AUDIODRIVERTYPE_IID_STR "4bcc3d73-c2fe-40db-b72f-0c2ca9d68496"
+#define AUDIODRIVERTYPE_IID { \
+ 0x4bcc3d73, 0xc2fe, 0x40db, \
+ { 0xb7, 0x2f, 0x0c, 0x2c, 0xa9, 0xd6, 0x84, 0x96 } \
+}
+enum AudioDriverType
+{
+ AudioDriverType_Null = 0,
+ AudioDriverType_WinMM = 1,
+ AudioDriverType_OSS = 2,
+ AudioDriverType_ALSA = 3,
+ AudioDriverType_DirectSound = 4,
+ AudioDriverType_CoreAudio = 5,
+ AudioDriverType_MMPM = 6,
+ AudioDriverType_Pulse = 7,
+ AudioDriverType_SolAudio = 8
+};
+/* End of enum AudioDriverType Declaration */
+
+
+/* Start of enum AudioControllerType Declaration */
+#define AUDIOCONTROLLERTYPE_IID_STR "7afd395c-42c3-444e-8788-3ce80292f36c"
+#define AUDIOCONTROLLERTYPE_IID { \
+ 0x7afd395c, 0x42c3, 0x444e, \
+ { 0x87, 0x88, 0x3c, 0xe8, 0x02, 0x92, 0xf3, 0x6c } \
+}
+enum AudioControllerType
+{
+ AudioControllerType_AC97 = 0,
+ AudioControllerType_SB16 = 1,
+ AudioControllerType_HDA = 2
+};
+/* End of enum AudioControllerType Declaration */
+
+
+/* Start of enum AuthType Declaration */
+#define AUTHTYPE_IID_STR "7eef6ef6-98c2-4dc2-ab35-10d2b292028d"
+#define AUTHTYPE_IID { \
+ 0x7eef6ef6, 0x98c2, 0x4dc2, \
+ { 0xab, 0x35, 0x10, 0xd2, 0xb2, 0x92, 0x02, 0x8d } \
+}
+enum AuthType
+{
+ AuthType_Null = 0,
+ AuthType_External = 1,
+ AuthType_Guest = 2
+};
+/* End of enum AuthType Declaration */
+
+
+/* Start of enum StorageBus Declaration */
+#define STORAGEBUS_IID_STR "eee67ab3-668d-4ef5-91e0-7025fe4a0d7a"
+#define STORAGEBUS_IID { \
+ 0xeee67ab3, 0x668d, 0x4ef5, \
+ { 0x91, 0xe0, 0x70, 0x25, 0xfe, 0x4a, 0x0d, 0x7a } \
+}
+enum StorageBus
+{
+ StorageBus_Null = 0,
+ StorageBus_IDE = 1,
+ StorageBus_SATA = 2,
+ StorageBus_SCSI = 3,
+ StorageBus_Floppy = 4,
+ StorageBus_SAS = 5
+};
+/* End of enum StorageBus Declaration */
+
+
+/* Start of enum StorageControllerType Declaration */
+#define STORAGECONTROLLERTYPE_IID_STR "8a412b8a-f43e-4456-bd37-b474f0879a58"
+#define STORAGECONTROLLERTYPE_IID { \
+ 0x8a412b8a, 0xf43e, 0x4456, \
+ { 0xbd, 0x37, 0xb4, 0x74, 0xf0, 0x87, 0x9a, 0x58 } \
+}
+enum StorageControllerType
+{
+ StorageControllerType_Null = 0,
+ StorageControllerType_LsiLogic = 1,
+ StorageControllerType_BusLogic = 2,
+ StorageControllerType_IntelAhci = 3,
+ StorageControllerType_PIIX3 = 4,
+ StorageControllerType_PIIX4 = 5,
+ StorageControllerType_ICH6 = 6,
+ StorageControllerType_I82078 = 7,
+ StorageControllerType_LsiLogicSas = 8
+};
+/* End of enum StorageControllerType Declaration */
+
+
+/* Start of enum ChipsetType Declaration */
+#define CHIPSETTYPE_IID_STR "8b4096a8-a7c3-4d3b-bbb1-05a0a51ec394"
+#define CHIPSETTYPE_IID { \
+ 0x8b4096a8, 0xa7c3, 0x4d3b, \
+ { 0xbb, 0xb1, 0x05, 0xa0, 0xa5, 0x1e, 0xc3, 0x94 } \
+}
+enum ChipsetType
+{
+ ChipsetType_Null = 0,
+ ChipsetType_PIIX3 = 1,
+ ChipsetType_ICH9 = 2
+};
+/* End of enum ChipsetType Declaration */
+
+
+/* Start of enum NATAliasMode Declaration */
+#define NATALIASMODE_IID_STR "67772168-50d9-11df-9669-7fb714ee4fa1"
+#define NATALIASMODE_IID { \
+ 0x67772168, 0x50d9, 0x11df, \
+ { 0x96, 0x69, 0x7f, 0xb7, 0x14, 0xee, 0x4f, 0xa1 } \
+}
+enum NATAliasMode
+{
+ NATAliasMode_AliasLog = 0x1,
+ NATAliasMode_AliasProxyOnly = 0x02,
+ NATAliasMode_AliasUseSamePorts = 0x04
+};
+/* End of enum NATAliasMode Declaration */
+
+
+/* Start of enum NATProtocol Declaration */
+#define NATPROTOCOL_IID_STR "e90164be-eb03-11de-94af-fff9b1c1b19f"
+#define NATPROTOCOL_IID { \
+ 0xe90164be, 0xeb03, 0x11de, \
+ { 0x94, 0xaf, 0xff, 0xf9, 0xb1, 0xc1, 0xb1, 0x9f } \
+}
+enum NATProtocol
+{
+ NATProtocol_UDP = 0,
+ NATProtocol_TCP = 1
+};
+/* End of enum NATProtocol Declaration */
+
+
+/* Start of enum BandwidthGroupType Declaration */
+#define BANDWIDTHGROUPTYPE_IID_STR "1d92b67d-dc69-4be9-ad4c-93a01e1e0c8e"
+#define BANDWIDTHGROUPTYPE_IID { \
+ 0x1d92b67d, 0xdc69, 0x4be9, \
+ { 0xad, 0x4c, 0x93, 0xa0, 0x1e, 0x1e, 0x0c, 0x8e } \
+}
+enum BandwidthGroupType
+{
+ BandwidthGroupType_Null = 0,
+ BandwidthGroupType_Disk = 1,
+ BandwidthGroupType_Network = 2
+};
+/* End of enum BandwidthGroupType Declaration */
+
+
+/* Start of enum VBoxEventType Declaration */
+#define VBOXEVENTTYPE_IID_STR "e71c487f-755e-46e9-a476-dd6a5d134597"
+#define VBOXEVENTTYPE_IID { \
+ 0xe71c487f, 0x755e, 0x46e9, \
+ { 0xa4, 0x76, 0xdd, 0x6a, 0x5d, 0x13, 0x45, 0x97 } \
+}
+enum VBoxEventType
+{
+ VBoxEventType_Invalid = 0,
+ VBoxEventType_Any = 1,
+ VBoxEventType_Vetoable = 2,
+ VBoxEventType_MachineEvent = 3,
+ VBoxEventType_SnapshotEvent = 4,
+ VBoxEventType_InputEvent = 5,
+ VBoxEventType_LastWildcard = 31,
+ VBoxEventType_OnMachineStateChanged = 32,
+ VBoxEventType_OnMachineDataChanged = 33,
+ VBoxEventType_OnExtraDataChanged = 34,
+ VBoxEventType_OnExtraDataCanChange = 35,
+ VBoxEventType_OnMediumRegistered = 36,
+ VBoxEventType_OnMachineRegistered = 37,
+ VBoxEventType_OnSessionStateChanged = 38,
+ VBoxEventType_OnSnapshotTaken = 39,
+ VBoxEventType_OnSnapshotDeleted = 40,
+ VBoxEventType_OnSnapshotChanged = 41,
+ VBoxEventType_OnGuestPropertyChanged = 42,
+ VBoxEventType_OnMousePointerShapeChanged = 43,
+ VBoxEventType_OnMouseCapabilityChanged = 44,
+ VBoxEventType_OnKeyboardLedsChanged = 45,
+ VBoxEventType_OnStateChanged = 46,
+ VBoxEventType_OnAdditionsStateChanged = 47,
+ VBoxEventType_OnNetworkAdapterChanged = 48,
+ VBoxEventType_OnSerialPortChanged = 49,
+ VBoxEventType_OnParallelPortChanged = 50,
+ VBoxEventType_OnStorageControllerChanged = 51,
+ VBoxEventType_OnMediumChanged = 52,
+ VBoxEventType_OnVRDEServerChanged = 53,
+ VBoxEventType_OnUSBControllerChanged = 54,
+ VBoxEventType_OnUSBDeviceStateChanged = 55,
+ VBoxEventType_OnSharedFolderChanged = 56,
+ VBoxEventType_OnRuntimeError = 57,
+ VBoxEventType_OnCanShowWindow = 58,
+ VBoxEventType_OnShowWindow = 59,
+ VBoxEventType_OnCPUChanged = 60,
+ VBoxEventType_OnVRDEServerInfoChanged = 61,
+ VBoxEventType_OnEventSourceChanged = 62,
+ VBoxEventType_OnCPUExecutionCapChanged = 63,
+ VBoxEventType_OnGuestKeyboard = 64,
+ VBoxEventType_OnGuestMouse = 65,
+ VBoxEventType_OnNATRedirect = 66,
+ VBoxEventType_OnHostPciDevicePlug = 67,
+ VBoxEventType_OnVBoxSVCAvailabilityChanged = 68,
+ VBoxEventType_OnBandwidthGroupChanged = 69,
+ VBoxEventType_OnGuestMonitorChanged = 70,
+ VBoxEventType_Last = 71
+};
+/* End of enum VBoxEventType Declaration */
+
+
+/* Start of enum GuestMonitorChangedEventType Declaration */
+#define GUESTMONITORCHANGEDEVENTTYPE_IID_STR "ef172985-7e36-4297-95be-e46396968d66"
+#define GUESTMONITORCHANGEDEVENTTYPE_IID { \
+ 0xef172985, 0x7e36, 0x4297, \
+ { 0x95, 0xbe, 0xe4, 0x63, 0x96, 0x96, 0x8d, 0x66 } \
+}
+enum GuestMonitorChangedEventType
+{
+ GuestMonitorChangedEventType_Enabled = 0,
+ GuestMonitorChangedEventType_Disabled = 1,
+ GuestMonitorChangedEventType_NewOrigin = 2
+};
+/* End of enum GuestMonitorChangedEventType Declaration */
+
+
+/* Start of struct IVirtualBoxErrorInfo Declaration */
+#define IVIRTUALBOXERRORINFO_IID_STR "e053d3c0-f493-491b-a735-3a9f0b1feed4"
+#define IVIRTUALBOXERRORINFO_IID { \
+ 0xe053d3c0, 0xf493, 0x491b, \
+ { 0xa7, 0x35, 0x3a, 0x9f, 0x0b, 0x1f, 0xee, 0xd4 } \
+}
+struct IVirtualBoxErrorInfo_vtbl
+{
+ struct nsIException_vtbl nsiexception;
+
+ nsresult (*GetResultCode)(IVirtualBoxErrorInfo *pThis, PRInt32 *resultCode);
+
+ nsresult (*GetInterfaceID)(IVirtualBoxErrorInfo *pThis, PRUnichar * *interfaceID);
+
+ nsresult (*GetComponent)(IVirtualBoxErrorInfo *pThis, PRUnichar * *component);
+
+ nsresult (*GetText)(IVirtualBoxErrorInfo *pThis, PRUnichar * *text);
+
+ nsresult (*GetNext)(IVirtualBoxErrorInfo *pThis, IVirtualBoxErrorInfo * *next);
+
+};
+
+struct IVirtualBoxErrorInfo
+{
+ struct IVirtualBoxErrorInfo_vtbl *vtbl;
+};
+/* End of struct IVirtualBoxErrorInfo Declaration */
+
+
+/* Start of struct IDHCPServer Declaration */
+#define IDHCPSERVER_IID_STR "6cfe387c-74fb-4ca7-bff6-973bec8af7a3"
+#define IDHCPSERVER_IID { \
+ 0x6cfe387c, 0x74fb, 0x4ca7, \
+ { 0xbf, 0xf6, 0x97, 0x3b, 0xec, 0x8a, 0xf7, 0xa3 } \
+}
+struct IDHCPServer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IDHCPServer *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IDHCPServer *pThis, PRBool enabled);
+
+ nsresult (*GetIPAddress)(IDHCPServer *pThis, PRUnichar * *IPAddress);
+
+ nsresult (*GetNetworkMask)(IDHCPServer *pThis, PRUnichar * *networkMask);
+
+ nsresult (*GetNetworkName)(IDHCPServer *pThis, PRUnichar * *networkName);
+
+ nsresult (*GetLowerIP)(IDHCPServer *pThis, PRUnichar * *lowerIP);
+
+ nsresult (*GetUpperIP)(IDHCPServer *pThis, PRUnichar * *upperIP);
+
+ nsresult (*SetConfiguration)(
+ IDHCPServer *pThis,
+ PRUnichar * IPAddress,
+ PRUnichar * networkMask,
+ PRUnichar * FromIPAddress,
+ PRUnichar * ToIPAddress
+ );
+
+ nsresult (*Start)(
+ IDHCPServer *pThis,
+ PRUnichar * networkName,
+ PRUnichar * trunkName,
+ PRUnichar * trunkType
+ );
+
+ nsresult (*Stop)(IDHCPServer *pThis );
+
+};
+
+struct IDHCPServer
+{
+ struct IDHCPServer_vtbl *vtbl;
+};
+/* End of struct IDHCPServer Declaration */
+
+
+/* Start of struct IVirtualBox Declaration */
+#define IVIRTUALBOX_IID_STR "d2de270c-1d4b-4c9e-843f-bbb9b47269ff"
+#define IVIRTUALBOX_IID { \
+ 0xd2de270c, 0x1d4b, 0x4c9e, \
+ { 0x84, 0x3f, 0xbb, 0xb9, 0xb4, 0x72, 0x69, 0xff } \
+}
+struct IVirtualBox_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetVersion)(IVirtualBox *pThis, PRUnichar * *version);
+
+ nsresult (*GetRevision)(IVirtualBox *pThis, PRUint32 *revision);
+
+ nsresult (*GetPackageType)(IVirtualBox *pThis, PRUnichar * *packageType);
+
+ nsresult (*GetHomeFolder)(IVirtualBox *pThis, PRUnichar * *homeFolder);
+
+ nsresult (*GetSettingsFilePath)(IVirtualBox *pThis, PRUnichar * *settingsFilePath);
+
+ nsresult (*GetHost)(IVirtualBox *pThis, IHost * *host);
+
+ nsresult (*GetSystemProperties)(IVirtualBox *pThis, ISystemProperties * *systemProperties);
+
+ nsresult (*GetMachines)(IVirtualBox *pThis, PRUint32 *machinesSize, IMachine * **machines);
+
+ nsresult (*GetHardDisks)(IVirtualBox *pThis, PRUint32 *hardDisksSize, IMedium * **hardDisks);
+
+ nsresult (*GetDVDImages)(IVirtualBox *pThis, PRUint32 *DVDImagesSize, IMedium * **DVDImages);
+
+ nsresult (*GetFloppyImages)(IVirtualBox *pThis, PRUint32 *floppyImagesSize, IMedium * **floppyImages);
+
+ nsresult (*GetProgressOperations)(IVirtualBox *pThis, PRUint32 *progressOperationsSize, IProgress * **progressOperations);
+
+ nsresult (*GetGuestOSTypes)(IVirtualBox *pThis, PRUint32 *guestOSTypesSize, IGuestOSType * **guestOSTypes);
+
+ nsresult (*GetSharedFolders)(IVirtualBox *pThis, PRUint32 *sharedFoldersSize, ISharedFolder * **sharedFolders);
+
+ nsresult (*GetPerformanceCollector)(IVirtualBox *pThis, IPerformanceCollector * *performanceCollector);
+
+ nsresult (*GetDHCPServers)(IVirtualBox *pThis, PRUint32 *DHCPServersSize, IDHCPServer * **DHCPServers);
+
+ nsresult (*GetEventSource)(IVirtualBox *pThis, IEventSource * *eventSource);
+
+ nsresult (*GetExtensionPackManager)(IVirtualBox *pThis, IExtPackManager * *extensionPackManager);
+
+ nsresult (*ComposeMachineFilename)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ PRUnichar * baseFolder,
+ PRUnichar * * file
+ );
+
+ nsresult (*CreateMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * settingsFile,
+ PRUnichar * name,
+ PRUnichar * osTypeId,
+ PRUnichar * id,
+ PRBool forceOverwrite,
+ IMachine * * machine
+ );
+
+ nsresult (*OpenMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * settingsFile,
+ IMachine * * machine
+ );
+
+ nsresult (*RegisterMachine)(
+ IVirtualBox *pThis,
+ IMachine * machine
+ );
+
+ nsresult (*FindMachine)(
+ IVirtualBox *pThis,
+ PRUnichar * nameOrId,
+ IMachine * * machine
+ );
+
+ nsresult (*CreateAppliance)(
+ IVirtualBox *pThis,
+ IAppliance * * appliance
+ );
+
+ nsresult (*CreateHardDisk)(
+ IVirtualBox *pThis,
+ PRUnichar * format,
+ PRUnichar * location,
+ IMedium * * medium
+ );
+
+ nsresult (*OpenMedium)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ PRUint32 deviceType,
+ PRUint32 accessMode,
+ IMedium * * medium
+ );
+
+ nsresult (*FindMedium)(
+ IVirtualBox *pThis,
+ PRUnichar * location,
+ PRUint32 type,
+ IMedium * * medium
+ );
+
+ nsresult (*GetGuestOSType)(
+ IVirtualBox *pThis,
+ PRUnichar * id,
+ IGuestOSType * * type
+ );
+
+ nsresult (*CreateSharedFolder)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ PRUnichar * hostPath,
+ PRBool writable,
+ PRBool automount
+ );
+
+ nsresult (*RemoveSharedFolder)(
+ IVirtualBox *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*GetExtraDataKeys)(
+ IVirtualBox *pThis,
+ PRUint32 *valueSize,
+ PRUnichar *** value
+ );
+
+ nsresult (*GetExtraData)(
+ IVirtualBox *pThis,
+ PRUnichar * key,
+ PRUnichar * * value
+ );
+
+ nsresult (*SetExtraData)(
+ IVirtualBox *pThis,
+ PRUnichar * key,
+ PRUnichar * value
+ );
+
+ nsresult (*CreateDHCPServer)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ IDHCPServer * * server
+ );
+
+ nsresult (*FindDHCPServerByNetworkName)(
+ IVirtualBox *pThis,
+ PRUnichar * name,
+ IDHCPServer * * server
+ );
+
+ nsresult (*RemoveDHCPServer)(
+ IVirtualBox *pThis,
+ IDHCPServer * server
+ );
+
+ nsresult (*CheckFirmwarePresent)(
+ IVirtualBox *pThis,
+ PRUint32 firmwareType,
+ PRUnichar * version,
+ PRUnichar * * url,
+ PRUnichar * * file,
+ PRBool * result
+ );
+
+};
+
+struct IVirtualBox
+{
+ struct IVirtualBox_vtbl *vtbl;
+};
+/* End of struct IVirtualBox Declaration */
+
+
+/* Start of struct IVFSExplorer Declaration */
+#define IVFSEXPLORER_IID_STR "003d7f92-d38e-487f-b790-8c5e8631cb2f"
+#define IVFSEXPLORER_IID { \
+ 0x003d7f92, 0xd38e, 0x487f, \
+ { 0xb7, 0x90, 0x8c, 0x5e, 0x86, 0x31, 0xcb, 0x2f } \
+}
+struct IVFSExplorer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetPath)(IVFSExplorer *pThis, PRUnichar * *path);
+
+ nsresult (*GetType)(IVFSExplorer *pThis, PRUint32 *type);
+
+ nsresult (*Update)(
+ IVFSExplorer *pThis,
+ IProgress * * aProgress
+ );
+
+ nsresult (*Cd)(
+ IVFSExplorer *pThis,
+ PRUnichar * aDir,
+ IProgress * * aProgress
+ );
+
+ nsresult (*CdUp)(
+ IVFSExplorer *pThis,
+ IProgress * * aProgress
+ );
+
+ nsresult (*EntryList)(
+ IVFSExplorer *pThis,
+ PRUint32 *aNamesSize,
+ PRUnichar *** aNames,
+ PRUint32 *aTypesSize,
+ PRUint32* aTypes,
+ PRUint32 *aSizesSize,
+ PRUint32* aSizes,
+ PRUint32 *aModesSize,
+ PRUint32* aModes
+ );
+
+ nsresult (*Exists)(
+ IVFSExplorer *pThis,
+ PRUint32 aNamesSize,
+ PRUnichar ** aNames,
+ PRUint32 *aExistsSize,
+ PRUnichar *** aExists
+ );
+
+ nsresult (*Remove)(
+ IVFSExplorer *pThis,
+ PRUint32 aNamesSize,
+ PRUnichar ** aNames,
+ IProgress * * aProgress
+ );
+
+};
+
+struct IVFSExplorer
+{
+ struct IVFSExplorer_vtbl *vtbl;
+};
+/* End of struct IVFSExplorer Declaration */
+
+
+/* Start of struct IAppliance Declaration */
+#define IAPPLIANCE_IID_STR "7b148032-4124-4f46-b56a-b48ac1273f5a"
+#define IAPPLIANCE_IID { \
+ 0x7b148032, 0x4124, 0x4f46, \
+ { 0xb5, 0x6a, 0xb4, 0x8a, 0xc1, 0x27, 0x3f, 0x5a } \
+}
+struct IAppliance_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetPath)(IAppliance *pThis, PRUnichar * *path);
+
+ nsresult (*GetDisks)(IAppliance *pThis, PRUint32 *disksSize, PRUnichar * **disks);
+
+ nsresult (*GetVirtualSystemDescriptions)(IAppliance *pThis, PRUint32 *virtualSystemDescriptionsSize, IVirtualSystemDescription * **virtualSystemDescriptions);
+
+ nsresult (*GetMachines)(IAppliance *pThis, PRUint32 *machinesSize, PRUnichar * **machines);
+
+ nsresult (*Read)(
+ IAppliance *pThis,
+ PRUnichar * file,
+ IProgress * * aProgress
+ );
+
+ nsresult (*Interpret)(IAppliance *pThis );
+
+ nsresult (*ImportMachines)(
+ IAppliance *pThis,
+ IProgress * * aProgress
+ );
+
+ nsresult (*CreateVFSExplorer)(
+ IAppliance *pThis,
+ PRUnichar * aUri,
+ IVFSExplorer * * aExplorer
+ );
+
+ nsresult (*Write)(
+ IAppliance *pThis,
+ PRUnichar * format,
+ PRBool manifest,
+ PRUnichar * path,
+ IProgress * * progress
+ );
+
+ nsresult (*GetWarnings)(
+ IAppliance *pThis,
+ PRUint32 *aWarningsSize,
+ PRUnichar *** aWarnings
+ );
+
+};
+
+struct IAppliance
+{
+ struct IAppliance_vtbl *vtbl;
+};
+/* End of struct IAppliance Declaration */
+
+
+/* Start of struct IVirtualSystemDescription Declaration */
+#define IVIRTUALSYSTEMDESCRIPTION_IID_STR "d7525e6c-531a-4c51-8e04-41235083a3d8"
+#define IVIRTUALSYSTEMDESCRIPTION_IID { \
+ 0xd7525e6c, 0x531a, 0x4c51, \
+ { 0x8e, 0x04, 0x41, 0x23, 0x50, 0x83, 0xa3, 0xd8 } \
+}
+struct IVirtualSystemDescription_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetCount)(IVirtualSystemDescription *pThis, PRUint32 *count);
+
+ nsresult (*GetDescription)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 *aTypesSize,
+ PRUint32* aTypes,
+ PRUint32 *aRefsSize,
+ PRUnichar *** aRefs,
+ PRUint32 *aOvfValuesSize,
+ PRUnichar *** aOvfValues,
+ PRUint32 *aVBoxValuesSize,
+ PRUnichar *** aVBoxValues,
+ PRUint32 *aExtraConfigValuesSize,
+ PRUnichar *** aExtraConfigValues
+ );
+
+ nsresult (*GetDescriptionByType)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aType,
+ PRUint32 *aTypesSize,
+ PRUint32* aTypes,
+ PRUint32 *aRefsSize,
+ PRUnichar *** aRefs,
+ PRUint32 *aOvfValuesSize,
+ PRUnichar *** aOvfValues,
+ PRUint32 *aVBoxValuesSize,
+ PRUnichar *** aVBoxValues,
+ PRUint32 *aExtraConfigValuesSize,
+ PRUnichar *** aExtraConfigValues
+ );
+
+ nsresult (*GetValuesByType)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aType,
+ PRUint32 aWhich,
+ PRUint32 *aValuesSize,
+ PRUnichar *** aValues
+ );
+
+ nsresult (*SetFinalValues)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aEnabledSize,
+ PRBool* aEnabled,
+ PRUint32 aVBoxValuesSize,
+ PRUnichar ** aVBoxValues,
+ PRUint32 aExtraConfigValuesSize,
+ PRUnichar ** aExtraConfigValues
+ );
+
+ nsresult (*AddDescription)(
+ IVirtualSystemDescription *pThis,
+ PRUint32 aType,
+ PRUnichar * aVBoxValue,
+ PRUnichar * aExtraConfigValue
+ );
+
+};
+
+struct IVirtualSystemDescription
+{
+ struct IVirtualSystemDescription_vtbl *vtbl;
+};
+/* End of struct IVirtualSystemDescription Declaration */
+
+
+/* Start of struct IInternalMachineControl Declaration */
+#define IINTERNALMACHINECONTROL_IID_STR "8e723ab0-812c-5662-dd8e-7ebc89637acf"
+#define IINTERNALMACHINECONTROL_IID { \
+ 0x8e723ab0, 0x812c, 0x5662, \
+ { 0xdd, 0x8e, 0x7e, 0xbc, 0x89, 0x63, 0x7a, 0xcf } \
+}
+struct IInternalMachineControl_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*SetRemoveSavedStateFile)(
+ IInternalMachineControl *pThis,
+ PRBool aRemove
+ );
+
+ nsresult (*UpdateState)(
+ IInternalMachineControl *pThis,
+ PRUint32 state
+ );
+
+ nsresult (*GetIPCId)(
+ IInternalMachineControl *pThis,
+ PRUnichar * * id
+ );
+
+ nsresult (*BeginPowerUp)(
+ IInternalMachineControl *pThis,
+ IProgress * aProgress
+ );
+
+ nsresult (*EndPowerUp)(
+ IInternalMachineControl *pThis,
+ PRInt32 result
+ );
+
+ nsresult (*BeginPoweringDown)(
+ IInternalMachineControl *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*EndPoweringDown)(
+ IInternalMachineControl *pThis,
+ PRInt32 result,
+ PRUnichar * errMsg
+ );
+
+ nsresult (*RunUSBDeviceFilters)(
+ IInternalMachineControl *pThis,
+ IUSBDevice * device,
+ PRBool * matched,
+ PRUint32 * maskedInterfaces
+ );
+
+ nsresult (*CaptureUSBDevice)(
+ IInternalMachineControl *pThis,
+ PRUnichar * id
+ );
+
+ nsresult (*DetachUSBDevice)(
+ IInternalMachineControl *pThis,
+ PRUnichar * id,
+ PRBool done
+ );
+
+ nsresult (*AutoCaptureUSBDevices)(IInternalMachineControl *pThis );
+
+ nsresult (*DetachAllUSBDevices)(
+ IInternalMachineControl *pThis,
+ PRBool done
+ );
+
+ nsresult (*OnSessionEnd)(
+ IInternalMachineControl *pThis,
+ ISession * session,
+ IProgress * * progress
+ );
+
+ nsresult (*BeginSavingState)(
+ IInternalMachineControl *pThis,
+ IProgress * * progress,
+ PRUnichar * * stateFilePath
+ );
+
+ nsresult (*EndSavingState)(
+ IInternalMachineControl *pThis,
+ PRInt32 result,
+ PRUnichar * errMsg
+ );
+
+ nsresult (*AdoptSavedState)(
+ IInternalMachineControl *pThis,
+ PRUnichar * savedStateFile
+ );
+
+ nsresult (*BeginTakingSnapshot)(
+ IInternalMachineControl *pThis,
+ IConsole * initiator,
+ PRUnichar * name,
+ PRUnichar * description,
+ IProgress * consoleProgress,
+ PRBool fTakingSnapshotOnline,
+ PRUnichar * * stateFilePath
+ );
+
+ nsresult (*EndTakingSnapshot)(
+ IInternalMachineControl *pThis,
+ PRBool success
+ );
+
+ nsresult (*DeleteSnapshot)(
+ IInternalMachineControl *pThis,
+ IConsole * initiator,
+ PRUnichar * id,
+ PRUint32 * machineState,
+ IProgress * * progress
+ );
+
+ nsresult (*FinishOnlineMergeMedium)(
+ IInternalMachineControl *pThis,
+ IMediumAttachment * mediumAttachment,
+ IMedium * source,
+ IMedium * target,
+ PRBool mergeForward,
+ IMedium * parentForTarget,
+ PRUint32 childrenToReparentSize,
+ IMedium ** childrenToReparent
+ );
+
+ nsresult (*RestoreSnapshot)(
+ IInternalMachineControl *pThis,
+ IConsole * initiator,
+ ISnapshot * snapshot,
+ PRUint32 * machineState,
+ IProgress * * progress
+ );
+
+ nsresult (*PullGuestProperties)(
+ IInternalMachineControl *pThis,
+ PRUint32 *nameSize,
+ PRUnichar *** name,
+ PRUint32 *valueSize,
+ PRUnichar *** value,
+ PRUint32 *timestampSize,
+ PRInt64* timestamp,
+ PRUint32 *flagsSize,
+ PRUnichar *** flags
+ );
+
+ nsresult (*PushGuestProperty)(
+ IInternalMachineControl *pThis,
+ PRUnichar * name,
+ PRUnichar * value,
+ PRInt64 timestamp,
+ PRUnichar * flags
+ );
+
+ nsresult (*LockMedia)(IInternalMachineControl *pThis );
+
+ nsresult (*UnlockMedia)(IInternalMachineControl *pThis );
+
+};
+
+struct IInternalMachineControl
+{
+ struct IInternalMachineControl_vtbl *vtbl;
+};
+/* End of struct IInternalMachineControl Declaration */
+
+
+/* Start of struct IBIOSSettings Declaration */
+#define IBIOSSETTINGS_IID_STR "38b54279-dc35-4f5e-a431-835b867c6b5e"
+#define IBIOSSETTINGS_IID { \
+ 0x38b54279, 0xdc35, 0x4f5e, \
+ { 0xa4, 0x31, 0x83, 0x5b, 0x86, 0x7c, 0x6b, 0x5e } \
+}
+struct IBIOSSettings_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetLogoFadeIn)(IBIOSSettings *pThis, PRBool *logoFadeIn);
+ nsresult (*SetLogoFadeIn)(IBIOSSettings *pThis, PRBool logoFadeIn);
+
+ nsresult (*GetLogoFadeOut)(IBIOSSettings *pThis, PRBool *logoFadeOut);
+ nsresult (*SetLogoFadeOut)(IBIOSSettings *pThis, PRBool logoFadeOut);
+
+ nsresult (*GetLogoDisplayTime)(IBIOSSettings *pThis, PRUint32 *logoDisplayTime);
+ nsresult (*SetLogoDisplayTime)(IBIOSSettings *pThis, PRUint32 logoDisplayTime);
+
+ nsresult (*GetLogoImagePath)(IBIOSSettings *pThis, PRUnichar * *logoImagePath);
+ nsresult (*SetLogoImagePath)(IBIOSSettings *pThis, PRUnichar * logoImagePath);
+
+ nsresult (*GetBootMenuMode)(IBIOSSettings *pThis, PRUint32 *bootMenuMode);
+ nsresult (*SetBootMenuMode)(IBIOSSettings *pThis, PRUint32 bootMenuMode);
+
+ nsresult (*GetACPIEnabled)(IBIOSSettings *pThis, PRBool *ACPIEnabled);
+ nsresult (*SetACPIEnabled)(IBIOSSettings *pThis, PRBool ACPIEnabled);
+
+ nsresult (*GetIOAPICEnabled)(IBIOSSettings *pThis, PRBool *IOAPICEnabled);
+ nsresult (*SetIOAPICEnabled)(IBIOSSettings *pThis, PRBool IOAPICEnabled);
+
+ nsresult (*GetTimeOffset)(IBIOSSettings *pThis, PRInt64 *timeOffset);
+ nsresult (*SetTimeOffset)(IBIOSSettings *pThis, PRInt64 timeOffset);
+
+ nsresult (*GetPXEDebugEnabled)(IBIOSSettings *pThis, PRBool *PXEDebugEnabled);
+ nsresult (*SetPXEDebugEnabled)(IBIOSSettings *pThis, PRBool PXEDebugEnabled);
+
+};
+
+struct IBIOSSettings
+{
+ struct IBIOSSettings_vtbl *vtbl;
+};
+/* End of struct IBIOSSettings Declaration */
+
+
+/* Start of struct IEventContext Declaration */
+#define IEVENTCONTEXT_IID_STR "7563F4E7-1583-40F7-B4C4-C9BA02CB0AE3"
+#define IEVENTCONTEXT_IID { \
+ 0x7563F4E7, 0x1583, 0x40F7, \
+ { 0xB4, 0xC4, 0xC9, 0xBA, 0x02, 0xCB, 0x0A, 0xE3 } \
+}
+struct IEventContext_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+};
+
+struct IEventContext
+{
+ struct IEventContext_vtbl *vtbl;
+};
+/* End of struct IEventContext Declaration */
+
+
+/* Start of struct IPciAddress Declaration */
+#define IPCIADDRESS_IID_STR "D88B324F-DB19-4D3B-A1A9-BF5B127199A8"
+#define IPCIADDRESS_IID { \
+ 0xD88B324F, 0xDB19, 0x4D3B, \
+ { 0xA1, 0xA9, 0xBF, 0x5B, 0x12, 0x71, 0x99, 0xA8 } \
+}
+struct IPciAddress_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetBus)(IPciAddress *pThis, PRInt16 *bus);
+ nsresult (*SetBus)(IPciAddress *pThis, PRInt16 bus);
+
+ nsresult (*GetDevice)(IPciAddress *pThis, PRInt16 *device);
+ nsresult (*SetDevice)(IPciAddress *pThis, PRInt16 device);
+
+ nsresult (*GetDevFunction)(IPciAddress *pThis, PRInt16 *devFunction);
+ nsresult (*SetDevFunction)(IPciAddress *pThis, PRInt16 devFunction);
+
+ nsresult (*AsLong)(
+ IPciAddress *pThis,
+ PRInt32 * result
+ );
+
+ nsresult (*FromLong)(
+ IPciAddress *pThis,
+ PRInt32 number
+ );
+
+};
+
+struct IPciAddress
+{
+ struct IPciAddress_vtbl *vtbl;
+};
+/* End of struct IPciAddress Declaration */
+
+
+/* Start of struct IPciDeviceAttachment Declaration */
+#define IPCIDEVICEATTACHMENT_IID_STR "91f33d6f-e621-4f70-a77e-15f0e3c714d5"
+#define IPCIDEVICEATTACHMENT_IID { \
+ 0x91f33d6f, 0xe621, 0x4f70, \
+ { 0xa7, 0x7e, 0x15, 0xf0, 0xe3, 0xc7, 0x14, 0xd5 } \
+}
+struct IPciDeviceAttachment_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IPciDeviceAttachment *pThis, PRUnichar * *name);
+
+ nsresult (*GetIsPhysicalDevice)(IPciDeviceAttachment *pThis, PRBool *isPhysicalDevice);
+
+ nsresult (*GetHostAddress)(IPciDeviceAttachment *pThis, PRInt32 *hostAddress);
+
+ nsresult (*GetGuestAddress)(IPciDeviceAttachment *pThis, PRInt32 *guestAddress);
+
+};
+
+struct IPciDeviceAttachment
+{
+ struct IPciDeviceAttachment_vtbl *vtbl;
+};
+/* End of struct IPciDeviceAttachment Declaration */
+
+
+/* Start of struct IMachine Declaration */
+#define IMACHINE_IID_STR "662c175e-a69d-40b8-a77a-1d719d0ab062"
+#define IMACHINE_IID { \
+ 0x662c175e, 0xa69d, 0x40b8, \
+ { 0xa7, 0x7a, 0x1d, 0x71, 0x9d, 0x0a, 0xb0, 0x62 } \
+}
+struct IMachine_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetParent)(IMachine *pThis, IVirtualBox * *parent);
+
+ nsresult (*GetAccessible)(IMachine *pThis, PRBool *accessible);
+
+ nsresult (*GetAccessError)(IMachine *pThis, IVirtualBoxErrorInfo * *accessError);
+
+ nsresult (*GetName)(IMachine *pThis, PRUnichar * *name);
+ nsresult (*SetName)(IMachine *pThis, PRUnichar * name);
+
+ nsresult (*GetDescription)(IMachine *pThis, PRUnichar * *description);
+ nsresult (*SetDescription)(IMachine *pThis, PRUnichar * description);
+
+ nsresult (*GetId)(IMachine *pThis, PRUnichar * *id);
+
+ nsresult (*GetOSTypeId)(IMachine *pThis, PRUnichar * *OSTypeId);
+ nsresult (*SetOSTypeId)(IMachine *pThis, PRUnichar * OSTypeId);
+
+ nsresult (*GetHardwareVersion)(IMachine *pThis, PRUnichar * *HardwareVersion);
+ nsresult (*SetHardwareVersion)(IMachine *pThis, PRUnichar * HardwareVersion);
+
+ nsresult (*GetHardwareUUID)(IMachine *pThis, PRUnichar * *hardwareUUID);
+ nsresult (*SetHardwareUUID)(IMachine *pThis, PRUnichar * hardwareUUID);
+
+ nsresult (*GetCPUCount)(IMachine *pThis, PRUint32 *CPUCount);
+ nsresult (*SetCPUCount)(IMachine *pThis, PRUint32 CPUCount);
+
+ nsresult (*GetCPUHotPlugEnabled)(IMachine *pThis, PRBool *CPUHotPlugEnabled);
+ nsresult (*SetCPUHotPlugEnabled)(IMachine *pThis, PRBool CPUHotPlugEnabled);
+
+ nsresult (*GetCPUExecutionCap)(IMachine *pThis, PRUint32 *CPUExecutionCap);
+ nsresult (*SetCPUExecutionCap)(IMachine *pThis, PRUint32 CPUExecutionCap);
+
+ nsresult (*GetMemorySize)(IMachine *pThis, PRUint32 *memorySize);
+ nsresult (*SetMemorySize)(IMachine *pThis, PRUint32 memorySize);
+
+ nsresult (*GetMemoryBalloonSize)(IMachine *pThis, PRUint32 *memoryBalloonSize);
+ nsresult (*SetMemoryBalloonSize)(IMachine *pThis, PRUint32 memoryBalloonSize);
+
+ nsresult (*GetPageFusionEnabled)(IMachine *pThis, PRBool *PageFusionEnabled);
+ nsresult (*SetPageFusionEnabled)(IMachine *pThis, PRBool PageFusionEnabled);
+
+ nsresult (*GetVRAMSize)(IMachine *pThis, PRUint32 *VRAMSize);
+ nsresult (*SetVRAMSize)(IMachine *pThis, PRUint32 VRAMSize);
+
+ nsresult (*GetAccelerate3DEnabled)(IMachine *pThis, PRBool *accelerate3DEnabled);
+ nsresult (*SetAccelerate3DEnabled)(IMachine *pThis, PRBool accelerate3DEnabled);
+
+ nsresult (*GetAccelerate2DVideoEnabled)(IMachine *pThis, PRBool *accelerate2DVideoEnabled);
+ nsresult (*SetAccelerate2DVideoEnabled)(IMachine *pThis, PRBool accelerate2DVideoEnabled);
+
+ nsresult (*GetMonitorCount)(IMachine *pThis, PRUint32 *monitorCount);
+ nsresult (*SetMonitorCount)(IMachine *pThis, PRUint32 monitorCount);
+
+ nsresult (*GetBIOSSettings)(IMachine *pThis, IBIOSSettings * *BIOSSettings);
+
+ nsresult (*GetFirmwareType)(IMachine *pThis, PRUint32 *firmwareType);
+ nsresult (*SetFirmwareType)(IMachine *pThis, PRUint32 firmwareType);
+
+ nsresult (*GetPointingHidType)(IMachine *pThis, PRUint32 *pointingHidType);
+ nsresult (*SetPointingHidType)(IMachine *pThis, PRUint32 pointingHidType);
+
+ nsresult (*GetKeyboardHidType)(IMachine *pThis, PRUint32 *keyboardHidType);
+ nsresult (*SetKeyboardHidType)(IMachine *pThis, PRUint32 keyboardHidType);
+
+ nsresult (*GetHpetEnabled)(IMachine *pThis, PRBool *hpetEnabled);
+ nsresult (*SetHpetEnabled)(IMachine *pThis, PRBool hpetEnabled);
+
+ nsresult (*GetChipsetType)(IMachine *pThis, PRUint32 *chipsetType);
+ nsresult (*SetChipsetType)(IMachine *pThis, PRUint32 chipsetType);
+
+ nsresult (*GetSnapshotFolder)(IMachine *pThis, PRUnichar * *snapshotFolder);
+ nsresult (*SetSnapshotFolder)(IMachine *pThis, PRUnichar * snapshotFolder);
+
+ nsresult (*GetVRDEServer)(IMachine *pThis, IVRDEServer * *VRDEServer);
+
+ nsresult (*GetMediumAttachments)(IMachine *pThis, PRUint32 *mediumAttachmentsSize, IMediumAttachment * **mediumAttachments);
+
+ nsresult (*GetUSBController)(IMachine *pThis, IUSBController * *USBController);
+
+ nsresult (*GetAudioAdapter)(IMachine *pThis, IAudioAdapter * *audioAdapter);
+
+ nsresult (*GetStorageControllers)(IMachine *pThis, PRUint32 *storageControllersSize, IStorageController * **storageControllers);
+
+ nsresult (*GetSettingsFilePath)(IMachine *pThis, PRUnichar * *settingsFilePath);
+
+ nsresult (*GetSettingsModified)(IMachine *pThis, PRBool *settingsModified);
+
+ nsresult (*GetSessionState)(IMachine *pThis, PRUint32 *sessionState);
+
+ nsresult (*GetSessionType)(IMachine *pThis, PRUnichar * *sessionType);
+
+ nsresult (*GetSessionPid)(IMachine *pThis, PRUint32 *sessionPid);
+
+ nsresult (*GetState)(IMachine *pThis, PRUint32 *state);
+
+ nsresult (*GetLastStateChange)(IMachine *pThis, PRInt64 *lastStateChange);
+
+ nsresult (*GetStateFilePath)(IMachine *pThis, PRUnichar * *stateFilePath);
+
+ nsresult (*GetLogFolder)(IMachine *pThis, PRUnichar * *logFolder);
+
+ nsresult (*GetCurrentSnapshot)(IMachine *pThis, ISnapshot * *currentSnapshot);
+
+ nsresult (*GetSnapshotCount)(IMachine *pThis, PRUint32 *snapshotCount);
+
+ nsresult (*GetCurrentStateModified)(IMachine *pThis, PRBool *currentStateModified);
+
+ nsresult (*GetSharedFolders)(IMachine *pThis, PRUint32 *sharedFoldersSize, ISharedFolder * **sharedFolders);
+
+ nsresult (*GetClipboardMode)(IMachine *pThis, PRUint32 *clipboardMode);
+ nsresult (*SetClipboardMode)(IMachine *pThis, PRUint32 clipboardMode);
+
+ nsresult (*GetGuestPropertyNotificationPatterns)(IMachine *pThis, PRUnichar * *guestPropertyNotificationPatterns);
+ nsresult (*SetGuestPropertyNotificationPatterns)(IMachine *pThis, PRUnichar * guestPropertyNotificationPatterns);
+
+ nsresult (*GetTeleporterEnabled)(IMachine *pThis, PRBool *teleporterEnabled);
+ nsresult (*SetTeleporterEnabled)(IMachine *pThis, PRBool teleporterEnabled);
+
+ nsresult (*GetTeleporterPort)(IMachine *pThis, PRUint32 *teleporterPort);
+ nsresult (*SetTeleporterPort)(IMachine *pThis, PRUint32 teleporterPort);
+
+ nsresult (*GetTeleporterAddress)(IMachine *pThis, PRUnichar * *teleporterAddress);
+ nsresult (*SetTeleporterAddress)(IMachine *pThis, PRUnichar * teleporterAddress);
+
+ nsresult (*GetTeleporterPassword)(IMachine *pThis, PRUnichar * *teleporterPassword);
+ nsresult (*SetTeleporterPassword)(IMachine *pThis, PRUnichar * teleporterPassword);
+
+ nsresult (*GetFaultToleranceState)(IMachine *pThis, PRUint32 *faultToleranceState);
+ nsresult (*SetFaultToleranceState)(IMachine *pThis, PRUint32 faultToleranceState);
+
+ nsresult (*GetFaultTolerancePort)(IMachine *pThis, PRUint32 *faultTolerancePort);
+ nsresult (*SetFaultTolerancePort)(IMachine *pThis, PRUint32 faultTolerancePort);
+
+ nsresult (*GetFaultToleranceAddress)(IMachine *pThis, PRUnichar * *faultToleranceAddress);
+ nsresult (*SetFaultToleranceAddress)(IMachine *pThis, PRUnichar * faultToleranceAddress);
+
+ nsresult (*GetFaultTolerancePassword)(IMachine *pThis, PRUnichar * *faultTolerancePassword);
+ nsresult (*SetFaultTolerancePassword)(IMachine *pThis, PRUnichar * faultTolerancePassword);
+
+ nsresult (*GetFaultToleranceSyncInterval)(IMachine *pThis, PRUint32 *faultToleranceSyncInterval);
+ nsresult (*SetFaultToleranceSyncInterval)(IMachine *pThis, PRUint32 faultToleranceSyncInterval);
+
+ nsresult (*GetRTCUseUTC)(IMachine *pThis, PRBool *RTCUseUTC);
+ nsresult (*SetRTCUseUTC)(IMachine *pThis, PRBool RTCUseUTC);
+
+ nsresult (*GetIoCacheEnabled)(IMachine *pThis, PRBool *ioCacheEnabled);
+ nsresult (*SetIoCacheEnabled)(IMachine *pThis, PRBool ioCacheEnabled);
+
+ nsresult (*GetIoCacheSize)(IMachine *pThis, PRUint32 *ioCacheSize);
+ nsresult (*SetIoCacheSize)(IMachine *pThis, PRUint32 ioCacheSize);
+
+ nsresult (*GetBandwidthControl)(IMachine *pThis, IBandwidthControl * *bandwidthControl);
+
+ nsresult (*GetPciDeviceAssignments)(IMachine *pThis, PRUint32 *pciDeviceAssignmentsSize, IPciDeviceAttachment * **pciDeviceAssignments);
+
+ nsresult (*LockMachine)(
+ IMachine *pThis,
+ ISession * session,
+ PRUint32 lockType
+ );
+
+ nsresult (*LaunchVMProcess)(
+ IMachine *pThis,
+ ISession * session,
+ PRUnichar * type,
+ PRUnichar * environment,
+ IProgress * * progress
+ );
+
+ nsresult (*SetBootOrder)(
+ IMachine *pThis,
+ PRUint32 position,
+ PRUint32 device
+ );
+
+ nsresult (*GetBootOrder)(
+ IMachine *pThis,
+ PRUint32 position,
+ PRUint32 * device
+ );
+
+ nsresult (*AttachDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ PRUint32 type,
+ IMedium * medium
+ );
+
+ nsresult (*DetachDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device
+ );
+
+ nsresult (*PassthroughDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ PRBool passthrough
+ );
+
+ nsresult (*SetBandwidthGroupForDevice)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ IBandwidthGroup * bandwidthGroup
+ );
+
+ nsresult (*MountMedium)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ IMedium * medium,
+ PRBool force
+ );
+
+ nsresult (*GetMedium)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ IMedium * * medium
+ );
+
+ nsresult (*GetMediumAttachmentsOfController)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUint32 *mediumAttachmentsSize,
+ IMediumAttachment *** mediumAttachments
+ );
+
+ nsresult (*GetMediumAttachment)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRInt32 controllerPort,
+ PRInt32 device,
+ IMediumAttachment * * attachment
+ );
+
+ nsresult (*AttachHostPciDevice)(
+ IMachine *pThis,
+ PRInt32 hostAddress,
+ PRInt32 desiredGuestAddress,
+ IEventContext * eventContext,
+ PRBool tryToUnbind
+ );
+
+ nsresult (*DetachHostPciDevice)(
+ IMachine *pThis,
+ PRInt32 hostAddress
+ );
+
+ nsresult (*GetNetworkAdapter)(
+ IMachine *pThis,
+ PRUint32 slot,
+ INetworkAdapter * * adapter
+ );
+
+ nsresult (*AddStorageController)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUint32 connectionType,
+ IStorageController * * controller
+ );
+
+ nsresult (*GetStorageControllerByName)(
+ IMachine *pThis,
+ PRUnichar * name,
+ IStorageController * * storageController
+ );
+
+ nsresult (*GetStorageControllerByInstance)(
+ IMachine *pThis,
+ PRUint32 instance,
+ IStorageController * * storageController
+ );
+
+ nsresult (*RemoveStorageController)(
+ IMachine *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*SetStorageControllerBootable)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRBool bootable
+ );
+
+ nsresult (*GetSerialPort)(
+ IMachine *pThis,
+ PRUint32 slot,
+ ISerialPort * * port
+ );
+
+ nsresult (*GetParallelPort)(
+ IMachine *pThis,
+ PRUint32 slot,
+ IParallelPort * * port
+ );
+
+ nsresult (*GetExtraDataKeys)(
+ IMachine *pThis,
+ PRUint32 *valueSize,
+ PRUnichar *** value
+ );
+
+ nsresult (*GetExtraData)(
+ IMachine *pThis,
+ PRUnichar * key,
+ PRUnichar * * value
+ );
+
+ nsresult (*SetExtraData)(
+ IMachine *pThis,
+ PRUnichar * key,
+ PRUnichar * value
+ );
+
+ nsresult (*GetCPUProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool * value
+ );
+
+ nsresult (*SetCPUProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool value
+ );
+
+ nsresult (*GetCPUIDLeaf)(
+ IMachine *pThis,
+ PRUint32 id,
+ PRUint32 * valEax,
+ PRUint32 * valEbx,
+ PRUint32 * valEcx,
+ PRUint32 * valEdx
+ );
+
+ nsresult (*SetCPUIDLeaf)(
+ IMachine *pThis,
+ PRUint32 id,
+ PRUint32 valEax,
+ PRUint32 valEbx,
+ PRUint32 valEcx,
+ PRUint32 valEdx
+ );
+
+ nsresult (*RemoveCPUIDLeaf)(
+ IMachine *pThis,
+ PRUint32 id
+ );
+
+ nsresult (*RemoveAllCPUIDLeaves)(IMachine *pThis );
+
+ nsresult (*GetHWVirtExProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool * value
+ );
+
+ nsresult (*SetHWVirtExProperty)(
+ IMachine *pThis,
+ PRUint32 property,
+ PRBool value
+ );
+
+ nsresult (*SaveSettings)(IMachine *pThis );
+
+ nsresult (*DiscardSettings)(IMachine *pThis );
+
+ nsresult (*Unregister)(
+ IMachine *pThis,
+ PRUint32 cleanupMode,
+ PRUint32 *aMediaSize,
+ IMedium *** aMedia
+ );
+
+ nsresult (*Delete)(
+ IMachine *pThis,
+ PRUint32 aMediaSize,
+ IMedium ** aMedia,
+ IProgress * * aProgress
+ );
+
+ nsresult (*Export)(
+ IMachine *pThis,
+ IAppliance * aAppliance,
+ PRUnichar * location,
+ IVirtualSystemDescription * * aDescription
+ );
+
+ nsresult (*FindSnapshot)(
+ IMachine *pThis,
+ PRUnichar * nameOrId,
+ ISnapshot * * snapshot
+ );
+
+ nsresult (*CreateSharedFolder)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUnichar * hostPath,
+ PRBool writable,
+ PRBool automount
+ );
+
+ nsresult (*RemoveSharedFolder)(
+ IMachine *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*CanShowConsoleWindow)(
+ IMachine *pThis,
+ PRBool * canShow
+ );
+
+ nsresult (*ShowConsoleWindow)(
+ IMachine *pThis,
+ PRInt64 * winId
+ );
+
+ nsresult (*GetGuestProperty)(
+ IMachine *pThis,
+ PRUnichar * name,
+ PRUnichar * * value,
+ PRInt64 * timestamp,
+ PRUnichar * * flags
+ );
+
+ nsresult (*GetGuestPropertyValue)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUnichar * * value
+ );
+
+ nsresult (*GetGuestPropertyTimestamp)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRInt64 * value
+ );
+
+ nsresult (*SetGuestProperty)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUnichar * value,
+ PRUnichar * flags
+ );
+
+ nsresult (*SetGuestPropertyValue)(
+ IMachine *pThis,
+ PRUnichar * property,
+ PRUnichar * value
+ );
+
+ nsresult (*EnumerateGuestProperties)(
+ IMachine *pThis,
+ PRUnichar * patterns,
+ PRUint32 *nameSize,
+ PRUnichar *** name,
+ PRUint32 *valueSize,
+ PRUnichar *** value,
+ PRUint32 *timestampSize,
+ PRInt64* timestamp,
+ PRUint32 *flagsSize,
+ PRUnichar *** flags
+ );
+
+ nsresult (*QuerySavedGuestSize)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * width,
+ PRUint32 * height
+ );
+
+ nsresult (*QuerySavedThumbnailSize)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * size,
+ PRUint32 * width,
+ PRUint32 * height
+ );
+
+ nsresult (*ReadSavedThumbnailToArray)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRBool BGR,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*ReadSavedThumbnailPNGToArray)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*QuerySavedScreenshotPNGSize)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * size,
+ PRUint32 * width,
+ PRUint32 * height
+ );
+
+ nsresult (*ReadSavedScreenshotPNGToArray)(
+ IMachine *pThis,
+ PRUint32 screenId,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*HotPlugCPU)(
+ IMachine *pThis,
+ PRUint32 cpu
+ );
+
+ nsresult (*HotUnplugCPU)(
+ IMachine *pThis,
+ PRUint32 cpu
+ );
+
+ nsresult (*GetCPUStatus)(
+ IMachine *pThis,
+ PRUint32 cpu,
+ PRBool * attached
+ );
+
+ nsresult (*QueryLogFilename)(
+ IMachine *pThis,
+ PRUint32 idx,
+ PRUnichar * * filename
+ );
+
+ nsresult (*ReadLog)(
+ IMachine *pThis,
+ PRUint32 idx,
+ PRInt64 offset,
+ PRInt64 size,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+};
+
+struct IMachine
+{
+ struct IMachine_vtbl *vtbl;
+};
+/* End of struct IMachine Declaration */
+
+
+/* Start of struct IVRDEServerInfo Declaration */
+#define IVRDESERVERINFO_IID_STR "714434a1-58c3-4aab-9049-7652c5df113b"
+#define IVRDESERVERINFO_IID { \
+ 0x714434a1, 0x58c3, 0x4aab, \
+ { 0x90, 0x49, 0x76, 0x52, 0xc5, 0xdf, 0x11, 0x3b } \
+}
+struct IVRDEServerInfo_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetActive)(IVRDEServerInfo *pThis, PRBool *active);
+
+ nsresult (*GetPort)(IVRDEServerInfo *pThis, PRInt32 *port);
+
+ nsresult (*GetNumberOfClients)(IVRDEServerInfo *pThis, PRUint32 *numberOfClients);
+
+ nsresult (*GetBeginTime)(IVRDEServerInfo *pThis, PRInt64 *beginTime);
+
+ nsresult (*GetEndTime)(IVRDEServerInfo *pThis, PRInt64 *endTime);
+
+ nsresult (*GetBytesSent)(IVRDEServerInfo *pThis, PRInt64 *bytesSent);
+
+ nsresult (*GetBytesSentTotal)(IVRDEServerInfo *pThis, PRInt64 *bytesSentTotal);
+
+ nsresult (*GetBytesReceived)(IVRDEServerInfo *pThis, PRInt64 *bytesReceived);
+
+ nsresult (*GetBytesReceivedTotal)(IVRDEServerInfo *pThis, PRInt64 *bytesReceivedTotal);
+
+ nsresult (*GetUser)(IVRDEServerInfo *pThis, PRUnichar * *user);
+
+ nsresult (*GetDomain)(IVRDEServerInfo *pThis, PRUnichar * *domain);
+
+ nsresult (*GetClientName)(IVRDEServerInfo *pThis, PRUnichar * *clientName);
+
+ nsresult (*GetClientIP)(IVRDEServerInfo *pThis, PRUnichar * *clientIP);
+
+ nsresult (*GetClientVersion)(IVRDEServerInfo *pThis, PRUint32 *clientVersion);
+
+ nsresult (*GetEncryptionStyle)(IVRDEServerInfo *pThis, PRUint32 *encryptionStyle);
+
+};
+
+struct IVRDEServerInfo
+{
+ struct IVRDEServerInfo_vtbl *vtbl;
+};
+/* End of struct IVRDEServerInfo Declaration */
+
+
+/* Start of struct IConsole Declaration */
+#define ICONSOLE_IID_STR "515e8e8d-f932-4d8e-9f32-79a52aead882"
+#define ICONSOLE_IID { \
+ 0x515e8e8d, 0xf932, 0x4d8e, \
+ { 0x9f, 0x32, 0x79, 0xa5, 0x2a, 0xea, 0xd8, 0x82 } \
+}
+struct IConsole_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMachine)(IConsole *pThis, IMachine * *machine);
+
+ nsresult (*GetState)(IConsole *pThis, PRUint32 *state);
+
+ nsresult (*GetGuest)(IConsole *pThis, IGuest * *guest);
+
+ nsresult (*GetKeyboard)(IConsole *pThis, IKeyboard * *keyboard);
+
+ nsresult (*GetMouse)(IConsole *pThis, IMouse * *mouse);
+
+ nsresult (*GetDisplay)(IConsole *pThis, IDisplay * *display);
+
+ nsresult (*GetDebugger)(IConsole *pThis, IMachineDebugger * *debugger);
+
+ nsresult (*GetUSBDevices)(IConsole *pThis, PRUint32 *USBDevicesSize, IUSBDevice * **USBDevices);
+
+ nsresult (*GetRemoteUSBDevices)(IConsole *pThis, PRUint32 *remoteUSBDevicesSize, IHostUSBDevice * **remoteUSBDevices);
+
+ nsresult (*GetSharedFolders)(IConsole *pThis, PRUint32 *sharedFoldersSize, ISharedFolder * **sharedFolders);
+
+ nsresult (*GetVRDEServerInfo)(IConsole *pThis, IVRDEServerInfo * *VRDEServerInfo);
+
+ nsresult (*GetEventSource)(IConsole *pThis, IEventSource * *eventSource);
+
+ nsresult (*GetAttachedPciDevices)(IConsole *pThis, PRUint32 *attachedPciDevicesSize, IPciDeviceAttachment * **attachedPciDevices);
+
+ nsresult (*PowerUp)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*PowerUpPaused)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*PowerDown)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*Reset)(IConsole *pThis );
+
+ nsresult (*Pause)(IConsole *pThis );
+
+ nsresult (*Resume)(IConsole *pThis );
+
+ nsresult (*PowerButton)(IConsole *pThis );
+
+ nsresult (*SleepButton)(IConsole *pThis );
+
+ nsresult (*GetPowerButtonHandled)(
+ IConsole *pThis,
+ PRBool * handled
+ );
+
+ nsresult (*GetGuestEnteredACPIMode)(
+ IConsole *pThis,
+ PRBool * entered
+ );
+
+ nsresult (*SaveState)(
+ IConsole *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*AdoptSavedState)(
+ IConsole *pThis,
+ PRUnichar * savedStateFile
+ );
+
+ nsresult (*DiscardSavedState)(
+ IConsole *pThis,
+ PRBool fRemoveFile
+ );
+
+ nsresult (*GetDeviceActivity)(
+ IConsole *pThis,
+ PRUint32 type,
+ PRUint32 * activity
+ );
+
+ nsresult (*AttachUSBDevice)(
+ IConsole *pThis,
+ PRUnichar * id
+ );
+
+ nsresult (*DetachUSBDevice)(
+ IConsole *pThis,
+ PRUnichar * id,
+ IUSBDevice * * device
+ );
+
+ nsresult (*FindUSBDeviceByAddress)(
+ IConsole *pThis,
+ PRUnichar * name,
+ IUSBDevice * * device
+ );
+
+ nsresult (*FindUSBDeviceById)(
+ IConsole *pThis,
+ PRUnichar * id,
+ IUSBDevice * * device
+ );
+
+ nsresult (*CreateSharedFolder)(
+ IConsole *pThis,
+ PRUnichar * name,
+ PRUnichar * hostPath,
+ PRBool writable,
+ PRBool automount
+ );
+
+ nsresult (*RemoveSharedFolder)(
+ IConsole *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*TakeSnapshot)(
+ IConsole *pThis,
+ PRUnichar * name,
+ PRUnichar * description,
+ IProgress * * progress
+ );
+
+ nsresult (*DeleteSnapshot)(
+ IConsole *pThis,
+ PRUnichar * id,
+ IProgress * * progress
+ );
+
+ nsresult (*RestoreSnapshot)(
+ IConsole *pThis,
+ ISnapshot * snapshot,
+ IProgress * * progress
+ );
+
+ nsresult (*Teleport)(
+ IConsole *pThis,
+ PRUnichar * hostname,
+ PRUint32 tcpport,
+ PRUnichar * password,
+ PRUint32 maxDowntime,
+ IProgress * * progress
+ );
+
+};
+
+struct IConsole
+{
+ struct IConsole_vtbl *vtbl;
+};
+/* End of struct IConsole Declaration */
+
+
+/* Start of struct IHostNetworkInterface Declaration */
+#define IHOSTNETWORKINTERFACE_IID_STR "ce6fae58-7642-4102-b5db-c9005c2320a8"
+#define IHOSTNETWORKINTERFACE_IID { \
+ 0xce6fae58, 0x7642, 0x4102, \
+ { 0xb5, 0xdb, 0xc9, 0x00, 0x5c, 0x23, 0x20, 0xa8 } \
+}
+struct IHostNetworkInterface_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IHostNetworkInterface *pThis, PRUnichar * *name);
+
+ nsresult (*GetId)(IHostNetworkInterface *pThis, PRUnichar * *id);
+
+ nsresult (*GetNetworkName)(IHostNetworkInterface *pThis, PRUnichar * *networkName);
+
+ nsresult (*GetDhcpEnabled)(IHostNetworkInterface *pThis, PRBool *dhcpEnabled);
+
+ nsresult (*GetIPAddress)(IHostNetworkInterface *pThis, PRUnichar * *IPAddress);
+
+ nsresult (*GetNetworkMask)(IHostNetworkInterface *pThis, PRUnichar * *networkMask);
+
+ nsresult (*GetIPV6Supported)(IHostNetworkInterface *pThis, PRBool *IPV6Supported);
+
+ nsresult (*GetIPV6Address)(IHostNetworkInterface *pThis, PRUnichar * *IPV6Address);
+
+ nsresult (*GetIPV6NetworkMaskPrefixLength)(IHostNetworkInterface *pThis, PRUint32 *IPV6NetworkMaskPrefixLength);
+
+ nsresult (*GetHardwareAddress)(IHostNetworkInterface *pThis, PRUnichar * *hardwareAddress);
+
+ nsresult (*GetMediumType)(IHostNetworkInterface *pThis, PRUint32 *mediumType);
+
+ nsresult (*GetStatus)(IHostNetworkInterface *pThis, PRUint32 *status);
+
+ nsresult (*GetInterfaceType)(IHostNetworkInterface *pThis, PRUint32 *interfaceType);
+
+ nsresult (*EnableStaticIpConfig)(
+ IHostNetworkInterface *pThis,
+ PRUnichar * IPAddress,
+ PRUnichar * networkMask
+ );
+
+ nsresult (*EnableStaticIpConfigV6)(
+ IHostNetworkInterface *pThis,
+ PRUnichar * IPV6Address,
+ PRUint32 IPV6NetworkMaskPrefixLength
+ );
+
+ nsresult (*EnableDynamicIpConfig)(IHostNetworkInterface *pThis );
+
+ nsresult (*DhcpRediscover)(IHostNetworkInterface *pThis );
+
+};
+
+struct IHostNetworkInterface
+{
+ struct IHostNetworkInterface_vtbl *vtbl;
+};
+/* End of struct IHostNetworkInterface Declaration */
+
+
+/* Start of struct IHost Declaration */
+#define IHOST_IID_STR "35b004f4-7806-4009-bfa8-d1308adba7e5"
+#define IHOST_IID { \
+ 0x35b004f4, 0x7806, 0x4009, \
+ { 0xbf, 0xa8, 0xd1, 0x30, 0x8a, 0xdb, 0xa7, 0xe5 } \
+}
+struct IHost_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetDVDDrives)(IHost *pThis, PRUint32 *DVDDrivesSize, IMedium * **DVDDrives);
+
+ nsresult (*GetFloppyDrives)(IHost *pThis, PRUint32 *floppyDrivesSize, IMedium * **floppyDrives);
+
+ nsresult (*GetUSBDevices)(IHost *pThis, PRUint32 *USBDevicesSize, IHostUSBDevice * **USBDevices);
+
+ nsresult (*GetUSBDeviceFilters)(IHost *pThis, PRUint32 *USBDeviceFiltersSize, IHostUSBDeviceFilter * **USBDeviceFilters);
+
+ nsresult (*GetNetworkInterfaces)(IHost *pThis, PRUint32 *networkInterfacesSize, IHostNetworkInterface * **networkInterfaces);
+
+ nsresult (*GetProcessorCount)(IHost *pThis, PRUint32 *processorCount);
+
+ nsresult (*GetProcessorOnlineCount)(IHost *pThis, PRUint32 *processorOnlineCount);
+
+ nsresult (*GetProcessorCoreCount)(IHost *pThis, PRUint32 *processorCoreCount);
+
+ nsresult (*GetMemorySize)(IHost *pThis, PRUint32 *memorySize);
+
+ nsresult (*GetMemoryAvailable)(IHost *pThis, PRUint32 *memoryAvailable);
+
+ nsresult (*GetOperatingSystem)(IHost *pThis, PRUnichar * *operatingSystem);
+
+ nsresult (*GetOSVersion)(IHost *pThis, PRUnichar * *OSVersion);
+
+ nsresult (*GetUTCTime)(IHost *pThis, PRInt64 *UTCTime);
+
+ nsresult (*GetAcceleration3DAvailable)(IHost *pThis, PRBool *Acceleration3DAvailable);
+
+ nsresult (*GetProcessorSpeed)(
+ IHost *pThis,
+ PRUint32 cpuId,
+ PRUint32 * speed
+ );
+
+ nsresult (*GetProcessorFeature)(
+ IHost *pThis,
+ PRUint32 feature,
+ PRBool * supported
+ );
+
+ nsresult (*GetProcessorDescription)(
+ IHost *pThis,
+ PRUint32 cpuId,
+ PRUnichar * * description
+ );
+
+ nsresult (*GetProcessorCPUIDLeaf)(
+ IHost *pThis,
+ PRUint32 cpuId,
+ PRUint32 leaf,
+ PRUint32 subLeaf,
+ PRUint32 * valEax,
+ PRUint32 * valEbx,
+ PRUint32 * valEcx,
+ PRUint32 * valEdx
+ );
+
+ nsresult (*CreateHostOnlyNetworkInterface)(
+ IHost *pThis,
+ IHostNetworkInterface * * hostInterface,
+ IProgress * * progress
+ );
+
+ nsresult (*RemoveHostOnlyNetworkInterface)(
+ IHost *pThis,
+ PRUnichar * id,
+ IProgress * * progress
+ );
+
+ nsresult (*CreateUSBDeviceFilter)(
+ IHost *pThis,
+ PRUnichar * name,
+ IHostUSBDeviceFilter * * filter
+ );
+
+ nsresult (*InsertUSBDeviceFilter)(
+ IHost *pThis,
+ PRUint32 position,
+ IHostUSBDeviceFilter * filter
+ );
+
+ nsresult (*RemoveUSBDeviceFilter)(
+ IHost *pThis,
+ PRUint32 position
+ );
+
+ nsresult (*FindHostDVDDrive)(
+ IHost *pThis,
+ PRUnichar * name,
+ IMedium * * drive
+ );
+
+ nsresult (*FindHostFloppyDrive)(
+ IHost *pThis,
+ PRUnichar * name,
+ IMedium * * drive
+ );
+
+ nsresult (*FindHostNetworkInterfaceByName)(
+ IHost *pThis,
+ PRUnichar * name,
+ IHostNetworkInterface * * networkInterface
+ );
+
+ nsresult (*FindHostNetworkInterfaceById)(
+ IHost *pThis,
+ PRUnichar * id,
+ IHostNetworkInterface * * networkInterface
+ );
+
+ nsresult (*FindHostNetworkInterfacesOfType)(
+ IHost *pThis,
+ PRUint32 type,
+ PRUint32 *networkInterfacesSize,
+ IHostNetworkInterface *** networkInterfaces
+ );
+
+ nsresult (*FindUSBDeviceById)(
+ IHost *pThis,
+ PRUnichar * id,
+ IHostUSBDevice * * device
+ );
+
+ nsresult (*FindUSBDeviceByAddress)(
+ IHost *pThis,
+ PRUnichar * name,
+ IHostUSBDevice * * device
+ );
+
+};
+
+struct IHost
+{
+ struct IHost_vtbl *vtbl;
+};
+/* End of struct IHost Declaration */
+
+
+/* Start of struct ISystemProperties Declaration */
+#define ISYSTEMPROPERTIES_IID_STR "51c81048-b261-4fa2-a44e-fd756f0db589"
+#define ISYSTEMPROPERTIES_IID { \
+ 0x51c81048, 0xb261, 0x4fa2, \
+ { 0xa4, 0x4e, 0xfd, 0x75, 0x6f, 0x0d, 0xb5, 0x89 } \
+}
+struct ISystemProperties_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMinGuestRAM)(ISystemProperties *pThis, PRUint32 *minGuestRAM);
+
+ nsresult (*GetMaxGuestRAM)(ISystemProperties *pThis, PRUint32 *maxGuestRAM);
+
+ nsresult (*GetMinGuestVRAM)(ISystemProperties *pThis, PRUint32 *minGuestVRAM);
+
+ nsresult (*GetMaxGuestVRAM)(ISystemProperties *pThis, PRUint32 *maxGuestVRAM);
+
+ nsresult (*GetMinGuestCPUCount)(ISystemProperties *pThis, PRUint32 *minGuestCPUCount);
+
+ nsresult (*GetMaxGuestCPUCount)(ISystemProperties *pThis, PRUint32 *maxGuestCPUCount);
+
+ nsresult (*GetMaxGuestMonitors)(ISystemProperties *pThis, PRUint32 *maxGuestMonitors);
+
+ nsresult (*GetInfoVDSize)(ISystemProperties *pThis, PRInt64 *infoVDSize);
+
+ nsresult (*GetNetworkAdapterCount)(ISystemProperties *pThis, PRUint32 *networkAdapterCount);
+
+ nsresult (*GetSerialPortCount)(ISystemProperties *pThis, PRUint32 *serialPortCount);
+
+ nsresult (*GetParallelPortCount)(ISystemProperties *pThis, PRUint32 *parallelPortCount);
+
+ nsresult (*GetMaxBootPosition)(ISystemProperties *pThis, PRUint32 *maxBootPosition);
+
+ nsresult (*GetDefaultMachineFolder)(ISystemProperties *pThis, PRUnichar * *defaultMachineFolder);
+ nsresult (*SetDefaultMachineFolder)(ISystemProperties *pThis, PRUnichar * defaultMachineFolder);
+
+ nsresult (*GetMediumFormats)(ISystemProperties *pThis, PRUint32 *mediumFormatsSize, IMediumFormat * **mediumFormats);
+
+ nsresult (*GetDefaultHardDiskFormat)(ISystemProperties *pThis, PRUnichar * *defaultHardDiskFormat);
+ nsresult (*SetDefaultHardDiskFormat)(ISystemProperties *pThis, PRUnichar * defaultHardDiskFormat);
+
+ nsresult (*GetFreeDiskSpaceWarning)(ISystemProperties *pThis, PRInt64 *freeDiskSpaceWarning);
+ nsresult (*SetFreeDiskSpaceWarning)(ISystemProperties *pThis, PRInt64 freeDiskSpaceWarning);
+
+ nsresult (*GetFreeDiskSpacePercentWarning)(ISystemProperties *pThis, PRUint32 *freeDiskSpacePercentWarning);
+ nsresult (*SetFreeDiskSpacePercentWarning)(ISystemProperties *pThis, PRUint32 freeDiskSpacePercentWarning);
+
+ nsresult (*GetFreeDiskSpaceError)(ISystemProperties *pThis, PRInt64 *freeDiskSpaceError);
+ nsresult (*SetFreeDiskSpaceError)(ISystemProperties *pThis, PRInt64 freeDiskSpaceError);
+
+ nsresult (*GetFreeDiskSpacePercentError)(ISystemProperties *pThis, PRUint32 *freeDiskSpacePercentError);
+ nsresult (*SetFreeDiskSpacePercentError)(ISystemProperties *pThis, PRUint32 freeDiskSpacePercentError);
+
+ nsresult (*GetVRDEAuthLibrary)(ISystemProperties *pThis, PRUnichar * *VRDEAuthLibrary);
+ nsresult (*SetVRDEAuthLibrary)(ISystemProperties *pThis, PRUnichar * VRDEAuthLibrary);
+
+ nsresult (*GetWebServiceAuthLibrary)(ISystemProperties *pThis, PRUnichar * *webServiceAuthLibrary);
+ nsresult (*SetWebServiceAuthLibrary)(ISystemProperties *pThis, PRUnichar * webServiceAuthLibrary);
+
+ nsresult (*GetDefaultVRDEExtPack)(ISystemProperties *pThis, PRUnichar * *defaultVRDEExtPack);
+ nsresult (*SetDefaultVRDEExtPack)(ISystemProperties *pThis, PRUnichar * defaultVRDEExtPack);
+
+ nsresult (*GetLogHistoryCount)(ISystemProperties *pThis, PRUint32 *LogHistoryCount);
+ nsresult (*SetLogHistoryCount)(ISystemProperties *pThis, PRUint32 LogHistoryCount);
+
+ nsresult (*GetDefaultAudioDriver)(ISystemProperties *pThis, PRUint32 *defaultAudioDriver);
+
+ nsresult (*GetMaxDevicesPerPortForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * maxDevicesPerPort
+ );
+
+ nsresult (*GetMinPortCountForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * minPortCount
+ );
+
+ nsresult (*GetMaxPortCountForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 * maxPortCount
+ );
+
+ nsresult (*GetMaxInstancesOfStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 chipset,
+ PRUint32 bus,
+ PRUint32 * maxInstances
+ );
+
+ nsresult (*GetDeviceTypesForStorageBus)(
+ ISystemProperties *pThis,
+ PRUint32 bus,
+ PRUint32 *deviceTypesSize,
+ PRUint32** deviceTypes
+ );
+
+ nsresult (*GetDefaultIoCacheSettingForStorageController)(
+ ISystemProperties *pThis,
+ PRUint32 controllerType,
+ PRBool * enabled
+ );
+
+};
+
+struct ISystemProperties
+{
+ struct ISystemProperties_vtbl *vtbl;
+};
+/* End of struct ISystemProperties Declaration */
+
+
+/* Start of struct IGuestOSType Declaration */
+#define IGUESTOSTYPE_IID_STR "432c1546-1354-4abf-bf08-878a32a373f5"
+#define IGUESTOSTYPE_IID { \
+ 0x432c1546, 0x1354, 0x4abf, \
+ { 0xbf, 0x08, 0x87, 0x8a, 0x32, 0xa3, 0x73, 0xf5 } \
+}
+struct IGuestOSType_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetFamilyId)(IGuestOSType *pThis, PRUnichar * *familyId);
+
+ nsresult (*GetFamilyDescription)(IGuestOSType *pThis, PRUnichar * *familyDescription);
+
+ nsresult (*GetId)(IGuestOSType *pThis, PRUnichar * *id);
+
+ nsresult (*GetDescription)(IGuestOSType *pThis, PRUnichar * *description);
+
+ nsresult (*GetIs64Bit)(IGuestOSType *pThis, PRBool *is64Bit);
+
+ nsresult (*GetRecommendedIOAPIC)(IGuestOSType *pThis, PRBool *recommendedIOAPIC);
+
+ nsresult (*GetRecommendedVirtEx)(IGuestOSType *pThis, PRBool *recommendedVirtEx);
+
+ nsresult (*GetRecommendedRAM)(IGuestOSType *pThis, PRUint32 *recommendedRAM);
+
+ nsresult (*GetRecommendedVRAM)(IGuestOSType *pThis, PRUint32 *recommendedVRAM);
+
+ nsresult (*GetRecommendedHDD)(IGuestOSType *pThis, PRInt64 *recommendedHDD);
+
+ nsresult (*GetAdapterType)(IGuestOSType *pThis, PRUint32 *adapterType);
+
+ nsresult (*GetRecommendedPae)(IGuestOSType *pThis, PRBool *recommendedPae);
+
+ nsresult (*GetRecommendedDvdStorageController)(IGuestOSType *pThis, PRUint32 *recommendedDvdStorageController);
+
+ nsresult (*GetRecommendedDvdStorageBus)(IGuestOSType *pThis, PRUint32 *recommendedDvdStorageBus);
+
+ nsresult (*GetRecommendedHdStorageController)(IGuestOSType *pThis, PRUint32 *recommendedHdStorageController);
+
+ nsresult (*GetRecommendedHdStorageBus)(IGuestOSType *pThis, PRUint32 *recommendedHdStorageBus);
+
+ nsresult (*GetRecommendedFirmware)(IGuestOSType *pThis, PRUint32 *recommendedFirmware);
+
+ nsresult (*GetRecommendedUsbHid)(IGuestOSType *pThis, PRBool *recommendedUsbHid);
+
+ nsresult (*GetRecommendedHpet)(IGuestOSType *pThis, PRBool *recommendedHpet);
+
+ nsresult (*GetRecommendedUsbTablet)(IGuestOSType *pThis, PRBool *recommendedUsbTablet);
+
+ nsresult (*GetRecommendedRtcUseUtc)(IGuestOSType *pThis, PRBool *recommendedRtcUseUtc);
+
+ nsresult (*GetRecommendedChipset)(IGuestOSType *pThis, PRUint32 *recommendedChipset);
+
+ nsresult (*GetRecommendedAudioController)(IGuestOSType *pThis, PRUint32 *recommendedAudioController);
+
+};
+
+struct IGuestOSType
+{
+ struct IGuestOSType_vtbl *vtbl;
+};
+/* End of struct IGuestOSType Declaration */
+
+
+/* Start of struct IGuest Declaration */
+#define IGUEST_IID_STR "7ce7e4d8-cdaa-4d83-a0f4-510c8ee70aea"
+#define IGUEST_IID { \
+ 0x7ce7e4d8, 0xcdaa, 0x4d83, \
+ { 0xa0, 0xf4, 0x51, 0x0c, 0x8e, 0xe7, 0x0a, 0xea } \
+}
+struct IGuest_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetOSTypeId)(IGuest *pThis, PRUnichar * *OSTypeId);
+
+ nsresult (*GetAdditionsRunLevel)(IGuest *pThis, PRUint32 *additionsRunLevel);
+
+ nsresult (*GetAdditionsVersion)(IGuest *pThis, PRUnichar * *additionsVersion);
+
+ nsresult (*GetSupportsSeamless)(IGuest *pThis, PRBool *supportsSeamless);
+
+ nsresult (*GetSupportsGraphics)(IGuest *pThis, PRBool *supportsGraphics);
+
+ nsresult (*GetMemoryBalloonSize)(IGuest *pThis, PRUint32 *memoryBalloonSize);
+ nsresult (*SetMemoryBalloonSize)(IGuest *pThis, PRUint32 memoryBalloonSize);
+
+ nsresult (*GetStatisticsUpdateInterval)(IGuest *pThis, PRUint32 *statisticsUpdateInterval);
+ nsresult (*SetStatisticsUpdateInterval)(IGuest *pThis, PRUint32 statisticsUpdateInterval);
+
+ nsresult (*InternalGetStatistics)(
+ IGuest *pThis,
+ PRUint32 * cpuUser,
+ PRUint32 * cpuKernel,
+ PRUint32 * cpuIdle,
+ PRUint32 * memTotal,
+ PRUint32 * memFree,
+ PRUint32 * memBalloon,
+ PRUint32 * memShared,
+ PRUint32 * memCache,
+ PRUint32 * pagedTotal,
+ PRUint32 * memAllocTotal,
+ PRUint32 * memFreeTotal,
+ PRUint32 * memBalloonTotal,
+ PRUint32 * memSharedTotal
+ );
+
+ nsresult (*GetAdditionsStatus)(
+ IGuest *pThis,
+ PRUint32 level,
+ PRBool * active
+ );
+
+ nsresult (*SetCredentials)(
+ IGuest *pThis,
+ PRUnichar * userName,
+ PRUnichar * password,
+ PRUnichar * domain,
+ PRBool allowInteractiveLogon
+ );
+
+ nsresult (*ExecuteProcess)(
+ IGuest *pThis,
+ PRUnichar * execName,
+ PRUint32 flags,
+ PRUint32 argumentsSize,
+ PRUnichar ** arguments,
+ PRUint32 environmentSize,
+ PRUnichar ** environment,
+ PRUnichar * userName,
+ PRUnichar * password,
+ PRUint32 timeoutMS,
+ PRUint32 * pid,
+ IProgress * * progress
+ );
+
+ nsresult (*GetProcessOutput)(
+ IGuest *pThis,
+ PRUint32 pid,
+ PRUint32 flags,
+ PRUint32 timeoutMS,
+ PRInt64 size,
+ PRUint32 *dataSize,
+ PRUint8** data
+ );
+
+ nsresult (*GetProcessStatus)(
+ IGuest *pThis,
+ PRUint32 pid,
+ PRUint32 * exitcode,
+ PRUint32 * flags,
+ PRUint32 * reason
+ );
+
+ nsresult (*CopyToGuest)(
+ IGuest *pThis,
+ PRUnichar * source,
+ PRUnichar * dest,
+ PRUnichar * userName,
+ PRUnichar * password,
+ PRUint32 flags,
+ IProgress * * progress
+ );
+
+ nsresult (*CreateDirectory)(
+ IGuest *pThis,
+ PRUnichar * directory,
+ PRUnichar * userName,
+ PRUnichar * password,
+ PRUint32 mode,
+ PRUint32 flags,
+ IProgress * * progress
+ );
+
+ nsresult (*SetProcessInput)(
+ IGuest *pThis,
+ PRUint32 pid,
+ PRUint32 flags,
+ PRUint32 timeoutMS,
+ PRUint32 dataSize,
+ PRUint8* data,
+ PRUint32 * written
+ );
+
+ nsresult (*UpdateGuestAdditions)(
+ IGuest *pThis,
+ PRUnichar * source,
+ PRUint32 flags,
+ IProgress * * progress
+ );
+
+};
+
+struct IGuest
+{
+ struct IGuest_vtbl *vtbl;
+};
+/* End of struct IGuest Declaration */
+
+
+/* Start of struct IProgress Declaration */
+#define IPROGRESS_IID_STR "A163C98F-8635-4AA8-B770-A9941737F3EF"
+#define IPROGRESS_IID { \
+ 0xA163C98F, 0x8635, 0x4AA8, \
+ { 0xB7, 0x70, 0xA9, 0x94, 0x17, 0x37, 0xF3, 0xEF } \
+}
+struct IProgress_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IProgress *pThis, PRUnichar * *id);
+
+ nsresult (*GetDescription)(IProgress *pThis, PRUnichar * *description);
+
+ nsresult (*GetInitiator)(IProgress *pThis, nsISupports * *initiator);
+
+ nsresult (*GetCancelable)(IProgress *pThis, PRBool *cancelable);
+
+ nsresult (*GetPercent)(IProgress *pThis, PRUint32 *percent);
+
+ nsresult (*GetTimeRemaining)(IProgress *pThis, PRInt32 *timeRemaining);
+
+ nsresult (*GetCompleted)(IProgress *pThis, PRBool *completed);
+
+ nsresult (*GetCanceled)(IProgress *pThis, PRBool *canceled);
+
+ nsresult (*GetResultCode)(IProgress *pThis, PRInt32 *resultCode);
+
+ nsresult (*GetErrorInfo)(IProgress *pThis, IVirtualBoxErrorInfo * *errorInfo);
+
+ nsresult (*GetOperationCount)(IProgress *pThis, PRUint32 *operationCount);
+
+ nsresult (*GetOperation)(IProgress *pThis, PRUint32 *operation);
+
+ nsresult (*GetOperationDescription)(IProgress *pThis, PRUnichar * *operationDescription);
+
+ nsresult (*GetOperationPercent)(IProgress *pThis, PRUint32 *operationPercent);
+
+ nsresult (*GetOperationWeight)(IProgress *pThis, PRUint32 *operationWeight);
+
+ nsresult (*GetTimeout)(IProgress *pThis, PRUint32 *timeout);
+ nsresult (*SetTimeout)(IProgress *pThis, PRUint32 timeout);
+
+ nsresult (*SetCurrentOperationProgress)(
+ IProgress *pThis,
+ PRUint32 percent
+ );
+
+ nsresult (*SetNextOperation)(
+ IProgress *pThis,
+ PRUnichar * nextOperationDescription,
+ PRUint32 nextOperationsWeight
+ );
+
+ nsresult (*WaitForCompletion)(
+ IProgress *pThis,
+ PRInt32 timeout
+ );
+
+ nsresult (*WaitForOperationCompletion)(
+ IProgress *pThis,
+ PRUint32 operation,
+ PRInt32 timeout
+ );
+
+ nsresult (*Cancel)(IProgress *pThis );
+
+};
+
+struct IProgress
+{
+ struct IProgress_vtbl *vtbl;
+};
+/* End of struct IProgress Declaration */
+
+
+/* Start of struct ISnapshot Declaration */
+#define ISNAPSHOT_IID_STR "1a2d0551-58a4-4107-857e-ef414fc42ffc"
+#define ISNAPSHOT_IID { \
+ 0x1a2d0551, 0x58a4, 0x4107, \
+ { 0x85, 0x7e, 0xef, 0x41, 0x4f, 0xc4, 0x2f, 0xfc } \
+}
+struct ISnapshot_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(ISnapshot *pThis, PRUnichar * *id);
+
+ nsresult (*GetName)(ISnapshot *pThis, PRUnichar * *name);
+ nsresult (*SetName)(ISnapshot *pThis, PRUnichar * name);
+
+ nsresult (*GetDescription)(ISnapshot *pThis, PRUnichar * *description);
+ nsresult (*SetDescription)(ISnapshot *pThis, PRUnichar * description);
+
+ nsresult (*GetTimeStamp)(ISnapshot *pThis, PRInt64 *timeStamp);
+
+ nsresult (*GetOnline)(ISnapshot *pThis, PRBool *online);
+
+ nsresult (*GetMachine)(ISnapshot *pThis, IMachine * *machine);
+
+ nsresult (*GetParent)(ISnapshot *pThis, ISnapshot * *parent);
+
+ nsresult (*GetChildren)(ISnapshot *pThis, PRUint32 *childrenSize, ISnapshot * **children);
+
+};
+
+struct ISnapshot
+{
+ struct ISnapshot_vtbl *vtbl;
+};
+/* End of struct ISnapshot Declaration */
+
+
+/* Start of struct IMediumAttachment Declaration */
+#define IMEDIUMATTACHMENT_IID_STR "aa4b4840-934f-454d-9a28-23e8f4235edf"
+#define IMEDIUMATTACHMENT_IID { \
+ 0xaa4b4840, 0x934f, 0x454d, \
+ { 0x9a, 0x28, 0x23, 0xe8, 0xf4, 0x23, 0x5e, 0xdf } \
+}
+struct IMediumAttachment_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMedium)(IMediumAttachment *pThis, IMedium * *medium);
+
+ nsresult (*GetController)(IMediumAttachment *pThis, PRUnichar * *controller);
+
+ nsresult (*GetPort)(IMediumAttachment *pThis, PRInt32 *port);
+
+ nsresult (*GetDevice)(IMediumAttachment *pThis, PRInt32 *device);
+
+ nsresult (*GetType)(IMediumAttachment *pThis, PRUint32 *type);
+
+ nsresult (*GetPassthrough)(IMediumAttachment *pThis, PRBool *passthrough);
+
+ nsresult (*GetBandwidthGroup)(IMediumAttachment *pThis, IBandwidthGroup * *bandwidthGroup);
+
+};
+
+struct IMediumAttachment
+{
+ struct IMediumAttachment_vtbl *vtbl;
+};
+/* End of struct IMediumAttachment Declaration */
+
+
+/* Start of struct IMedium Declaration */
+#define IMEDIUM_IID_STR "9edda847-1279-4b0a-9af7-9d66251ccc18"
+#define IMEDIUM_IID { \
+ 0x9edda847, 0x1279, 0x4b0a, \
+ { 0x9a, 0xf7, 0x9d, 0x66, 0x25, 0x1c, 0xcc, 0x18 } \
+}
+struct IMedium_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IMedium *pThis, PRUnichar * *id);
+
+ nsresult (*GetDescription)(IMedium *pThis, PRUnichar * *description);
+ nsresult (*SetDescription)(IMedium *pThis, PRUnichar * description);
+
+ nsresult (*GetState)(IMedium *pThis, PRUint32 *state);
+
+ nsresult (*GetVariant)(IMedium *pThis, PRUint32 *variant);
+
+ nsresult (*GetLocation)(IMedium *pThis, PRUnichar * *location);
+ nsresult (*SetLocation)(IMedium *pThis, PRUnichar * location);
+
+ nsresult (*GetName)(IMedium *pThis, PRUnichar * *name);
+
+ nsresult (*GetDeviceType)(IMedium *pThis, PRUint32 *deviceType);
+
+ nsresult (*GetHostDrive)(IMedium *pThis, PRBool *hostDrive);
+
+ nsresult (*GetSize)(IMedium *pThis, PRInt64 *size);
+
+ nsresult (*GetFormat)(IMedium *pThis, PRUnichar * *format);
+
+ nsresult (*GetMediumFormat)(IMedium *pThis, IMediumFormat * *mediumFormat);
+
+ nsresult (*GetType)(IMedium *pThis, PRUint32 *type);
+ nsresult (*SetType)(IMedium *pThis, PRUint32 type);
+
+ nsresult (*GetParent)(IMedium *pThis, IMedium * *parent);
+
+ nsresult (*GetChildren)(IMedium *pThis, PRUint32 *childrenSize, IMedium * **children);
+
+ nsresult (*GetBase)(IMedium *pThis, IMedium * *base);
+
+ nsresult (*GetReadOnly)(IMedium *pThis, PRBool *readOnly);
+
+ nsresult (*GetLogicalSize)(IMedium *pThis, PRInt64 *logicalSize);
+
+ nsresult (*GetAutoReset)(IMedium *pThis, PRBool *autoReset);
+ nsresult (*SetAutoReset)(IMedium *pThis, PRBool autoReset);
+
+ nsresult (*GetLastAccessError)(IMedium *pThis, PRUnichar * *lastAccessError);
+
+ nsresult (*GetMachineIds)(IMedium *pThis, PRUint32 *machineIdsSize, PRUnichar * **machineIds);
+
+ nsresult (*SetIDs)(
+ IMedium *pThis,
+ PRBool setImageId,
+ PRUnichar * imageId,
+ PRBool setParentId,
+ PRUnichar * parentId
+ );
+
+ nsresult (*RefreshState)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*GetSnapshotIds)(
+ IMedium *pThis,
+ PRUnichar * machineId,
+ PRUint32 *snapshotIdsSize,
+ PRUnichar *** snapshotIds
+ );
+
+ nsresult (*LockRead)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*UnlockRead)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*LockWrite)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*UnlockWrite)(
+ IMedium *pThis,
+ PRUint32 * state
+ );
+
+ nsresult (*Close)(IMedium *pThis );
+
+ nsresult (*GetProperty)(
+ IMedium *pThis,
+ PRUnichar * name,
+ PRUnichar * * value
+ );
+
+ nsresult (*SetProperty)(
+ IMedium *pThis,
+ PRUnichar * name,
+ PRUnichar * value
+ );
+
+ nsresult (*GetProperties)(
+ IMedium *pThis,
+ PRUnichar * names,
+ PRUint32 *returnNamesSize,
+ PRUnichar *** returnNames,
+ PRUint32 *returnValuesSize,
+ PRUnichar *** returnValues
+ );
+
+ nsresult (*SetProperties)(
+ IMedium *pThis,
+ PRUint32 namesSize,
+ PRUnichar ** names,
+ PRUint32 valuesSize,
+ PRUnichar ** values
+ );
+
+ nsresult (*CreateBaseStorage)(
+ IMedium *pThis,
+ PRInt64 logicalSize,
+ PRUint32 variant,
+ IProgress * * progress
+ );
+
+ nsresult (*DeleteStorage)(
+ IMedium *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*CreateDiffStorage)(
+ IMedium *pThis,
+ IMedium * target,
+ PRUint32 variant,
+ IProgress * * progress
+ );
+
+ nsresult (*MergeTo)(
+ IMedium *pThis,
+ IMedium * target,
+ IProgress * * progress
+ );
+
+ nsresult (*CloneTo)(
+ IMedium *pThis,
+ IMedium * target,
+ PRUint32 variant,
+ IMedium * parent,
+ IProgress * * progress
+ );
+
+ nsresult (*Compact)(
+ IMedium *pThis,
+ IProgress * * progress
+ );
+
+ nsresult (*Resize)(
+ IMedium *pThis,
+ PRInt64 logicalSize,
+ IProgress * * progress
+ );
+
+ nsresult (*Reset)(
+ IMedium *pThis,
+ IProgress * * progress
+ );
+
+};
+
+struct IMedium
+{
+ struct IMedium_vtbl *vtbl;
+};
+/* End of struct IMedium Declaration */
+
+
+/* Start of struct IMediumFormat Declaration */
+#define IMEDIUMFORMAT_IID_STR "4e9a873f-0599-434a-8345-619ef3fb3111"
+#define IMEDIUMFORMAT_IID { \
+ 0x4e9a873f, 0x0599, 0x434a, \
+ { 0x83, 0x45, 0x61, 0x9e, 0xf3, 0xfb, 0x31, 0x11 } \
+}
+struct IMediumFormat_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IMediumFormat *pThis, PRUnichar * *id);
+
+ nsresult (*GetName)(IMediumFormat *pThis, PRUnichar * *name);
+
+ nsresult (*GetCapabilities)(IMediumFormat *pThis, PRUint32 *capabilities);
+
+ nsresult (*DescribeFileExtensions)(
+ IMediumFormat *pThis,
+ PRUint32 *extensionsSize,
+ PRUnichar *** extensions,
+ PRUint32 *typeSize,
+ PRUint32* type
+ );
+
+ nsresult (*DescribeProperties)(
+ IMediumFormat *pThis,
+ PRUint32 *namesSize,
+ PRUnichar *** names,
+ PRUint32 *descriptionSize,
+ PRUnichar *** description,
+ PRUint32 *typesSize,
+ PRUint32* types,
+ PRUint32 *flagsSize,
+ PRUint32* flags,
+ PRUint32 *defaultsSize,
+ PRUnichar *** defaults
+ );
+
+};
+
+struct IMediumFormat
+{
+ struct IMediumFormat_vtbl *vtbl;
+};
+/* End of struct IMediumFormat Declaration */
+
+
+/* Start of struct IKeyboard Declaration */
+#define IKEYBOARD_IID_STR "f6916ec5-a881-4237-898f-7de58cf88672"
+#define IKEYBOARD_IID { \
+ 0xf6916ec5, 0xa881, 0x4237, \
+ { 0x89, 0x8f, 0x7d, 0xe5, 0x8c, 0xf8, 0x86, 0x72 } \
+}
+struct IKeyboard_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEventSource)(IKeyboard *pThis, IEventSource * *eventSource);
+
+ nsresult (*PutScancode)(
+ IKeyboard *pThis,
+ PRInt32 scancode
+ );
+
+ nsresult (*PutScancodes)(
+ IKeyboard *pThis,
+ PRUint32 scancodesSize,
+ PRInt32* scancodes,
+ PRUint32 * codesStored
+ );
+
+ nsresult (*PutCAD)(IKeyboard *pThis );
+
+};
+
+struct IKeyboard
+{
+ struct IKeyboard_vtbl *vtbl;
+};
+/* End of struct IKeyboard Declaration */
+
+
+/* Start of struct IMouse Declaration */
+#define IMOUSE_IID_STR "05044a52-7811-4f00-ae3a-0ab7ff707b10"
+#define IMOUSE_IID { \
+ 0x05044a52, 0x7811, 0x4f00, \
+ { 0xae, 0x3a, 0x0a, 0xb7, 0xff, 0x70, 0x7b, 0x10 } \
+}
+struct IMouse_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetAbsoluteSupported)(IMouse *pThis, PRBool *absoluteSupported);
+
+ nsresult (*GetRelativeSupported)(IMouse *pThis, PRBool *relativeSupported);
+
+ nsresult (*GetNeedsHostCursor)(IMouse *pThis, PRBool *needsHostCursor);
+
+ nsresult (*GetEventSource)(IMouse *pThis, IEventSource * *eventSource);
+
+ nsresult (*PutMouseEvent)(
+ IMouse *pThis,
+ PRInt32 dx,
+ PRInt32 dy,
+ PRInt32 dz,
+ PRInt32 dw,
+ PRInt32 buttonState
+ );
+
+ nsresult (*PutMouseEventAbsolute)(
+ IMouse *pThis,
+ PRInt32 x,
+ PRInt32 y,
+ PRInt32 dz,
+ PRInt32 dw,
+ PRInt32 buttonState
+ );
+
+};
+
+struct IMouse
+{
+ struct IMouse_vtbl *vtbl;
+};
+/* End of struct IMouse Declaration */
+
+
+/* Start of struct IFramebuffer Declaration */
+#define IFRAMEBUFFER_IID_STR "b7ed347a-5765-40a0-ae1c-f543eb4ddeaf"
+#define IFRAMEBUFFER_IID { \
+ 0xb7ed347a, 0x5765, 0x40a0, \
+ { 0xae, 0x1c, 0xf5, 0x43, 0xeb, 0x4d, 0xde, 0xaf } \
+}
+struct IFramebuffer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetAddress)(IFramebuffer *pThis, PRUint8 * *address);
+
+ nsresult (*GetWidth)(IFramebuffer *pThis, PRUint32 *width);
+
+ nsresult (*GetHeight)(IFramebuffer *pThis, PRUint32 *height);
+
+ nsresult (*GetBitsPerPixel)(IFramebuffer *pThis, PRUint32 *bitsPerPixel);
+
+ nsresult (*GetBytesPerLine)(IFramebuffer *pThis, PRUint32 *bytesPerLine);
+
+ nsresult (*GetPixelFormat)(IFramebuffer *pThis, PRUint32 *pixelFormat);
+
+ nsresult (*GetUsesGuestVRAM)(IFramebuffer *pThis, PRBool *usesGuestVRAM);
+
+ nsresult (*GetHeightReduction)(IFramebuffer *pThis, PRUint32 *heightReduction);
+
+ nsresult (*GetOverlay)(IFramebuffer *pThis, IFramebufferOverlay * *overlay);
+
+ nsresult (*GetWinId)(IFramebuffer *pThis, PRInt64 *winId);
+
+ nsresult (*Lock)(IFramebuffer *pThis );
+
+ nsresult (*Unlock)(IFramebuffer *pThis );
+
+ nsresult (*NotifyUpdate)(
+ IFramebuffer *pThis,
+ PRUint32 x,
+ PRUint32 y,
+ PRUint32 width,
+ PRUint32 height
+ );
+
+ nsresult (*RequestResize)(
+ IFramebuffer *pThis,
+ PRUint32 screenId,
+ PRUint32 pixelFormat,
+ PRUint8 * VRAM,
+ PRUint32 bitsPerPixel,
+ PRUint32 bytesPerLine,
+ PRUint32 width,
+ PRUint32 height,
+ PRBool * finished
+ );
+
+ nsresult (*VideoModeSupported)(
+ IFramebuffer *pThis,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 bpp,
+ PRBool * supported
+ );
+
+ nsresult (*GetVisibleRegion)(
+ IFramebuffer *pThis,
+ PRUint8 * rectangles,
+ PRUint32 count,
+ PRUint32 * countCopied
+ );
+
+ nsresult (*SetVisibleRegion)(
+ IFramebuffer *pThis,
+ PRUint8 * rectangles,
+ PRUint32 count
+ );
+
+ nsresult (*ProcessVHWACommand)(
+ IFramebuffer *pThis,
+ PRUint8 * command
+ );
+
+};
+
+struct IFramebuffer
+{
+ struct IFramebuffer_vtbl *vtbl;
+};
+/* End of struct IFramebuffer Declaration */
+
+
+/* Start of struct IFramebufferOverlay Declaration */
+#define IFRAMEBUFFEROVERLAY_IID_STR "0bcc1c7e-e415-47d2-bfdb-e4c705fb0f47"
+#define IFRAMEBUFFEROVERLAY_IID { \
+ 0x0bcc1c7e, 0xe415, 0x47d2, \
+ { 0xbf, 0xdb, 0xe4, 0xc7, 0x05, 0xfb, 0x0f, 0x47 } \
+}
+struct IFramebufferOverlay_vtbl
+{
+ struct IFramebuffer_vtbl iframebuffer;
+
+ nsresult (*GetX)(IFramebufferOverlay *pThis, PRUint32 *x);
+
+ nsresult (*GetY)(IFramebufferOverlay *pThis, PRUint32 *y);
+
+ nsresult (*GetVisible)(IFramebufferOverlay *pThis, PRBool *visible);
+ nsresult (*SetVisible)(IFramebufferOverlay *pThis, PRBool visible);
+
+ nsresult (*GetAlpha)(IFramebufferOverlay *pThis, PRUint32 *alpha);
+ nsresult (*SetAlpha)(IFramebufferOverlay *pThis, PRUint32 alpha);
+
+ nsresult (*Move)(
+ IFramebufferOverlay *pThis,
+ PRUint32 x,
+ PRUint32 y
+ );
+
+};
+
+struct IFramebufferOverlay
+{
+ struct IFramebufferOverlay_vtbl *vtbl;
+};
+/* End of struct IFramebufferOverlay Declaration */
+
+
+/* Start of struct IDisplay Declaration */
+#define IDISPLAY_IID_STR "09EED313-CD56-4D06-BD56-FAC0F716B5DD"
+#define IDISPLAY_IID { \
+ 0x09EED313, 0xCD56, 0x4D06, \
+ { 0xBD, 0x56, 0xFA, 0xC0, 0xF7, 0x16, 0xB5, 0xDD } \
+}
+struct IDisplay_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetScreenResolution)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint32 * width,
+ PRUint32 * height,
+ PRUint32 * bitsPerPixel
+ );
+
+ nsresult (*SetFramebuffer)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ IFramebuffer * framebuffer
+ );
+
+ nsresult (*GetFramebuffer)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ IFramebuffer * * framebuffer,
+ PRInt32 * xOrigin,
+ PRInt32 * yOrigin
+ );
+
+ nsresult (*SetVideoModeHint)(
+ IDisplay *pThis,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 bitsPerPixel,
+ PRUint32 display
+ );
+
+ nsresult (*SetSeamlessMode)(
+ IDisplay *pThis,
+ PRBool enabled
+ );
+
+ nsresult (*TakeScreenShot)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint8 * address,
+ PRUint32 width,
+ PRUint32 height
+ );
+
+ nsresult (*TakeScreenShotToArray)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 *screenDataSize,
+ PRUint8** screenData
+ );
+
+ nsresult (*TakeScreenShotPNGToArray)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint32 width,
+ PRUint32 height,
+ PRUint32 *screenDataSize,
+ PRUint8** screenData
+ );
+
+ nsresult (*DrawToScreen)(
+ IDisplay *pThis,
+ PRUint32 screenId,
+ PRUint8 * address,
+ PRUint32 x,
+ PRUint32 y,
+ PRUint32 width,
+ PRUint32 height
+ );
+
+ nsresult (*InvalidateAndUpdate)(IDisplay *pThis );
+
+ nsresult (*ResizeCompleted)(
+ IDisplay *pThis,
+ PRUint32 screenId
+ );
+
+ nsresult (*CompleteVHWACommand)(
+ IDisplay *pThis,
+ PRUint8 * command
+ );
+
+};
+
+struct IDisplay
+{
+ struct IDisplay_vtbl *vtbl;
+};
+/* End of struct IDisplay Declaration */
+
+
+/* Start of struct INetworkAdapter Declaration */
+#define INETWORKADAPTER_IID_STR "9bf58a46-c3f7-4f31-80fa-dde9a5dc0b7b"
+#define INETWORKADAPTER_IID { \
+ 0x9bf58a46, 0xc3f7, 0x4f31, \
+ { 0x80, 0xfa, 0xdd, 0xe9, 0xa5, 0xdc, 0x0b, 0x7b } \
+}
+struct INetworkAdapter_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetAdapterType)(INetworkAdapter *pThis, PRUint32 *adapterType);
+ nsresult (*SetAdapterType)(INetworkAdapter *pThis, PRUint32 adapterType);
+
+ nsresult (*GetSlot)(INetworkAdapter *pThis, PRUint32 *slot);
+
+ nsresult (*GetEnabled)(INetworkAdapter *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(INetworkAdapter *pThis, PRBool enabled);
+
+ nsresult (*GetMACAddress)(INetworkAdapter *pThis, PRUnichar * *MACAddress);
+ nsresult (*SetMACAddress)(INetworkAdapter *pThis, PRUnichar * MACAddress);
+
+ nsresult (*GetAttachmentType)(INetworkAdapter *pThis, PRUint32 *attachmentType);
+
+ nsresult (*GetHostInterface)(INetworkAdapter *pThis, PRUnichar * *hostInterface);
+ nsresult (*SetHostInterface)(INetworkAdapter *pThis, PRUnichar * hostInterface);
+
+ nsresult (*GetInternalNetwork)(INetworkAdapter *pThis, PRUnichar * *internalNetwork);
+ nsresult (*SetInternalNetwork)(INetworkAdapter *pThis, PRUnichar * internalNetwork);
+
+ nsresult (*GetNATNetwork)(INetworkAdapter *pThis, PRUnichar * *NATNetwork);
+ nsresult (*SetNATNetwork)(INetworkAdapter *pThis, PRUnichar * NATNetwork);
+
+ nsresult (*GetVDENetwork)(INetworkAdapter *pThis, PRUnichar * *VDENetwork);
+ nsresult (*SetVDENetwork)(INetworkAdapter *pThis, PRUnichar * VDENetwork);
+
+ nsresult (*GetCableConnected)(INetworkAdapter *pThis, PRBool *cableConnected);
+ nsresult (*SetCableConnected)(INetworkAdapter *pThis, PRBool cableConnected);
+
+ nsresult (*GetLineSpeed)(INetworkAdapter *pThis, PRUint32 *lineSpeed);
+ nsresult (*SetLineSpeed)(INetworkAdapter *pThis, PRUint32 lineSpeed);
+
+ nsresult (*GetTraceEnabled)(INetworkAdapter *pThis, PRBool *traceEnabled);
+ nsresult (*SetTraceEnabled)(INetworkAdapter *pThis, PRBool traceEnabled);
+
+ nsresult (*GetTraceFile)(INetworkAdapter *pThis, PRUnichar * *traceFile);
+ nsresult (*SetTraceFile)(INetworkAdapter *pThis, PRUnichar * traceFile);
+
+ nsresult (*GetNatDriver)(INetworkAdapter *pThis, INATEngine * *natDriver);
+
+ nsresult (*GetBootPriority)(INetworkAdapter *pThis, PRUint32 *bootPriority);
+ nsresult (*SetBootPriority)(INetworkAdapter *pThis, PRUint32 bootPriority);
+
+ nsresult (*GetBandwidthLimit)(INetworkAdapter *pThis, PRUint32 *bandwidthLimit);
+ nsresult (*SetBandwidthLimit)(INetworkAdapter *pThis, PRUint32 bandwidthLimit);
+
+ nsresult (*AttachToNAT)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToBridgedInterface)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToInternalNetwork)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToHostOnlyInterface)(INetworkAdapter *pThis );
+
+ nsresult (*AttachToVDE)(INetworkAdapter *pThis );
+
+ nsresult (*Detach)(INetworkAdapter *pThis );
+
+};
+
+struct INetworkAdapter
+{
+ struct INetworkAdapter_vtbl *vtbl;
+};
+/* End of struct INetworkAdapter Declaration */
+
+
+/* Start of struct ISerialPort Declaration */
+#define ISERIALPORT_IID_STR "937f6970-5103-4745-b78e-d28dcf1479a8"
+#define ISERIALPORT_IID { \
+ 0x937f6970, 0x5103, 0x4745, \
+ { 0xb7, 0x8e, 0xd2, 0x8d, 0xcf, 0x14, 0x79, 0xa8 } \
+}
+struct ISerialPort_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetSlot)(ISerialPort *pThis, PRUint32 *slot);
+
+ nsresult (*GetEnabled)(ISerialPort *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(ISerialPort *pThis, PRBool enabled);
+
+ nsresult (*GetIOBase)(ISerialPort *pThis, PRUint32 *IOBase);
+ nsresult (*SetIOBase)(ISerialPort *pThis, PRUint32 IOBase);
+
+ nsresult (*GetIRQ)(ISerialPort *pThis, PRUint32 *IRQ);
+ nsresult (*SetIRQ)(ISerialPort *pThis, PRUint32 IRQ);
+
+ nsresult (*GetHostMode)(ISerialPort *pThis, PRUint32 *hostMode);
+ nsresult (*SetHostMode)(ISerialPort *pThis, PRUint32 hostMode);
+
+ nsresult (*GetServer)(ISerialPort *pThis, PRBool *server);
+ nsresult (*SetServer)(ISerialPort *pThis, PRBool server);
+
+ nsresult (*GetPath)(ISerialPort *pThis, PRUnichar * *path);
+ nsresult (*SetPath)(ISerialPort *pThis, PRUnichar * path);
+
+};
+
+struct ISerialPort
+{
+ struct ISerialPort_vtbl *vtbl;
+};
+/* End of struct ISerialPort Declaration */
+
+
+/* Start of struct IParallelPort Declaration */
+#define IPARALLELPORT_IID_STR "0c925f06-dd10-4b77-8de8-294d738c3214"
+#define IPARALLELPORT_IID { \
+ 0x0c925f06, 0xdd10, 0x4b77, \
+ { 0x8d, 0xe8, 0x29, 0x4d, 0x73, 0x8c, 0x32, 0x14 } \
+}
+struct IParallelPort_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetSlot)(IParallelPort *pThis, PRUint32 *slot);
+
+ nsresult (*GetEnabled)(IParallelPort *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IParallelPort *pThis, PRBool enabled);
+
+ nsresult (*GetIOBase)(IParallelPort *pThis, PRUint32 *IOBase);
+ nsresult (*SetIOBase)(IParallelPort *pThis, PRUint32 IOBase);
+
+ nsresult (*GetIRQ)(IParallelPort *pThis, PRUint32 *IRQ);
+ nsresult (*SetIRQ)(IParallelPort *pThis, PRUint32 IRQ);
+
+ nsresult (*GetPath)(IParallelPort *pThis, PRUnichar * *path);
+ nsresult (*SetPath)(IParallelPort *pThis, PRUnichar * path);
+
+};
+
+struct IParallelPort
+{
+ struct IParallelPort_vtbl *vtbl;
+};
+/* End of struct IParallelPort Declaration */
+
+
+/* Start of struct IMachineDebugger Declaration */
+#define IMACHINEDEBUGGER_IID_STR "1bfd2fa9-0d91-44d3-9515-368dcbb3eb4d"
+#define IMACHINEDEBUGGER_IID { \
+ 0x1bfd2fa9, 0x0d91, 0x44d3, \
+ { 0x95, 0x15, 0x36, 0x8d, 0xcb, 0xb3, 0xeb, 0x4d } \
+}
+struct IMachineDebugger_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetSinglestep)(IMachineDebugger *pThis, PRBool *singlestep);
+ nsresult (*SetSinglestep)(IMachineDebugger *pThis, PRBool singlestep);
+
+ nsresult (*GetRecompileUser)(IMachineDebugger *pThis, PRBool *recompileUser);
+ nsresult (*SetRecompileUser)(IMachineDebugger *pThis, PRBool recompileUser);
+
+ nsresult (*GetRecompileSupervisor)(IMachineDebugger *pThis, PRBool *recompileSupervisor);
+ nsresult (*SetRecompileSupervisor)(IMachineDebugger *pThis, PRBool recompileSupervisor);
+
+ nsresult (*GetPATMEnabled)(IMachineDebugger *pThis, PRBool *PATMEnabled);
+ nsresult (*SetPATMEnabled)(IMachineDebugger *pThis, PRBool PATMEnabled);
+
+ nsresult (*GetCSAMEnabled)(IMachineDebugger *pThis, PRBool *CSAMEnabled);
+ nsresult (*SetCSAMEnabled)(IMachineDebugger *pThis, PRBool CSAMEnabled);
+
+ nsresult (*GetLogEnabled)(IMachineDebugger *pThis, PRBool *logEnabled);
+ nsresult (*SetLogEnabled)(IMachineDebugger *pThis, PRBool logEnabled);
+
+ nsresult (*GetLogFlags)(IMachineDebugger *pThis, PRUnichar * *logFlags);
+
+ nsresult (*GetLogGroups)(IMachineDebugger *pThis, PRUnichar * *logGroups);
+
+ nsresult (*GetLogDestinations)(IMachineDebugger *pThis, PRUnichar * *logDestinations);
+
+ nsresult (*GetHWVirtExEnabled)(IMachineDebugger *pThis, PRBool *HWVirtExEnabled);
+
+ nsresult (*GetHWVirtExNestedPagingEnabled)(IMachineDebugger *pThis, PRBool *HWVirtExNestedPagingEnabled);
+
+ nsresult (*GetHWVirtExVPIDEnabled)(IMachineDebugger *pThis, PRBool *HWVirtExVPIDEnabled);
+
+ nsresult (*GetOSName)(IMachineDebugger *pThis, PRUnichar * *OSName);
+
+ nsresult (*GetOSVersion)(IMachineDebugger *pThis, PRUnichar * *OSVersion);
+
+ nsresult (*GetPAEEnabled)(IMachineDebugger *pThis, PRBool *PAEEnabled);
+
+ nsresult (*GetVirtualTimeRate)(IMachineDebugger *pThis, PRUint32 *virtualTimeRate);
+ nsresult (*SetVirtualTimeRate)(IMachineDebugger *pThis, PRUint32 virtualTimeRate);
+
+ nsresult (*GetVM)(IMachineDebugger *pThis, PRInt64 *VM);
+
+ nsresult (*DumpGuestCore)(
+ IMachineDebugger *pThis,
+ PRUnichar * filename,
+ PRUnichar * compression
+ );
+
+ nsresult (*DumpHostProcessCore)(
+ IMachineDebugger *pThis,
+ PRUnichar * filename,
+ PRUnichar * compression
+ );
+
+ nsresult (*Info)(
+ IMachineDebugger *pThis,
+ PRUnichar * name,
+ PRUnichar * args,
+ PRUnichar * * info
+ );
+
+ nsresult (*InjectNMI)(IMachineDebugger *pThis );
+
+ nsresult (*ModifyLogGroups)(
+ IMachineDebugger *pThis,
+ PRUnichar * settings
+ );
+
+ nsresult (*ModifyLogFlags)(
+ IMachineDebugger *pThis,
+ PRUnichar * settings
+ );
+
+ nsresult (*ModifyLogDestinations)(
+ IMachineDebugger *pThis,
+ PRUnichar * settings
+ );
+
+ nsresult (*ReadPhysicalMemory)(
+ IMachineDebugger *pThis,
+ PRInt64 address,
+ PRUint32 size,
+ PRUint32 *bytesSize,
+ PRUint8** bytes
+ );
+
+ nsresult (*WritePhysicalMemory)(
+ IMachineDebugger *pThis,
+ PRInt64 address,
+ PRUint32 size,
+ PRUint32 bytesSize,
+ PRUint8* bytes
+ );
+
+ nsresult (*ReadVirtualMemory)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRInt64 address,
+ PRUint32 size,
+ PRUint32 *bytesSize,
+ PRUint8** bytes
+ );
+
+ nsresult (*WriteVirtualMemory)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRInt64 address,
+ PRUint32 size,
+ PRUint32 bytesSize,
+ PRUint8* bytes
+ );
+
+ nsresult (*DetectOS)(
+ IMachineDebugger *pThis,
+ PRUnichar * * os
+ );
+
+ nsresult (*GetRegister)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRUnichar * name,
+ PRUnichar * * value
+ );
+
+ nsresult (*GetRegisters)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRUint32 *namesSize,
+ PRUnichar *** names,
+ PRUint32 *valuesSize,
+ PRUnichar *** values
+ );
+
+ nsresult (*SetRegister)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRUnichar * name,
+ PRUnichar * value
+ );
+
+ nsresult (*SetRegisters)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRUint32 namesSize,
+ PRUnichar ** names,
+ PRUint32 valuesSize,
+ PRUnichar ** values
+ );
+
+ nsresult (*DumpGuestStack)(
+ IMachineDebugger *pThis,
+ PRUint32 cpuId,
+ PRUnichar * * stack
+ );
+
+ nsresult (*ResetStats)(
+ IMachineDebugger *pThis,
+ PRUnichar * pattern
+ );
+
+ nsresult (*DumpStats)(
+ IMachineDebugger *pThis,
+ PRUnichar * pattern
+ );
+
+ nsresult (*GetStats)(
+ IMachineDebugger *pThis,
+ PRUnichar * pattern,
+ PRBool withDescriptions,
+ PRUnichar * * stats
+ );
+
+};
+
+struct IMachineDebugger
+{
+ struct IMachineDebugger_vtbl *vtbl;
+};
+/* End of struct IMachineDebugger Declaration */
+
+
+/* Start of struct IUSBController Declaration */
+#define IUSBCONTROLLER_IID_STR "6fdcccc5-abd3-4fec-9387-2ad3914fc4a8"
+#define IUSBCONTROLLER_IID { \
+ 0x6fdcccc5, 0xabd3, 0x4fec, \
+ { 0x93, 0x87, 0x2a, 0xd3, 0x91, 0x4f, 0xc4, 0xa8 } \
+}
+struct IUSBController_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IUSBController *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IUSBController *pThis, PRBool enabled);
+
+ nsresult (*GetEnabledEhci)(IUSBController *pThis, PRBool *enabledEhci);
+ nsresult (*SetEnabledEhci)(IUSBController *pThis, PRBool enabledEhci);
+
+ nsresult (*GetProxyAvailable)(IUSBController *pThis, PRBool *proxyAvailable);
+
+ nsresult (*GetUSBStandard)(IUSBController *pThis, PRUint16 *USBStandard);
+
+ nsresult (*GetDeviceFilters)(IUSBController *pThis, PRUint32 *deviceFiltersSize, IUSBDeviceFilter * **deviceFilters);
+
+ nsresult (*CreateDeviceFilter)(
+ IUSBController *pThis,
+ PRUnichar * name,
+ IUSBDeviceFilter * * filter
+ );
+
+ nsresult (*InsertDeviceFilter)(
+ IUSBController *pThis,
+ PRUint32 position,
+ IUSBDeviceFilter * filter
+ );
+
+ nsresult (*RemoveDeviceFilter)(
+ IUSBController *pThis,
+ PRUint32 position,
+ IUSBDeviceFilter * * filter
+ );
+
+};
+
+struct IUSBController
+{
+ struct IUSBController_vtbl *vtbl;
+};
+/* End of struct IUSBController Declaration */
+
+
+/* Start of struct IUSBDevice Declaration */
+#define IUSBDEVICE_IID_STR "f8967b0b-4483-400f-92b5-8b675d98a85b"
+#define IUSBDEVICE_IID { \
+ 0xf8967b0b, 0x4483, 0x400f, \
+ { 0x92, 0xb5, 0x8b, 0x67, 0x5d, 0x98, 0xa8, 0x5b } \
+}
+struct IUSBDevice_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetId)(IUSBDevice *pThis, PRUnichar * *id);
+
+ nsresult (*GetVendorId)(IUSBDevice *pThis, PRUint16 *vendorId);
+
+ nsresult (*GetProductId)(IUSBDevice *pThis, PRUint16 *productId);
+
+ nsresult (*GetRevision)(IUSBDevice *pThis, PRUint16 *revision);
+
+ nsresult (*GetManufacturer)(IUSBDevice *pThis, PRUnichar * *manufacturer);
+
+ nsresult (*GetProduct)(IUSBDevice *pThis, PRUnichar * *product);
+
+ nsresult (*GetSerialNumber)(IUSBDevice *pThis, PRUnichar * *serialNumber);
+
+ nsresult (*GetAddress)(IUSBDevice *pThis, PRUnichar * *address);
+
+ nsresult (*GetPort)(IUSBDevice *pThis, PRUint16 *port);
+
+ nsresult (*GetVersion)(IUSBDevice *pThis, PRUint16 *version);
+
+ nsresult (*GetPortVersion)(IUSBDevice *pThis, PRUint16 *portVersion);
+
+ nsresult (*GetRemote)(IUSBDevice *pThis, PRBool *remote);
+
+};
+
+struct IUSBDevice
+{
+ struct IUSBDevice_vtbl *vtbl;
+};
+/* End of struct IUSBDevice Declaration */
+
+
+/* Start of struct IUSBDeviceFilter Declaration */
+#define IUSBDEVICEFILTER_IID_STR "d6831fb4-1a94-4c2c-96ef-8d0d6192066d"
+#define IUSBDEVICEFILTER_IID { \
+ 0xd6831fb4, 0x1a94, 0x4c2c, \
+ { 0x96, 0xef, 0x8d, 0x0d, 0x61, 0x92, 0x06, 0x6d } \
+}
+struct IUSBDeviceFilter_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IUSBDeviceFilter *pThis, PRUnichar * *name);
+ nsresult (*SetName)(IUSBDeviceFilter *pThis, PRUnichar * name);
+
+ nsresult (*GetActive)(IUSBDeviceFilter *pThis, PRBool *active);
+ nsresult (*SetActive)(IUSBDeviceFilter *pThis, PRBool active);
+
+ nsresult (*GetVendorId)(IUSBDeviceFilter *pThis, PRUnichar * *vendorId);
+ nsresult (*SetVendorId)(IUSBDeviceFilter *pThis, PRUnichar * vendorId);
+
+ nsresult (*GetProductId)(IUSBDeviceFilter *pThis, PRUnichar * *productId);
+ nsresult (*SetProductId)(IUSBDeviceFilter *pThis, PRUnichar * productId);
+
+ nsresult (*GetRevision)(IUSBDeviceFilter *pThis, PRUnichar * *revision);
+ nsresult (*SetRevision)(IUSBDeviceFilter *pThis, PRUnichar * revision);
+
+ nsresult (*GetManufacturer)(IUSBDeviceFilter *pThis, PRUnichar * *manufacturer);
+ nsresult (*SetManufacturer)(IUSBDeviceFilter *pThis, PRUnichar * manufacturer);
+
+ nsresult (*GetProduct)(IUSBDeviceFilter *pThis, PRUnichar * *product);
+ nsresult (*SetProduct)(IUSBDeviceFilter *pThis, PRUnichar * product);
+
+ nsresult (*GetSerialNumber)(IUSBDeviceFilter *pThis, PRUnichar * *serialNumber);
+ nsresult (*SetSerialNumber)(IUSBDeviceFilter *pThis, PRUnichar * serialNumber);
+
+ nsresult (*GetPort)(IUSBDeviceFilter *pThis, PRUnichar * *port);
+ nsresult (*SetPort)(IUSBDeviceFilter *pThis, PRUnichar * port);
+
+ nsresult (*GetRemote)(IUSBDeviceFilter *pThis, PRUnichar * *remote);
+ nsresult (*SetRemote)(IUSBDeviceFilter *pThis, PRUnichar * remote);
+
+ nsresult (*GetMaskedInterfaces)(IUSBDeviceFilter *pThis, PRUint32 *maskedInterfaces);
+ nsresult (*SetMaskedInterfaces)(IUSBDeviceFilter *pThis, PRUint32 maskedInterfaces);
+
+};
+
+struct IUSBDeviceFilter
+{
+ struct IUSBDeviceFilter_vtbl *vtbl;
+};
+/* End of struct IUSBDeviceFilter Declaration */
+
+
+/* Start of struct IHostUSBDevice Declaration */
+#define IHOSTUSBDEVICE_IID_STR "173b4b44-d268-4334-a00d-b6521c9a740a"
+#define IHOSTUSBDEVICE_IID { \
+ 0x173b4b44, 0xd268, 0x4334, \
+ { 0xa0, 0x0d, 0xb6, 0x52, 0x1c, 0x9a, 0x74, 0x0a } \
+}
+struct IHostUSBDevice_vtbl
+{
+ struct IUSBDevice_vtbl iusbdevice;
+
+ nsresult (*GetState)(IHostUSBDevice *pThis, PRUint32 *state);
+
+};
+
+struct IHostUSBDevice
+{
+ struct IHostUSBDevice_vtbl *vtbl;
+};
+/* End of struct IHostUSBDevice Declaration */
+
+
+/* Start of struct IHostUSBDeviceFilter Declaration */
+#define IHOSTUSBDEVICEFILTER_IID_STR "4cc70246-d74a-400f-8222-3900489c0374"
+#define IHOSTUSBDEVICEFILTER_IID { \
+ 0x4cc70246, 0xd74a, 0x400f, \
+ { 0x82, 0x22, 0x39, 0x00, 0x48, 0x9c, 0x03, 0x74 } \
+}
+struct IHostUSBDeviceFilter_vtbl
+{
+ struct IUSBDeviceFilter_vtbl iusbdevicefilter;
+
+ nsresult (*GetAction)(IHostUSBDeviceFilter *pThis, PRUint32 *action);
+ nsresult (*SetAction)(IHostUSBDeviceFilter *pThis, PRUint32 action);
+
+};
+
+struct IHostUSBDeviceFilter
+{
+ struct IHostUSBDeviceFilter_vtbl *vtbl;
+};
+/* End of struct IHostUSBDeviceFilter Declaration */
+
+
+/* Start of struct IAudioAdapter Declaration */
+#define IAUDIOADAPTER_IID_STR "921873db-5f3f-4b69-91f9-7be9e535a2cb"
+#define IAUDIOADAPTER_IID { \
+ 0x921873db, 0x5f3f, 0x4b69, \
+ { 0x91, 0xf9, 0x7b, 0xe9, 0xe5, 0x35, 0xa2, 0xcb } \
+}
+struct IAudioAdapter_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IAudioAdapter *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IAudioAdapter *pThis, PRBool enabled);
+
+ nsresult (*GetAudioController)(IAudioAdapter *pThis, PRUint32 *audioController);
+ nsresult (*SetAudioController)(IAudioAdapter *pThis, PRUint32 audioController);
+
+ nsresult (*GetAudioDriver)(IAudioAdapter *pThis, PRUint32 *audioDriver);
+ nsresult (*SetAudioDriver)(IAudioAdapter *pThis, PRUint32 audioDriver);
+
+};
+
+struct IAudioAdapter
+{
+ struct IAudioAdapter_vtbl *vtbl;
+};
+/* End of struct IAudioAdapter Declaration */
+
+
+/* Start of struct IVRDEServer Declaration */
+#define IVRDESERVER_IID_STR "be24e0db-e1d6-4d58-b85b-21053d1511b4"
+#define IVRDESERVER_IID { \
+ 0xbe24e0db, 0xe1d6, 0x4d58, \
+ { 0xb8, 0x5b, 0x21, 0x05, 0x3d, 0x15, 0x11, 0xb4 } \
+}
+struct IVRDEServer_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetEnabled)(IVRDEServer *pThis, PRBool *enabled);
+ nsresult (*SetEnabled)(IVRDEServer *pThis, PRBool enabled);
+
+ nsresult (*GetAuthType)(IVRDEServer *pThis, PRUint32 *authType);
+ nsresult (*SetAuthType)(IVRDEServer *pThis, PRUint32 authType);
+
+ nsresult (*GetAuthTimeout)(IVRDEServer *pThis, PRUint32 *authTimeout);
+ nsresult (*SetAuthTimeout)(IVRDEServer *pThis, PRUint32 authTimeout);
+
+ nsresult (*GetAllowMultiConnection)(IVRDEServer *pThis, PRBool *allowMultiConnection);
+ nsresult (*SetAllowMultiConnection)(IVRDEServer *pThis, PRBool allowMultiConnection);
+
+ nsresult (*GetReuseSingleConnection)(IVRDEServer *pThis, PRBool *reuseSingleConnection);
+ nsresult (*SetReuseSingleConnection)(IVRDEServer *pThis, PRBool reuseSingleConnection);
+
+ nsresult (*GetVRDEExtPack)(IVRDEServer *pThis, PRUnichar * *VRDEExtPack);
+ nsresult (*SetVRDEExtPack)(IVRDEServer *pThis, PRUnichar * VRDEExtPack);
+
+ nsresult (*GetAuthLibrary)(IVRDEServer *pThis, PRUnichar * *AuthLibrary);
+ nsresult (*SetAuthLibrary)(IVRDEServer *pThis, PRUnichar * AuthLibrary);
+
+ nsresult (*GetVRDEProperties)(IVRDEServer *pThis, PRUint32 *VRDEPropertiesSize, PRUnichar * **VRDEProperties);
+
+ nsresult (*SetVRDEProperty)(
+ IVRDEServer *pThis,
+ PRUnichar * key,
+ PRUnichar * value
+ );
+
+ nsresult (*GetVRDEProperty)(
+ IVRDEServer *pThis,
+ PRUnichar * key,
+ PRUnichar * * value
+ );
+
+};
+
+struct IVRDEServer
+{
+ struct IVRDEServer_vtbl *vtbl;
+};
+/* End of struct IVRDEServer Declaration */
+
+
+/* Start of struct ISharedFolder Declaration */
+#define ISHAREDFOLDER_IID_STR "8388da11-b559-4574-a5b7-2bd7acd5cef8"
+#define ISHAREDFOLDER_IID { \
+ 0x8388da11, 0xb559, 0x4574, \
+ { 0xa5, 0xb7, 0x2b, 0xd7, 0xac, 0xd5, 0xce, 0xf8 } \
+}
+struct ISharedFolder_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(ISharedFolder *pThis, PRUnichar * *name);
+
+ nsresult (*GetHostPath)(ISharedFolder *pThis, PRUnichar * *hostPath);
+
+ nsresult (*GetAccessible)(ISharedFolder *pThis, PRBool *accessible);
+
+ nsresult (*GetWritable)(ISharedFolder *pThis, PRBool *writable);
+
+ nsresult (*GetAutoMount)(ISharedFolder *pThis, PRBool *autoMount);
+
+ nsresult (*GetLastAccessError)(ISharedFolder *pThis, PRUnichar * *lastAccessError);
+
+};
+
+struct ISharedFolder
+{
+ struct ISharedFolder_vtbl *vtbl;
+};
+/* End of struct ISharedFolder Declaration */
+
+
+/* Start of struct IInternalSessionControl Declaration */
+#define IINTERNALSESSIONCONTROL_IID_STR "a2fbf834-149d-41da-ae52-0dc3b0f032b3"
+#define IINTERNALSESSIONCONTROL_IID { \
+ 0xa2fbf834, 0x149d, 0x41da, \
+ { 0xae, 0x52, 0x0d, 0xc3, 0xb0, 0xf0, 0x32, 0xb3 } \
+}
+struct IInternalSessionControl_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetPID)(
+ IInternalSessionControl *pThis,
+ PRUint32 * pid
+ );
+
+ nsresult (*GetRemoteConsole)(
+ IInternalSessionControl *pThis,
+ IConsole * * console
+ );
+
+ nsresult (*AssignMachine)(
+ IInternalSessionControl *pThis,
+ IMachine * machine
+ );
+
+ nsresult (*AssignRemoteMachine)(
+ IInternalSessionControl *pThis,
+ IMachine * machine,
+ IConsole * console
+ );
+
+ nsresult (*UpdateMachineState)(
+ IInternalSessionControl *pThis,
+ PRUint32 aMachineState
+ );
+
+ nsresult (*Uninitialize)(IInternalSessionControl *pThis );
+
+ nsresult (*OnNetworkAdapterChange)(
+ IInternalSessionControl *pThis,
+ INetworkAdapter * networkAdapter,
+ PRBool changeAdapter
+ );
+
+ nsresult (*OnSerialPortChange)(
+ IInternalSessionControl *pThis,
+ ISerialPort * serialPort
+ );
+
+ nsresult (*OnParallelPortChange)(
+ IInternalSessionControl *pThis,
+ IParallelPort * parallelPort
+ );
+
+ nsresult (*OnStorageControllerChange)(IInternalSessionControl *pThis );
+
+ nsresult (*OnMediumChange)(
+ IInternalSessionControl *pThis,
+ IMediumAttachment * mediumAttachment,
+ PRBool force
+ );
+
+ nsresult (*OnCPUChange)(
+ IInternalSessionControl *pThis,
+ PRUint32 cpu,
+ PRBool add
+ );
+
+ nsresult (*OnCPUExecutionCapChange)(
+ IInternalSessionControl *pThis,
+ PRUint32 executionCap
+ );
+
+ nsresult (*OnVRDEServerChange)(
+ IInternalSessionControl *pThis,
+ PRBool restart
+ );
+
+ nsresult (*OnUSBControllerChange)(IInternalSessionControl *pThis );
+
+ nsresult (*OnSharedFolderChange)(
+ IInternalSessionControl *pThis,
+ PRBool global
+ );
+
+ nsresult (*OnUSBDeviceAttach)(
+ IInternalSessionControl *pThis,
+ IUSBDevice * device,
+ IVirtualBoxErrorInfo * error,
+ PRUint32 maskedInterfaces
+ );
+
+ nsresult (*OnUSBDeviceDetach)(
+ IInternalSessionControl *pThis,
+ PRUnichar * id,
+ IVirtualBoxErrorInfo * error
+ );
+
+ nsresult (*OnShowWindow)(
+ IInternalSessionControl *pThis,
+ PRBool check,
+ PRBool * canShow,
+ PRInt64 * winId
+ );
+
+ nsresult (*OnBandwidthGroupChange)(
+ IInternalSessionControl *pThis,
+ IBandwidthGroup * bandwidthGroup
+ );
+
+ nsresult (*AccessGuestProperty)(
+ IInternalSessionControl *pThis,
+ PRUnichar * name,
+ PRUnichar * value,
+ PRUnichar * flags,
+ PRBool isSetter,
+ PRUnichar * * retValue,
+ PRInt64 * retTimestamp,
+ PRUnichar * * retFlags
+ );
+
+ nsresult (*EnumerateGuestProperties)(
+ IInternalSessionControl *pThis,
+ PRUnichar * patterns,
+ PRUint32 *keySize,
+ PRUnichar *** key,
+ PRUint32 *valueSize,
+ PRUnichar *** value,
+ PRUint32 *timestampSize,
+ PRInt64* timestamp,
+ PRUint32 *flagsSize,
+ PRUnichar *** flags
+ );
+
+ nsresult (*OnlineMergeMedium)(
+ IInternalSessionControl *pThis,
+ IMediumAttachment * mediumAttachment,
+ PRUint32 sourceIdx,
+ PRUint32 targetIdx,
+ IMedium * source,
+ IMedium * target,
+ PRBool mergeForward,
+ IMedium * parentForTarget,
+ PRUint32 childrenToReparentSize,
+ IMedium ** childrenToReparent,
+ IProgress * progress
+ );
+
+};
+
+struct IInternalSessionControl
+{
+ struct IInternalSessionControl_vtbl *vtbl;
+};
+/* End of struct IInternalSessionControl Declaration */
+
+
+/* Start of struct ISession Declaration */
+#define ISESSION_IID_STR "12F4DCDB-12B2-4EC1-B7CD-DDD9F6C5BF4D"
+#define ISESSION_IID { \
+ 0x12F4DCDB, 0x12B2, 0x4EC1, \
+ { 0xB7, 0xCD, 0xDD, 0xD9, 0xF6, 0xC5, 0xBF, 0x4D } \
+}
+struct ISession_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetState)(ISession *pThis, PRUint32 *state);
+
+ nsresult (*GetType)(ISession *pThis, PRUint32 *type);
+
+ nsresult (*GetMachine)(ISession *pThis, IMachine * *machine);
+
+ nsresult (*GetConsole)(ISession *pThis, IConsole * *console);
+
+ nsresult (*UnlockMachine)(ISession *pThis );
+
+};
+
+struct ISession
+{
+ struct ISession_vtbl *vtbl;
+};
+/* End of struct ISession Declaration */
+
+
+/* Start of struct IStorageController Declaration */
+#define ISTORAGECONTROLLER_IID_STR "a1556333-09b6-46d9-bfb7-fc239b7fbe1e"
+#define ISTORAGECONTROLLER_IID { \
+ 0xa1556333, 0x09b6, 0x46d9, \
+ { 0xbf, 0xb7, 0xfc, 0x23, 0x9b, 0x7f, 0xbe, 0x1e } \
+}
+struct IStorageController_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IStorageController *pThis, PRUnichar * *name);
+
+ nsresult (*GetMaxDevicesPerPortCount)(IStorageController *pThis, PRUint32 *maxDevicesPerPortCount);
+
+ nsresult (*GetMinPortCount)(IStorageController *pThis, PRUint32 *minPortCount);
+
+ nsresult (*GetMaxPortCount)(IStorageController *pThis, PRUint32 *maxPortCount);
+
+ nsresult (*GetInstance)(IStorageController *pThis, PRUint32 *instance);
+ nsresult (*SetInstance)(IStorageController *pThis, PRUint32 instance);
+
+ nsresult (*GetPortCount)(IStorageController *pThis, PRUint32 *portCount);
+ nsresult (*SetPortCount)(IStorageController *pThis, PRUint32 portCount);
+
+ nsresult (*GetBus)(IStorageController *pThis, PRUint32 *bus);
+
+ nsresult (*GetControllerType)(IStorageController *pThis, PRUint32 *controllerType);
+ nsresult (*SetControllerType)(IStorageController *pThis, PRUint32 controllerType);
+
+ nsresult (*GetUseHostIOCache)(IStorageController *pThis, PRBool *useHostIOCache);
+ nsresult (*SetUseHostIOCache)(IStorageController *pThis, PRBool useHostIOCache);
+
+ nsresult (*GetBootable)(IStorageController *pThis, PRBool *bootable);
+
+ nsresult (*GetIDEEmulationPort)(
+ IStorageController *pThis,
+ PRInt32 devicePosition,
+ PRInt32 * portNumber
+ );
+
+ nsresult (*SetIDEEmulationPort)(
+ IStorageController *pThis,
+ PRInt32 devicePosition,
+ PRInt32 portNumber
+ );
+
+};
+
+struct IStorageController
+{
+ struct IStorageController_vtbl *vtbl;
+};
+/* End of struct IStorageController Declaration */
+
+
+/* Start of struct IPerformanceMetric Declaration */
+#define IPERFORMANCEMETRIC_IID_STR "2a1a60ae-9345-4019-ad53-d34ba41cbfe9"
+#define IPERFORMANCEMETRIC_IID { \
+ 0x2a1a60ae, 0x9345, 0x4019, \
+ { 0xad, 0x53, 0xd3, 0x4b, 0xa4, 0x1c, 0xbf, 0xe9 } \
+}
+struct IPerformanceMetric_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMetricName)(IPerformanceMetric *pThis, PRUnichar * *metricName);
+
+ nsresult (*GetObject)(IPerformanceMetric *pThis, nsISupports * *object);
+
+ nsresult (*GetDescription)(IPerformanceMetric *pThis, PRUnichar * *description);
+
+ nsresult (*GetPeriod)(IPerformanceMetric *pThis, PRUint32 *period);
+
+ nsresult (*GetCount)(IPerformanceMetric *pThis, PRUint32 *count);
+
+ nsresult (*GetUnit)(IPerformanceMetric *pThis, PRUnichar * *unit);
+
+ nsresult (*GetMinimumValue)(IPerformanceMetric *pThis, PRInt32 *minimumValue);
+
+ nsresult (*GetMaximumValue)(IPerformanceMetric *pThis, PRInt32 *maximumValue);
+
+};
+
+struct IPerformanceMetric
+{
+ struct IPerformanceMetric_vtbl *vtbl;
+};
+/* End of struct IPerformanceMetric Declaration */
+
+
+/* Start of struct IPerformanceCollector Declaration */
+#define IPERFORMANCECOLLECTOR_IID_STR "e22e1acb-ac4a-43bb-a31c-17321659b0c6"
+#define IPERFORMANCECOLLECTOR_IID { \
+ 0xe22e1acb, 0xac4a, 0x43bb, \
+ { 0xa3, 0x1c, 0x17, 0x32, 0x16, 0x59, 0xb0, 0xc6 } \
+}
+struct IPerformanceCollector_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetMetricNames)(IPerformanceCollector *pThis, PRUint32 *metricNamesSize, PRUnichar * **metricNames);
+
+ nsresult (*GetMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *metricsSize,
+ IPerformanceMetric *** metrics
+ );
+
+ nsresult (*SetupMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 period,
+ PRUint32 count,
+ PRUint32 *affectedMetricsSize,
+ IPerformanceMetric *** affectedMetrics
+ );
+
+ nsresult (*EnableMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *affectedMetricsSize,
+ IPerformanceMetric *** affectedMetrics
+ );
+
+ nsresult (*DisableMetrics)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *affectedMetricsSize,
+ IPerformanceMetric *** affectedMetrics
+ );
+
+ nsresult (*QueryMetricsData)(
+ IPerformanceCollector *pThis,
+ PRUint32 metricNamesSize,
+ PRUnichar ** metricNames,
+ PRUint32 objectsSize,
+ nsISupports ** objects,
+ PRUint32 *returnMetricNamesSize,
+ PRUnichar *** returnMetricNames,
+ PRUint32 *returnObjectsSize,
+ nsISupports ** returnObjects,
+ PRUint32 *returnUnitsSize,
+ PRUnichar *** returnUnits,
+ PRUint32 *returnScalesSize,
+ PRUint32* returnScales,
+ PRUint32 *returnSequenceNumbersSize,
+ PRUint32* returnSequenceNumbers,
+ PRUint32 *returnDataIndicesSize,
+ PRUint32* returnDataIndices,
+ PRUint32 *returnDataLengthsSize,
+ PRUint32* returnDataLengths,
+ PRUint32 *returnDataSize,
+ PRInt32** returnData
+ );
+
+};
+
+struct IPerformanceCollector
+{
+ struct IPerformanceCollector_vtbl *vtbl;
+};
+/* End of struct IPerformanceCollector Declaration */
+
+
+/* Start of struct INATEngine Declaration */
+#define INATENGINE_IID_STR "4b286616-eb03-11de-b0fb-1701eca42246"
+#define INATENGINE_IID { \
+ 0x4b286616, 0xeb03, 0x11de, \
+ { 0xb0, 0xfb, 0x17, 0x01, 0xec, 0xa4, 0x22, 0x46 } \
+}
+struct INATEngine_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetNetwork)(INATEngine *pThis, PRUnichar * *network);
+ nsresult (*SetNetwork)(INATEngine *pThis, PRUnichar * network);
+
+ nsresult (*GetHostIP)(INATEngine *pThis, PRUnichar * *hostIP);
+ nsresult (*SetHostIP)(INATEngine *pThis, PRUnichar * hostIP);
+
+ nsresult (*GetTftpPrefix)(INATEngine *pThis, PRUnichar * *tftpPrefix);
+ nsresult (*SetTftpPrefix)(INATEngine *pThis, PRUnichar * tftpPrefix);
+
+ nsresult (*GetTftpBootFile)(INATEngine *pThis, PRUnichar * *tftpBootFile);
+ nsresult (*SetTftpBootFile)(INATEngine *pThis, PRUnichar * tftpBootFile);
+
+ nsresult (*GetTftpNextServer)(INATEngine *pThis, PRUnichar * *tftpNextServer);
+ nsresult (*SetTftpNextServer)(INATEngine *pThis, PRUnichar * tftpNextServer);
+
+ nsresult (*GetAliasMode)(INATEngine *pThis, PRUint32 *aliasMode);
+ nsresult (*SetAliasMode)(INATEngine *pThis, PRUint32 aliasMode);
+
+ nsresult (*GetDnsPassDomain)(INATEngine *pThis, PRBool *dnsPassDomain);
+ nsresult (*SetDnsPassDomain)(INATEngine *pThis, PRBool dnsPassDomain);
+
+ nsresult (*GetDnsProxy)(INATEngine *pThis, PRBool *dnsProxy);
+ nsresult (*SetDnsProxy)(INATEngine *pThis, PRBool dnsProxy);
+
+ nsresult (*GetDnsUseHostResolver)(INATEngine *pThis, PRBool *dnsUseHostResolver);
+ nsresult (*SetDnsUseHostResolver)(INATEngine *pThis, PRBool dnsUseHostResolver);
+
+ nsresult (*GetRedirects)(INATEngine *pThis, PRUint32 *redirectsSize, PRUnichar * **redirects);
+
+ nsresult (*SetNetworkSettings)(
+ INATEngine *pThis,
+ PRUint32 mtu,
+ PRUint32 sockSnd,
+ PRUint32 sockRcv,
+ PRUint32 TcpWndSnd,
+ PRUint32 TcpWndRcv
+ );
+
+ nsresult (*GetNetworkSettings)(
+ INATEngine *pThis,
+ PRUint32 * mtu,
+ PRUint32 * sockSnd,
+ PRUint32 * sockRcv,
+ PRUint32 * TcpWndSnd,
+ PRUint32 * TcpWndRcv
+ );
+
+ nsresult (*AddRedirect)(
+ INATEngine *pThis,
+ PRUnichar * name,
+ PRUint32 proto,
+ PRUnichar * hostIp,
+ PRUint16 hostPort,
+ PRUnichar * guestIp,
+ PRUint16 guestPort
+ );
+
+ nsresult (*RemoveRedirect)(
+ INATEngine *pThis,
+ PRUnichar * name
+ );
+
+};
+
+struct INATEngine
+{
+ struct INATEngine_vtbl *vtbl;
+};
+/* End of struct INATEngine Declaration */
+
+
+/* Start of struct IExtPackPlugIn Declaration */
+#define IEXTPACKPLUGIN_IID_STR "58000040-e718-4746-bbce-4b86d96da461"
+#define IEXTPACKPLUGIN_IID { \
+ 0x58000040, 0xe718, 0x4746, \
+ { 0xbb, 0xce, 0x4b, 0x86, 0xd9, 0x6d, 0xa4, 0x61 } \
+}
+struct IExtPackPlugIn_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IExtPackPlugIn *pThis, PRUnichar * *name);
+
+ nsresult (*GetDescription)(IExtPackPlugIn *pThis, PRUnichar * *description);
+
+ nsresult (*GetFrontend)(IExtPackPlugIn *pThis, PRUnichar * *frontend);
+
+ nsresult (*GetModulePath)(IExtPackPlugIn *pThis, PRUnichar * *modulePath);
+
+};
+
+struct IExtPackPlugIn
+{
+ struct IExtPackPlugIn_vtbl *vtbl;
+};
+/* End of struct IExtPackPlugIn Declaration */
+
+
+/* Start of struct IExtPackBase Declaration */
+#define IEXTPACKBASE_IID_STR "5ffb0b64-0ad6-467d-af62-1157e7dc3c99"
+#define IEXTPACKBASE_IID { \
+ 0x5ffb0b64, 0x0ad6, 0x467d, \
+ { 0xaf, 0x62, 0x11, 0x57, 0xe7, 0xdc, 0x3c, 0x99 } \
+}
+struct IExtPackBase_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IExtPackBase *pThis, PRUnichar * *name);
+
+ nsresult (*GetDescription)(IExtPackBase *pThis, PRUnichar * *description);
+
+ nsresult (*GetVersion)(IExtPackBase *pThis, PRUnichar * *version);
+
+ nsresult (*GetRevision)(IExtPackBase *pThis, PRUint32 *revision);
+
+ nsresult (*GetVRDEModule)(IExtPackBase *pThis, PRUnichar * *VRDEModule);
+
+ nsresult (*GetPlugIns)(IExtPackBase *pThis, PRUint32 *plugInsSize, IExtPackPlugIn * **plugIns);
+
+ nsresult (*GetUsable)(IExtPackBase *pThis, PRBool *usable);
+
+ nsresult (*GetWhyUnusable)(IExtPackBase *pThis, PRUnichar * *whyUnusable);
+
+ nsresult (*GetShowLicense)(IExtPackBase *pThis, PRBool *showLicense);
+
+ nsresult (*GetLicense)(IExtPackBase *pThis, PRUnichar * *license);
+
+ nsresult (*QueryLicense)(
+ IExtPackBase *pThis,
+ PRUnichar * preferredLocale,
+ PRUnichar * preferredLanguage,
+ PRUnichar * format,
+ PRUnichar * * licenseText
+ );
+
+};
+
+struct IExtPackBase
+{
+ struct IExtPackBase_vtbl *vtbl;
+};
+/* End of struct IExtPackBase Declaration */
+
+
+/* Start of struct IExtPack Declaration */
+#define IEXTPACK_IID_STR "431685da-3618-4ebc-b038-833ba829b4b2"
+#define IEXTPACK_IID { \
+ 0x431685da, 0x3618, 0x4ebc, \
+ { 0xb0, 0x38, 0x83, 0x3b, 0xa8, 0x29, 0xb4, 0xb2 } \
+}
+struct IExtPack_vtbl
+{
+ struct IExtPackBase_vtbl iextpackbase;
+
+ nsresult (*QueryObject)(
+ IExtPack *pThis,
+ PRUnichar * objUuid,
+ nsISupports * * returnInterface
+ );
+
+};
+
+struct IExtPack
+{
+ struct IExtPack_vtbl *vtbl;
+};
+/* End of struct IExtPack Declaration */
+
+
+/* Start of struct IExtPackFile Declaration */
+#define IEXTPACKFILE_IID_STR "b6b49f55-efcc-4f08-b486-56e8d8afb10b"
+#define IEXTPACKFILE_IID { \
+ 0xb6b49f55, 0xefcc, 0x4f08, \
+ { 0xb4, 0x86, 0x56, 0xe8, 0xd8, 0xaf, 0xb1, 0x0b } \
+}
+struct IExtPackFile_vtbl
+{
+ struct IExtPackBase_vtbl iextpackbase;
+
+ nsresult (*GetFilePath)(IExtPackFile *pThis, PRUnichar * *filePath);
+
+ nsresult (*Install)(
+ IExtPackFile *pThis,
+ PRBool replace,
+ PRUnichar * displayInfo,
+ IProgress * * progess
+ );
+
+};
+
+struct IExtPackFile
+{
+ struct IExtPackFile_vtbl *vtbl;
+};
+/* End of struct IExtPackFile Declaration */
+
+
+/* Start of struct IExtPackManager Declaration */
+#define IEXTPACKMANAGER_IID_STR "2451b1ba-ab1c-42fb-b453-c58433bea8c7"
+#define IEXTPACKMANAGER_IID { \
+ 0x2451b1ba, 0xab1c, 0x42fb, \
+ { 0xb4, 0x53, 0xc5, 0x84, 0x33, 0xbe, 0xa8, 0xc7 } \
+}
+struct IExtPackManager_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetInstalledExtPacks)(IExtPackManager *pThis, PRUint32 *installedExtPacksSize, IExtPack * **installedExtPacks);
+
+ nsresult (*Find)(
+ IExtPackManager *pThis,
+ PRUnichar * name,
+ IExtPack * * returnData
+ );
+
+ nsresult (*OpenExtPackFile)(
+ IExtPackManager *pThis,
+ PRUnichar * path,
+ IExtPackFile * * file
+ );
+
+ nsresult (*Uninstall)(
+ IExtPackManager *pThis,
+ PRUnichar * name,
+ PRBool forcedRemoval,
+ PRUnichar * displayInfo,
+ IProgress * * progess
+ );
+
+ nsresult (*Cleanup)(IExtPackManager *pThis );
+
+ nsresult (*QueryAllPlugInsForFrontend)(
+ IExtPackManager *pThis,
+ PRUnichar * frontendName,
+ PRUint32 *plugInModulesSize,
+ PRUnichar *** plugInModules
+ );
+
+ nsresult (*IsExtPackUsable)(
+ IExtPackManager *pThis,
+ PRUnichar * name,
+ PRBool * usable
+ );
+
+};
+
+struct IExtPackManager
+{
+ struct IExtPackManager_vtbl *vtbl;
+};
+/* End of struct IExtPackManager Declaration */
+
+
+/* Start of struct IBandwidthGroup Declaration */
+#define IBANDWIDTHGROUP_IID_STR "badea2d7-0261-4146-89f0-6a57cc34833d"
+#define IBANDWIDTHGROUP_IID { \
+ 0xbadea2d7, 0x0261, 0x4146, \
+ { 0x89, 0xf0, 0x6a, 0x57, 0xcc, 0x34, 0x83, 0x3d } \
+}
+struct IBandwidthGroup_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetName)(IBandwidthGroup *pThis, PRUnichar * *name);
+
+ nsresult (*GetType)(IBandwidthGroup *pThis, PRUint32 *type);
+
+ nsresult (*GetReference)(IBandwidthGroup *pThis, PRUint32 *reference);
+
+ nsresult (*GetMaxMbPerSec)(IBandwidthGroup *pThis, PRUint32 *maxMbPerSec);
+ nsresult (*SetMaxMbPerSec)(IBandwidthGroup *pThis, PRUint32 maxMbPerSec);
+
+};
+
+struct IBandwidthGroup
+{
+ struct IBandwidthGroup_vtbl *vtbl;
+};
+/* End of struct IBandwidthGroup Declaration */
+
+
+/* Start of struct IBandwidthControl Declaration */
+#define IBANDWIDTHCONTROL_IID_STR "d0a24db0-f756-11df-98cf-0800200c9a66"
+#define IBANDWIDTHCONTROL_IID { \
+ 0xd0a24db0, 0xf756, 0x11df, \
+ { 0x98, 0xcf, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } \
+}
+struct IBandwidthControl_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetNumGroups)(IBandwidthControl *pThis, PRUint32 *numGroups);
+
+ nsresult (*CreateBandwidthGroup)(
+ IBandwidthControl *pThis,
+ PRUnichar * name,
+ PRUint32 type,
+ PRUint32 maxMbPerSec
+ );
+
+ nsresult (*DeleteBandwidthGroup)(
+ IBandwidthControl *pThis,
+ PRUnichar * name
+ );
+
+ nsresult (*GetBandwidthGroup)(
+ IBandwidthControl *pThis,
+ PRUnichar * name,
+ IBandwidthGroup * * bandwidthGroup
+ );
+
+ nsresult (*GetAllBandwidthGroups)(
+ IBandwidthControl *pThis,
+ PRUint32 *bandwidthGroupsSize,
+ IBandwidthGroup *** bandwidthGroups
+ );
+
+};
+
+struct IBandwidthControl
+{
+ struct IBandwidthControl_vtbl *vtbl;
+};
+/* End of struct IBandwidthControl Declaration */
+
+
+/* Start of struct IVirtualBoxClient Declaration */
+#define IVIRTUALBOXCLIENT_IID_STR "5fe0bd48-1181-40d1-991f-3b02f269a823"
+#define IVIRTUALBOXCLIENT_IID { \
+ 0x5fe0bd48, 0x1181, 0x40d1, \
+ { 0x99, 0x1f, 0x3b, 0x02, 0xf2, 0x69, 0xa8, 0x23 } \
+}
+struct IVirtualBoxClient_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetVirtualBox)(IVirtualBoxClient *pThis, IVirtualBox * *virtualBox);
+
+ nsresult (*GetSession)(IVirtualBoxClient *pThis, ISession * *session);
+
+ nsresult (*GetEventSource)(IVirtualBoxClient *pThis, IEventSource * *eventSource);
+
+};
+
+struct IVirtualBoxClient
+{
+ struct IVirtualBoxClient_vtbl *vtbl;
+};
+/* End of struct IVirtualBoxClient Declaration */
+
+
+/* Start of struct IEventSource Declaration */
+#define IEVENTSOURCE_IID_STR "9b6e1aee-35f3-4f4d-b5bb-ed0ecefd8538"
+#define IEVENTSOURCE_IID { \
+ 0x9b6e1aee, 0x35f3, 0x4f4d, \
+ { 0xb5, 0xbb, 0xed, 0x0e, 0xce, 0xfd, 0x85, 0x38 } \
+}
+struct IEventSource_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*CreateListener)(
+ IEventSource *pThis,
+ IEventListener * * listener
+ );
+
+ nsresult (*CreateAggregator)(
+ IEventSource *pThis,
+ PRUint32 subordinatesSize,
+ IEventSource ** subordinates,
+ IEventSource * * result
+ );
+
+ nsresult (*RegisterListener)(
+ IEventSource *pThis,
+ IEventListener * listener,
+ PRUint32 interestingSize,
+ PRUint32* interesting,
+ PRBool active
+ );
+
+ nsresult (*UnregisterListener)(
+ IEventSource *pThis,
+ IEventListener * listener
+ );
+
+ nsresult (*FireEvent)(
+ IEventSource *pThis,
+ IEvent * event,
+ PRInt32 timeout,
+ PRBool * result
+ );
+
+ nsresult (*GetEvent)(
+ IEventSource *pThis,
+ IEventListener * listener,
+ PRInt32 timeout,
+ IEvent * * event
+ );
+
+ nsresult (*EventProcessed)(
+ IEventSource *pThis,
+ IEventListener * listener,
+ IEvent * event
+ );
+
+};
+
+struct IEventSource
+{
+ struct IEventSource_vtbl *vtbl;
+};
+/* End of struct IEventSource Declaration */
+
+
+/* Start of struct IEventListener Declaration */
+#define IEVENTLISTENER_IID_STR "67099191-32e7-4f6c-85ee-422304c71b90"
+#define IEVENTLISTENER_IID { \
+ 0x67099191, 0x32e7, 0x4f6c, \
+ { 0x85, 0xee, 0x42, 0x23, 0x04, 0xc7, 0x1b, 0x90 } \
+}
+struct IEventListener_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*HandleEvent)(
+ IEventListener *pThis,
+ IEvent * event
+ );
+
+};
+
+struct IEventListener
+{
+ struct IEventListener_vtbl *vtbl;
+};
+/* End of struct IEventListener Declaration */
+
+
+/* Start of struct IEvent Declaration */
+#define IEVENT_IID_STR "0ca2adba-8f30-401b-a8cd-fe31dbe839c0"
+#define IEVENT_IID { \
+ 0x0ca2adba, 0x8f30, 0x401b, \
+ { 0xa8, 0xcd, 0xfe, 0x31, 0xdb, 0xe8, 0x39, 0xc0 } \
+}
+struct IEvent_vtbl
+{
+ struct nsISupports_vtbl nsisupports;
+
+ nsresult (*GetType)(IEvent *pThis, PRUint32 *type);
+
+ nsresult (*GetSource)(IEvent *pThis, IEventSource * *source);
+
+ nsresult (*GetWaitable)(IEvent *pThis, PRBool *waitable);
+
+ nsresult (*SetProcessed)(IEvent *pThis );
+
+ nsresult (*WaitProcessed)(
+ IEvent *pThis,
+ PRInt32 timeout,
+ PRBool * result
+ );
+
+};
+
+struct IEvent
+{
+ struct IEvent_vtbl *vtbl;
+};
+/* End of struct IEvent Declaration */
+
+
+/* Start of struct IReusableEvent Declaration */
+#define IREUSABLEEVENT_IID_STR "69bfb134-80f6-4266-8e20-16371f68fa25"
+#define IREUSABLEEVENT_IID { \
+ 0x69bfb134, 0x80f6, 0x4266, \
+ { 0x8e, 0x20, 0x16, 0x37, 0x1f, 0x68, 0xfa, 0x25 } \
+}
+struct IReusableEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetGeneration)(IReusableEvent *pThis, PRUint32 *generation);
+
+ nsresult (*Reuse)(IReusableEvent *pThis );
+
+};
+
+struct IReusableEvent
+{
+ struct IReusableEvent_vtbl *vtbl;
+};
+/* End of struct IReusableEvent Declaration */
+
+
+/* Start of struct IMachineEvent Declaration */
+#define IMACHINEEVENT_IID_STR "92ed7b1a-0d96-40ed-ae46-a564d484325e"
+#define IMACHINEEVENT_IID { \
+ 0x92ed7b1a, 0x0d96, 0x40ed, \
+ { 0xae, 0x46, 0xa5, 0x64, 0xd4, 0x84, 0x32, 0x5e } \
+}
+struct IMachineEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetMachineId)(IMachineEvent *pThis, PRUnichar * *machineId);
+
+};
+
+struct IMachineEvent
+{
+ struct IMachineEvent_vtbl *vtbl;
+};
+/* End of struct IMachineEvent Declaration */
+
+
+/* Start of struct IMachineStateChangedEvent Declaration */
+#define IMACHINESTATECHANGEDEVENT_IID_STR "5748F794-48DF-438D-85EB-98FFD70D18C9"
+#define IMACHINESTATECHANGEDEVENT_IID { \
+ 0x5748F794, 0x48DF, 0x438D, \
+ { 0x85, 0xEB, 0x98, 0xFF, 0xD7, 0x0D, 0x18, 0xC9 } \
+}
+struct IMachineStateChangedEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetState)(IMachineStateChangedEvent *pThis, PRUint32 *state);
+
+};
+
+struct IMachineStateChangedEvent
+{
+ struct IMachineStateChangedEvent_vtbl *vtbl;
+};
+/* End of struct IMachineStateChangedEvent Declaration */
+
+
+/* Start of struct IMachineDataChangedEvent Declaration */
+#define IMACHINEDATACHANGEDEVENT_IID_STR "6AA70A6C-0DCA-4810-8C5C-457B278E3D49"
+#define IMACHINEDATACHANGEDEVENT_IID { \
+ 0x6AA70A6C, 0x0DCA, 0x4810, \
+ { 0x8C, 0x5C, 0x45, 0x7B, 0x27, 0x8E, 0x3D, 0x49 } \
+}
+struct IMachineDataChangedEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+};
+
+struct IMachineDataChangedEvent
+{
+ struct IMachineDataChangedEvent_vtbl *vtbl;
+};
+/* End of struct IMachineDataChangedEvent Declaration */
+
+
+/* Start of struct IMediumRegisteredEvent Declaration */
+#define IMEDIUMREGISTEREDEVENT_IID_STR "53fac49a-b7f1-4a5a-a4ef-a11dd9c2a458"
+#define IMEDIUMREGISTEREDEVENT_IID { \
+ 0x53fac49a, 0xb7f1, 0x4a5a, \
+ { 0xa4, 0xef, 0xa1, 0x1d, 0xd9, 0xc2, 0xa4, 0x58 } \
+}
+struct IMediumRegisteredEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetMediumId)(IMediumRegisteredEvent *pThis, PRUnichar * *mediumId);
+
+ nsresult (*GetMediumType)(IMediumRegisteredEvent *pThis, PRUint32 *mediumType);
+
+ nsresult (*GetRegistered)(IMediumRegisteredEvent *pThis, PRBool *registered);
+
+};
+
+struct IMediumRegisteredEvent
+{
+ struct IMediumRegisteredEvent_vtbl *vtbl;
+};
+/* End of struct IMediumRegisteredEvent Declaration */
+
+
+/* Start of struct IMachineRegisteredEvent Declaration */
+#define IMACHINEREGISTEREDEVENT_IID_STR "c354a762-3ff2-4f2e-8f09-07382ee25088"
+#define IMACHINEREGISTEREDEVENT_IID { \
+ 0xc354a762, 0x3ff2, 0x4f2e, \
+ { 0x8f, 0x09, 0x07, 0x38, 0x2e, 0xe2, 0x50, 0x88 } \
+}
+struct IMachineRegisteredEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetRegistered)(IMachineRegisteredEvent *pThis, PRBool *registered);
+
+};
+
+struct IMachineRegisteredEvent
+{
+ struct IMachineRegisteredEvent_vtbl *vtbl;
+};
+/* End of struct IMachineRegisteredEvent Declaration */
+
+
+/* Start of struct ISessionStateChangedEvent Declaration */
+#define ISESSIONSTATECHANGEDEVENT_IID_STR "714a3eef-799a-4489-86cd-fe8e45b2ff8e"
+#define ISESSIONSTATECHANGEDEVENT_IID { \
+ 0x714a3eef, 0x799a, 0x4489, \
+ { 0x86, 0xcd, 0xfe, 0x8e, 0x45, 0xb2, 0xff, 0x8e } \
+}
+struct ISessionStateChangedEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetState)(ISessionStateChangedEvent *pThis, PRUint32 *state);
+
+};
+
+struct ISessionStateChangedEvent
+{
+ struct ISessionStateChangedEvent_vtbl *vtbl;
+};
+/* End of struct ISessionStateChangedEvent Declaration */
+
+
+/* Start of struct IGuestPropertyChangedEvent Declaration */
+#define IGUESTPROPERTYCHANGEDEVENT_IID_STR "3f63597a-26f1-4edb-8dd2-6bddd0912368"
+#define IGUESTPROPERTYCHANGEDEVENT_IID { \
+ 0x3f63597a, 0x26f1, 0x4edb, \
+ { 0x8d, 0xd2, 0x6b, 0xdd, 0xd0, 0x91, 0x23, 0x68 } \
+}
+struct IGuestPropertyChangedEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetName)(IGuestPropertyChangedEvent *pThis, PRUnichar * *name);
+
+ nsresult (*GetValue)(IGuestPropertyChangedEvent *pThis, PRUnichar * *value);
+
+ nsresult (*GetFlags)(IGuestPropertyChangedEvent *pThis, PRUnichar * *flags);
+
+};
+
+struct IGuestPropertyChangedEvent
+{
+ struct IGuestPropertyChangedEvent_vtbl *vtbl;
+};
+/* End of struct IGuestPropertyChangedEvent Declaration */
+
+
+/* Start of struct ISnapshotEvent Declaration */
+#define ISNAPSHOTEVENT_IID_STR "21637b0e-34b8-42d3-acfb-7e96daf77c22"
+#define ISNAPSHOTEVENT_IID { \
+ 0x21637b0e, 0x34b8, 0x42d3, \
+ { 0xac, 0xfb, 0x7e, 0x96, 0xda, 0xf7, 0x7c, 0x22 } \
+}
+struct ISnapshotEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetSnapshotId)(ISnapshotEvent *pThis, PRUnichar * *snapshotId);
+
+};
+
+struct ISnapshotEvent
+{
+ struct ISnapshotEvent_vtbl *vtbl;
+};
+/* End of struct ISnapshotEvent Declaration */
+
+
+/* Start of struct ISnapshotTakenEvent Declaration */
+#define ISNAPSHOTTAKENEVENT_IID_STR "d27c0b3d-6038-422c-b45e-6d4a0503d9f1"
+#define ISNAPSHOTTAKENEVENT_IID { \
+ 0xd27c0b3d, 0x6038, 0x422c, \
+ { 0xb4, 0x5e, 0x6d, 0x4a, 0x05, 0x03, 0xd9, 0xf1 } \
+}
+struct ISnapshotTakenEvent_vtbl
+{
+ struct ISnapshotEvent_vtbl isnapshotevent;
+
+};
+
+struct ISnapshotTakenEvent
+{
+ struct ISnapshotTakenEvent_vtbl *vtbl;
+};
+/* End of struct ISnapshotTakenEvent Declaration */
+
+
+/* Start of struct ISnapshotDeletedEvent Declaration */
+#define ISNAPSHOTDELETEDEVENT_IID_STR "c48f3401-4a9e-43f4-b7a7-54bd285e22f4"
+#define ISNAPSHOTDELETEDEVENT_IID { \
+ 0xc48f3401, 0x4a9e, 0x43f4, \
+ { 0xb7, 0xa7, 0x54, 0xbd, 0x28, 0x5e, 0x22, 0xf4 } \
+}
+struct ISnapshotDeletedEvent_vtbl
+{
+ struct ISnapshotEvent_vtbl isnapshotevent;
+
+};
+
+struct ISnapshotDeletedEvent
+{
+ struct ISnapshotDeletedEvent_vtbl *vtbl;
+};
+/* End of struct ISnapshotDeletedEvent Declaration */
+
+
+/* Start of struct ISnapshotChangedEvent Declaration */
+#define ISNAPSHOTCHANGEDEVENT_IID_STR "07541941-8079-447a-a33e-47a69c7980db"
+#define ISNAPSHOTCHANGEDEVENT_IID { \
+ 0x07541941, 0x8079, 0x447a, \
+ { 0xa3, 0x3e, 0x47, 0xa6, 0x9c, 0x79, 0x80, 0xdb } \
+}
+struct ISnapshotChangedEvent_vtbl
+{
+ struct ISnapshotEvent_vtbl isnapshotevent;
+
+};
+
+struct ISnapshotChangedEvent
+{
+ struct ISnapshotChangedEvent_vtbl *vtbl;
+};
+/* End of struct ISnapshotChangedEvent Declaration */
+
+
+/* Start of struct IMousePointerShapeChangedEvent Declaration */
+#define IMOUSEPOINTERSHAPECHANGEDEVENT_IID_STR "a6dcf6e8-416b-4181-8c4a-45ec95177aef"
+#define IMOUSEPOINTERSHAPECHANGEDEVENT_IID { \
+ 0xa6dcf6e8, 0x416b, 0x4181, \
+ { 0x8c, 0x4a, 0x45, 0xec, 0x95, 0x17, 0x7a, 0xef } \
+}
+struct IMousePointerShapeChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetVisible)(IMousePointerShapeChangedEvent *pThis, PRBool *visible);
+
+ nsresult (*GetAlpha)(IMousePointerShapeChangedEvent *pThis, PRBool *alpha);
+
+ nsresult (*GetXhot)(IMousePointerShapeChangedEvent *pThis, PRUint32 *xhot);
+
+ nsresult (*GetYhot)(IMousePointerShapeChangedEvent *pThis, PRUint32 *yhot);
+
+ nsresult (*GetWidth)(IMousePointerShapeChangedEvent *pThis, PRUint32 *width);
+
+ nsresult (*GetHeight)(IMousePointerShapeChangedEvent *pThis, PRUint32 *height);
+
+ nsresult (*GetShape)(IMousePointerShapeChangedEvent *pThis, PRUint32 *shapeSize, PRUint8 **shape);
+
+};
+
+struct IMousePointerShapeChangedEvent
+{
+ struct IMousePointerShapeChangedEvent_vtbl *vtbl;
+};
+/* End of struct IMousePointerShapeChangedEvent Declaration */
+
+
+/* Start of struct IMouseCapabilityChangedEvent Declaration */
+#define IMOUSECAPABILITYCHANGEDEVENT_IID_STR "d633ad48-820c-4207-b46c-6bd3596640d5"
+#define IMOUSECAPABILITYCHANGEDEVENT_IID { \
+ 0xd633ad48, 0x820c, 0x4207, \
+ { 0xb4, 0x6c, 0x6b, 0xd3, 0x59, 0x66, 0x40, 0xd5 } \
+}
+struct IMouseCapabilityChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetSupportsAbsolute)(IMouseCapabilityChangedEvent *pThis, PRBool *supportsAbsolute);
+
+ nsresult (*GetSupportsRelative)(IMouseCapabilityChangedEvent *pThis, PRBool *supportsRelative);
+
+ nsresult (*GetNeedsHostCursor)(IMouseCapabilityChangedEvent *pThis, PRBool *needsHostCursor);
+
+};
+
+struct IMouseCapabilityChangedEvent
+{
+ struct IMouseCapabilityChangedEvent_vtbl *vtbl;
+};
+/* End of struct IMouseCapabilityChangedEvent Declaration */
+
+
+/* Start of struct IKeyboardLedsChangedEvent Declaration */
+#define IKEYBOARDLEDSCHANGEDEVENT_IID_STR "6DDEF35E-4737-457B-99FC-BC52C851A44F"
+#define IKEYBOARDLEDSCHANGEDEVENT_IID { \
+ 0x6DDEF35E, 0x4737, 0x457B, \
+ { 0x99, 0xFC, 0xBC, 0x52, 0xC8, 0x51, 0xA4, 0x4F } \
+}
+struct IKeyboardLedsChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetNumLock)(IKeyboardLedsChangedEvent *pThis, PRBool *numLock);
+
+ nsresult (*GetCapsLock)(IKeyboardLedsChangedEvent *pThis, PRBool *capsLock);
+
+ nsresult (*GetScrollLock)(IKeyboardLedsChangedEvent *pThis, PRBool *scrollLock);
+
+};
+
+struct IKeyboardLedsChangedEvent
+{
+ struct IKeyboardLedsChangedEvent_vtbl *vtbl;
+};
+/* End of struct IKeyboardLedsChangedEvent Declaration */
+
+
+/* Start of struct IStateChangedEvent Declaration */
+#define ISTATECHANGEDEVENT_IID_STR "4376693C-CF37-453B-9289-3B0F521CAF27"
+#define ISTATECHANGEDEVENT_IID { \
+ 0x4376693C, 0xCF37, 0x453B, \
+ { 0x92, 0x89, 0x3B, 0x0F, 0x52, 0x1C, 0xAF, 0x27 } \
+}
+struct IStateChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetState)(IStateChangedEvent *pThis, PRUint32 *state);
+
+};
+
+struct IStateChangedEvent
+{
+ struct IStateChangedEvent_vtbl *vtbl;
+};
+/* End of struct IStateChangedEvent Declaration */
+
+
+/* Start of struct IAdditionsStateChangedEvent Declaration */
+#define IADDITIONSSTATECHANGEDEVENT_IID_STR "D70F7915-DA7C-44C8-A7AC-9F173490446A"
+#define IADDITIONSSTATECHANGEDEVENT_IID { \
+ 0xD70F7915, 0xDA7C, 0x44C8, \
+ { 0xA7, 0xAC, 0x9F, 0x17, 0x34, 0x90, 0x44, 0x6A } \
+}
+struct IAdditionsStateChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+};
+
+struct IAdditionsStateChangedEvent
+{
+ struct IAdditionsStateChangedEvent_vtbl *vtbl;
+};
+/* End of struct IAdditionsStateChangedEvent Declaration */
+
+
+/* Start of struct INetworkAdapterChangedEvent Declaration */
+#define INETWORKADAPTERCHANGEDEVENT_IID_STR "08889892-1EC6-4883-801D-77F56CFD0103"
+#define INETWORKADAPTERCHANGEDEVENT_IID { \
+ 0x08889892, 0x1EC6, 0x4883, \
+ { 0x80, 0x1D, 0x77, 0xF5, 0x6C, 0xFD, 0x01, 0x03 } \
+}
+struct INetworkAdapterChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetNetworkAdapter)(INetworkAdapterChangedEvent *pThis, INetworkAdapter * *networkAdapter);
+
+};
+
+struct INetworkAdapterChangedEvent
+{
+ struct INetworkAdapterChangedEvent_vtbl *vtbl;
+};
+/* End of struct INetworkAdapterChangedEvent Declaration */
+
+
+/* Start of struct ISerialPortChangedEvent Declaration */
+#define ISERIALPORTCHANGEDEVENT_IID_STR "3BA329DC-659C-488B-835C-4ECA7AE71C6C"
+#define ISERIALPORTCHANGEDEVENT_IID { \
+ 0x3BA329DC, 0x659C, 0x488B, \
+ { 0x83, 0x5C, 0x4E, 0xCA, 0x7A, 0xE7, 0x1C, 0x6C } \
+}
+struct ISerialPortChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetSerialPort)(ISerialPortChangedEvent *pThis, ISerialPort * *serialPort);
+
+};
+
+struct ISerialPortChangedEvent
+{
+ struct ISerialPortChangedEvent_vtbl *vtbl;
+};
+/* End of struct ISerialPortChangedEvent Declaration */
+
+
+/* Start of struct IParallelPortChangedEvent Declaration */
+#define IPARALLELPORTCHANGEDEVENT_IID_STR "813C99FC-9849-4F47-813E-24A75DC85615"
+#define IPARALLELPORTCHANGEDEVENT_IID { \
+ 0x813C99FC, 0x9849, 0x4F47, \
+ { 0x81, 0x3E, 0x24, 0xA7, 0x5D, 0xC8, 0x56, 0x15 } \
+}
+struct IParallelPortChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetParallelPort)(IParallelPortChangedEvent *pThis, IParallelPort * *parallelPort);
+
+};
+
+struct IParallelPortChangedEvent
+{
+ struct IParallelPortChangedEvent_vtbl *vtbl;
+};
+/* End of struct IParallelPortChangedEvent Declaration */
+
+
+/* Start of struct IStorageControllerChangedEvent Declaration */
+#define ISTORAGECONTROLLERCHANGEDEVENT_IID_STR "715212BF-DA59-426E-8230-3831FAA52C56"
+#define ISTORAGECONTROLLERCHANGEDEVENT_IID { \
+ 0x715212BF, 0xDA59, 0x426E, \
+ { 0x82, 0x30, 0x38, 0x31, 0xFA, 0xA5, 0x2C, 0x56 } \
+}
+struct IStorageControllerChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+};
+
+struct IStorageControllerChangedEvent
+{
+ struct IStorageControllerChangedEvent_vtbl *vtbl;
+};
+/* End of struct IStorageControllerChangedEvent Declaration */
+
+
+/* Start of struct IMediumChangedEvent Declaration */
+#define IMEDIUMCHANGEDEVENT_IID_STR "0FE2DA40-5637-472A-9736-72019EABD7DE"
+#define IMEDIUMCHANGEDEVENT_IID { \
+ 0x0FE2DA40, 0x5637, 0x472A, \
+ { 0x97, 0x36, 0x72, 0x01, 0x9E, 0xAB, 0xD7, 0xDE } \
+}
+struct IMediumChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetMediumAttachment)(IMediumChangedEvent *pThis, IMediumAttachment * *mediumAttachment);
+
+};
+
+struct IMediumChangedEvent
+{
+ struct IMediumChangedEvent_vtbl *vtbl;
+};
+/* End of struct IMediumChangedEvent Declaration */
+
+
+/* Start of struct ICPUChangedEvent Declaration */
+#define ICPUCHANGEDEVENT_IID_STR "D0F0BECC-EE17-4D17-A8CC-383B0EB55E9D"
+#define ICPUCHANGEDEVENT_IID { \
+ 0xD0F0BECC, 0xEE17, 0x4D17, \
+ { 0xA8, 0xCC, 0x38, 0x3B, 0x0E, 0xB5, 0x5E, 0x9D } \
+}
+struct ICPUChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetCpu)(ICPUChangedEvent *pThis, PRUint32 *cpu);
+
+ nsresult (*GetAdd)(ICPUChangedEvent *pThis, PRBool *add);
+
+};
+
+struct ICPUChangedEvent
+{
+ struct ICPUChangedEvent_vtbl *vtbl;
+};
+/* End of struct ICPUChangedEvent Declaration */
+
+
+/* Start of struct ICPUExecutionCapChangedEvent Declaration */
+#define ICPUEXECUTIONCAPCHANGEDEVENT_IID_STR "dfa7e4f5-b4a4-44ce-85a8-127ac5eb59dc"
+#define ICPUEXECUTIONCAPCHANGEDEVENT_IID { \
+ 0xdfa7e4f5, 0xb4a4, 0x44ce, \
+ { 0x85, 0xa8, 0x12, 0x7a, 0xc5, 0xeb, 0x59, 0xdc } \
+}
+struct ICPUExecutionCapChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetExecutionCap)(ICPUExecutionCapChangedEvent *pThis, PRUint32 *executionCap);
+
+};
+
+struct ICPUExecutionCapChangedEvent
+{
+ struct ICPUExecutionCapChangedEvent_vtbl *vtbl;
+};
+/* End of struct ICPUExecutionCapChangedEvent Declaration */
+
+
+/* Start of struct IGuestKeyboardEvent Declaration */
+#define IGUESTKEYBOARDEVENT_IID_STR "88394258-7006-40d4-b339-472ee3801844"
+#define IGUESTKEYBOARDEVENT_IID { \
+ 0x88394258, 0x7006, 0x40d4, \
+ { 0xb3, 0x39, 0x47, 0x2e, 0xe3, 0x80, 0x18, 0x44 } \
+}
+struct IGuestKeyboardEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetScancodes)(IGuestKeyboardEvent *pThis, PRUint32 *scancodesSize, PRInt32 **scancodes);
+
+};
+
+struct IGuestKeyboardEvent
+{
+ struct IGuestKeyboardEvent_vtbl *vtbl;
+};
+/* End of struct IGuestKeyboardEvent Declaration */
+
+
+/* Start of struct IGuestMouseEvent Declaration */
+#define IGUESTMOUSEEVENT_IID_STR "1f85d35c-c524-40ff-8e98-307000df0992"
+#define IGUESTMOUSEEVENT_IID { \
+ 0x1f85d35c, 0xc524, 0x40ff, \
+ { 0x8e, 0x98, 0x30, 0x70, 0x00, 0xdf, 0x09, 0x92 } \
+}
+struct IGuestMouseEvent_vtbl
+{
+ struct IReusableEvent_vtbl ireusableevent;
+
+ nsresult (*GetAbsolute)(IGuestMouseEvent *pThis, PRBool *absolute);
+
+ nsresult (*GetX)(IGuestMouseEvent *pThis, PRInt32 *x);
+
+ nsresult (*GetY)(IGuestMouseEvent *pThis, PRInt32 *y);
+
+ nsresult (*GetZ)(IGuestMouseEvent *pThis, PRInt32 *z);
+
+ nsresult (*GetW)(IGuestMouseEvent *pThis, PRInt32 *w);
+
+ nsresult (*GetButtons)(IGuestMouseEvent *pThis, PRInt32 *buttons);
+
+};
+
+struct IGuestMouseEvent
+{
+ struct IGuestMouseEvent_vtbl *vtbl;
+};
+/* End of struct IGuestMouseEvent Declaration */
+
+
+/* Start of struct IVRDEServerChangedEvent Declaration */
+#define IVRDESERVERCHANGEDEVENT_IID_STR "a06fd66a-3188-4c8c-8756-1395e8cb691c"
+#define IVRDESERVERCHANGEDEVENT_IID { \
+ 0xa06fd66a, 0x3188, 0x4c8c, \
+ { 0x87, 0x56, 0x13, 0x95, 0xe8, 0xcb, 0x69, 0x1c } \
+}
+struct IVRDEServerChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+};
+
+struct IVRDEServerChangedEvent
+{
+ struct IVRDEServerChangedEvent_vtbl *vtbl;
+};
+/* End of struct IVRDEServerChangedEvent Declaration */
+
+
+/* Start of struct IVRDEServerInfoChangedEvent Declaration */
+#define IVRDESERVERINFOCHANGEDEVENT_IID_STR "dd6a1080-e1b7-4339-a549-f0878115596e"
+#define IVRDESERVERINFOCHANGEDEVENT_IID { \
+ 0xdd6a1080, 0xe1b7, 0x4339, \
+ { 0xa5, 0x49, 0xf0, 0x87, 0x81, 0x15, 0x59, 0x6e } \
+}
+struct IVRDEServerInfoChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+};
+
+struct IVRDEServerInfoChangedEvent
+{
+ struct IVRDEServerInfoChangedEvent_vtbl *vtbl;
+};
+/* End of struct IVRDEServerInfoChangedEvent Declaration */
+
+
+/* Start of struct IUSBControllerChangedEvent Declaration */
+#define IUSBCONTROLLERCHANGEDEVENT_IID_STR "93BADC0C-61D9-4940-A084-E6BB29AF3D83"
+#define IUSBCONTROLLERCHANGEDEVENT_IID { \
+ 0x93BADC0C, 0x61D9, 0x4940, \
+ { 0xA0, 0x84, 0xE6, 0xBB, 0x29, 0xAF, 0x3D, 0x83 } \
+}
+struct IUSBControllerChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+};
+
+struct IUSBControllerChangedEvent
+{
+ struct IUSBControllerChangedEvent_vtbl *vtbl;
+};
+/* End of struct IUSBControllerChangedEvent Declaration */
+
+
+/* Start of struct IUSBDeviceStateChangedEvent Declaration */
+#define IUSBDEVICESTATECHANGEDEVENT_IID_STR "806da61b-6679-422a-b629-51b06b0c6d93"
+#define IUSBDEVICESTATECHANGEDEVENT_IID { \
+ 0x806da61b, 0x6679, 0x422a, \
+ { 0xb6, 0x29, 0x51, 0xb0, 0x6b, 0x0c, 0x6d, 0x93 } \
+}
+struct IUSBDeviceStateChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetDevice)(IUSBDeviceStateChangedEvent *pThis, IUSBDevice * *device);
+
+ nsresult (*GetAttached)(IUSBDeviceStateChangedEvent *pThis, PRBool *attached);
+
+ nsresult (*GetError)(IUSBDeviceStateChangedEvent *pThis, IVirtualBoxErrorInfo * *error);
+
+};
+
+struct IUSBDeviceStateChangedEvent
+{
+ struct IUSBDeviceStateChangedEvent_vtbl *vtbl;
+};
+/* End of struct IUSBDeviceStateChangedEvent Declaration */
+
+
+/* Start of struct ISharedFolderChangedEvent Declaration */
+#define ISHAREDFOLDERCHANGEDEVENT_IID_STR "B66349B5-3534-4239-B2DE-8E1535D94C0B"
+#define ISHAREDFOLDERCHANGEDEVENT_IID { \
+ 0xB66349B5, 0x3534, 0x4239, \
+ { 0xB2, 0xDE, 0x8E, 0x15, 0x35, 0xD9, 0x4C, 0x0B } \
+}
+struct ISharedFolderChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetScope)(ISharedFolderChangedEvent *pThis, PRUint32 *scope);
+
+};
+
+struct ISharedFolderChangedEvent
+{
+ struct ISharedFolderChangedEvent_vtbl *vtbl;
+};
+/* End of struct ISharedFolderChangedEvent Declaration */
+
+
+/* Start of struct IRuntimeErrorEvent Declaration */
+#define IRUNTIMEERROREVENT_IID_STR "883DD18B-0721-4CDE-867C-1A82ABAF914C"
+#define IRUNTIMEERROREVENT_IID { \
+ 0x883DD18B, 0x0721, 0x4CDE, \
+ { 0x86, 0x7C, 0x1A, 0x82, 0xAB, 0xAF, 0x91, 0x4C } \
+}
+struct IRuntimeErrorEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetFatal)(IRuntimeErrorEvent *pThis, PRBool *fatal);
+
+ nsresult (*GetId)(IRuntimeErrorEvent *pThis, PRUnichar * *id);
+
+ nsresult (*GetMessage)(IRuntimeErrorEvent *pThis, PRUnichar * *message);
+
+};
+
+struct IRuntimeErrorEvent
+{
+ struct IRuntimeErrorEvent_vtbl *vtbl;
+};
+/* End of struct IRuntimeErrorEvent Declaration */
+
+
+/* Start of struct IEventSourceChangedEvent Declaration */
+#define IEVENTSOURCECHANGEDEVENT_IID_STR "e7932cb8-f6d4-4ab6-9cbf-558eb8959a6a"
+#define IEVENTSOURCECHANGEDEVENT_IID { \
+ 0xe7932cb8, 0xf6d4, 0x4ab6, \
+ { 0x9c, 0xbf, 0x55, 0x8e, 0xb8, 0x95, 0x9a, 0x6a } \
+}
+struct IEventSourceChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetListener)(IEventSourceChangedEvent *pThis, IEventListener * *listener);
+
+ nsresult (*GetAdd)(IEventSourceChangedEvent *pThis, PRBool *add);
+
+};
+
+struct IEventSourceChangedEvent
+{
+ struct IEventSourceChangedEvent_vtbl *vtbl;
+};
+/* End of struct IEventSourceChangedEvent Declaration */
+
+
+/* Start of struct IExtraDataChangedEvent Declaration */
+#define IEXTRADATACHANGEDEVENT_IID_STR "024F00CE-6E0B-492A-A8D0-968472A94DC7"
+#define IEXTRADATACHANGEDEVENT_IID { \
+ 0x024F00CE, 0x6E0B, 0x492A, \
+ { 0xA8, 0xD0, 0x96, 0x84, 0x72, 0xA9, 0x4D, 0xC7 } \
+}
+struct IExtraDataChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetMachineId)(IExtraDataChangedEvent *pThis, PRUnichar * *machineId);
+
+ nsresult (*GetKey)(IExtraDataChangedEvent *pThis, PRUnichar * *key);
+
+ nsresult (*GetValue)(IExtraDataChangedEvent *pThis, PRUnichar * *value);
+
+};
+
+struct IExtraDataChangedEvent
+{
+ struct IExtraDataChangedEvent_vtbl *vtbl;
+};
+/* End of struct IExtraDataChangedEvent Declaration */
+
+
+/* Start of struct IVetoEvent Declaration */
+#define IVETOEVENT_IID_STR "9a1a4130-69fe-472f-ac10-c6fa25d75007"
+#define IVETOEVENT_IID { \
+ 0x9a1a4130, 0x69fe, 0x472f, \
+ { 0xac, 0x10, 0xc6, 0xfa, 0x25, 0xd7, 0x50, 0x07 } \
+}
+struct IVetoEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*AddVeto)(
+ IVetoEvent *pThis,
+ PRUnichar * reason
+ );
+
+ nsresult (*IsVetoed)(
+ IVetoEvent *pThis,
+ PRBool * result
+ );
+
+ nsresult (*GetVetos)(
+ IVetoEvent *pThis,
+ PRUint32 *resultSize,
+ PRUnichar *** result
+ );
+
+};
+
+struct IVetoEvent
+{
+ struct IVetoEvent_vtbl *vtbl;
+};
+/* End of struct IVetoEvent Declaration */
+
+
+/* Start of struct IExtraDataCanChangeEvent Declaration */
+#define IEXTRADATACANCHANGEEVENT_IID_STR "245d88bd-800a-40f8-87a6-170d02249a55"
+#define IEXTRADATACANCHANGEEVENT_IID { \
+ 0x245d88bd, 0x800a, 0x40f8, \
+ { 0x87, 0xa6, 0x17, 0x0d, 0x02, 0x24, 0x9a, 0x55 } \
+}
+struct IExtraDataCanChangeEvent_vtbl
+{
+ struct IVetoEvent_vtbl ivetoevent;
+
+ nsresult (*GetMachineId)(IExtraDataCanChangeEvent *pThis, PRUnichar * *machineId);
+
+ nsresult (*GetKey)(IExtraDataCanChangeEvent *pThis, PRUnichar * *key);
+
+ nsresult (*GetValue)(IExtraDataCanChangeEvent *pThis, PRUnichar * *value);
+
+};
+
+struct IExtraDataCanChangeEvent
+{
+ struct IExtraDataCanChangeEvent_vtbl *vtbl;
+};
+/* End of struct IExtraDataCanChangeEvent Declaration */
+
+
+/* Start of struct ICanShowWindowEvent Declaration */
+#define ICANSHOWWINDOWEVENT_IID_STR "adf292b0-92c9-4a77-9d35-e058b39fe0b9"
+#define ICANSHOWWINDOWEVENT_IID { \
+ 0xadf292b0, 0x92c9, 0x4a77, \
+ { 0x9d, 0x35, 0xe0, 0x58, 0xb3, 0x9f, 0xe0, 0xb9 } \
+}
+struct ICanShowWindowEvent_vtbl
+{
+ struct IVetoEvent_vtbl ivetoevent;
+
+};
+
+struct ICanShowWindowEvent
+{
+ struct ICanShowWindowEvent_vtbl *vtbl;
+};
+/* End of struct ICanShowWindowEvent Declaration */
+
+
+/* Start of struct IShowWindowEvent Declaration */
+#define ISHOWWINDOWEVENT_IID_STR "B0A0904D-2F05-4D28-855F-488F96BAD2B2"
+#define ISHOWWINDOWEVENT_IID { \
+ 0xB0A0904D, 0x2F05, 0x4D28, \
+ { 0x85, 0x5F, 0x48, 0x8F, 0x96, 0xBA, 0xD2, 0xB2 } \
+}
+struct IShowWindowEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetWinId)(IShowWindowEvent *pThis, PRInt64 *winId);
+ nsresult (*SetWinId)(IShowWindowEvent *pThis, PRInt64 winId);
+
+};
+
+struct IShowWindowEvent
+{
+ struct IShowWindowEvent_vtbl *vtbl;
+};
+/* End of struct IShowWindowEvent Declaration */
+
+
+/* Start of struct INATRedirectEvent Declaration */
+#define INATREDIRECTEVENT_IID_STR "57DE97D7-3CBB-42A0-888F-610D5832D16B"
+#define INATREDIRECTEVENT_IID { \
+ 0x57DE97D7, 0x3CBB, 0x42A0, \
+ { 0x88, 0x8F, 0x61, 0x0D, 0x58, 0x32, 0xD1, 0x6B } \
+}
+struct INATRedirectEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetSlot)(INATRedirectEvent *pThis, PRUint32 *slot);
+
+ nsresult (*GetRemove)(INATRedirectEvent *pThis, PRBool *remove);
+
+ nsresult (*GetName)(INATRedirectEvent *pThis, PRUnichar * *name);
+
+ nsresult (*GetProto)(INATRedirectEvent *pThis, PRUint32 *proto);
+
+ nsresult (*GetHostIp)(INATRedirectEvent *pThis, PRUnichar * *hostIp);
+
+ nsresult (*GetHostPort)(INATRedirectEvent *pThis, PRInt32 *hostPort);
+
+ nsresult (*GetGuestIp)(INATRedirectEvent *pThis, PRUnichar * *guestIp);
+
+ nsresult (*GetGuestPort)(INATRedirectEvent *pThis, PRInt32 *guestPort);
+
+};
+
+struct INATRedirectEvent
+{
+ struct INATRedirectEvent_vtbl *vtbl;
+};
+/* End of struct INATRedirectEvent Declaration */
+
+
+/* Start of struct IHostPciDevicePlugEvent Declaration */
+#define IHOSTPCIDEVICEPLUGEVENT_IID_STR "EDD4782B-DB74-43A0-B724-2BAA36F039CC"
+#define IHOSTPCIDEVICEPLUGEVENT_IID { \
+ 0xEDD4782B, 0xDB74, 0x43A0, \
+ { 0xB7, 0x24, 0x2B, 0xAA, 0x36, 0xF0, 0x39, 0xCC } \
+}
+struct IHostPciDevicePlugEvent_vtbl
+{
+ struct IMachineEvent_vtbl imachineevent;
+
+ nsresult (*GetPlugged)(IHostPciDevicePlugEvent *pThis, PRBool *plugged);
+
+ nsresult (*GetSuccess)(IHostPciDevicePlugEvent *pThis, PRBool *success);
+
+ nsresult (*GetAttachment)(IHostPciDevicePlugEvent *pThis, IPciDeviceAttachment * *attachment);
+
+ nsresult (*GetEventContext)(IHostPciDevicePlugEvent *pThis, IEventContext * *eventContext);
+
+ nsresult (*GetMessage)(IHostPciDevicePlugEvent *pThis, PRUnichar * *message);
+
+};
+
+struct IHostPciDevicePlugEvent
+{
+ struct IHostPciDevicePlugEvent_vtbl *vtbl;
+};
+/* End of struct IHostPciDevicePlugEvent Declaration */
+
+
+/* Start of struct IVBoxSVCAvailabilityChangedEvent Declaration */
+#define IVBOXSVCAVAILABILITYCHANGEDEVENT_IID_STR "97c78fcd-d4fc-485f-8613-5af88bfcfcdc"
+#define IVBOXSVCAVAILABILITYCHANGEDEVENT_IID { \
+ 0x97c78fcd, 0xd4fc, 0x485f, \
+ { 0x86, 0x13, 0x5a, 0xf8, 0x8b, 0xfc, 0xfc, 0xdc } \
+}
+struct IVBoxSVCAvailabilityChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetAvailable)(IVBoxSVCAvailabilityChangedEvent *pThis, PRBool *available);
+
+};
+
+struct IVBoxSVCAvailabilityChangedEvent
+{
+ struct IVBoxSVCAvailabilityChangedEvent_vtbl *vtbl;
+};
+/* End of struct IVBoxSVCAvailabilityChangedEvent Declaration */
+
+
+/* Start of struct IBandwidthGroupChangedEvent Declaration */
+#define IBANDWIDTHGROUPCHANGEDEVENT_IID_STR "334df94a-7556-4cbc-8c04-043096b02d82"
+#define IBANDWIDTHGROUPCHANGEDEVENT_IID { \
+ 0x334df94a, 0x7556, 0x4cbc, \
+ { 0x8c, 0x04, 0x04, 0x30, 0x96, 0xb0, 0x2d, 0x82 } \
+}
+struct IBandwidthGroupChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetBandwidthGroup)(IBandwidthGroupChangedEvent *pThis, IBandwidthGroup * *bandwidthGroup);
+
+};
+
+struct IBandwidthGroupChangedEvent
+{
+ struct IBandwidthGroupChangedEvent_vtbl *vtbl;
+};
+/* End of struct IBandwidthGroupChangedEvent Declaration */
+
+
+/* Start of struct IGuestMonitorChangedEvent Declaration */
+#define IGUESTMONITORCHANGEDEVENT_IID_STR "0f7b8a22-c71f-4a36-8e5f-a77d01d76090"
+#define IGUESTMONITORCHANGEDEVENT_IID { \
+ 0x0f7b8a22, 0xc71f, 0x4a36, \
+ { 0x8e, 0x5f, 0xa7, 0x7d, 0x01, 0xd7, 0x60, 0x90 } \
+}
+struct IGuestMonitorChangedEvent_vtbl
+{
+ struct IEvent_vtbl ievent;
+
+ nsresult (*GetChangeType)(IGuestMonitorChangedEvent *pThis, PRUint32 *changeType);
+
+ nsresult (*GetScreenId)(IGuestMonitorChangedEvent *pThis, PRUint32 *screenId);
+
+ nsresult (*GetOriginX)(IGuestMonitorChangedEvent *pThis, PRUint32 *originX);
+
+ nsresult (*GetOriginY)(IGuestMonitorChangedEvent *pThis, PRUint32 *originY);
+
+ nsresult (*GetWidth)(IGuestMonitorChangedEvent *pThis, PRUint32 *width);
+
+ nsresult (*GetHeight)(IGuestMonitorChangedEvent *pThis, PRUint32 *height);
+
+};
+
+struct IGuestMonitorChangedEvent
+{
+ struct IGuestMonitorChangedEvent_vtbl *vtbl;
+};
+/* End of struct IGuestMonitorChangedEvent Declaration */
+
+
+
+#define NS_VIRTUALBOX_CID { \
+ 0xB1A7A4F2, 0x47B9, 0x4A1E, \
+ { 0x82, 0xB2, 0x07, 0xCC, 0xD5, 0x32, 0x3C, 0x3F } \
+}
+#define NS_VIRTUALBOX_CONTRACTID "@virtualbox.org/VirtualBox;1"
+/* for compatibility with Win32 */
+#define CLSID_VirtualBox (nsCID) NS_VIRTUALBOX_CID
+
+
+
+#define NS_VIRTUALBOXCLIENT_CID { \
+ 0xdd3fc71d, 0x26c0, 0x4fe1, \
+ { 0xbf, 0x6f, 0x67, 0xf6, 0x33, 0x26, 0x5b, 0xba } \
+}
+#define NS_VIRTUALBOXCLIENT_CONTRACTID "@virtualbox.org/VirtualBoxClient;1"
+/* for compatibility with Win32 */
+#define CLSID_VirtualBoxClient (nsCID) NS_VIRTUALBOXCLIENT_CID
+
+
+
+#define NS_SESSION_CID { \
+ 0x3C02F46D, 0xC9D2, 0x4F11, \
+ { 0xA3, 0x84, 0x53, 0xF0, 0xCF, 0x91, 0x72, 0x14 } \
+}
+#define NS_SESSION_CONTRACTID "@virtualbox.org/Session;1"
+/* for compatibility with Win32 */
+#define CLSID_Session (nsCID) NS_SESSION_CID
+
+
+
+#endif /* !__cplusplus */
+
+#ifdef IN_VBOXXPCOMC
+# define VBOXXPCOMC_DECL(type) PR_EXPORT(type)
+#else
+# define VBOXXPCOMC_DECL(type) PR_IMPORT(type)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Function table for dynamic linking.
+ * Use VBoxGetFunctions() to obtain the pointer to it.
+ */
+typedef struct VBOXXPCOMC
+{
+ /** The size of the structure. */
+ unsigned cb;
+ /** The structure version. */
+ unsigned uVersion;
+
+ unsigned int (*pfnGetVersion)(void);
+
+ void (*pfnComInitialize)(const char *pszVirtualBoxIID,
+ IVirtualBox **ppVirtualBox,
+ const char *pszSessionIID,
+ ISession **ppSession);
+ void (*pfnComUninitialize)(void);
+
+ void (*pfnComUnallocMem)(void *pv);
+ void (*pfnUtf16Free)(PRUnichar *pwszString);
+ void (*pfnUtf8Free)(char *pszString);
+
+ int (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
+ int (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
+
+ void (*pfnGetEventQueue)(nsIEventQueue **eventQueue);
+
+ /** Tail version, same as uVersion. */
+ unsigned uEndVersion;
+} VBOXXPCOMC;
+/** Pointer to a const VBoxXPCOMC function table. */
+typedef VBOXXPCOMC const *PCVBOXXPCOM;
+
+/** The current interface version.
+ * For use with VBoxGetXPCOMCFunctions and to be found in
+ * VBOXXPCOMC::uVersion. */
+#define VBOX_XPCOMC_VERSION 0x00020000U
+
+VBOXXPCOMC_DECL(PCVBOXXPCOM) VBoxGetXPCOMCFunctions(unsigned uVersion);
+/** Typedef for VBoxGetXPCOMCFunctions. */
+typedef PCVBOXXPCOM (*PFNVBOXGETXPCOMCFUNCTIONS)(unsigned uVersion);
+
+/** The symbol name of VBoxGetXPCOMCFunctions. */
+#if defined(__OS2__)
+# define VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME "_VBoxGetXPCOMCFunctions"
+#else
+# define VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME "VBoxGetXPCOMCFunctions"
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !___VirtualBox_CXPCOM_h */
diff --git a/src/VBox/Main/cbinding/VBoxXPCOMC.cpp b/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
index 505ee7202..63c6ab4f6 100644
--- a/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
+++ b/src/VBox/Main/cbinding/VBoxXPCOMC.cpp
@@ -24,7 +24,7 @@
#include <iprt/env.h>
#include <VBox/log.h>
-#include "VBoxCAPI_v3_2.h"
+#include "VBoxCAPI.h"
#include "VBox/com/com.h"
#include "VBox/version.h"
diff --git a/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h b/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
index 3edd49a79..0f42a4bc0 100644
--- a/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
+++ b/src/VBox/Main/cbinding/VBoxXPCOMCGlue.h
@@ -1,10 +1,10 @@
-/* $Revision: 61277 $ */
+/* $Revision: 75929 $ */
/** @file VBoxXPCOMCGlue.h
* Glue for dynamically linking with VBoxXPCOMC.
*/
/*
- * Copyright (C) 2008-2009 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -31,7 +31,7 @@
#ifndef ___VBoxXPCOMC_cglue_h
#define ___VBoxXPCOMC_cglue_h
-#include "VBoxCAPI_v3_2.h"
+#include "VBoxCAPI_v4_1.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/VBox/Main/cbinding/xpcidl.xsl b/src/VBox/Main/cbinding/xpcidl.xsl
index fdab2a8ba..d4019c6f5 100644
--- a/src/VBox/Main/cbinding/xpcidl.xsl
+++ b/src/VBox/Main/cbinding/xpcidl.xsl
@@ -5,7 +5,7 @@
* A template to generate a XPCOM IDL compatible interface definition file
* from the generic interface definition expressed in XML.
- Copyright (C) 2008-2010 Oracle Corporation
+ Copyright (C) 2008-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;
@@ -115,12 +115,12 @@
* xpcom/include/nsprpub/prtypes.h
* xpcom/include/xpcom/nsISupportsBase.h
*
- * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Sun
+ * These files were originally triple-licensed (MPL/GPL2/LGPL2.1). Oracle
* elects to distribute this derived work under the LGPL2.1 only.
*/
/*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-2012 Oracle Corporation
*
* This file is part of a free software library; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General
diff --git a/src/VBox/Main/glue/com.cpp b/src/VBox/Main/glue/com.cpp
index 896c1d91f..93c3a7de7 100644
--- a/src/VBox/Main/glue/com.cpp
+++ b/src/VBox/Main/glue/com.cpp
@@ -205,7 +205,7 @@ int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen)
/* ensure the home directory exists */
if (RT_SUCCESS(vrc))
if (!RTDirExists(aDir))
- vrc = RTDirCreateFullPath(aDir, 0777);
+ vrc = RTDirCreateFullPath(aDir, 0700);
}
return vrc;
diff --git a/src/VBox/Main/glue/glue-java.xsl b/src/VBox/Main/glue/glue-java.xsl
index 46427c9e0..e4efae5a8 100644
--- a/src/VBox/Main/glue/glue-java.xsl
+++ b/src/VBox/Main/glue/glue-java.xsl
@@ -1214,7 +1214,26 @@
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$safearray='yes'">
- <xsl:value-of select="concat('Helper.unwrap(',$value,')')"/>
+ <xsl:choose>
+ <xsl:when test="$idltype='boolean'">
+ <xsl:value-of select="concat('Helper.unwrapBoolean(',$value,')')"/>
+ </xsl:when>
+ <xsl:when test="($idltype='long') or ($idltype='unsigned long') or ($idltype='integer')">
+ <xsl:value-of select="concat('Helper.unwrapInteger(',$value,')')"/>
+ </xsl:when>
+ <xsl:when test="($idltype='short') or ($idltype='unsigned short')">
+ <xsl:value-of select="concat('Helper.unwrapUShort(',$value,')')"/>
+ </xsl:when>
+ <xsl:when test="($idltype='unsigned long long') or ($idltype='long long')">
+ <xsl:value-of select="concat('Helper.unwrapULong(',$value,')')"/>
+ </xsl:when>
+ <xsl:when test="($idltype='wstring') or ($idltype='uuid')">
+ <xsl:value-of select="concat('Helper.unwrapStr(',$value,')')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$value"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value"/>
@@ -2652,8 +2671,7 @@ public class Helper {
throw new AssertionError(e);
}
}
-
- public static short[] unwrap(List<Short> vals) {
+ public static short[] unwrapUShort(List<Short> vals) {
if (vals==null)
return null;
@@ -2665,7 +2683,7 @@ public class Helper {
return ret;
}
- public static int[] unwrap(List<Integer> vals) {
+ public static int[] unwrapInteger(List<Integer> vals) {
if (vals == null)
return null;
@@ -2677,7 +2695,7 @@ public class Helper {
return ret;
}
- public static long[] unwrap(List<Long> vals) {
+ public static long[] unwrapULong(List<Long> vals) {
if (vals == null)
return null;
@@ -2689,7 +2707,7 @@ public class Helper {
return ret;
}
- public static boolean[] unwrap(List<Boolean> vals) {
+ public static boolean[] unwrapBoolean(List<Boolean> vals) {
if (vals==null)
return null;
@@ -2701,7 +2719,7 @@ public class Helper {
return ret;
}
- public static String[] unwrap(List<String> vals) {
+ public static String[] unwrapStr(List<String> vals) {
if (vals==null)
return null;
diff --git a/src/VBox/Main/idl/VirtualBox.xidl b/src/VBox/Main/idl/VirtualBox.xidl
index 101a18587..e04180182 100644
--- a/src/VBox/Main/idl/VirtualBox.xidl
+++ b/src/VBox/Main/idl/VirtualBox.xidl
@@ -2957,7 +2957,7 @@
<interface
name="IInternalMachineControl" extends="$unknown"
- uuid="2087906d-bb92-43a0-8014-4cab009e4888"
+ uuid="ec824977-e43f-479c-81c9-ac6cae1423a5"
internal="yes"
wsmap="suppress"
>
@@ -3415,6 +3415,57 @@
</desc>
</param>
</method>
+
+ <method name="reportGuestStatistics">
+ <desc>
+ Passes collected guest statistics to VBoxSVC.
+ </desc>
+ <param name="validStats" type="unsigned long" dir="in">
+ <desc>
+ Mask defining which parameters are valid. For example: 0x11 means
+ that cpuIdle and XXX are valid. Other parameters should be ignored.
+ </desc>
+ </param>
+ <param name="cpuUser" type="unsigned long" dir="in">
+ <desc>Percentage of processor time spent in user mode as seen by the guest.</desc>
+ </param>
+ <param name="cpuKernel" type="unsigned long" dir="in">
+ <desc>Percentage of processor time spent in kernel mode as seen by the guest.</desc>
+ </param>
+ <param name="cpuIdle" type="unsigned long" dir="in">
+ <desc>Percentage of processor time spent idling as seen by the guest.</desc>
+ </param>
+ <param name="memTotal" type="unsigned long" dir="in">
+ <desc>Total amount of physical guest RAM.</desc>
+ </param>
+ <param name="memFree" type="unsigned long" dir="in">
+ <desc>Free amount of physical guest RAM.</desc>
+ </param>
+ <param name="memBalloon" type="unsigned long" dir="in">
+ <desc>Amount of ballooned physical guest RAM.</desc>
+ </param>
+ <param name="memShared" type="unsigned long" dir="in">
+ <desc>Amount of shared physical guest RAM.</desc>
+ </param>
+ <param name="memCache" type="unsigned long" dir="in">
+ <desc>Total amount of guest (disk) cache memory.</desc>
+ </param>
+ <param name="pagedTotal" type="unsigned long" dir="in">
+ <desc>Total amount of space in the page file.</desc>
+ </param>
+ <param name="memAllocTotal" type="unsigned long" dir="in">
+ <desc>Total amount of memory allocated by the hypervisor.</desc>
+ </param>
+ <param name="memFreeTotal" type="unsigned long" dir="in">
+ <desc>Total amount of free memory available in the hypervisor.</desc>
+ </param>
+ <param name="memBalloonTotal" type="unsigned long" dir="in">
+ <desc>Total amount of memory ballooned by the hypervisor.</desc>
+ </param>
+ <param name="memSharedTotal" type="unsigned long" dir="in">
+ <desc>Total amount of shared memory in the hypervisor.</desc>
+ </param>
+ </method>
</interface>
<interface
@@ -8220,6 +8271,9 @@
<const name="VBoxGuestDriver" value="20">
<desc>VirtualBox base driver (VBoxGuest).</desc>
</const>
+ <const name="AutoLogon" value="90">
+ <desc>Auto-logon modules (VBoxGINA, VBoxCredProv, pam_vbox).</desc>
+ </const>
<const name="VBoxService" value="100">
<desc>VirtualBox system service (VBoxService).</desc>
</const>
@@ -8399,11 +8453,17 @@
<desc>Do not report an error when executed processes are still alive when VBoxService or the guest OS is shutting down.</desc>
</const>
<const name="Hidden" value="4">
- <desc>Don't show the started process according to the guest OS guidelines.</desc>
+ <desc>Do not show the started process according to the guest OS guidelines.</desc>
</const>
<const name="NoProfile" value="8">
<desc>Do not use the user's profile data when exeuting a process.</desc>
</const>
+ <const name="WaitForStdOut" value="16">
+ <desc>The guest process waits until all data from stdout is read out.</desc>
+ </const>
+ <const name="WaitForStdErr" value="32">
+ <desc>The guest process waits until all data from stderr is read out.</desc>
+ </const>
</enum>
<enum
@@ -8734,14 +8794,16 @@
Executes an existing program inside the guest VM.
<note>
- Starting at VirtualBox 4.1.2 guest process execution by default is limited
- to serve up to 5 guest processes at a time. If a new guest process gets started
- which would exceed this limit, the oldest not running guest process will be discarded
- in order to be able to run that new process. Also, retrieving output from this
- old guest process will not be possible anymore then. If all 5 guest processes
+ Starting at VirtualBox 4.1.8 guest process execution by default is limited
+ to serve up to 25 guest processes at a time. If all 25 guest processes
are still active and running, starting a new guest process will result in an
appropriate error message.
+ If ExecuteProcessFlag_WaitForStdOut and/or respectively
+ ExecuteProcessFlag_WaitForStdErr of <link to="ExecuteProcessFlag"/> is
+ set, the guest process will not exit until all data from the specified
+ stream(s) is/are read out.
+
To raise or lower the guest process execution limit, either the guest property
"/VirtualBox/GuestAdd/VBoxService/--control-procs-max-kept" or VBoxService'
command line by specifying "--control-procs-max-kept" needs to be modified.
@@ -8806,7 +8868,15 @@
<method name="getProcessOutput">
<desc>
- Retrieves output of a formerly started process.
+ Retrieves output of a formerly started and running guest process.
+
+ <note>
+ Starting with VirtualBox 4.1.8 this only will return output data
+ from stdout or stderr if flag ExecuteProcessFlag_WaitForStdOut
+ and/or respectively ExecuteProcessFlag_WaitForStdErr of
+ <link to="ExecuteProcessFlag"/> is set in the
+ former <link to="#executeProcess"/> call for this guest process.
+ </note>
<result name="VBOX_E_IPRT_ERROR">
Could not retrieve output.
@@ -8846,7 +8916,10 @@
<method name="getProcessStatus">
<desc>
- Retrieves status, exit code and the exit reason of a formerly started process.
+ Retrieves status, exit code and the exit reason of a formerly started
+ guest process. If a guest process exited or got terminated this function
+ returns its final status and removes this process from the list of
+ known guest processes for further retrieval.
<result name="VBOX_E_IPRT_ERROR">
Process with specified PID was not found.
@@ -14186,7 +14259,7 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
<interface
name="IInternalSessionControl" extends="$unknown"
- uuid="0bdda5da-67c8-47be-a610-b83a7fa3e8b6"
+ uuid="c2b4cd5f-d3ce-4dd6-b915-123272163ef5"
internal="yes"
wsmap="suppress"
>
@@ -14639,6 +14712,23 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
</param>
</method>
+ <method name="enableVMMStatistics">
+ <desc>
+ Enables or disables collection of VMM RAM statistics.
+
+ <result name="VBOX_E_INVALID_VM_STATE">
+ Machine session is not open.
+ </result>
+ <result name="VBOX_E_INVALID_OBJECT_STATE">
+ Session type is not direct.
+ </result>
+
+ </desc>
+ <param name="enable" type="boolean" dir="in">
+ <desc>True enables statistics collection.</desc>
+ </param>
+ </method>
+
</interface>
<interface
@@ -15860,7 +15950,8 @@ Snapshot 1 (B.vdi) Snapshot 1 (B.vdi)
installation.
</desc>
<param name="path" type="wstring" dir="in">
- <desc>The path of the extension pack tarball.</desc>
+ <desc>The path of the extension pack tarball. This can optionally be
+ followed by a "::SHA-256=hex-digit" of the tarball. </desc>
</param>
<param name="file" type="IExtPackFile" dir="return">
<desc>The interface of the extension pack file object.</desc>
diff --git a/src/VBox/Main/include/AdditionsFacilityImpl.h b/src/VBox/Main/include/AdditionsFacilityImpl.h
index d7a4b75d3..46193a997 100644
--- a/src/VBox/Main/include/AdditionsFacilityImpl.h
+++ b/src/VBox/Main/include/AdditionsFacilityImpl.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 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;
@@ -18,9 +18,11 @@
#ifndef ____H_ADDITIONSFACILITYIMPL
#define ____H_ADDITIONSFACILITYIMPL
-#include "VirtualBoxBase.h"
+#include <vector>
#include <iprt/time.h>
+#include "VirtualBoxBase.h"
+
class Guest;
class ATL_NO_VTABLE AdditionsFacility :
@@ -41,7 +43,8 @@ public:
DECLARE_EMPTY_CTOR_DTOR(AdditionsFacility)
// public initializer/uninitializer for internal purposes only
- HRESULT init(Guest *aParent, AdditionsFacilityType_T enmFacility, AdditionsFacilityStatus_T enmStatus);
+ HRESULT init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
void uninit();
HRESULT FinalConstruct();
@@ -59,13 +62,13 @@ public:
struct FacilityInfo
{
/** The facilitie's name. */
- const char *mName; /* utf-8 */
+ const char *mName; /* utf-8 */
/** The facilitie's type. */
AdditionsFacilityType_T mType;
/** The facilitie's class. */
AdditionsFacilityClass_T mClass;
};
- static const FacilityInfo sFacilityInfo[8];
+ static const FacilityInfo s_aFacilityInfo[8];
// public internal methods
static const AdditionsFacility::FacilityInfo &typeToInfo(AdditionsFacilityType_T aType);
@@ -74,19 +77,27 @@ public:
Bstr getName() const;
AdditionsFacilityStatus_T getStatus() const;
AdditionsFacilityType_T getType() const;
- HRESULT update(AdditionsFacilityStatus_T aStatus, RTTIMESPEC aTimestamp);
+ void update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
private:
- struct Data
+ /** A structure for keeping a facility status
+ * set at a certain time. Good for book-keeping. */
+ struct FacilityState
{
- /** Timestamp of last updated status.
- * @todo Add a UpdateRecord struct to keep track of all
- * status changed + their time; nice for some GUIs. */
- RTTIMESPEC mLastUpdated;
+ RTTIMESPEC mTimestamp;
/** The facilitie's current status. */
AdditionsFacilityStatus_T mStatus;
+ };
+
+ struct Data
+ {
+ /** Record of current and previous facility
+ * states, limited to the 10 last states set.
+ * Note: This intentionally only is kept in
+ * Main so far! */
+ std::vector<FacilityState> mStates;
/** The facilitie's ID/type. */
- AdditionsFacilityType_T mType;
+ AdditionsFacilityType_T mType;
} mData;
};
diff --git a/src/VBox/Main/include/ConsoleImpl.h b/src/VBox/Main/include/ConsoleImpl.h
index 3d858d499..d23a54bb4 100644
--- a/src/VBox/Main/include/ConsoleImpl.h
+++ b/src/VBox/Main/include/ConsoleImpl.h
@@ -228,6 +228,20 @@ public:
void VRDPInterceptClipboard(uint32_t u32ClientId);
void processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList, bool fDescExt);
+ void reportGuestStatistics(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM)
+ {
+ mControl->ReportGuestStatistics(aValidStats, aCpuUser, aCpuKernel, aCpuIdle,
+ aMemTotal, aMemFree, aMemBalloon, aMemShared,
+ aMemCache, aPageTotal, aAllocVMM, aFreeVMM,
+ aBalloonedVMM, aSharedVMM);
+ }
+ void enableVMMStatistics(BOOL aEnable);
// callback callers (partly; for some events console callbacks are notified
// directly from IInternalSessionControl event handlers declared above)
diff --git a/src/VBox/Main/include/ExtPackManagerImpl.h b/src/VBox/Main/include/ExtPackManagerImpl.h
index 894f5d5d1..08ca31676 100644
--- a/src/VBox/Main/include/ExtPackManagerImpl.h
+++ b/src/VBox/Main/include/ExtPackManagerImpl.h
@@ -43,7 +43,7 @@ public:
HRESULT FinalConstruct();
void FinalRelease();
- HRESULT initWithFile(const char *a_pszFile, class ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox);
+ HRESULT initWithFile(const char *a_pszFile, const char *a_pszDigest, class ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox);
void uninit();
RTMEMEF_NEW_AND_DELETE_OPERATORS();
/** @} */
diff --git a/src/VBox/Main/include/ExtPackUtil.h b/src/VBox/Main/include/ExtPackUtil.h
index b4b32204f..d7e3c253d 100644
--- a/src/VBox/Main/include/ExtPackUtil.h
+++ b/src/VBox/Main/include/ExtPackUtil.h
@@ -126,9 +126,11 @@ bool VBoxExtPackIsValidEditionString(const char *pszEdition);
bool VBoxExtPackIsValidModuleString(const char *pszModule);
int VBoxExtPackValidateMember(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOBJ hVfsObj, char *pszError, size_t cbError);
-int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss);
-int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName, const char *pszTarball,
- char *pszError, size_t cbError, PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile);
+int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss, PRTMANIFEST phFileManifest);
+int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
+ const char *pszTarball, const char *pszTarballDigest,
+ char *pszError, size_t cbError,
+ PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile, RTCString *pStrDigest);
#endif
diff --git a/src/VBox/Main/include/GuestCtrlImplPrivate.h b/src/VBox/Main/include/GuestCtrlImplPrivate.h
index 00ba41c66..8f7149ffc 100644
--- a/src/VBox/Main/include/GuestCtrlImplPrivate.h
+++ b/src/VBox/Main/include/GuestCtrlImplPrivate.h
@@ -36,25 +36,25 @@ class Guest;
class Progress;
/** Structure representing the "value" side of a "key=value" pair. */
-class VBOXGUESTCTRL_STREAMVALUE
+class GuestProcessStreamValue
{
public:
- VBOXGUESTCTRL_STREAMVALUE() { }
- VBOXGUESTCTRL_STREAMVALUE(const char *pszValue)
+ GuestProcessStreamValue() { }
+ GuestProcessStreamValue(const char *pszValue)
: mValue(pszValue) {}
- VBOXGUESTCTRL_STREAMVALUE(const VBOXGUESTCTRL_STREAMVALUE& aThat)
+ GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
: mValue(aThat.mValue) {}
Utf8Str mValue;
};
/** Map containing "key=value" pairs of a guest process stream. */
-typedef std::pair< Utf8Str, VBOXGUESTCTRL_STREAMVALUE > GuestCtrlStreamPair;
-typedef std::map < Utf8Str, VBOXGUESTCTRL_STREAMVALUE > GuestCtrlStreamPairMap;
-typedef std::map < Utf8Str, VBOXGUESTCTRL_STREAMVALUE >::iterator GuestCtrlStreamPairMapIter;
-typedef std::map < Utf8Str, VBOXGUESTCTRL_STREAMVALUE >::const_iterator GuestCtrlStreamPairMapIterConst;
+typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
+typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
+typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
+typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
/**
* Class representing a block of stream pairs (key=value). Each block in a raw guest
@@ -75,6 +75,10 @@ public:
void Clear();
+#ifdef DEBUG
+ void Dump();
+#endif
+
int GetInt64Ex(const char *pszKey, int64_t *piVal);
int64_t GetInt64(const char *pszKey);
@@ -118,8 +122,14 @@ public:
void Destroy();
+#ifdef DEBUG
+ void Dump(const char *pszFile);
+#endif
+
uint32_t GetOffset();
+ uint32_t GetSize();
+
int ParseBlock(GuestProcessStreamBlock &streamBlock);
protected:
@@ -165,8 +175,8 @@ public:
ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest);
TaskType taskType;
- Guest *pGuest;
- ComObjPtr<Progress> progress;
+ ComObjPtr<Guest> pGuest;
+ ComObjPtr<Progress> pProgress;
HRESULT rc;
/* Task data. */
diff --git a/src/VBox/Main/include/GuestImpl.h b/src/VBox/Main/include/GuestImpl.h
index 9a03d5ff1..e38a32f3d 100644
--- a/src/VBox/Main/include/GuestImpl.h
+++ b/src/VBox/Main/include/GuestImpl.h
@@ -77,7 +77,7 @@ public:
// IGuest properties
STDMETHOD(COMGETTER(OSTypeId)) (BSTR *aOSTypeId);
STDMETHOD(COMGETTER(AdditionsRunLevel)) (AdditionsRunLevelType_T *aRunLevel);
- STDMETHOD(COMGETTER(AdditionsVersion)) (BSTR *aAdditionsVersion);
+ STDMETHOD(COMGETTER(AdditionsVersion))(BSTR *a_pbstrAdditionsVersion);
STDMETHOD(COMGETTER(Facilities)) (ComSafeArrayOut(IAdditionsFacility*, aFacilities));
STDMETHOD(COMGETTER(MemoryBalloonSize)) (ULONG *aMemoryBalloonSize);
STDMETHOD(COMSETTER(MemoryBalloonSize)) (ULONG aMemoryBalloonSize);
@@ -120,10 +120,10 @@ public:
// Public methods that are not in IDL (only called internally).
void setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType);
- void setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision);
+ void setAdditionsInfo2(uint32_t a_uFullVersion, const char *a_pszName, uint32_t a_uRevision, uint32_t a_fFeatures);
bool facilityIsActive(VBoxGuestFacilityType enmFacility);
- HRESULT facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus);
- void setAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus, ULONG aFlags);
+ void facilityUpdate(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
+ void setAdditionsStatus(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS);
void setSupportedFeatures(uint32_t aCaps);
HRESULT setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal);
BOOL isPageFusionEnabled();
@@ -152,17 +152,23 @@ public:
HRESULT executeAndWaitForTool(IN_BSTR aTool, IN_BSTR aDescription,
ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
IN_BSTR aUsername, IN_BSTR aPassword,
+ ULONG uFlagsToAdd,
+ GuestCtrlStreamObjects *pObjStdOut, GuestCtrlStreamObjects *pObjStdErr,
IProgress **aProgress, ULONG *aPID);
HRESULT executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
IN_BSTR aUsername, IN_BSTR aPassword,
ULONG aTimeoutMS, ULONG *aPID, IProgress **aProgress, int *pRC);
+ HRESULT getProcessOutputInternal(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
+ LONG64 aSize, ComSafeArrayOut(BYTE, aData), int *pRC);
HRESULT executeProcessResult(const char *pszCommand, const char *pszUser, ULONG ulTimeout, PCALLBACKDATAEXECSTATUS pExecStatus, ULONG *puPID);
- HRESULT executeStreamQueryFsObjInfo(IN_BSTR aObjName,GuestProcessStreamBlock &streamBlock, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttribs);
- int executeStreamDrain(ULONG aPID, GuestProcessStream &stream);
- int executeStreamGetNextBlock(ULONG aPID, GuestProcessStream &stream, GuestProcessStreamBlock &streamBlock);
- HRESULT executeStreamParse(ULONG aPID, GuestCtrlStreamObjects &streamObjects);
- HRESULT executeWaitForStatusChange(ULONG uPID, ULONG uTimeoutMS, ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode);
+ int executeStreamQueryFsObjInfo(IN_BSTR aObjName,GuestProcessStreamBlock &streamBlock, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttribs);
+ int executeStreamDrain(ULONG aPID, ULONG ulFlags, GuestProcessStream &stream);
+ int executeStreamGetNextBlock(ULONG ulPID, ULONG ulFlags, GuestProcessStream &stream, GuestProcessStreamBlock &streamBlock);
+ int executeStreamParseNextBlock(ULONG ulPID, ULONG ulFlags, GuestProcessStream &stream, GuestProcessStreamBlock &streamBlock);
+ HRESULT executeStreamParse(ULONG uPID, ULONG ulFlags, GuestCtrlStreamObjects &streamObjects);
+ HRESULT executeWaitForExit(ULONG uPID, ComPtr<IProgress> pProgress, ULONG uTimeoutMS,
+ ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode);
// Internal guest file functions
HRESULT fileExistsInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists);
HRESULT fileQueryInfoInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, PRTFSOBJINFO aObjInfo, RTFSOBJATTRADD enmAddAttribs, int *pRC);
@@ -178,6 +184,7 @@ public:
HRESULT taskCopyFileFromGuest(GuestTask *aTask);
HRESULT taskUpdateGuestAdditions(GuestTask *aTask);
# endif
+ void enableVMMStatistics(BOOL aEnable) { mCollectVMMStats = aEnable; };
private:
@@ -199,6 +206,7 @@ private:
int callbackAdd(const PVBOXGUESTCTRL_CALLBACK pCallbackData, uint32_t *puContextID);
void callbackDestroy(uint32_t uContextID);
+ void callbackRemove(uint32_t uContextID);
bool callbackExists(uint32_t uContextID);
void callbackFreeUserData(void *pvData);
int callbackGetUserData(uint32_t uContextID, eVBoxGuestCtrlCallbackType *pEnmType, void **ppvData, size_t *pcbData);
@@ -228,9 +236,8 @@ private:
typedef std::map< uint32_t, VBOXGUESTCTRL_PROCESS >::iterator GuestProcessMapIter;
typedef std::map< uint32_t, VBOXGUESTCTRL_PROCESS >::const_iterator GuestProcessMapIterConst;
- int processAdd(uint32_t u32PID, ExecuteProcessStatus_T enmStatus, uint32_t uExitCode, uint32_t uFlags);
- int processGetByPID(uint32_t u32PID, PVBOXGUESTCTRL_PROCESS pProcess);
- int processSetStatus(uint32_t u32PID, ExecuteProcessStatus_T enmStatus, uint32_t uExitCode, uint32_t uFlags);
+ int processGetStatus(uint32_t u32PID, PVBOXGUESTCTRL_PROCESS pProcess, bool fRemove);
+ int processSetStatus(uint32_t u32PID, ExecuteProcessStatus_T enmStatus, uint32_t uExitCode, uint32_t uFlags);
// Internal guest directory representation.
typedef struct VBOXGUESTCTRL_DIRECTORY
@@ -269,18 +276,25 @@ private:
struct Data
{
- Data() : mAdditionsRunLevel (AdditionsRunLevelType_None) {}
+ Data() : mAdditionsRunLevel(AdditionsRunLevelType_None)
+ , mAdditionsVersionFull(0), mAdditionsRevision(0), mAdditionsFeatures(0)
+ { }
Bstr mOSTypeId;
FacilityMap mFacilityMap;
AdditionsRunLevelType_T mAdditionsRunLevel;
- Bstr mAdditionsVersion;
+ uint32_t mAdditionsVersionFull;
+ Bstr mAdditionsVersionNew;
+ uint32_t mAdditionsRevision;
+ uint32_t mAdditionsFeatures;
Bstr mInterfaceVersion;
};
ULONG mMemoryBalloonSize;
ULONG mStatUpdateInterval;
ULONG mCurrentGuestStat[GUESTSTATTYPE_MAX];
+ ULONG mGuestValidStats;
+ BOOL mCollectVMMStats;
BOOL mfPageFusionEnabled;
Console *mParent;
@@ -297,7 +311,12 @@ private:
GuestDirectoryMap mGuestDirectoryMap;
GuestProcessMap mGuestProcessMap;
# endif
+ static void staticUpdateStats(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
+ void updateStats(uint64_t iTick);
+ RTTIMERLR mStatTimer;
+ uint32_t mMagic;
};
+#define GUEST_MAGIC 0xCEED2006u
#endif // ____H_GUESTIMPL
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/include/MachineImpl.h b/src/VBox/Main/include/MachineImpl.h
index e2857c437..5611571b4 100644
--- a/src/VBox/Main/include/MachineImpl.h
+++ b/src/VBox/Main/include/MachineImpl.h
@@ -1015,6 +1015,13 @@ public:
STDMETHOD(UnlockMedia)() { unlockMedia(); return S_OK; }
STDMETHOD(EjectMedium)(IMediumAttachment *aAttachment,
IMediumAttachment **aNewAttachment);
+ STDMETHOD(ReportGuestStatistics)(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM);
// public methods only for internal purposes
diff --git a/src/VBox/Main/include/Performance.h b/src/VBox/Main/include/Performance.h
index 84c458668..f7de94eda 100644
--- a/src/VBox/Main/include/Performance.h
+++ b/src/VBox/Main/include/Performance.h
@@ -24,11 +24,13 @@
#include <iprt/types.h>
#include <iprt/err.h>
+#include <iprt/cpp/lock.h>
#include <algorithm>
#include <functional> /* For std::fun_ptr in testcase */
#include <list>
#include <vector>
+#include <queue>
/* Forward decl. */
class Machine;
@@ -139,20 +141,133 @@ namespace pm
};
/* Guest Collector Classes *********************************/
+ /*
+ * WARNING! The bits in the following masks must correspond to parameters
+ * of CollectorGuest::updateStats().
+ */
+ typedef enum
+ {
+ GUESTSTATMASK_NONE = 0x00000000,
+ GUESTSTATMASK_CPUUSER = 0x00000001,
+ GUESTSTATMASK_CPUKERNEL = 0x00000002,
+ GUESTSTATMASK_CPUIDLE = 0x00000004,
+ GUESTSTATMASK_MEMTOTAL = 0x00000008,
+ GUESTSTATMASK_MEMFREE = 0x00000010,
+ GUESTSTATMASK_MEMBALLOON = 0x00000020,
+ GUESTSTATMASK_MEMSHARED = 0x00000040,
+ GUESTSTATMASK_MEMCACHE = 0x00000080,
+ GUESTSTATMASK_PAGETOTAL = 0x00000100,
+ GUESTSTATMASK_ALLOCVMM = 0x00000200,
+ GUESTSTATMASK_FREEVMM = 0x00000400,
+ GUESTSTATMASK_BALOONVMM = 0x00000800,
+ GUESTSTATMASK_SHAREDVMM = 0x00001000
+ } GUESTSTATMASK;
+
+ const ULONG GUESTSTATS_CPULOAD =
+ GUESTSTATMASK_CPUUSER|GUESTSTATMASK_CPUKERNEL|GUESTSTATMASK_CPUIDLE;
+ const ULONG GUESTSTATS_RAMUSAGE =
+ GUESTSTATMASK_MEMTOTAL|GUESTSTATMASK_MEMFREE|GUESTSTATMASK_MEMBALLOON|
+ GUESTSTATMASK_MEMSHARED|GUESTSTATMASK_MEMCACHE|
+ GUESTSTATMASK_PAGETOTAL;
+ const ULONG GUESTSTATS_VMMRAM =
+ GUESTSTATMASK_ALLOCVMM|GUESTSTATMASK_FREEVMM|
+ GUESTSTATMASK_BALOONVMM|GUESTSTATMASK_SHAREDVMM;
+ const ULONG GUESTSTATS_ALL = GUESTSTATS_CPULOAD|GUESTSTATS_RAMUSAGE|GUESTSTATS_VMMRAM;
+
+ class CollectorGuest;
+
+ class CollectorGuestRequest
+ {
+ public:
+ CollectorGuestRequest()
+ : mCGuest(0) {};
+ virtual ~CollectorGuestRequest() {};
+ void setGuest(CollectorGuest *aGuest) { mCGuest = aGuest; };
+ CollectorGuest *getGuest() { return mCGuest; };
+ virtual int execute() = 0;
+
+ virtual void debugPrint(void *aObject, const char *aFunction, const char *aText) = 0;
+ protected:
+ CollectorGuest *mCGuest;
+ const char *mDebugName;
+ };
+
+ class CGRQEnable : public CollectorGuestRequest
+ {
+ public:
+ CGRQEnable(ULONG aMask)
+ : mMask(aMask) {};
+ int execute();
+
+ void debugPrint(void *aObject, const char *aFunction, const char *aText);
+ private:
+ ULONG mMask;
+ };
+
+ class CGRQDisable : public CollectorGuestRequest
+ {
+ public:
+ CGRQDisable(ULONG aMask)
+ : mMask(aMask) {};
+ int execute();
+
+ void debugPrint(void *aObject, const char *aFunction, const char *aText);
+ private:
+ ULONG mMask;
+ };
+
+ class CGRQAbort : public CollectorGuestRequest
+ {
+ public:
+ CGRQAbort() {};
+ int execute();
+
+ void debugPrint(void *aObject, const char *aFunction, const char *aText);
+ };
+
+ class CollectorGuestQueue
+ {
+ public:
+ CollectorGuestQueue();
+ ~CollectorGuestQueue();
+ void push(CollectorGuestRequest* rq);
+ CollectorGuestRequest* pop();
+ private:
+ RTCLockMtx mLockMtx;
+ RTSEMEVENT mEvent;
+ std::queue<CollectorGuestRequest*> mQueue;
+ };
+
+ class CollectorGuestManager;
+
class CollectorGuest
{
public:
CollectorGuest(Machine *machine, RTPROCESS process);
~CollectorGuest();
- bool isUnregistered() { return mUnregistered; };
- bool isEnabled() { return mEnabled; };
- bool isValid() { return mValid; };
- void invalidateStats() { mValid = false; };
- void unregister() { mUnregistered = true; };
- int updateStats();
- int enable();
- int disable();
+ void setManager(CollectorGuestManager *aManager)
+ { mManager = aManager; };
+ bool isUnregistered() { return mUnregistered; };
+ bool isEnabled() { return mEnabled != 0; };
+ bool isValid(ULONG mask) { return (mValid & mask) == mask; };
+ void invalidate(ULONG mask) { mValid &= ~mask; };
+ void unregister() { mUnregistered = true; };
+ void updateStats(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM);
+ int enable(ULONG mask);
+ int disable(ULONG mask);
+
+ int enqueueRequest(CollectorGuestRequest *aRequest);
+ int enableInternal(ULONG mask);
+ int disableInternal(ULONG mask);
+
+ const com::Utf8Str& getVMName() const { return mMachineName; };
RTPROCESS getProcess() { return mProcess; };
ULONG getCpuUser() { return mCpuUser; };
@@ -170,10 +285,15 @@ namespace pm
ULONG getSharedVMM() { return mSharedVMM; };
private:
+ int enableVMMStats(bool mCollectVMMStats);
+
+ CollectorGuestManager *mManager;
+
bool mUnregistered;
- bool mEnabled;
- bool mValid;
+ ULONG mEnabled;
+ ULONG mValid;
Machine *mMachine;
+ com::Utf8Str mMachineName;
RTPROCESS mProcess;
ComPtr<IConsole> mConsole;
ComPtr<IGuest> mGuest;
@@ -196,16 +316,24 @@ namespace pm
class CollectorGuestManager
{
public:
- CollectorGuestManager() : mVMMStatsProvider(NULL) {};
- ~CollectorGuestManager() { Assert(mGuests.size() == 0); };
+ CollectorGuestManager();
+ ~CollectorGuestManager();
void registerGuest(CollectorGuest* pGuest);
void unregisterGuest(CollectorGuest* pGuest);
CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
void preCollect(CollectorHints& hints, uint64_t iTick);
void destroyUnregistered();
+ int enqueueRequest(CollectorGuestRequest *aRequest);
+
+ CollectorGuest *getBlockedGuest() { return mGuestBeingCalled; };
+
+ static DECLCALLBACK(int) requestProcessingThread(RTTHREAD aThread, void *pvUser);
private:
- CollectorGuestList mGuests;
- CollectorGuest *mVMMStatsProvider;
+ RTTHREAD mThread;
+ CollectorGuestList mGuests;
+ CollectorGuest *mVMMStatsProvider;
+ CollectorGuestQueue mQueue;
+ CollectorGuest *mGuestBeingCalled;
};
/* Collector Hardware Abstraction Layer *********************************/
@@ -253,8 +381,8 @@ namespace pm
bool collectorBeat(uint64_t nowAt);
- void enable() { mEnabled = true; };
- void disable() { mEnabled = false; };
+ virtual int enable() { mEnabled = true; return S_OK; };
+ virtual int disable() { mEnabled = false; return S_OK; };
void unregister() { mUnregistered = true; };
bool isUnregistered() { return mUnregistered; };
@@ -358,6 +486,7 @@ namespace pm
SubMetric *mAvailable;
};
+#ifndef VBOX_COLLECTOR_TEST_CASE
class HostRamVmm : public BaseMetric
{
public:
@@ -370,6 +499,8 @@ namespace pm
void init(ULONG period, ULONG length);
void preCollect(CollectorHints& hints, uint64_t iTick);
void collect();
+ int enable();
+ int disable();
const char *getUnit() { return "kB"; };
ULONG getMinValue() { return 0; };
ULONG getMaxValue() { return INT32_MAX; };
@@ -386,6 +517,7 @@ namespace pm
ULONG mBalloonedCurrent;
ULONG mSharedCurrent;
};
+#endif /* VBOX_COLLECTOR_TEST_CASE */
class MachineCpuLoad : public BaseMetric
{
@@ -440,6 +572,7 @@ namespace pm
};
+#ifndef VBOX_COLLECTOR_TEST_CASE
class GuestCpuLoad : public BaseGuestMetric
{
public:
@@ -450,6 +583,8 @@ namespace pm
void init(ULONG period, ULONG length);
void preCollect(CollectorHints& hints, uint64_t iTick);
void collect();
+ int enable();
+ int disable();
const char *getUnit() { return "%"; };
ULONG getMinValue() { return 0; };
ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
@@ -470,6 +605,8 @@ namespace pm
void init(ULONG period, ULONG length);
void preCollect(CollectorHints& hints, uint64_t iTick);
void collect();
+ int enable();
+ int disable();
const char *getUnit() { return "kB"; };
ULONG getMinValue() { return 0; };
ULONG getMaxValue() { return INT32_MAX; };
@@ -477,6 +614,7 @@ namespace pm
private:
SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
};
+#endif /* VBOX_COLLECTOR_TEST_CASE */
/* Aggregate Functions **************************************************/
class Aggregate
diff --git a/src/VBox/Main/include/PerformanceImpl.h b/src/VBox/Main/include/PerformanceImpl.h
index 1ac7304fd..69851718c 100644
--- a/src/VBox/Main/include/PerformanceImpl.h
+++ b/src/VBox/Main/include/PerformanceImpl.h
@@ -194,6 +194,8 @@ private:
static void staticSamplerCallback (RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
void samplerCallback(uint64_t iTick);
+ const Utf8Str& getFailedGuestName();
+
typedef std::list<pm::Metric*> MetricList;
typedef std::list<pm::BaseMetric*> BaseMetricList;
@@ -203,6 +205,7 @@ private:
};
unsigned int mMagic;
+ const Utf8Str mUnknownGuest;
struct Data
{
diff --git a/src/VBox/Main/include/SessionImpl.h b/src/VBox/Main/include/SessionImpl.h
index 43ed62927..96a78c445 100644
--- a/src/VBox/Main/include/SessionImpl.h
+++ b/src/VBox/Main/include/SessionImpl.h
@@ -112,6 +112,7 @@ public:
BOOL aMergeForward, IMedium *aParentForTarget,
ComSafeArrayIn(IMedium *, aChildrenToReparent),
IProgress *aProgress);
+ STDMETHOD(EnableVMMStatistics)(BOOL aEnable);
private:
diff --git a/src/VBox/Main/src-all/ExtPackManagerImpl.cpp b/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
index 6bff51b0a..229ec5ea5 100644
--- a/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
+++ b/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
@@ -88,6 +88,8 @@ struct ExtPackFile::Data : public ExtPackBaseData
public:
/** The path to the tarball. */
Utf8Str strExtPackFile;
+ /** The SHA-256 hash of the file (as string). */
+ Utf8Str strDigest;
/** The file handle of the extension pack file. */
RTFILE hExtPackFile;
/** Our manifest for the tarball. */
@@ -219,10 +221,11 @@ HRESULT ExtPackFile::FinalConstruct()
*
* @returns COM status code.
* @param a_pszFile The path to the extension pack file.
+ * @param a_pszDigest The SHA-256 digest of the file. Or an empty string.
* @param a_pExtPackMgr Pointer to the extension pack manager.
* @param a_pVirtualBox Pointer to the VirtualBox object.
*/
-HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox)
+HRESULT ExtPackFile::initWithFile(const char *a_pszFile, const char *a_pszDigest, ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox)
{
AutoInitSpan autoInitSpan(this);
AssertReturn(autoInitSpan.isOk(), E_FAIL);
@@ -236,6 +239,7 @@ HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtP
m->fUsable = false;
m->strWhyUnusable = tr("ExtPack::init failed");
m->strExtPackFile = a_pszFile;
+ m->strDigest = a_pszDigest;
m->hExtPackFile = NIL_RTFILE;
m->hOurManifest = NIL_RTMANIFEST;
m->ptrExtPackMgr = a_pExtPackMgr;
@@ -275,8 +279,8 @@ HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtP
*/
char szError[8192];
RTVFSFILE hXmlFile;
- vrc = VBoxExtPackValidateTarball(m->hExtPackFile, NULL /*pszExtPackName*/, a_pszFile,
- szError, sizeof(szError), &m->hOurManifest, &hXmlFile);
+ vrc = VBoxExtPackValidateTarball(m->hExtPackFile, NULL /*pszExtPackName*/, a_pszFile, a_pszDigest,
+ szError, sizeof(szError), &m->hOurManifest, &hXmlFile, &m->strDigest);
if (RT_FAILURE(vrc))
return initFailed(tr("%s"), szError);
@@ -548,7 +552,7 @@ STDMETHODIMP ExtPackFile::QueryLicense(IN_BSTR a_bstrPreferredLocale, IN_BSTR a_
{
RTVFSFSSTREAM hTarFss;
char szError[8192];
- int vrc = VBoxExtPackOpenTarFss(m->hExtPackFile, szError, sizeof(szError), &hTarFss);
+ int vrc = VBoxExtPackOpenTarFss(m->hExtPackFile, szError, sizeof(szError), &hTarFss, NULL);
if (RT_SUCCESS(vrc))
{
for (;;)
@@ -2024,17 +2028,34 @@ STDMETHODIMP ExtPackManager::Find(IN_BSTR a_bstrName, IExtPack **a_pExtPack)
return hrc;
}
-STDMETHODIMP ExtPackManager::OpenExtPackFile(IN_BSTR a_bstrTarball, IExtPackFile **a_ppExtPackFile)
+STDMETHODIMP ExtPackManager::OpenExtPackFile(IN_BSTR a_bstrTarballAndDigest, IExtPackFile **a_ppExtPackFile)
{
- CheckComArgNotNull(a_bstrTarball);
+ CheckComArgNotNull(a_bstrTarballAndDigest);
CheckComArgOutPointerValid(a_ppExtPackFile);
- Utf8Str strTarball(a_bstrTarball);
AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
+ /* The API can optionally take a ::SHA-256=<hex-digest> attribute at the
+ end of the file name. This is just a temporary measure for
+ backporting, in 4.2 we'll add another parameter to the method. */
+ Utf8Str strTarball;
+ Utf8Str strDigest;
+ Utf8Str strTarballAndDigest(a_bstrTarballAndDigest);
+ size_t offSha256 = Utf8Str::npos;
+ const char *pszFilename = RTPathFilename(strTarballAndDigest.c_str());
+ if (pszFilename)
+ offSha256 = strTarballAndDigest.find("::SHA-256=", pszFilename - strTarballAndDigest.c_str());
+ if (offSha256 == Utf8Str::npos)
+ strTarball = strTarballAndDigest;
+ else
+ {
+ strTarball = strTarballAndDigest.substr(0, offSha256);
+ strDigest = strTarballAndDigest.substr(offSha256 + sizeof("::SHA-256=") - 1);
+ }
+
ComObjPtr<ExtPackFile> NewExtPackFile;
HRESULT hrc = NewExtPackFile.createObject();
if (SUCCEEDED(hrc))
- hrc = NewExtPackFile->initWithFile(strTarball.c_str(), this, m->pVirtualBox);
+ hrc = NewExtPackFile->initWithFile(strTarball.c_str(), strDigest.c_str(), this, m->pVirtualBox);
if (SUCCEEDED(hrc))
NewExtPackFile.queryInterfaceTo(a_ppExtPackFile);
@@ -2598,8 +2619,9 @@ HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnusableIs
HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo)
{
AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
- RTCString const * const pStrName = &a_pExtPackFile->m->Desc.strName;
- RTCString const * const pStrTarball = &a_pExtPackFile->m->strExtPackFile;
+ RTCString const * const pStrName = &a_pExtPackFile->m->Desc.strName;
+ RTCString const * const pStrTarball = &a_pExtPackFile->m->strExtPackFile;
+ RTCString const * const pStrTarballDigest = &a_pExtPackFile->m->strDigest;
AutoCaller autoCaller(this);
HRESULT hrc = autoCaller.rc();
@@ -2630,13 +2652,13 @@ HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace,
* installation. Then create an object for the packet (we do this
* even on failure, to be on the safe side).
*/
- /** @todo add a hash (SHA-256) of the tarball or maybe just the manifest. */
hrc = runSetUidToRootHelper(a_pstrDisplayInfo,
"install",
"--base-dir", m->strBaseDir.c_str(),
"--cert-dir", m->strCertificatDirPath.c_str(),
"--name", pStrName->c_str(),
"--tarball", pStrTarball->c_str(),
+ "--sha-256", pStrTarballDigest->c_str(),
pExtPack ? "--replace" : (const char *)NULL,
(const char *)NULL);
if (SUCCEEDED(hrc))
diff --git a/src/VBox/Main/src-all/ExtPackUtil.cpp b/src/VBox/Main/src-all/ExtPackUtil.cpp
index bcdc91aec..cda2268f3 100644
--- a/src/VBox/Main/src-all/ExtPackUtil.cpp
+++ b/src/VBox/Main/src-all/ExtPackUtil.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010-2011 Oracle Corporation
+ * Copyright (C) 2010-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;
@@ -27,6 +27,7 @@
#include <iprt/manifest.h>
#include <iprt/param.h>
#include <iprt/path.h>
+#include <iprt/sha.h>
#include <iprt/string.h>
#include <iprt/vfs.h>
#include <iprt/tar.h>
@@ -786,6 +787,79 @@ static int vboxExtPackVerifyManifestAndSignature(RTMANIFEST hOurManifest, RTVFSF
/**
+ * Verifies the file digest (if specified) and returns the SHA-256 of the file.
+ *
+ * @returns
+ * @param hFileManifest Manifest containing a SHA-256 digest of the file
+ * that was calculated as the file was processed.
+ * @param pszFileDigest SHA-256 digest of the file.
+ * @param pStrDigest Where to return the SHA-256 digest. Optional.
+ * @param pszError Where to write an error message on failure.
+ * @param cbError The size of the @a pszError buffer.
+ */
+static int vboxExtPackVerifyFileDigest(RTMANIFEST hFileManifest, const char *pszFileDigest,
+ RTCString *pStrDigest, char *pszError, size_t cbError)
+{
+ /*
+ * Extract the SHA-256 entry for the extpack file.
+ */
+ char szCalculatedDigest[RTSHA256_DIGEST_LEN + 1];
+ int rc = RTManifestEntryQueryAttr(hFileManifest, "extpack", NULL /*no name*/, RTMANIFEST_ATTR_SHA256,
+ szCalculatedDigest, sizeof(szCalculatedDigest), NULL);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Convert the two strings to binary form before comparing.
+ * We convert the calculated hash even if we don't have anything to
+ * compare with, just to validate it.
+ */
+ uint8_t abCalculatedHash[RTSHA256_HASH_SIZE];
+ rc = RTSha256FromString(szCalculatedDigest, abCalculatedHash);
+ if (RT_SUCCESS(rc))
+ {
+ if ( pszFileDigest
+ && *pszFileDigest != '\0')
+ {
+ uint8_t abFileHash[RTSHA256_HASH_SIZE];
+ rc = RTSha256FromString(pszFileDigest, abFileHash);
+ if (RT_SUCCESS(rc))
+ {
+ if (memcmp(abFileHash, abCalculatedHash, sizeof(abFileHash)))
+ {
+ vboxExtPackSetError(pszError, cbError, "The extension pack file has changed (SHA-256 mismatch)");
+ rc = VERR_NOT_EQUAL;
+ }
+ }
+ else
+ vboxExtPackSetError(pszError, cbError, "Bad SHA-256 '%s': %Rrc", szCalculatedDigest, rc);
+ }
+
+ /*
+ * Set the output hash on success.
+ */
+ if (pStrDigest && RT_SUCCESS(rc))
+ {
+ try
+ {
+ *pStrDigest = szCalculatedDigest;
+ }
+ catch (std::bad_alloc)
+ {
+ rc = VERR_NO_MEMORY;
+ }
+ }
+ }
+ else
+ vboxExtPackSetError(pszError, cbError, "Bad SHA-256 '%s': %Rrc", szCalculatedDigest, rc);
+ }
+ else
+ vboxExtPackSetError(pszError, cbError, "RTManifestEntryGetAttr: %Rrc", rc);
+ return rc;
+}
+
+
+
+/**
* Validates a standard file.
*
* Generally all files are
@@ -1043,8 +1117,12 @@ int VBoxExtPackValidateMember(const char *pszName, RTVFSOBJTYPE enmType, RTVFSOB
* @param pszError Where to store an error message on failure.
* @param cbError The size of the buffer @a pszError points to.
* @param phTarFss Where to return the filesystem stream handle.
+ * @param phFileManifest Where to return a manifest where the tarball is
+ * gettting hashed. The entry will be called
+ * "extpack" and be ready when the file system
+ * stream is at an end. Optional.
*/
-int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss)
+int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, PRTVFSFSSTREAM phTarFss, PRTMANIFEST phFileManifest)
{
Assert(cbError > 0);
*pszError = '\0';
@@ -1063,24 +1141,47 @@ int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, P
if (RT_FAILURE(rc))
return vboxExtPackReturnError(rc, pszError, cbError, "RTVfsIoStrmFromRTFile failed: %Rrc", rc);
- RTVFSIOSTREAM hGunzipIos;
- rc = RTZipGzipDecompressIoStream(hTarballIos, 0 /*fFlags*/, &hGunzipIos);
+ RTMANIFEST hFileManifest = NIL_RTMANIFEST;
+ rc = RTManifestCreate(0 /*fFlags*/, &hFileManifest);
if (RT_SUCCESS(rc))
{
- RTVFSFSSTREAM hTarFss;
- rc = RTZipTarFsStreamFromIoStream(hGunzipIos, 0 /*fFlags*/, &hTarFss);
+ RTVFSIOSTREAM hPtIos;
+ rc = RTManifestEntryAddPassthruIoStream(hFileManifest, hTarballIos, "extpack", RTMANIFEST_ATTR_SHA256, true /*read*/, &hPtIos);
if (RT_SUCCESS(rc))
{
- RTVfsIoStrmRelease(hGunzipIos);
- RTVfsIoStrmRelease(hTarballIos);
- *phTarFss = hTarFss;
- return VINF_SUCCESS;
+ RTVFSIOSTREAM hGunzipIos;
+ rc = RTZipGzipDecompressIoStream(hPtIos, 0 /*fFlags*/, &hGunzipIos);
+ if (RT_SUCCESS(rc))
+ {
+ RTVFSFSSTREAM hTarFss;
+ rc = RTZipTarFsStreamFromIoStream(hGunzipIos, 0 /*fFlags*/, &hTarFss);
+ if (RT_SUCCESS(rc))
+ {
+ RTVfsIoStrmRelease(hPtIos);
+ RTVfsIoStrmRelease(hGunzipIos);
+ RTVfsIoStrmRelease(hTarballIos);
+ *phTarFss = hTarFss;
+ if (phFileManifest)
+ *phFileManifest = hFileManifest;
+ else
+ RTManifestRelease(hFileManifest);
+ return VINF_SUCCESS;
+ }
+
+ vboxExtPackSetError(pszError, cbError, "RTZipTarFsStreamFromIoStream failed: %Rrc", rc);
+ RTVfsIoStrmRelease(hGunzipIos);
+ }
+ else
+ vboxExtPackSetError(pszError, cbError, "RTZipGzipDecompressIoStream failed: %Rrc", rc);
+ RTVfsIoStrmRelease(hPtIos);
}
- vboxExtPackSetError(pszError, cbError, "RTZipTarFsStreamFromIoStream failed: %Rrc", rc);
- RTVfsIoStrmRelease(hGunzipIos);
+ else
+ vboxExtPackSetError(pszError, cbError, "RTManifestEntryAddPassthruIoStream failed: %Rrc", rc);
+ RTManifestRelease(hFileManifest);
}
else
- vboxExtPackSetError(pszError, cbError, "RTZipGzipDecompressIoStream failed: %Rrc", rc);
+ vboxExtPackSetError(pszError, cbError, "RTManifestCreate failed: %Rrc", rc);
+
RTVfsIoStrmRelease(hTarballIos);
return rc;
}
@@ -1101,6 +1202,8 @@ int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, P
* the name is not fixed.
* @param pszTarball The name of the tarball in case we have to
* complain about something.
+ * @param pszTarballDigest The SHA-256 digest of the tarball. Empty string
+ * if no digest available.
* @param pszError Where to store an error message on failure.
* @param cbError The size of the buffer @a pszError points to.
* @param phValidManifest Where to optionally return the handle to fully
@@ -1108,11 +1211,13 @@ int VBoxExtPackOpenTarFss(RTFILE hTarballFile, char *pszError, size_t cbError, P
* This includes all files.
* @param phXmlFile Where to optionally return the memorized XML
* file.
- *
- * @todo This function is a bit too long and should be split up if possible.
+ * @param pStrDigest Where to return the digest of the file.
+ * Optional.
*/
-int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName, const char *pszTarball,
- char *pszError, size_t cbError, PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile)
+int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
+ const char *pszTarball, const char *pszTarballDigest,
+ char *pszError, size_t cbError,
+ PRTMANIFEST phValidManifest, PRTVFSFILE phXmlFile, RTCString *pStrDigest)
{
/*
* Clear return values.
@@ -1128,8 +1233,9 @@ int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
/*
* Open the tar.gz filesystem stream and set up an manifest in-memory file.
*/
- RTVFSFSSTREAM hTarFss;
- int rc = VBoxExtPackOpenTarFss(hTarballFile, pszError, cbError, &hTarFss);
+ RTMANIFEST hFileManifest;
+ RTVFSFSSTREAM hTarFss;
+ int rc = VBoxExtPackOpenTarFss(hTarballFile, pszError, cbError, &hTarFss, &hFileManifest);
if (RT_FAILURE(rc))
return rc;
@@ -1140,9 +1246,9 @@ int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
/*
* Process the tarball (would be nice to move this to a function).
*/
- RTVFSFILE hXmlFile = NIL_RTVFSFILE;
- RTVFSFILE hManifestFile = NIL_RTVFSFILE;
- RTVFSFILE hSignatureFile= NIL_RTVFSFILE;
+ RTVFSFILE hXmlFile = NIL_RTVFSFILE;
+ RTVFSFILE hManifestFile = NIL_RTVFSFILE;
+ RTVFSFILE hSignatureFile = NIL_RTVFSFILE;
for (;;)
{
/*
@@ -1209,6 +1315,16 @@ int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
}
/*
+ * Check the integrity of the tarball file.
+ */
+ if (RT_SUCCESS(rc))
+ {
+ RTVfsFsStrmRelease(hTarFss);
+ hTarFss = NIL_RTVFSFSSTREAM;
+ rc = vboxExtPackVerifyFileDigest(hFileManifest, pszTarballDigest, pStrDigest, pszError, cbError);
+ }
+
+ /*
* If we've successfully processed the tarball, verify that the
* mandatory files are present.
*/
@@ -1262,6 +1378,7 @@ int VBoxExtPackValidateTarball(RTFILE hTarballFile, const char *pszExtPackName,
else
vboxExtPackSetError(pszError, cbError, "RTManifestCreate failed: %Rrc", rc);
RTVfsFsStrmRelease(hTarFss);
+ RTManifestRelease(hFileManifest);
return rc;
}
diff --git a/src/VBox/Main/src-all/Global.cpp b/src/VBox/Main/src-all/Global.cpp
index a26431818..5c89b4a4f 100644
--- a/src/VBox/Main/src-all/Global.cpp
+++ b/src/VBox/Main/src-all/Global.cpp
@@ -56,11 +56,11 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
128, 16, 2 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows2000, "Windows 2000",
- VBOXOSTYPE_Win2k, VBOXOSHINT_NONE | VBOXOSHINT_USBTABLET,
+ VBOXOSTYPE_Win2k, VBOXOSHINT_USBTABLET,
168, 16, 4 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_WindowsXP, "Windows XP",
- VBOXOSTYPE_WinXP, VBOXOSHINT_NONE | VBOXOSHINT_USBTABLET,
+ VBOXOSTYPE_WinXP, VBOXOSHINT_USBTABLET,
192, 16, 10 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_WindowsXP_64, "Windows XP (64 bit)",
@@ -68,7 +68,7 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
192, 16, 10 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows2003, "Windows 2003",
- VBOXOSTYPE_Win2k3, VBOXOSHINT_NONE | VBOXOSHINT_USBTABLET,
+ VBOXOSTYPE_Win2k3, VBOXOSHINT_USBTABLET,
256, 16, 20 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97 },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows2003_64, "Windows 2003 (64 bit)",
@@ -76,7 +76,7 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
256, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_WindowsVista, "Windows Vista",
- VBOXOSTYPE_WinVista, VBOXOSHINT_NONE | VBOXOSHINT_USBTABLET,
+ VBOXOSTYPE_WinVista, VBOXOSHINT_USBTABLET,
512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_WindowsVista_64, "Windows Vista (64 bit)",
@@ -84,7 +84,7 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows2008, "Windows 2008",
- VBOXOSTYPE_Win2k8, VBOXOSHINT_NONE | VBOXOSHINT_USBTABLET,
+ VBOXOSTYPE_Win2k8, VBOXOSHINT_USBTABLET,
512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows2008_64, "Windows 2008 (64 bit)",
@@ -92,7 +92,7 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows7, "Windows 7",
- VBOXOSTYPE_Win7, VBOXOSHINT_NONE | VBOXOSHINT_USBTABLET,
+ VBOXOSTYPE_Win7, VBOXOSHINT_USBTABLET,
512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows7_64, "Windows 7 (64 bit)",
@@ -100,12 +100,12 @@ const Global::OSType Global::sOSTypes[SchemaDefs::OSTypeId_COUNT] =
512, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows8, "Windows 8",
- VBOXOSTYPE_Win8, VBOXOSHINT_NONE | VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET,
- 1024, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ VBOXOSTYPE_Win8, VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET | VBOXOSHINT_PAE,
+ 1024,128, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_Windows8_64, "Windows 8 (64 bit)",
VBOXOSTYPE_Win8_x64, VBOXOSHINT_64BIT | VBOXOSHINT_HWVIRTEX | VBOXOSHINT_IOAPIC | VBOXOSHINT_USBTABLET,
- 1536, 16, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
+ 1536,128, 20 * _1G64, NetworkAdapterType_I82540EM, 0, StorageControllerType_PIIX4, StorageBus_IDE,
StorageControllerType_IntelAhci, StorageBus_SATA, ChipsetType_PIIX3, AudioControllerType_HDA },
{ "Windows", "Microsoft Windows", SchemaDefs_OSTypeId_WindowsNT, "Other Windows",
VBOXOSTYPE_WinNT, VBOXOSHINT_NONE,
diff --git a/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp b/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp
index da91146ed..408a22fa1 100644
--- a/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp
+++ b/src/VBox/Main/src-client/AdditionsFacilityImpl.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 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;
@@ -22,11 +22,12 @@
#include "Logging.h"
/* static */
-const AdditionsFacility::FacilityInfo AdditionsFacility::sFacilityInfo[8] =
+const AdditionsFacility::FacilityInfo AdditionsFacility::s_aFacilityInfo[8] =
{
/* NOTE: We assume that unknown is always the first entry! */
{ "Unknown", AdditionsFacilityType_None, AdditionsFacilityClass_None },
{ "VirtualBox Base Driver", AdditionsFacilityType_VBoxGuestDriver, AdditionsFacilityClass_Driver },
+ { "Auto Logon", AdditionsFacilityType_AutoLogon, AdditionsFacilityClass_Feature },
{ "VirtualBox System Service", AdditionsFacilityType_VBoxService, AdditionsFacilityClass_Service },
{ "VirtualBox Desktop Integration", AdditionsFacilityType_VBoxTrayClient, AdditionsFacilityClass_Program },
{ "Seamless Mode", AdditionsFacilityType_Seamless, AdditionsFacilityClass_Feature },
@@ -55,18 +56,25 @@ void AdditionsFacility::FinalRelease()
// public initializer/uninitializer for internal purposes only
/////////////////////////////////////////////////////////////////////////////
-HRESULT AdditionsFacility::init(Guest *aParent, AdditionsFacilityType_T enmFacility, AdditionsFacilityStatus_T enmStatus)
+HRESULT AdditionsFacility::init(Guest *a_pParent, AdditionsFacilityType_T a_enmFacility, AdditionsFacilityStatus_T a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
{
- LogFlowThisFunc(("aParent=%p\n", aParent));
+ LogFlowThisFunc(("a_pParent=%p\n", a_pParent));
/* Enclose the state transition NotReady->InInit->Ready. */
AutoInitSpan autoInitSpan(this);
AssertReturn(autoInitSpan.isOk(), E_FAIL);
- RTTimeNow(&mData.mLastUpdated);
- mData.mStatus = enmStatus;
- mData.mType = enmFacility;
+ FacilityState state;
+ state.mStatus = a_enmStatus;
+ state.mTimestamp = *a_pTimeSpecTS;
+ NOREF(a_fFlags);
+
+ Assert(mData.mStates.size() == 0);
+ mData.mStates.push_back(state);
+ mData.mType = a_enmFacility;
/** @todo mClass is not initialized here. */
+ NOREF(a_fFlags);
/* Confirm a successful initialization when it's the case. */
autoInitSpan.setSucceeded();
@@ -86,6 +94,8 @@ void AdditionsFacility::uninit()
AutoUninitSpan autoUninitSpan(this);
if (autoUninitSpan.uninitDone())
return;
+
+ mData.mStates.clear();
}
STDMETHODIMP AdditionsFacility::COMGETTER(ClassType)(AdditionsFacilityClass_T *aClass)
@@ -170,12 +180,12 @@ STDMETHODIMP AdditionsFacility::COMGETTER(Type)(AdditionsFacilityType_T *aType)
const AdditionsFacility::FacilityInfo &AdditionsFacility::typeToInfo(AdditionsFacilityType_T aType)
{
- for (size_t i = 0; i < RT_ELEMENTS(sFacilityInfo); ++i)
+ for (size_t i = 0; i < RT_ELEMENTS(s_aFacilityInfo); ++i)
{
- if (sFacilityInfo[i].mType == aType)
- return sFacilityInfo[i];
+ if (s_aFacilityInfo[i].mType == aType)
+ return s_aFacilityInfo[i];
}
- return sFacilityInfo[0]; /* Return unknown type. */
+ return s_aFacilityInfo[0]; /* Return unknown type. */
}
AdditionsFacilityClass_T AdditionsFacility::getClass() const
@@ -190,12 +200,20 @@ Bstr AdditionsFacility::getName() const
LONG64 AdditionsFacility::getLastUpdated() const
{
- return RTTimeSpecGetMilli(&mData.mLastUpdated);
+ if (mData.mStates.size())
+ return RTTimeSpecGetMilli(&mData.mStates.front().mTimestamp);
+
+ AssertMsgFailed(("Unknown timestamp of facility!\n"));
+ return 0; /* Should never happen! */
}
AdditionsFacilityStatus_T AdditionsFacility::getStatus() const
{
- return mData.mStatus;
+ if (mData.mStates.size())
+ return mData.mStates.back().mStatus;
+
+ AssertMsgFailed(("Unknown status of facility!\n"));
+ return AdditionsFacilityStatus_Unknown; /* Should never happen! */
}
AdditionsFacilityType_T AdditionsFacility::getType() const
@@ -203,11 +221,18 @@ AdditionsFacilityType_T AdditionsFacility::getType() const
return mData.mType;
}
-HRESULT AdditionsFacility::update(AdditionsFacilityStatus_T aStatus, RTTIMESPEC aTimestamp)
+/**
+ * Method used by IGuest::facilityUpdate to make updates.
+ */
+void AdditionsFacility::update(AdditionsFacilityStatus_T a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
{
- mData.mStatus = aStatus;
- mData.mLastUpdated = aTimestamp;
+ FacilityState state;
+ state.mStatus = a_enmStatus;
+ state.mTimestamp = *a_pTimeSpecTS;
+ NOREF(a_fFlags);
- return S_OK;
+ mData.mStates.push_back(state);
+ if (mData.mStates.size() > 10) /* Only keep the last 10 states. */
+ mData.mStates.erase(mData.mStates.begin());
}
diff --git a/src/VBox/Main/src-client/AudioSnifferInterface.cpp b/src/VBox/Main/src-client/AudioSnifferInterface.cpp
index ee8ea5218..f1b642086 100644
--- a/src/VBox/Main/src-client/AudioSnifferInterface.cpp
+++ b/src/VBox/Main/src-client/AudioSnifferInterface.cpp
@@ -250,7 +250,7 @@ const PDMDRVREG AudioSniffer::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_AUDIO,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVAUDIOSNIFFER),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-client/ConsoleImpl.cpp b/src/VBox/Main/src-client/ConsoleImpl.cpp
index d6c6e0d4a..c64c68ad0 100644
--- a/src/VBox/Main/src-client/ConsoleImpl.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl.cpp
@@ -2586,7 +2586,7 @@ STDMETHODIMP Console::SaveState(IProgress **aProgress)
dir.stripFilename();
if (!RTDirExists(dir.c_str()))
{
- int vrc = RTDirCreateFullPath(dir.c_str(), 0777);
+ int vrc = RTDirCreateFullPath(dir.c_str(), 0700);
if (RT_FAILURE(vrc))
{
rc = setError(VBOX_E_FILE_ERROR,
@@ -5576,6 +5576,15 @@ HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
/**
+ * Merely passes the call to Guest::enableVMMStatistics().
+ */
+void Console::enableVMMStatistics(BOOL aEnable)
+{
+ if (mGuest)
+ mGuest->enableVMMStatistics(aEnable);
+}
+
+/**
* Gets called by Session::UpdateMachineState()
* (IInternalSessionControl::updateMachineState()).
*
@@ -5978,7 +5987,7 @@ HRESULT Console::consoleInitReleaseLog(const ComPtr<IMachine> aMachine)
/* make sure the Logs folder exists */
Assert(logDir.length());
if (!RTDirExists(logDir.c_str()))
- RTDirCreateFullPath(logDir.c_str(), 0777);
+ RTDirCreateFullPath(logDir.c_str(), 0700);
Utf8Str logFile = Utf8StrFmt("%s%cVBox.log",
logDir.c_str(), RTPATH_DELIMITER);
@@ -6468,7 +6477,7 @@ HRESULT Console::powerUp(IProgress **aProgress, bool aPaused)
/*
* Try create the directory.
*/
- vrc = RTDirCreateFullPath(pszDumpDir, 0777);
+ vrc = RTDirCreateFullPath(pszDumpDir, 0700);
if (RT_FAILURE(vrc))
throw setError(E_FAIL, "Failed to setup CoreDumper. Couldn't create dump directory '%s' (%Rrc)\n", pszDumpDir, vrc);
}
@@ -9742,7 +9751,7 @@ const PDMDRVREG Console::DrvStatusReg =
/* fClass. */
PDM_DRVREG_CLASS_STATUS,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINSTATUS),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-client/ConsoleImpl2.cpp b/src/VBox/Main/src-client/ConsoleImpl2.cpp
index 40610844f..3b4fc4fe0 100644
--- a/src/VBox/Main/src-client/ConsoleImpl2.cpp
+++ b/src/VBox/Main/src-client/ConsoleImpl2.cpp
@@ -1713,9 +1713,9 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
ComPtr<INetworkAdapter> networkAdapter;
hrc = pMachine->GetNetworkAdapter(ulInstance, networkAdapter.asOutParam()); H();
- BOOL fEnabled = FALSE;
- hrc = networkAdapter->COMGETTER(Enabled)(&fEnabled); H();
- if (!fEnabled)
+ BOOL fEnabledNetAdapter = FALSE;
+ hrc = networkAdapter->COMGETTER(Enabled)(&fEnabledNetAdapter); H();
+ if (!fEnabledNetAdapter)
continue;
/*
@@ -1928,10 +1928,10 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
ComPtr<ISerialPort> serialPort;
hrc = pMachine->GetSerialPort(ulInstance, serialPort.asOutParam()); H();
- BOOL fEnabled = FALSE;
+ BOOL fEnabledSerPort = FALSE;
if (serialPort)
- hrc = serialPort->COMGETTER(Enabled)(&fEnabled); H();
- if (!fEnabled)
+ hrc = serialPort->COMGETTER(Enabled)(&fEnabledSerPort); H();
+ if (!fEnabledSerPort)
continue;
InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
@@ -1989,12 +1989,12 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
{
ComPtr<IParallelPort> parallelPort;
hrc = pMachine->GetParallelPort(ulInstance, parallelPort.asOutParam()); H();
- BOOL fEnabled = FALSE;
+ BOOL fEnabledParPort = FALSE;
if (parallelPort)
{
- hrc = parallelPort->COMGETTER(Enabled)(&fEnabled); H();
+ hrc = parallelPort->COMGETTER(Enabled)(&fEnabledParPort); H();
}
- if (!fEnabled)
+ if (!fEnabledParPort)
continue;
InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pInst);
@@ -2457,11 +2457,21 @@ int Console::configConstructorInner(PVM pVM, AutoWriteLock *pAlock)
* crOpenGL
*/
{
- BOOL fEnabled = false;
- hrc = pMachine->COMGETTER(Accelerate3DEnabled)(&fEnabled); H();
+ BOOL fEnabled3D = false;
+ hrc = pMachine->COMGETTER(Accelerate3DEnabled)(&fEnabled3D); H();
- if (fEnabled)
+ if (fEnabled3D)
{
+ BOOL fSupports3D = false;
+ hrc = host->COMGETTER(Acceleration3DAvailable)(&fSupports3D); H();
+ if (!fSupports3D)
+ return VMSetError(pVM, VERR_NOT_AVAILABLE, RT_SRC_POS,
+ N_("This VM was configured to use 3D acceleration. However, the "
+ "3D support of the host is not working properly and the "
+ "VM cannot be started. To fix this problem, either "
+ "fix the host 3D support (update the host graphics driver?) "
+ "or disable 3D acceleration in the VM settings"));
+
/* Load the service */
rc = pVMMDev->hgcmLoadService("VBoxSharedCrOpenGL", "VBoxSharedCrOpenGL");
if (RT_FAILURE(rc))
@@ -4527,15 +4537,15 @@ int Console::configNetwork(const char *pszDevice,
if (SUCCEEDED(hrc))
{
/* there is a DHCP server available for this network */
- BOOL fEnabled;
- hrc = dhcpServer->COMGETTER(Enabled)(&fEnabled);
+ BOOL fEnabledDhcp;
+ hrc = dhcpServer->COMGETTER(Enabled)(&fEnabledDhcp);
if (FAILED(hrc))
{
LogRel(("DHCP svr: COMGETTER(Enabled) failed, hrc (%Rhrc)", hrc));
H();
}
- if (fEnabled)
+ if (fEnabledDhcp)
hrc = dhcpServer->Start(networkName.raw(),
trunkName.raw(),
trunkType.raw());
diff --git a/src/VBox/Main/src-client/DisplayImpl.cpp b/src/VBox/Main/src-client/DisplayImpl.cpp
index 224560efd..e395a705b 100644
--- a/src/VBox/Main/src-client/DisplayImpl.cpp
+++ b/src/VBox/Main/src-client/DisplayImpl.cpp
@@ -4112,7 +4112,7 @@ const PDMDRVREG Display::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_DISPLAY,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINDISPLAY),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-client/GuestCtrlIO.cpp b/src/VBox/Main/src-client/GuestCtrlIO.cpp
index a7aa568cb..2199a32cb 100644
--- a/src/VBox/Main/src-client/GuestCtrlIO.cpp
+++ b/src/VBox/Main/src-client/GuestCtrlIO.cpp
@@ -20,7 +20,10 @@
* Header Files *
******************************************************************************/
#include "GuestCtrlImplPrivate.h"
-
+#ifdef DEBUG
+# include "Logging.h"
+# include <iprt/file.h>
+#endif /* DEBUG */
/******************************************************************************
* Structures and Typedefs *
@@ -64,6 +67,20 @@ void GuestProcessStreamBlock::Clear()
m_mapPairs.clear();
}
+#ifdef DEBUG
+void GuestProcessStreamBlock::Dump()
+{
+ LogFlowFunc(("Dumping contents of stream block=0x%p (%ld items):\n",
+ this, m_mapPairs.size()));
+
+ for (GuestCtrlStreamPairMapIterConst it = m_mapPairs.begin();
+ it != m_mapPairs.end(); it++)
+ {
+ LogFlowFunc(("\t%s=%s\n", it->first.c_str(), it->second.mValue.c_str()));
+ }
+}
+#endif
+
/**
* Returns a 64-bit signed integer of a specified key.
*
@@ -192,7 +209,7 @@ int GuestProcessStreamBlock::SetValue(const char *pszKey, const char *pszValue)
if (pszValue)
{
- VBOXGUESTCTRL_STREAMVALUE val(pszValue);
+ GuestProcessStreamValue val(pszValue);
m_mapPairs[Utf8Key] = val;
}
}
@@ -306,6 +323,22 @@ void GuestProcessStream::Destroy()
m_cbOffset = 0;
}
+#ifdef DEBUG
+void GuestProcessStream::Dump(const char *pszFile)
+{
+ LogFlowFunc(("Dumping contents of stream=0x%p (cbAlloc=%u, cbSize=%u, cbOff=%u) to %s\n",
+ m_pbBuffer, m_cbAllocated, m_cbSize, m_cbOffset, pszFile));
+
+ RTFILE hFile;
+ int rc = RTFileOpen(&hFile, pszFile, RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTFileWrite(hFile, m_pbBuffer, m_cbSize, NULL /* pcbWritten */);
+ RTFileClose(hFile);
+ }
+}
+#endif
+
/**
* Returns the current offset of the parser within
* the internal data buffer.
@@ -317,6 +350,11 @@ uint32_t GuestProcessStream::GetOffset()
return m_cbOffset;
}
+uint32_t GuestProcessStream::GetSize()
+{
+ return m_cbSize;
+}
+
/**
* Tries to parse the next upcoming pair block within the internal
* buffer.
@@ -349,12 +387,14 @@ int GuestProcessStream::ParseBlock(GuestProcessStreamBlock &streamBlock)
int rc = VINF_SUCCESS;
- char *pszOff = (char*)&m_pbBuffer[m_cbOffset];
- char *pszStart = pszOff;
+ char *pszOff = (char*)&m_pbBuffer[m_cbOffset];
+ char *pszStart = pszOff;
+ uint32_t uDistance;
while (*pszStart)
{
size_t pairLen = strlen(pszStart);
- if ((pszStart - pszOff) + pairLen + 1 >= m_cbSize)
+ uDistance = (pszStart - pszOff);
+ if (m_cbOffset + uDistance + pairLen + 1 >= m_cbSize)
{
rc = VERR_MORE_DATA;
break;
@@ -387,7 +427,7 @@ int GuestProcessStream::ParseBlock(GuestProcessStreamBlock &streamBlock)
/* If we did not do any movement but we have stuff left
* in our buffer just skip the current termination so that
* we can try next time. */
- uint32_t uDistance = (pszStart - pszOff);
+ uDistance = (pszStart - pszOff);
if ( !uDistance
&& *pszStart == '\0'
&& m_cbOffset < m_cbSize)
diff --git a/src/VBox/Main/src-client/GuestCtrlImpl.cpp b/src/VBox/Main/src-client/GuestCtrlImpl.cpp
index 10c9ee96d..e2fd672d6 100644
--- a/src/VBox/Main/src-client/GuestCtrlImpl.cpp
+++ b/src/VBox/Main/src-client/GuestCtrlImpl.cpp
@@ -115,7 +115,9 @@ int Guest::callbackAdd(const PVBOXGUESTCTRL_CALLBACK pCallback, uint32_t *puCont
AssertPtrReturn(pCallback, VERR_INVALID_PARAMETER);
/* puContextID is optional. */
- int rc;
+ int rc = VERR_NOT_FOUND;
+
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
/* Create a new context ID and assign it. */
uint32_t uNewContextID = 0;
@@ -138,8 +140,6 @@ int Guest::callbackAdd(const PVBOXGUESTCTRL_CALLBACK pCallback, uint32_t *puCont
if (RT_SUCCESS(rc))
{
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
/* Add callback with new context ID to our callback map. */
mCallbackMap[uNewContextID] = *pCallback;
Assert(mCallbackMap.size());
@@ -153,6 +153,8 @@ int Guest::callbackAdd(const PVBOXGUESTCTRL_CALLBACK pCallback, uint32_t *puCont
}
/**
+ * Destroys the formerly allocated callback data. The callback then
+ * needs to get removed from the callback map via callbackRemove().
* Does not do locking!
*
* @param uContextID
@@ -161,27 +163,33 @@ void Guest::callbackDestroy(uint32_t uContextID)
{
AssertReturnVoid(uContextID);
- LogFlowFunc(("Destroying callback with CID=%u ...\n", uContextID));
-
- /* Notify callback (if necessary). */
- int rc = callbackNotifyEx(uContextID, VERR_CANCELLED,
- Guest::tr("VM is shutting down, canceling uncompleted guest requests ..."));
- AssertRC(rc);
-
CallbackMapIter it = mCallbackMap.find(uContextID);
if (it != mCallbackMap.end())
{
+ LogFlowFunc(("Callback with CID=%u found\n", uContextID));
if (it->second.pvData)
{
+ LogFlowFunc(("Destroying callback with CID=%u ...\n", uContextID));
+
callbackFreeUserData(it->second.pvData);
it->second.cbData = 0;
}
-
- /* Remove callback context (not used anymore). */
- mCallbackMap.erase(it);
}
}
+/**
+ * Removes a callback from the callback map.
+ * Does not do locking!
+ *
+ * @param uContextID
+ */
+void Guest::callbackRemove(uint32_t uContextID)
+{
+ callbackDestroy(uContextID);
+
+ mCallbackMap.erase(uContextID);
+}
+
bool Guest::callbackExists(uint32_t uContextID)
{
AssertReturn(uContextID, false);
@@ -206,29 +214,31 @@ int Guest::callbackGetUserData(uint32_t uContextID, eVBoxGuestCtrlCallbackType *
{
AssertReturn(uContextID, VERR_INVALID_PARAMETER);
/* pEnmType is optional. */
- AssertPtrReturn(ppvData, VERR_INVALID_PARAMETER);
+ /* ppvData is optional. */
/* pcbData is optional. */
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
CallbackMapIterConst it = mCallbackMap.find(uContextID);
- if (it != mCallbackMap.end())
- {
- if (pEnmType)
- *pEnmType = it->second.mType;
+ if (it == mCallbackMap.end())
+ return VERR_NOT_FOUND;
+
+ if (pEnmType)
+ *pEnmType = it->second.mType;
+ if ( ppvData
+ && it->second.cbData)
+ {
void *pvData = RTMemAlloc(it->second.cbData);
AssertPtrReturn(pvData, VERR_NO_MEMORY);
memcpy(pvData, it->second.pvData, it->second.cbData);
*ppvData = pvData;
-
- if (pcbData)
- *pcbData = it->second.cbData;
-
- return VINF_SUCCESS;
}
- return VERR_NOT_FOUND;
+ if (pcbData)
+ *pcbData = it->second.cbData;
+
+ return VINF_SUCCESS;
}
/* Does not do locking! Caller has to take care of it because the caller needs to
@@ -255,7 +265,7 @@ int Guest::callbackInit(PVBOXGUESTCTRL_CALLBACK pCallback, eVBoxGuestCtrlCallbac
AssertPtrReturn(pCallback, VERR_INVALID_POINTER);
/* Everything else is optional. */
- int rc = VINF_SUCCESS;
+ int vrc = VINF_SUCCESS;
switch (enmType)
{
case VBOXGUESTCTRLCALLBACKTYPE_EXEC_START:
@@ -282,32 +292,32 @@ int Guest::callbackInit(PVBOXGUESTCTRL_CALLBACK pCallback, eVBoxGuestCtrlCallbac
{
PCALLBACKDATAEXECINSTATUS pData = (PCALLBACKDATAEXECINSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECINSTATUS));
AssertPtrReturn(pData, VERR_NO_MEMORY);
- RT_BZERO(pData, sizeof(PCALLBACKDATAEXECINSTATUS));
- pCallback->cbData = sizeof(PCALLBACKDATAEXECINSTATUS);
+ RT_BZERO(pData, sizeof(CALLBACKDATAEXECINSTATUS));
+ pCallback->cbData = sizeof(CALLBACKDATAEXECINSTATUS);
pCallback->pvData = pData;
break;
}
default:
- rc = VERR_INVALID_PARAMETER;
+ vrc = VERR_INVALID_PARAMETER;
break;
}
- if (RT_SUCCESS(rc))
+ if (RT_SUCCESS(vrc))
{
/* Init/set common stuff. */
pCallback->mType = enmType;
pCallback->pProgress = pProgress;
}
- return rc;
+ return vrc;
}
bool Guest::callbackIsCanceled(uint32_t uContextID)
{
AssertReturn(uContextID, true);
- Progress *pProgress = NULL;
+ ComPtr<IProgress> pProgress;
{
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -334,7 +344,7 @@ bool Guest::callbackIsComplete(uint32_t uContextID)
{
AssertReturn(uContextID, true);
- Progress *pProgress = NULL;
+ ComPtr<IProgress> pProgress;
{
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -362,7 +372,7 @@ int Guest::callbackMoveForward(uint32_t uContextID, const char *pszMessage)
AssertReturn(uContextID, VERR_INVALID_PARAMETER);
AssertPtrReturn(pszMessage, VERR_INVALID_PARAMETER);
- Progress *pProgress = NULL;
+ ComPtr<IProgress> pProgress;
{
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -384,7 +394,7 @@ int Guest::callbackMoveForward(uint32_t uContextID, const char *pszMessage)
}
/**
- * TODO
+ * Notifies a specified callback about its final status.
*
* @return IPRT status code.
* @param uContextID
@@ -394,11 +404,13 @@ int Guest::callbackMoveForward(uint32_t uContextID, const char *pszMessage)
int Guest::callbackNotifyEx(uint32_t uContextID, int iRC, const char *pszMessage)
{
AssertReturn(uContextID, VERR_INVALID_PARAMETER);
+ if (RT_FAILURE(iRC))
+ AssertReturn(pszMessage, VERR_INVALID_PARAMETER);
- LogFlowFunc(("Notifying callback with CID=%u, iRC=%d, pszMsg=%s ...\n",
+ LogFlowFunc(("Checking whether callback (CID=%u) needs notification iRC=%Rrc, pszMsg=%s\n",
uContextID, iRC, pszMessage ? pszMessage : "<No message given>"));
- Progress *pProgress = NULL;
+ ComObjPtr<Progress> pProgress;
{
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -429,6 +441,9 @@ int Guest::callbackNotifyEx(uint32_t uContextID, int iRC, const char *pszMessage
if ( SUCCEEDED(hRC)
&& !fCompleted)
{
+ LogFlowFunc(("Notifying callback with CID=%u, iRC=%Rrc, pszMsg=%s\n",
+ uContextID, iRC, pszMessage ? pszMessage : "<No message given>"));
+
/*
* To get waitForCompletion completed (unblocked) we have to notify it if necessary (only
* cancel won't work!). This could happen if the client thread (e.g. VBoxService, thread of a spawned process)
@@ -436,21 +451,24 @@ int Guest::callbackNotifyEx(uint32_t uContextID, int iRC, const char *pszMessage
* have to abort here to make sure the host never hangs/gets stuck while waiting for the
* progress object to become signalled.
*/
- if ( RT_SUCCESS(iRC)
- && !pszMessage)
+ if (RT_SUCCESS(iRC))
{
hRC = pProgress->notifyComplete(S_OK);
}
else
{
- AssertPtrReturn(pszMessage, VERR_INVALID_PARAMETER);
+
hRC = pProgress->notifyComplete(VBOX_E_IPRT_ERROR /* Must not be S_OK. */,
COM_IIDOF(IGuest),
Guest::getStaticComponentName(),
pszMessage);
}
+
+ LogFlowFunc(("Notified callback with CID=%u returned %Rhrc (0x%x)\n",
+ uContextID, hRC, hRC));
}
- ComAssertComRC(hRC);
+ else
+ LogFlowFunc(("Callback with CID=%u already notified\n", uContextID));
/*
* Do *not* NULL pProgress here, because waiting function like executeProcess()
@@ -550,7 +568,7 @@ int Guest::callbackWaitForCompletion(uint32_t uContextID, LONG lStage, LONG lTim
*/
int vrc = VINF_SUCCESS;
- Progress *pProgress = NULL;
+ ComPtr<IProgress> pProgress;
{
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -563,6 +581,8 @@ int Guest::callbackWaitForCompletion(uint32_t uContextID, LONG lStage, LONG lTim
if (RT_SUCCESS(vrc))
{
+ LogFlowFunc(("Waiting for callback completion (CID=%u, Stage=%RI32, timeout=%RI32ms) ...\n",
+ uContextID, lStage, lTimeout));
HRESULT rc;
if (lStage < 0)
rc = pProgress->WaitForCompletion(lTimeout);
@@ -578,6 +598,8 @@ int Guest::callbackWaitForCompletion(uint32_t uContextID, LONG lStage, LONG lTim
vrc = VERR_TIMEOUT;
}
+ LogFlowFunc(("Callback (CID=%u) completed with rc=%Rrc\n",
+ uContextID, vrc));
return vrc;
}
@@ -602,7 +624,7 @@ DECLCALLBACK(int) Guest::notifyCtrlDispatcher(void *pvExtension,
* changes to the object state.
*/
#ifdef DEBUG_andy
- LogFlowFunc(("pvExtension = %p, u32Function = %d, pvParms = %p, cbParms = %d\n",
+ LogFlowFunc(("pvExtension=%p, u32Function=%d, pvParms=%p, cbParms=%d\n",
pvExtension, u32Function, pvParms, cbParms));
#endif
ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension);
@@ -685,6 +707,9 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function,
{
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ LogFlowFunc(("Execution status (CID=%u, pData=0x%p)\n",
+ uContextID, pData));
+
PCALLBACKDATAEXECSTATUS pCallbackData =
(PCALLBACKDATAEXECSTATUS)callbackGetUserDataMutableRaw(uContextID, NULL /* cbData */);
if (pCallbackData)
@@ -694,18 +719,46 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function,
pCallbackData->u32Flags = pData->u32Flags;
/** @todo Copy void* buffer contents? */
}
- else
- AssertReleaseMsgFailed(("Process status (PID=%u, CID=%u) does not have allocated callback data!\n",
- pData->u32PID, uContextID));
+ /* If pCallbackData is NULL this might be an old request for which no user data
+ * might exist anymore. */
}
- int vrc = VINF_SUCCESS;
+ int vrc = VINF_SUCCESS; /* Function result. */
+ int rcCallback = VINF_SUCCESS; /* Callback result. */
Utf8Str errMsg;
/* Was progress canceled before? */
- bool fCbCanceled = callbackIsCanceled(uContextID);
- if (!fCbCanceled)
+ bool fCanceled = callbackIsCanceled(uContextID);
+ if (!fCanceled)
{
+ /* Handle process map. This needs to be done first in order to have a valid
+ * map in case some callback gets notified a bit below. */
+
+ /* Note: PIDs never get removed here in case the guest process signalled its
+ * end; instead the next call of GetProcessStatus() will remove the PID
+ * from the process map after we got the process' final (exit) status.
+ * See waitpid() for an example. */
+ if (pData->u32PID) /* Only add/change a process if it has a valid PID (>0). */
+ {
+ switch (pData->u32Status)
+ {
+ /* Just reach through flags. */
+ case PROC_STS_TES:
+ case PROC_STS_TOK:
+ vrc = processSetStatus(pData->u32PID,
+ (ExecuteProcessStatus_T)pData->u32Status,
+ 0 /* Exit code. */, pData->u32Flags);
+ break;
+ /* Interprete u32Flags as the guest process' exit code. */
+ default:
+ vrc = processSetStatus(pData->u32PID,
+ (ExecuteProcessStatus_T)pData->u32Status,
+ pData->u32Flags /* Exit code. */, 0 /* Flags. */);
+
+ break;
+ }
+ }
+
/* Do progress handling. */
switch (pData->u32Status)
{
@@ -724,6 +777,7 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function,
pData->u32PID, pData->u32Flags)); /** @todo Add process name */
errMsg = Utf8StrFmt(Guest::tr("Process terminated abnormally with status '%u'"),
pData->u32Flags);
+ rcCallback = VERR_GENERAL_FAILURE; /** @todo */
break;
case PROC_STS_TES: /* Terminated through signal. */
@@ -731,16 +785,19 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function,
pData->u32PID, pData->u32Flags)); /** @todo Add process name */
errMsg = Utf8StrFmt(Guest::tr("Process terminated via signal with status '%u'"),
pData->u32Flags);
+ rcCallback = VERR_GENERAL_FAILURE; /** @todo */
break;
case PROC_STS_TOK:
LogRel(("Guest process (PID %u) timed out and was killed\n", pData->u32PID)); /** @todo Add process name */
errMsg = Utf8StrFmt(Guest::tr("Process timed out and was killed"));
+ rcCallback = VERR_TIMEOUT;
break;
case PROC_STS_TOA:
LogRel(("Guest process (PID %u) timed out and could not be killed\n", pData->u32PID)); /** @todo Add process name */
errMsg = Utf8StrFmt(Guest::tr("Process timed out and could not be killed"));
+ rcCallback = VERR_TIMEOUT;
break;
case PROC_STS_DWN:
@@ -757,82 +814,80 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function,
vrc = callbackNotifyComplete(uContextID);
}
else
+ {
errMsg = Utf8StrFmt(Guest::tr("Process killed because system is shutting down"));
+ rcCallback = VERR_CANCELLED;
+ }
break;
case PROC_STS_ERROR:
- LogRel(("Guest process (PID %u) could not be started because of rc=%Rrc\n",
- pData->u32PID, pData->u32Flags)); /** @todo Add process name */
+ if (pData->u32PID)
+ {
+ LogRel(("Guest process (PID %u) could not be started because of rc=%Rrc\n",
+ pData->u32PID, pData->u32Flags)); /** @todo Add process name */
+ }
+ else
+ {
+ switch (pData->u32Flags)
+ {
+ case VERR_MAX_PROCS_REACHED:
+ LogRel(("Guest process could not be started because maximum number of parallel guest processes has been reached\n"));
+ break;
+
+ default:
+ LogRel(("Guest process could not be started because of rc=%Rrc\n",
+ pData->u32Flags));
+ }
+
+ }
errMsg = Utf8StrFmt(Guest::tr("Process execution failed with rc=%Rrc"), pData->u32Flags);
+ rcCallback = pData->u32Flags; /* Report back rc. */
break;
default:
vrc = VERR_INVALID_PARAMETER;
break;
}
-
- /* Handle process map. */
- /** @todo What happens on/deal with PID reuse? */
- /** @todo How to deal with multiple updates at once? */
- if (pData->u32PID)
- {
- VBOXGUESTCTRL_PROCESS process;
- vrc = processGetByPID(pData->u32PID, &process);
- if (vrc == VERR_NOT_FOUND)
- {
- /* Not found, add to map. */
- vrc = processAdd(pData->u32PID,
- (ExecuteProcessStatus_T)pData->u32Status,
- pData->u32Flags /* Contains exit code. */,
- 0 /*Flags. */);
- AssertRC(vrc);
- }
- else if (RT_SUCCESS(vrc))
- {
- /* Process found, update process map. */
- vrc = processSetStatus(pData->u32PID,
- (ExecuteProcessStatus_T)pData->u32Status,
- pData->u32Flags /* Contains exit code. */,
- 0 /*Flags. */);
- AssertRC(vrc);
- }
- else
- AssertReleaseMsgFailed(("Process was neither found nor absent!?\n"));
- }
}
else
+ {
errMsg = Utf8StrFmt(Guest::tr("Process execution canceled"));
+ rcCallback = VERR_CANCELLED;
+ }
- if (!callbackIsComplete(uContextID))
+ /* Do we need to handle the callback error? */
+ if (RT_FAILURE(rcCallback))
{
- if ( errMsg.length()
- || fCbCanceled) /* If canceled we have to report E_FAIL! */
- {
- /* Notify all callbacks which are still waiting on something
- * which is related to the current PID. */
- if (pData->u32PID)
- {
- vrc = callbackNotifyAllForPID(pData->u32PID, VERR_GENERAL_FAILURE, errMsg.c_str());
- if (RT_FAILURE(vrc))
- LogFlowFunc(("Failed to notify other callbacks for PID=%u\n",
- pData->u32PID));
- }
+ AssertMsg(!errMsg.isEmpty(), ("Error message must not be empty!\n"));
- /* Let the caller know what went wrong ... */
- int rc2 = callbackNotifyEx(uContextID, VERR_GENERAL_FAILURE, errMsg.c_str());
+ /* Notify all callbacks which are still waiting on something
+ * which is related to the current PID. */
+ if (pData->u32PID)
+ {
+ int rc2 = callbackNotifyAllForPID(pData->u32PID, rcCallback, errMsg.c_str());
if (RT_FAILURE(rc2))
{
- LogFlowFunc(("Failed to notify callback CID=%u for PID=%u\n",
- uContextID, pData->u32PID));
-
+ LogFlowFunc(("Failed to notify other callbacks for PID=%u\n",
+ pData->u32PID));
if (RT_SUCCESS(vrc))
vrc = rc2;
}
- LogFlowFunc(("Process (CID=%u, status=%u) reported error: %s\n",
- uContextID, pData->u32Status, errMsg.c_str()));
}
+
+ /* Let the caller know what went wrong ... */
+ int rc2 = callbackNotifyEx(uContextID, rcCallback, errMsg.c_str());
+ if (RT_FAILURE(rc2))
+ {
+ LogFlowFunc(("Failed to notify callback CID=%u for PID=%u\n",
+ uContextID, pData->u32PID));
+ if (RT_SUCCESS(vrc))
+ vrc = rc2;
+ }
+ LogFlowFunc(("Process (CID=%u, status=%u) reported: %s\n",
+ uContextID, pData->u32Status, errMsg.c_str()));
}
- LogFlowFunc(("Returned with rc=%Rrc\n", vrc));
+ LogFlowFunc(("Returned with rc=%Rrc, rcCallback=%Rrc\n",
+ vrc, rcCallback));
return vrc;
}
@@ -850,6 +905,9 @@ int Guest::notifyCtrlExecOut(uint32_t u32Function,
{
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ LogFlowFunc(("Output status (CID=%u, pData=0x%p)\n",
+ uContextID, pData));
+
PCALLBACKDATAEXECOUT pCallbackData =
(PCALLBACKDATAEXECOUT)callbackGetUserDataMutableRaw(uContextID, NULL /* cbData */);
if (pCallbackData)
@@ -877,9 +935,8 @@ int Guest::notifyCtrlExecOut(uint32_t u32Function,
pCallbackData->cbData = 0;
}
}
- else
- AssertReleaseMsgFailed(("Process output status (PID=%u, CID=%u) does not have allocated callback data!\n",
- pData->u32PID, uContextID));
+ /* If pCallbackData is NULL this might be an old request for which no user data
+ * might exist anymore. */
}
int vrc;
@@ -908,19 +965,21 @@ int Guest::notifyCtrlExecInStatus(uint32_t u32Function,
{
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ LogFlowFunc(("Input status (CID=%u, pData=0x%p)\n",
+ uContextID, pData));
+
PCALLBACKDATAEXECINSTATUS pCallbackData =
(PCALLBACKDATAEXECINSTATUS)callbackGetUserDataMutableRaw(uContextID, NULL /* cbData */);
if (pCallbackData)
{
/* Save bytes processed. */
pCallbackData->cbProcessed = pData->cbProcessed;
- pCallbackData->u32Status = pData->u32Status;
- pCallbackData->u32Flags = pData->u32Flags;
- pCallbackData->u32PID = pData->u32PID;
+ pCallbackData->u32Status = pData->u32Status;
+ pCallbackData->u32Flags = pData->u32Flags;
+ pCallbackData->u32PID = pData->u32PID;
}
- else
- AssertReleaseMsgFailed(("Process input status (PID=%u, CID=%u) does not have allocated callback data!\n",
- pData->u32PID, uContextID));
+ /* If pCallbackData is NULL this might be an old request for which no user data
+ * might exist anymore. */
}
return callbackNotifyComplete(uContextID);
@@ -935,47 +994,47 @@ int Guest::notifyCtrlClientDisconnected(uint32_t u32Funct
uint32_t uContextID = pData->hdr.u32ContextID;
Assert(uContextID);
- return callbackNotifyEx(uContextID, S_OK,
- Guest::tr("Client disconnected"));
-}
-
-int Guest::processAdd(uint32_t u32PID, ExecuteProcessStatus_T enmStatus,
- uint32_t uExitCode, uint32_t uFlags)
-{
- AssertReturn(u32PID, VERR_INVALID_PARAMETER);
-
- AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- GuestProcessMapIterConst it = mGuestProcessMap.find(u32PID);
- if (it == mGuestProcessMap.end())
- {
- VBOXGUESTCTRL_PROCESS process;
-
- process.mStatus = enmStatus;
- process.mExitCode = uExitCode;
- process.mFlags = uFlags;
-
- mGuestProcessMap[u32PID] = process;
-
- return VINF_SUCCESS;
- }
+ LogFlowFunc(("Client disconnected (CID=%u)\n,", uContextID));
- return VERR_ALREADY_EXISTS;
+ return callbackNotifyEx(uContextID, VERR_CANCELLED,
+ Guest::tr("Client disconnected"));
}
-int Guest::processGetByPID(uint32_t u32PID, PVBOXGUESTCTRL_PROCESS pProcess)
+/**
+ * Gets guest process information. Removes the process from the map
+ * after the process was marked as exited/terminated.
+ *
+ * @return IPRT status code.
+ * @param u32PID PID of process to get status for.
+ * @param pProcess Where to store the process information. Optional.
+ * @param fRemove Flag indicating whether to remove the
+ * process from the map when process marked a
+ * exited/terminated.
+ */
+int Guest::processGetStatus(uint32_t u32PID, PVBOXGUESTCTRL_PROCESS pProcess,
+ bool fRemove)
{
AssertReturn(u32PID, VERR_INVALID_PARAMETER);
- AssertPtrReturn(pProcess, VERR_INVALID_PARAMETER);
AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
- GuestProcessMapIterConst it = mGuestProcessMap.find(u32PID);
+ GuestProcessMapIter it = mGuestProcessMap.find(u32PID);
if (it != mGuestProcessMap.end())
{
- pProcess->mStatus = it->second.mStatus;
- pProcess->mExitCode = it->second.mExitCode;
- pProcess->mFlags = it->second.mFlags;
+ if (pProcess)
+ {
+ pProcess->mStatus = it->second.mStatus;
+ pProcess->mExitCode = it->second.mExitCode;
+ pProcess->mFlags = it->second.mFlags;
+ }
+
+ /* If the is marked as stopped/terminated
+ * remove it from the map. */
+ if ( fRemove
+ && it->second.mStatus != ExecuteProcessStatus_Started)
+ {
+ mGuestProcessMap.erase(it);
+ }
return VINF_SUCCESS;
}
@@ -987,7 +1046,7 @@ int Guest::processSetStatus(uint32_t u32PID, ExecuteProcessStatus_T enmStatus, u
{
AssertReturn(u32PID, VERR_INVALID_PARAMETER);
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
GuestProcessMapIter it = mGuestProcessMap.find(u32PID);
if (it != mGuestProcessMap.end())
@@ -995,11 +1054,19 @@ int Guest::processSetStatus(uint32_t u32PID, ExecuteProcessStatus_T enmStatus, u
it->second.mStatus = enmStatus;
it->second.mExitCode = uExitCode;
it->second.mFlags = uFlags;
+ }
+ else
+ {
+ VBOXGUESTCTRL_PROCESS process;
- return VINF_SUCCESS;
+ process.mStatus = enmStatus;
+ process.mExitCode = uExitCode;
+ process.mFlags = uFlags;
+
+ mGuestProcessMap[u32PID] = process;
}
- return VERR_NOT_FOUND;
+ return VINF_SUCCESS;
}
HRESULT Guest::handleErrorCompletion(int rc)
@@ -1079,73 +1146,83 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags,
* @param aFlags Execution flags.
* @param aUsername Username to execute tool under.
* @param aPassword The user's password.
+ * @param uFlagsToAdd ExecuteProcessFlag flags to add to the execution operation.
* @param aProgress Pointer which receives the tool's progress object. Optional.
* @param aPID Pointer which receives the tool's PID. Optional.
*/
HRESULT Guest::executeAndWaitForTool(IN_BSTR aTool, IN_BSTR aDescription,
ComSafeArrayIn(IN_BSTR, aArguments), ComSafeArrayIn(IN_BSTR, aEnvironment),
IN_BSTR aUsername, IN_BSTR aPassword,
+ ULONG uFlagsToAdd,
+ GuestCtrlStreamObjects *pObjStdOut, GuestCtrlStreamObjects *pObjStdErr,
IProgress **aProgress, ULONG *aPID)
{
ComPtr<IProgress> progressTool;
ULONG uPID;
+ ULONG uFlags = ExecuteProcessFlag_Hidden;
+ if (uFlagsToAdd)
+ uFlags |= uFlagsToAdd;
+
+ bool fWaitForOutput = false;
+ if ( ( (uFlags & ExecuteProcessFlag_WaitForStdOut)
+ && pObjStdOut)
+ || ( (uFlags & ExecuteProcessFlag_WaitForStdErr)
+ && pObjStdErr))
+ {
+ fWaitForOutput = true;
+ }
HRESULT rc = ExecuteProcess(aTool,
- ExecuteProcessFlag_Hidden,
+ uFlags,
ComSafeArrayInArg(aArguments),
ComSafeArrayInArg(aEnvironment),
aUsername, aPassword,
- 5 * 1000 /* Wait 5s for getting the process started. */,
+ 0 /* No timeout. */,
&uPID, progressTool.asOutParam());
- if (SUCCEEDED(rc))
+ if ( SUCCEEDED(rc)
+ && fWaitForOutput)
{
- /* Wait for process to exit ... */
- rc = progressTool->WaitForCompletion(-1);
- if (FAILED(rc)) return rc;
+ BOOL fCompleted;
+ while ( SUCCEEDED(progressTool->COMGETTER(Completed)(&fCompleted))
+ && !fCompleted)
+ {
+ BOOL fCanceled;
+ rc = progressTool->COMGETTER(Canceled)(&fCanceled);
+ AssertComRC(rc);
+ if (fCanceled)
+ {
+ rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
+ tr("%s was cancelled"), Utf8Str(aDescription).c_str());
+ break;
+ }
- BOOL fCompleted = FALSE;
- BOOL fCanceled = FALSE;
- progressTool->COMGETTER(Completed)(&fCompleted);
- if (!fCompleted)
- progressTool->COMGETTER(Canceled)(&fCanceled);
+ if ( (uFlags & ExecuteProcessFlag_WaitForStdOut)
+ && pObjStdOut)
+ {
+ rc = executeStreamParse(uPID, ProcessOutputFlag_None /* StdOut */, *pObjStdOut);
+ }
- if (fCompleted)
- {
- ExecuteProcessStatus_T retStatus;
- ULONG uRetExitCode, uRetFlags;
- if (SUCCEEDED(rc))
+ if ( (uFlags & ExecuteProcessFlag_WaitForStdErr)
+ && pObjStdErr)
{
- rc = GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &retStatus);
- if (SUCCEEDED(rc))
- {
- if (uRetExitCode != 0) /* Not equal 0 means some error occured. */
- {
- /** @todo IPRT exit code to string! */
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("%s: Error %u occured"),
- Utf8Str(aDescription).c_str(), uRetExitCode);
- }
- else /* Return code 0, success. */
- {
- if (aProgress)
- {
- /* Return the progress to the caller. */
- progressTool.queryInterfaceTo(aProgress);
- }
- if (aPID)
- *aPID = uPID;
- }
- }
+ rc = executeStreamParse(uPID, ProcessOutputFlag_StdErr, *pObjStdErr);
}
+
+ if (FAILED(rc))
+ break;
}
- else if (fCanceled)
+ }
+
+ if (SUCCEEDED(rc))
+ {
+ if (aProgress)
{
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("%s was aborted"), aDescription);
+ /* Return the progress to the caller. */
+ progressTool.queryInterfaceTo(aProgress);
}
- else
- AssertReleaseMsgFailed(("%s: Operation neither completed nor canceled!?\n",
- Utf8Str(aDescription).c_str()));
+
+ if (aPID)
+ *aPID = uPID;
}
return rc;
@@ -1245,58 +1322,159 @@ HRESULT Guest::executeProcessResult(const char *pszCommand, const char *pszUser,
* @param pObjInfo
* @param enmAddAttribs
*/
-HRESULT Guest::executeStreamQueryFsObjInfo(IN_BSTR aObjName,
- GuestProcessStreamBlock &streamBlock,
- PRTFSOBJINFO pObjInfo,
- RTFSOBJATTRADD enmAddAttribs)
+int Guest::executeStreamQueryFsObjInfo(IN_BSTR aObjName,
+ GuestProcessStreamBlock &streamBlock,
+ PRTFSOBJINFO pObjInfo,
+ RTFSOBJATTRADD enmAddAttribs)
{
- HRESULT rc = S_OK;
Utf8Str Utf8ObjName(aObjName);
-
int64_t iVal;
- int vrc = streamBlock.GetInt64Ex("st_size", &iVal);
- if (RT_SUCCESS(vrc))
+ int rc = streamBlock.GetInt64Ex("st_size", &iVal);
+ if (RT_SUCCESS(rc))
pObjInfo->cbObject = iVal;
- else
- rc = setError(VBOX_E_IPRT_ERROR,
- tr("Unable to retrieve size for \"%s\" (%Rrc)"),
- Utf8ObjName.c_str(), vrc);
/** @todo Add more stuff! */
return rc;
}
/**
- * Tries to drain the guest's output (from stdout) and fill it into
+ * Tries to drain the guest's output and fill it into
* a guest process stream object for later usage.
*
+ * @todo What's about specifying stderr?
* @return IPRT status code.
* @param aPID PID of process to get the output from.
+ * @param aFlags Which stream to drain (stdout or stderr).
* @param stream Reference to guest process stream to fill.
*/
-int Guest::executeStreamDrain(ULONG aPID, GuestProcessStream &stream)
+int Guest::executeStreamDrain(ULONG aPID, ULONG aFlags, GuestProcessStream &stream)
{
AssertReturn(aPID, VERR_INVALID_PARAMETER);
- /** @todo Should we try to drain the stream harder? */
-
int rc = VINF_SUCCESS;
for (;;)
{
- SafeArray<BYTE> aOutputData;
- HRESULT hr = GetProcessOutput(aPID, ProcessOutputFlag_None /* Stdout */,
- 10 * 1000 /* Timeout in ms */,
- _64K, ComSafeArrayAsOutParam(aOutputData));
- if ( SUCCEEDED(hr)
- && aOutputData.size())
+ SafeArray<BYTE> aData;
+ HRESULT hr = getProcessOutputInternal(aPID, aFlags,
+ 0 /* Infinite timeout */,
+ _64K, ComSafeArrayAsOutParam(aData), &rc);
+ if (SUCCEEDED(hr))
{
- rc = stream.AddData(aOutputData.raw(), aOutputData.size());
- if (RT_UNLIKELY(RT_FAILURE(rc)))
- break;
+ if (aData.size())
+ {
+ rc = stream.AddData(aData.raw(), aData.size());
+ if (RT_UNLIKELY(RT_FAILURE(rc)))
+ break;
+ }
+
+ continue; /* Try one more time. */
}
else /* No more output and/or error! */
+ {
+ if ( rc == VERR_NOT_FOUND
+ || rc == VERR_BROKEN_PIPE)
+ {
+ rc = VINF_SUCCESS;
+ }
+
+ /* In any case remove the (terminated/broken) process from
+ * the process table. */
+ int rc2 = processGetStatus(aPID, NULL /* PVBOXGUESTCTRL_PROCESS */,
+ true /* Remove from table */);
+ AssertRC(rc2);
break;
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * Tries to retrieve the next stream block of a given stream and
+ * drains the process output only as much as needed to get this next
+ * stream block.
+ *
+ * @return IPRT status code.
+ * @param ulPID
+ * @param ulFlags
+ * @param stream
+ * @param streamBlock
+ */
+int Guest::executeStreamGetNextBlock(ULONG ulPID,
+ ULONG ulFlags,
+ GuestProcessStream &stream,
+ GuestProcessStreamBlock &streamBlock)
+{
+ AssertReturn(!streamBlock.GetCount(), VERR_INVALID_PARAMETER);
+
+ LogFlowFunc(("Getting next stream block of PID=%u, Flags=%u; cbStrmSize=%u, cbStrmOff=%u\n",
+ ulPID, ulFlags, stream.GetSize(), stream.GetOffset()));
+
+ int rc;
+
+ uint32_t cPairs = 0;
+ bool fDrainStream = true;
+
+ do
+ {
+ rc = stream.ParseBlock(streamBlock);
+ LogFlowFunc(("Parsing block rc=%Rrc, strmBlockCnt=%ld\n",
+ rc, streamBlock.GetCount()));
+
+ if (RT_FAILURE(rc)) /* More data needed or empty buffer? */
+ {
+ if (fDrainStream)
+ {
+ SafeArray<BYTE> aData;
+ HRESULT hr = getProcessOutputInternal(ulPID, ulFlags,
+ 0 /* Infinite timeout */,
+ _64K, ComSafeArrayAsOutParam(aData), &rc);
+ if (SUCCEEDED(hr))
+ {
+ LogFlowFunc(("Got %ld bytes of additional data\n", aData.size()));
+
+ if (aData.size())
+ {
+ rc = stream.AddData(aData.raw(), aData.size());
+ if (RT_UNLIKELY(RT_FAILURE(rc)))
+ break;
+ }
+
+ /* Reset found pairs to not break out too early and let all the new
+ * data to be parsed as well. */
+ cPairs = 0;
+ continue; /* Try one more time. */
+ }
+ else
+ {
+ LogFlowFunc(("Getting output returned hr=%Rhrc\n", hr));
+
+ /* No more output to drain from stream. */
+ if (rc == VERR_NOT_FOUND)
+ {
+ fDrainStream = false;
+ continue;
+ }
+
+ break;
+ }
+ }
+ else
+ {
+ /* We haved drained the stream as much as we can and reached the
+ * end of our stream buffer -- that means that there simply is no
+ * stream block anymore, which is ok. */
+ if (rc == VERR_NO_DATA)
+ rc = VINF_SUCCESS;
+ break;
+ }
+ }
+ else
+ cPairs = streamBlock.GetCount();
}
+ while (!cPairs);
+ LogFlowFunc(("Returned with strmBlockCnt=%ld, cPairs=%ld, rc=%Rrc\n",
+ streamBlock.GetCount(), cPairs, rc));
return rc;
}
@@ -1305,32 +1483,27 @@ int Guest::executeStreamDrain(ULONG aPID, GuestProcessStream &stream)
* by first draining its output and then processing the received guest stream.
*
* @return IPRT status code.
- * @param aPID PID of process to get/parse the output from.
+ * @param ulPID PID of process to get/parse the output from.
+ * @param ulFlags ?
* @param stream Reference to process stream object to use.
* @param streamBlock Reference that receives the next stream block data.
*
*/
-int Guest::executeStreamGetNextBlock(ULONG aPID, GuestProcessStream &stream,
- GuestProcessStreamBlock &streamBlock)
+int Guest::executeStreamParseNextBlock(ULONG ulPID,
+ ULONG ulFlags,
+ GuestProcessStream &stream,
+ GuestProcessStreamBlock &streamBlock)
{
- int rc = executeStreamDrain(aPID, stream);
- if (RT_SUCCESS(rc))
- {
- do
- {
- rc = stream.ParseBlock(streamBlock);
- if (streamBlock.GetCount())
- break; /* We got a block, bail out! */
- } while (RT_SUCCESS(rc));
+ AssertReturn(!streamBlock.GetCount(), VERR_INVALID_PARAMETER);
- /* In case this was the last block, VERR_NO_DATA is returned.
- * Overwrite this to get a proper return value for the last block. */
- if( streamBlock.GetCount()
- && rc == VERR_NO_DATA)
- {
- rc = VINF_SUCCESS;
- }
+ int rc;
+ do
+ {
+ rc = stream.ParseBlock(streamBlock);
+ if (RT_FAILURE(rc))
+ break;
}
+ while (!streamBlock.GetCount());
return rc;
}
@@ -1341,92 +1514,93 @@ int Guest::executeStreamGetNextBlock(ULONG aPID, GuestProcessStream &stream,
* multiple stream blocks (which in turn then can contain key=value pairs).
*
* @return HRESULT
- * @param aPID PID of process to get/parse the output from.
+ * @param ulPID PID of process to get/parse the output from.
+ * @param ulFlags ?
* @param streamObjects Reference to a guest stream object structure for
* storing the parsed data.
*/
-HRESULT Guest::executeStreamParse(ULONG aPID, GuestCtrlStreamObjects &streamObjects)
+HRESULT Guest::executeStreamParse(ULONG ulPID, ULONG ulFlags, GuestCtrlStreamObjects &streamObjects)
{
- GuestProcessStream guestStream;
- HRESULT hr = executeStreamDrain(aPID, guestStream);
- if (SUCCEEDED(hr))
+ GuestProcessStream stream;
+ int rc = executeStreamDrain(ulPID, ulFlags, stream);
+ if (RT_SUCCESS(rc))
{
- for (;;)
+ do
{
/* Try to parse the stream output we gathered until now. If we still need more
* data the parsing routine will tell us and we just do another poll round. */
GuestProcessStreamBlock curBlock;
- int vrc = guestStream.ParseBlock(curBlock);
- if (RT_SUCCESS(vrc))
- {
- if (curBlock.GetCount())
- {
- streamObjects.push_back(curBlock);
- }
- else
- break; /* No more data. */
- }
- else /* Everything else would be an error! */
- hr = setError(VBOX_E_IPRT_ERROR,
- tr("Error while parsing guest output (%Rrc)"), vrc);
- }
- }
+ rc = executeStreamParseNextBlock(ulPID, ulFlags, stream, curBlock);
+ if (RT_SUCCESS(rc))
+ streamObjects.push_back(curBlock);
+ } while (RT_SUCCESS(rc));
- /** @todo Add check if there now are any sream objects at all! */
+ if (rc == VERR_NO_DATA) /* End of data reached. */
+ rc = VINF_SUCCESS;
+ }
- return hr;
+ if (RT_FAILURE(rc))
+ return setError(VBOX_E_IPRT_ERROR,
+ tr("Error while parsing guest output (%Rrc)"), rc);
+ return rc;
}
/**
- * Does busy waiting on a formerly started guest process.
+ * Waits for a fomerly started guest process to exit using its progress
+ * object and returns its final status. Returns E_ABORT if guest process
+ * was canceled.
*
- * @return HRESULT
+ * @return IPRT status code.
* @param uPID PID of guest process to wait for.
- * @param uTimeoutMS Waiting timeout (in ms). Specify 0 for an infinite timeout.
- * @param pRetStatus Pointer which receives current process status after the change.
- * Optional.
- * @param puRetExitCode Pointer which receives the final exit code in case of guest process
- * termination. Optional.
+ * @param pProgress Progress object to wait for.
+ * @param uTimeoutMS Timeout (in ms) for waiting; use 0 for
+ * an indefinite timeout.
+ * @param pRetStatus Pointer where to store the final process
+ * status. Optional.
+ * @param puRetExitCode Pointer where to store the final process
+ * exit code. Optional.
*/
-HRESULT Guest::executeWaitForStatusChange(ULONG uPID, ULONG uTimeoutMS,
- ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode)
+HRESULT Guest::executeWaitForExit(ULONG uPID, ComPtr<IProgress> pProgress, ULONG uTimeoutMS,
+ ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode)
{
- if (uTimeoutMS == 0)
- uTimeoutMS = UINT32_MAX;
+ HRESULT rc = S_OK;
- uint64_t u64StartMS = RTTimeMilliTS();
+ BOOL fCanceled = FALSE;
+ if ( SUCCEEDED(pProgress->COMGETTER(Canceled(&fCanceled)))
+ && fCanceled)
+ {
+ return E_ABORT;
+ }
- HRESULT hRC;
- ULONG uExitCode, uRetFlags;
- ExecuteProcessStatus_T curStatus;
- hRC = GetProcessStatus(uPID, &uExitCode, &uRetFlags, &curStatus);
- if (FAILED(hRC))
- return hRC;
+ BOOL fCompleted = FALSE;
+ if ( SUCCEEDED(pProgress->COMGETTER(Completed(&fCompleted)))
+ && !fCompleted)
+ {
+ rc = pProgress->WaitForCompletion( !uTimeoutMS
+ ? -1 /* No timeout */
+ : uTimeoutMS);
+ if (FAILED(rc))
+ rc = setError(VBOX_E_IPRT_ERROR,
+ tr("Waiting for guest process to end failed (%Rhrc)"),
+ rc);
+ }
- do
+ if (SUCCEEDED(rc))
{
- if ( uTimeoutMS != UINT32_MAX
- && RTTimeMilliTS() - u64StartMS > uTimeoutMS)
- {
- hRC = setError(VBOX_E_IPRT_ERROR,
- tr("The process (PID %u) did not change its status within time (%ums)"),
- uPID, uTimeoutMS);
- break;
- }
- hRC = GetProcessStatus(uPID, &uExitCode, &uRetFlags, &curStatus);
+ ULONG uExitCode, uRetFlags;
+ ExecuteProcessStatus_T enmStatus;
+ HRESULT hRC = GetProcessStatus(uPID, &uExitCode, &uRetFlags, &enmStatus);
if (FAILED(hRC))
- break;
- RTThreadSleep(100);
- } while(*pRetStatus == curStatus);
+ return hRC;
- if (SUCCEEDED(hRC))
- {
if (pRetStatus)
- *pRetStatus = curStatus;
+ *pRetStatus = enmStatus;
if (puRetExitCode)
*puRetExitCode = uExitCode;
+ /** @todo Flags? */
}
- return hRC;
+
+ return rc;
}
/**
@@ -1460,7 +1634,9 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
if ( !(aFlags & ExecuteProcessFlag_IgnoreOrphanedProcesses)
&& !(aFlags & ExecuteProcessFlag_WaitForProcessStartOnly)
&& !(aFlags & ExecuteProcessFlag_Hidden)
- && !(aFlags & ExecuteProcessFlag_NoProfile))
+ && !(aFlags & ExecuteProcessFlag_NoProfile)
+ && !(aFlags & ExecuteProcessFlag_WaitForStdOut)
+ && !(aFlags & ExecuteProcessFlag_WaitForStdErr))
{
if (pRC)
*pRC = VERR_INVALID_PARAMETER;
@@ -1552,16 +1728,6 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
VBOXGUESTCTRL_CALLBACK callback;
vrc = callbackInit(&callback, VBOXGUESTCTRLCALLBACKTYPE_EXEC_START, pProgress);
if (RT_SUCCESS(vrc))
- {
- /* Allocate and assign payload. */
- callback.cbData = sizeof(CALLBACKDATAEXECSTATUS);
- PCALLBACKDATAEXECSTATUS pData = (PCALLBACKDATAEXECSTATUS)RTMemAlloc(callback.cbData);
- AssertReturn(pData, E_OUTOFMEMORY);
- RT_BZERO(pData, callback.cbData);
- callback.pvData = pData;
- }
-
- if (RT_SUCCESS(vrc))
vrc = callbackAdd(&callback, &uContextID);
if (RT_SUCCESS(vrc))
@@ -1618,7 +1784,7 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
if (RT_SUCCESS(vrc))
{
- LogFlowFunc(("Waiting for HGCM callback (timeout=%dms) ...\n", aTimeoutMS));
+ LogFlowFunc(("Waiting for HGCM callback (timeout=%RI32ms) ...\n", aTimeoutMS));
/*
* Wait for the HGCM low level callback until the process
@@ -1628,7 +1794,7 @@ HRESULT Guest::executeProcessInternal(IN_BSTR aCommand, ULONG aFlags,
PCALLBACKDATAEXECSTATUS pExecStatus = NULL;
- /*
+ /*
* Wait for the first stage (=0) to complete (that is starting the process).
*/
vrc = callbackWaitForCompletion(uContextID, 0 /* Stage */, aTimeoutMS);
@@ -1712,7 +1878,7 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
try
{
VBOXGUESTCTRL_PROCESS process;
- int vrc = processGetByPID(aPID, &process);
+ int vrc = processGetStatus(aPID, &process, false /* Don't remove */);
if (RT_SUCCESS(vrc))
{
/* PID exists; check if process is still running. */
@@ -1724,7 +1890,7 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
rc = setError(VBOX_E_IPRT_ERROR,
Guest::tr("Cannot inject input to non-existent process (PID %u)"), aPID);
- if (SUCCEEDED(rc))
+ if (RT_SUCCESS(vrc))
{
uint32_t uContextID = 0;
@@ -1794,6 +1960,8 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
LogFlowFunc(("hgcmHostCall numParms=%d\n", i));
vrc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_SET_INPUT,
i, paParms);
+ if (RT_FAILURE(vrc))
+ rc = handleErrorHGCM(vrc);
}
}
}
@@ -1802,33 +1970,43 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
{
LogFlowFunc(("Waiting for HGCM callback ...\n"));
- /*
- * Wait for the HGCM low level callback until the process
- * has been started (or something went wrong). This is necessary to
- * get the PID.
- */
-
- PCALLBACKDATAEXECINSTATUS pExecStatusIn = NULL;
-
/*
- * Wait for the first stage (=0) to complete (that is starting the process).
+ * Wait for getting back the input response from the guest.
*/
- vrc = callbackWaitForCompletion(uContextID, 0 /* Stage */, aTimeoutMS);
+ vrc = callbackWaitForCompletion(uContextID, -1 /* No staging required */, aTimeoutMS);
if (RT_SUCCESS(vrc))
{
+ PCALLBACKDATAEXECINSTATUS pExecStatusIn;
vrc = callbackGetUserData(uContextID, NULL /* We know the type. */,
(void**)&pExecStatusIn, NULL /* Don't need the size. */);
if (RT_SUCCESS(vrc))
{
+ AssertPtr(pExecStatusIn);
switch (pExecStatusIn->u32Status)
{
case INPUT_STS_WRITTEN:
*aBytesWritten = pExecStatusIn->cbProcessed;
break;
- default:
+ case INPUT_STS_ERROR:
+ rc = setError(VBOX_E_IPRT_ERROR,
+ tr("Client reported error %Rrc while processing input data"),
+ pExecStatusIn->u32Flags);
+ break;
+
+ case INPUT_STS_TERMINATED:
+ rc = setError(VBOX_E_IPRT_ERROR,
+ tr("Client terminated while processing input data"));
+ break;
+
+ case INPUT_STS_OVERFLOW:
rc = setError(VBOX_E_IPRT_ERROR,
- tr("Client error %u while processing input data"), pExecStatusIn->u32Status);
+ tr("Client reported buffer overflow while processing input data"));
+ break;
+
+ default:
+ /*AssertReleaseMsgFailed(("Client reported unknown input error, status=%u, flags=%u\n",
+ pExecStatusIn->u32Status, pExecStatusIn->u32Flags));*/
break;
}
@@ -1843,16 +2021,13 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
else
rc = handleErrorCompletion(vrc);
}
- else
- rc = handleErrorHGCM(vrc);
- if (SUCCEEDED(rc))
{
- /* Nothing to do here yet. */
- }
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* The callback isn't needed anymore -- just was kept locally. */
- callbackDestroy(uContextID);
+ /* The callback isn't needed anymore -- just was kept locally. */
+ callbackRemove(uContextID);
+ }
/* Cleanup. */
if (!pProgress.isNull())
@@ -1870,6 +2045,19 @@ STDMETHODIMP Guest::SetProcessInput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, LONG64 aSize, ComSafeArrayOut(BYTE, aData))
{
+#ifndef VBOX_WITH_GUEST_CONTROL
+ ReturnComNotImplemented();
+#else /* VBOX_WITH_GUEST_CONTROL */
+ using namespace guestControl;
+
+ return getProcessOutputInternal(aPID, aFlags, aTimeoutMS,
+ aSize, ComSafeArrayOutArg(aData), NULL /* rc */);
+#endif
+}
+
+HRESULT Guest::getProcessOutputInternal(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
+ LONG64 aSize, ComSafeArrayOut(BYTE, aData), int *pRC)
+{
/** @todo r=bird: Eventually we should clean up all the timeout parameters
* in the API and have the same way of specifying infinite waits! */
#ifndef VBOX_WITH_GUEST_CONTROL
@@ -1897,13 +2085,23 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
try
{
- VBOXGUESTCTRL_PROCESS process;
- int vrc = processGetByPID(aPID, &process);
+ VBOXGUESTCTRL_PROCESS proc;
+ int vrc = processGetStatus(aPID, &proc, false /* Don't remove */);
if (RT_FAILURE(vrc))
+ {
rc = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Cannot get output from non-existent guest process (PID %u)"), aPID);
+ Guest::tr("Guest process (PID %u) does not exist"), aPID);
+ }
+ else if (proc.mStatus != ExecuteProcessStatus_Started)
+ {
+ /* If the process is still in the process table but does not run anymore
+ * don't remove it but report back an appropriate error. */
+ vrc = VERR_BROKEN_PIPE;
+ rc = setError(VBOX_E_IPRT_ERROR,
+ Guest::tr("Guest process (PID %u) does not run anymore"), aPID);
+ }
- if (SUCCEEDED(rc))
+ if (RT_SUCCESS(vrc))
{
uint32_t uContextID = 0;
@@ -1933,6 +2131,9 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
if (aFlags & ProcessOutputFlag_StdErr)
uHandleID = OUTPUT_HANDLE_ID_STDERR;
+ /** @todo Use a buffer for next iteration if returned data is too big
+ * for current read.
+ * aSize is bogus -- will be ignored atm! */
VBOXGUESTCTRL_CALLBACK callback;
vrc = callbackInit(&callback, VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT, pProgress);
if (RT_SUCCESS(vrc))
@@ -1978,7 +2179,7 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
if (RT_SUCCESS(vrc))
{
- LogFlowFunc(("Waiting for HGCM callback (timeout=%dms) ...\n", aTimeoutMS));
+ LogFlowFunc(("Waiting for HGCM callback (timeout=%RI32ms) ...\n", aTimeoutMS));
/*
* Wait for the HGCM low level callback until the process
@@ -1986,14 +2187,13 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
* get the PID.
*/
- PCALLBACKDATAEXECOUT pExecOut = NULL;
-
/*
* Wait for the first output callback notification to arrive.
*/
- vrc = callbackWaitForCompletion(uContextID, -1 /* No staging */, aTimeoutMS);
+ vrc = callbackWaitForCompletion(uContextID, -1 /* No staging required */, aTimeoutMS);
if (RT_SUCCESS(vrc))
{
+ PCALLBACKDATAEXECOUT pExecOut = NULL;
vrc = callbackGetUserData(uContextID, NULL /* We know the type. */,
(void**)&pExecOut, NULL /* Don't need the size. */);
if (RT_SUCCESS(vrc))
@@ -2002,18 +2202,26 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
if (pExecOut->cbData)
{
+ bool fResize;
+
/* Do we need to resize the array? */
if (pExecOut->cbData > aSize)
- outputData.resize(pExecOut->cbData);
+ {
+ fResize = outputData.resize(pExecOut->cbData);
+ Assert(fResize);
+ }
/* Fill output in supplied out buffer. */
+ Assert(outputData.size() >= pExecOut->cbData);
memcpy(outputData.raw(), pExecOut->pvData, pExecOut->cbData);
- outputData.resize(pExecOut->cbData); /* Shrink to fit actual buffer size. */
+ fResize = outputData.resize(pExecOut->cbData); /* Shrink to fit actual buffer size. */
+ Assert(fResize);
}
else
{
/* No data within specified timeout available. */
- outputData.resize(0);
+ bool fResize = outputData.resize(0);
+ Assert(fResize);
}
/* Detach output buffer to output argument. */
@@ -2024,7 +2232,7 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
else
{
rc = setErrorNoLog(VBOX_E_IPRT_ERROR,
- tr("Unable to retrieve process output data"));
+ tr("Unable to retrieve process output data (%Rrc)"), vrc);
}
}
else
@@ -2033,14 +2241,21 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS,
else
rc = handleErrorHGCM(vrc);
- /* The callback isn't needed anymore -- just was kept locally. */
- callbackDestroy(uContextID);
+ {
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+ /* The callback isn't needed anymore -- just was kept locally. */
+ callbackRemove(uContextID);
+ }
/* Cleanup. */
if (!pProgress.isNull())
pProgress->uninit();
pProgress.setNull();
}
+
+ if (pRC)
+ *pRC = vrc;
}
catch (std::bad_alloc &)
{
@@ -2055,9 +2270,6 @@ STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else /* VBOX_WITH_GUEST_CONTROL */
- CheckComArgNotNull(aExitCode);
- CheckComArgNotNull(aFlags);
- CheckComArgNotNull(aStatus);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -2067,12 +2279,16 @@ STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags
try
{
VBOXGUESTCTRL_PROCESS process;
- int vrc = processGetByPID(aPID, &process);
+ int vrc = processGetStatus(aPID, &process,
+ true /* Remove when terminated */);
if (RT_SUCCESS(vrc))
{
- *aExitCode = process.mExitCode;
- *aFlags = process.mFlags;
- *aStatus = process.mStatus;
+ if (aExitCode)
+ *aExitCode = process.mExitCode;
+ if (aFlags)
+ *aFlags = process.mFlags;
+ if (aStatus)
+ *aStatus = process.mStatus;
}
else
rc = setError(VBOX_E_IPRT_ERROR,
@@ -2095,10 +2311,12 @@ STDMETHODIMP Guest::CopyFromGuest(IN_BSTR aSource, IN_BSTR aDest,
#else /* VBOX_WITH_GUEST_CONTROL */
CheckComArgStrNotEmptyOrNull(aSource);
CheckComArgStrNotEmptyOrNull(aDest);
- CheckComArgStrNotEmptyOrNull(aUsername);
- CheckComArgStrNotEmptyOrNull(aPassword);
CheckComArgOutPointerValid(aProgress);
+ /* Do not allow anonymous executions (with system rights). */
+ if (RT_UNLIKELY((aUsername) == NULL || *(aUsername) == '\0'))
+ return setError(E_INVALIDARG, tr("No user name specified"));
+
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -2170,10 +2388,12 @@ STDMETHODIMP Guest::CopyToGuest(IN_BSTR aSource, IN_BSTR aDest,
#else /* VBOX_WITH_GUEST_CONTROL */
CheckComArgStrNotEmptyOrNull(aSource);
CheckComArgStrNotEmptyOrNull(aDest);
- CheckComArgStrNotEmptyOrNull(aUsername);
- CheckComArgStrNotEmptyOrNull(aPassword);
CheckComArgOutPointerValid(aProgress);
+ /* Do not allow anonymous executions (with system rights). */
+ if (RT_UNLIKELY((aUsername) == NULL || *(aUsername) == '\0'))
+ return setError(E_INVALIDARG, tr("No user name specified"));
+
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
diff --git a/src/VBox/Main/src-client/GuestCtrlImplDir.cpp b/src/VBox/Main/src-client/GuestCtrlImplDir.cpp
index 756da6413..bb54c052e 100644
--- a/src/VBox/Main/src-client/GuestCtrlImplDir.cpp
+++ b/src/VBox/Main/src-client/GuestCtrlImplDir.cpp
@@ -29,6 +29,8 @@
#include <VBox/VMMDev.h>
#ifdef VBOX_WITH_GUEST_CONTROL
+# include <iprt/path.h>
+
# include <VBox/com/array.h>
# include <VBox/com/ErrorInfo.h>
#endif
@@ -123,6 +125,8 @@ HRESULT Guest::directoryCreateInternal(IN_BSTR aDirectory,
ComSafeArrayAsInParam(args),
ComSafeArrayAsInParam(env),
aUsername, aPassword,
+ ExecuteProcessFlag_None,
+ NULL, NULL,
NULL /* Progress */, NULL /* PID */);
}
catch (std::bad_alloc &)
@@ -245,17 +249,13 @@ HRESULT Guest::directoryExistsInternal(IN_BSTR aDirectory, IN_BSTR aUsername, IN
*aExists = TRUE;
break;
- case VERR_FILE_NOT_FOUND:
+ case VERR_PATH_NOT_FOUND:
*aExists = FALSE;
break;
- case VERR_NOT_FOUND:
- rc = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Unable to query directory existence"));
- break;
-
default:
- AssertReleaseMsgFailed(("directoryExistsInternal: Unknown return value (%Rrc)\n", rc));
+ hr = setError(VBOX_E_IPRT_ERROR,
+ Guest::tr("Unable to query directory existence (%Rrc)"), rc);
break;
}
}
@@ -297,7 +297,11 @@ int Guest::directoryGetNextEntry(uint32_t uHandle, GuestProcessStreamBlock &stre
GuestDirectoryMapIter it = mGuestDirectoryMap.find(uHandle);
if (it != mGuestDirectoryMap.end())
{
+#ifdef DEBUG
+ it->second.mStream.Dump("/tmp/stream.txt");
+#endif
return executeStreamGetNextBlock(it->second.mPID,
+ ProcessOutputFlag_None /* StdOut */,
it->second.mStream, streamBlock);
}
@@ -391,37 +395,41 @@ HRESULT Guest::directoryOpenInternal(IN_BSTR aDirectory, IN_BSTR aFilter,
/* Construct and hand in actual directory name + filter we want to open. */
char *pszDirectoryFinal;
- int cbRet;
if (Utf8Filter.isEmpty())
- cbRet = RTStrAPrintf(&pszDirectoryFinal, "%s", Utf8Directory.c_str());
+ pszDirectoryFinal = RTStrDup(Utf8Directory.c_str());
else
- cbRet = RTStrAPrintf(&pszDirectoryFinal, "%s/%s",
- Utf8Directory.c_str(), Utf8Filter.c_str());
- if (!cbRet)
+ pszDirectoryFinal = RTPathJoinA(Utf8Directory.c_str(), Utf8Filter.c_str());
+ if (!pszDirectoryFinal)
return setError(E_OUTOFMEMORY, tr("Out of memory while allocating final directory"));
args.push_back(Bstr(pszDirectoryFinal).raw()); /* The directory we want to open. */
+ RTStrFree(pszDirectoryFinal);
ULONG uPID;
- /** @todo Don't wait for tool to finish! Might take a lot of time! */
+ /* We only start the directory listing and requesting stdout data but don't get its
+ * data here; this is done in sequential IGuest::DirectoryRead calls then. */
hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_LS).raw(), Bstr("Opening directory").raw(),
ComSafeArrayAsInParam(args),
ComSafeArrayAsInParam(env),
aUsername, aPassword,
+ ExecuteProcessFlag_WaitForStdOut,
+ NULL, NULL,
NULL /* Progress */, &uPID);
if (SUCCEEDED(hr))
{
/* Assign new directory handle ID. */
ULONG uHandleNew;
- int vrc = directoryCreateHandle(&uHandleNew, uPID,
- aDirectory, aFilter, aFlags);
- if (RT_SUCCESS(vrc))
+ int rc = directoryCreateHandle(&uHandleNew, uPID,
+ aDirectory, aFilter, aFlags);
+ if (RT_SUCCESS(rc))
{
*aHandle = uHandleNew;
}
else
hr = setError(VBOX_E_IPRT_ERROR,
- tr("Unable to create guest directory handle (%Rrc)"), vrc);
+ tr("Unable to create guest directory handle (%Rrc)"), rc);
+ if (pRC)
+ *pRC = rc;
}
}
catch (std::bad_alloc &)
@@ -473,40 +481,41 @@ HRESULT Guest::directoryQueryInfoInternal(IN_BSTR aDirectory,
* Execute guest process.
*/
ULONG uPID;
+ GuestCtrlStreamObjects stdOut;
hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_STAT).raw(), Bstr("Querying directory information").raw(),
ComSafeArrayAsInParam(args),
ComSafeArrayAsInParam(env),
aUsername, aPassword,
+ ExecuteProcessFlag_WaitForStdOut,
+ &stdOut, NULL /* stdErr */,
NULL /* Progress */, &uPID);
if (SUCCEEDED(hr))
{
- GuestCtrlStreamObjects streamObjs;
- hr = executeStreamParse(uPID, streamObjs);
- if (SUCCEEDED(hr))
+ int rc = VINF_SUCCESS;
+ if (stdOut.size())
{
- int rc = VINF_SUCCESS;
-
- Assert(streamObjs.size());
- const char *pszFsType = streamObjs[0].GetString("ftype");
+ const char *pszFsType = stdOut[0].GetString("ftype");
if (!pszFsType) /* Attribute missing? */
- rc = VERR_NOT_FOUND;
+ rc = VERR_PATH_NOT_FOUND;
if ( RT_SUCCESS(rc)
&& strcmp(pszFsType, "d")) /* Directory? */
{
- rc = VERR_FILE_NOT_FOUND;
+ rc = VERR_PATH_NOT_FOUND;
/* This is not critical for Main, so don't set hr --
* we will take care of rc then. */
}
if ( RT_SUCCESS(rc)
&& aObjInfo) /* Do we want object details? */
{
- hr = executeStreamQueryFsObjInfo(aDirectory, streamObjs[0],
+ rc = executeStreamQueryFsObjInfo(aDirectory, stdOut[0],
aObjInfo, enmAddAttribs);
}
-
- if (pRC)
- *pRC = rc;
}
+ else
+ rc = VERR_NO_DATA;
+
+ if (pRC)
+ *pRC = rc;
}
}
catch (std::bad_alloc &)
@@ -536,24 +545,30 @@ STDMETHODIMP Guest::DirectoryRead(ULONG aHandle, IGuestDirEntry **aDirEntry)
int rc = directoryGetNextEntry(aHandle, streamBlock);
if (RT_SUCCESS(rc))
{
- ComObjPtr <GuestDirEntry> pDirEntry;
- hr = pDirEntry.createObject();
- ComAssertComRC(hr);
-
- Assert(streamBlock.GetCount());
- hr = pDirEntry->init(this, streamBlock);
- if (SUCCEEDED(hr))
+ if (streamBlock.GetCount())
{
- pDirEntry.queryInterfaceTo(aDirEntry);
+ ComObjPtr <GuestDirEntry> pDirEntry;
+ hr = pDirEntry.createObject();
+ ComAssertComRC(hr);
+
+ hr = pDirEntry->init(this, streamBlock);
+ if (SUCCEEDED(hr))
+ {
+ pDirEntry.queryInterfaceTo(aDirEntry);
+ }
+ else
+ {
+#ifdef DEBUG
+ streamBlock.Dump();
+#endif
+ hr = VBOX_E_FILE_ERROR;
+ }
}
else
- hr = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Failed to init guest directory entry"));
- }
- else if (rc == VERR_NO_DATA)
- {
- /* No more directory entries to read. That's fine. */
- hr = E_ABORT; /** @todo Find/define a better rc! */
+ {
+ /* No more directory entries to read. That's fine. */
+ hr = E_ABORT; /** @todo Find/define a better rc! */
+ }
}
else
hr = setError(VBOX_E_IPRT_ERROR,
diff --git a/src/VBox/Main/src-client/GuestCtrlImplFile.cpp b/src/VBox/Main/src-client/GuestCtrlImplFile.cpp
index d04abe217..824e47cda 100644
--- a/src/VBox/Main/src-client/GuestCtrlImplFile.cpp
+++ b/src/VBox/Main/src-client/GuestCtrlImplFile.cpp
@@ -85,13 +85,9 @@ HRESULT Guest::fileExistsInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPas
*aExists = FALSE;
break;
- case VERR_NOT_FOUND:
- hr = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Unable to query file existence"));
- break;
-
default:
- AssertReleaseMsgFailed(("fileExistsInternal: Unknown return value (%Rrc)\n", rc));
+ hr = setError(VBOX_E_IPRT_ERROR,
+ Guest::tr("Unable to query file existence (%Rrc)"), rc);
break;
}
}
@@ -134,38 +130,45 @@ HRESULT Guest::fileQueryInfoInternal(IN_BSTR aFile,
* Execute guest process.
*/
ULONG uPID;
+ GuestCtrlStreamObjects stdOut;
hr = executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_STAT).raw(), Bstr("Querying file information").raw(),
ComSafeArrayAsInParam(args),
ComSafeArrayAsInParam(env),
aUsername, aPassword,
+ ExecuteProcessFlag_WaitForStdOut,
+ &stdOut, NULL,
NULL /* Progress */, &uPID);
if (SUCCEEDED(hr))
{
- GuestCtrlStreamObjects streamObjs;
- hr = executeStreamParse(uPID, streamObjs);
- if (SUCCEEDED(hr))
+ int rc = VINF_SUCCESS;
+ if (stdOut.size())
{
- int rc = VINF_SUCCESS;
- const char *pszFsType = streamObjs[0].GetString("ftype");
- if (!pszFsType) /* Attribute missing? */
- rc = VERR_NOT_FOUND;
+#if 0
+ /* Dump the parsed stream contents to Log(). */
+ stdOut[0].Dump();
+#endif
+ const char *pszFsType = stdOut[0].GetString("ftype");
+ if (!pszFsType) /* Was an object found at all? */
+ rc = VERR_FILE_NOT_FOUND;
if ( RT_SUCCESS(rc)
&& strcmp(pszFsType, "-")) /* Regular file? */
{
- rc = VERR_FILE_NOT_FOUND;
- /* This is not critical for Main, so don't set hr --
- * we will take care of rc then. */
+ rc = VERR_FILE_NOT_FOUND;
+ /* This is not critical for Main, so don't set hr --
+ * we will take care of rc then. */
}
if ( RT_SUCCESS(rc)
&& aObjInfo) /* Do we want object details? */
{
- hr = executeStreamQueryFsObjInfo(aFile, streamObjs[0],
+ rc = executeStreamQueryFsObjInfo(aFile, stdOut[0],
aObjInfo, enmAddAttribs);
}
-
- if (pRC)
- *pRC = rc;
}
+ else
+ rc = VERR_NO_DATA;
+
+ if (pRC)
+ *pRC = rc;
}
}
catch (std::bad_alloc &)
@@ -219,21 +222,18 @@ HRESULT Guest::fileQuerySizeInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR a
break;
case VERR_FILE_NOT_FOUND:
- rc = setError(VBOX_E_IPRT_ERROR,
+ hr = setError(VBOX_E_IPRT_ERROR,
Guest::tr("File not found"));
break;
- case VERR_NOT_FOUND:
- rc = setError(VBOX_E_IPRT_ERROR,
- Guest::tr("Unable to query file size"));
- break;
-
default:
- AssertReleaseMsgFailed(("fileExistsInternal: Unknown return value (%Rrc)\n", rc));
+ hr = setError(VBOX_E_IPRT_ERROR,
+ Guest::tr("Unable to query file size (%Rrc)"), rc);
break;
}
}
- return rc;
+
+ return hr;
}
#endif /* VBOX_WITH_GUEST_CONTROL */
diff --git a/src/VBox/Main/src-client/GuestCtrlImplTasks.cpp b/src/VBox/Main/src-client/GuestCtrlImplTasks.cpp
index b026322b3..c45416f59 100644
--- a/src/VBox/Main/src-client/GuestCtrlImplTasks.cpp
+++ b/src/VBox/Main/src-client/GuestCtrlImplTasks.cpp
@@ -42,7 +42,7 @@
GuestTask::GuestTask(TaskType aTaskType, Guest *aThat, Progress *aProgress)
: taskType(aTaskType),
pGuest(aThat),
- progress(aProgress),
+ pProgress(aProgress),
rc(S_OK)
{
@@ -66,10 +66,9 @@ DECLCALLBACK(int) GuestTask::taskThread(RTTHREAD /* aThread */, void *pvUser)
std::auto_ptr<GuestTask> task(static_cast<GuestTask*>(pvUser));
AssertReturn(task.get(), VERR_GENERAL_FAILURE);
- Guest *pGuest = task->pGuest;
+ ComObjPtr<Guest> pGuest = task->pGuest;
LogFlowFuncEnter();
- LogFlowFunc(("Guest %p\n", pGuest));
HRESULT rc = S_OK;
@@ -109,13 +108,13 @@ int GuestTask::uploadProgress(unsigned uPercent, void *pvUser)
GuestTask *pTask = *(GuestTask**)pvUser;
if ( pTask
- && !pTask->progress.isNull())
+ && !pTask->pProgress.isNull())
{
BOOL fCanceled;
- pTask->progress->COMGETTER(Canceled)(&fCanceled);
+ pTask->pProgress->COMGETTER(Canceled)(&fCanceled);
if (fCanceled)
return -1;
- pTask->progress->SetCurrentOperationProgress(uPercent);
+ pTask->pProgress->SetCurrentOperationProgress(uPercent);
}
return VINF_SUCCESS;
}
@@ -172,13 +171,12 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
try
{
- Guest *pGuest = aTask->pGuest;
- AssertPtr(pGuest);
+ ComObjPtr<Guest> pGuest = aTask->pGuest;
/* Does our source file exist? */
if (!RTFileExists(aTask->strSource.c_str()))
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Source file \"%s\" does not exist, or is not a file"),
aTask->strSource.c_str());
}
@@ -189,7 +187,7 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
if (RT_FAILURE(vrc))
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Could not open source file \"%s\" for reading (%Rrc)"),
aTask->strSource.c_str(), vrc);
}
@@ -199,7 +197,7 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
vrc = RTFileGetSize(fileSource, &cbSize);
if (RT_FAILURE(vrc))
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Could not query file size of \"%s\" (%Rrc)"),
aTask->strSource.c_str(), vrc);
}
@@ -233,7 +231,7 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
}
else
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Error preparing command line"));
}
@@ -247,51 +245,61 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
* Okay, since we gathered all stuff we need until now to start the
* actual copying, start the guest part now.
*/
- rc = pGuest->ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
- ExecuteProcessFlag_Hidden
- | ExecuteProcessFlag_WaitForProcessStartOnly,
- ComSafeArrayAsInParam(args),
- ComSafeArrayAsInParam(env),
- Bstr(aTask->strUserName).raw(),
- Bstr(aTask->strPassword).raw(),
- 5 * 1000 /* Wait 5s for getting the process started. */,
- &uPID, execProgress.asOutParam());
+ rc = pGuest->executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
+ Bstr("Copying file to guest").raw(),
+ ComSafeArrayAsInParam(args),
+ ComSafeArrayAsInParam(env),
+ Bstr(aTask->strUserName).raw(),
+ Bstr(aTask->strPassword).raw(),
+ ExecuteProcessFlag_WaitForProcessStartOnly,
+ NULL, NULL,
+ execProgress.asOutParam(), &uPID);
if (FAILED(rc))
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
}
if (SUCCEEDED(rc))
{
BOOL fCompleted = FALSE;
BOOL fCanceled = FALSE;
+ uint64_t cbTransferedTotal = 0;
- size_t cbToRead = cbSize;
- size_t cbTransfered = 0;
- size_t cbRead;
SafeArray<BYTE> aInputData(_64K);
while ( SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted)))
&& !fCompleted)
{
- if (!cbToRead)
- cbRead = 0;
- else
+ size_t cbToRead = cbSize;
+ size_t cbRead = 0;
+ if (cbSize) /* If we have nothing to read, take a shortcut. */
{
- vrc = RTFileRead(fileSource, (uint8_t*)aInputData.raw(),
- RT_MIN(cbToRead, _64K), &cbRead);
- /*
- * Some other error occured? There might be a chance that RTFileRead
- * could not resolve/map the native error code to an IPRT code, so just
- * print a generic error.
- */
- if (RT_FAILURE(vrc))
+ /** @todo Not very efficient, but works for now. */
+ vrc = RTFileSeek(fileSource, cbTransferedTotal,
+ RTFILE_SEEK_BEGIN, NULL /* poffActual */);
+ if (RT_SUCCESS(vrc))
+ {
+ vrc = RTFileRead(fileSource, (uint8_t*)aInputData.raw(),
+ RT_MIN(cbToRead, _64K), &cbRead);
+ /*
+ * Some other error occured? There might be a chance that RTFileRead
+ * could not resolve/map the native error code to an IPRT code, so just
+ * print a generic error.
+ */
+ if (RT_FAILURE(vrc))
+ {
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
+ Guest::tr("Could not read from file \"%s\" (%Rrc)"),
+ aTask->strSource.c_str(), vrc);
+ break;
+ }
+ }
+ else
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
- Guest::tr("Could not read from file \"%s\" (%Rrc)"),
- aTask->strSource.c_str(), vrc);
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
+ Guest::tr("Seeking file \"%s\" failed; offset = %RU64 (%Rrc)"),
+ aTask->strSource.c_str(), cbTransferedTotal, vrc);
break;
}
}
-
/* Resize buffer to reflect amount we just have read.
* Size 0 is allowed! */
aInputData.resize(cbRead);
@@ -302,21 +310,20 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
/* Did we reach the last block which is exactly _64K? */
|| (cbToRead - cbRead == 0)
/* ... or does the user want to cancel? */
- || ( SUCCEEDED(aTask->progress->COMGETTER(Canceled(&fCanceled)))
+ || ( SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
&& fCanceled)
)
{
uFlags |= ProcessInputFlag_EndOfFile;
}
- /* Transfer the current chunk ... */
- ULONG uBytesWritten;
+ ULONG uBytesWritten = 0;
rc = pGuest->SetProcessInput(uPID, uFlags,
- 10 * 1000 /* Wait 10s for getting the input data transfered. */,
+ 0 /* Infinite timeout */,
ComSafeArrayAsInParam(aInputData), &uBytesWritten);
if (FAILED(rc))
{
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
break;
}
@@ -324,9 +331,9 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
Assert(cbToRead >= cbRead);
cbToRead -= cbRead;
- cbTransfered += uBytesWritten;
- Assert(cbTransfered <= cbSize);
- aTask->progress->SetCurrentOperationProgress(cbTransfered / (cbSize / 100.0));
+ cbTransferedTotal += uBytesWritten;
+ Assert(cbTransferedTotal <= cbSize);
+ aTask->pProgress->SetCurrentOperationProgress(cbTransferedTotal / (cbSize / 100.0));
/* End of file reached? */
if (cbToRead == 0)
@@ -340,7 +347,7 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
if ( SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled)))
&& fCanceled)
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Copy operation of file \"%s\" was canceled on guest side"),
aTask->strSource.c_str());
break;
@@ -355,20 +362,21 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
*/
ExecuteProcessStatus_T retStatus;
ULONG uRetExitCode;
- rc = pGuest->executeWaitForStatusChange(uPID, 10 * 1000 /* 10s timeout. */,
- &retStatus, &uRetExitCode);
+
+ rc = executeWaitForExit(uPID, execProgress, 0 /* No timeout */,
+ &retStatus, &uRetExitCode);
if (FAILED(rc))
{
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
}
else
{
if ( uRetExitCode != 0
|| retStatus != ExecuteProcessStatus_TerminatedNormally)
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
- Guest::tr("Guest reported error %u while copying file \"%s\" to \"%s\""),
- uRetExitCode, aTask->strSource.c_str(), aTask->strDest.c_str());
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
+ Guest::tr("Guest process reported error %u (status: %u) while copying file \"%s\" to \"%s\""),
+ uRetExitCode, retStatus, aTask->strSource.c_str(), aTask->strDest.c_str());
}
}
}
@@ -381,7 +389,7 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
* In order to make the progress object to behave nicely, we also have to
* notify the object with a complete event when it's canceled.
*/
- aTask->progress->notifyComplete(VBOX_E_IPRT_ERROR,
+ aTask->pProgress->notifyComplete(VBOX_E_IPRT_ERROR,
COM_IIDOF(IGuest),
Guest::getStaticComponentName(),
Guest::tr("Copying file \"%s\" canceled"), aTask->strSource.c_str());
@@ -393,23 +401,23 @@ HRESULT Guest::taskCopyFileToGuest(GuestTask *aTask)
* everything.
*/
if ( cbSize > 0
- && cbTransfered == 0)
+ && cbTransferedTotal == 0)
{
/* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write
* to the destination -> access denied. */
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Access denied when copying file \"%s\" to \"%s\""),
aTask->strSource.c_str(), aTask->strDest.c_str());
}
- else if (cbTransfered < cbSize)
+ else if (cbTransferedTotal < cbSize)
{
/* If we did not copy all let the user know. */
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Copying file \"%s\" failed (%u/%u bytes transfered)"),
- aTask->strSource.c_str(), cbTransfered, cbSize);
+ aTask->strSource.c_str(), cbTransferedTotal, cbSize);
}
else /* Yay, all went fine! */
- aTask->progress->notifyComplete(S_OK);
+ aTask->pProgress->notifyComplete(S_OK);
}
}
}
@@ -449,8 +457,7 @@ HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
try
{
- Guest *pGuest = aTask->pGuest;
- AssertPtr(pGuest);
+ ComObjPtr<Guest> pGuest = aTask->pGuest;
/* Does our source file exist? */
BOOL fFileExists;
@@ -460,12 +467,12 @@ HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
if (SUCCEEDED(rc))
{
if (!fFileExists)
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Source file \"%s\" does not exist, or is not a file"),
aTask->strSource.c_str());
}
else
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
/* Query file size to make an estimate for our progress object. */
if (SUCCEEDED(rc))
@@ -475,7 +482,7 @@ HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
Bstr(aTask->strUserName).raw(), Bstr(aTask->strPassword).raw(),
&lFileSize);
if (FAILED(rc))
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
com::SafeArray<IN_BSTR> args;
com::SafeArray<IN_BSTR> env;
@@ -506,7 +513,7 @@ HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
args.push_back(Bstr(szSource).raw()); /* Tell our cat tool which file to output. */
}
else
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Error preparing command line"));
}
@@ -521,16 +528,18 @@ HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
* Okay, since we gathered all stuff we need until now to start the
* actual copying, start the guest part now.
*/
- rc = pGuest->ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
- ExecuteProcessFlag_Hidden,
- ComSafeArrayAsInParam(args),
- ComSafeArrayAsInParam(env),
- Bstr(aTask->strUserName).raw(),
- Bstr(aTask->strPassword).raw(),
- 5 * 1000 /* Wait 5s for getting the process started. */,
- &uPID, execProgress.asOutParam());
+ rc = pGuest->executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
+ Bstr("Copying file to host").raw(),
+ ComSafeArrayAsInParam(args),
+ ComSafeArrayAsInParam(env),
+ Bstr(aTask->strUserName).raw(),
+ Bstr(aTask->strPassword).raw(),
+ ExecuteProcessFlag_WaitForProcessStartOnly
+ | ExecuteProcessFlag_WaitForStdOut,
+ NULL, NULL,
+ execProgress.asOutParam(), &uPID);
if (FAILED(rc))
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
}
if (SUCCEEDED(rc))
@@ -542,63 +551,69 @@ HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask)
int vrc = RTFileOpen(&hFileDest, aTask->strDest.c_str(),
RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE);
if (RT_FAILURE(vrc))
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Unable to create/open destination file \"%s\", rc=%Rrc"),
aTask->strDest.c_str(), vrc);
else
{
size_t cbToRead = lFileSize;
size_t cbTransfered = 0;
- SafeArray<BYTE> aOutputData(_64K);
- while (SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted))))
+ while ( SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted)))
+ && !fCompleted)
{
- rc = this->GetProcessOutput(uPID, ProcessOutputFlag_None,
- 10 * 1000 /* Timeout in ms */,
- _64K, ComSafeArrayAsOutParam(aOutputData));
+ SafeArray<BYTE> aOutputData;
+ rc = pGuest->GetProcessOutput(uPID, ProcessOutputFlag_None /* StdOut */,
+ 0 /* No timeout. */,
+ _64K, ComSafeArrayAsOutParam(aOutputData));
if (SUCCEEDED(rc))
{
- if (!aOutputData.size())
+ if (aOutputData.size())
{
- /*
- * Only bitch about an unexpected end of a file when there already
- * was data read from that file. If this was the very first read we can
- * be (almost) sure that this file is not meant to be read by the specified user.
- */
- if ( cbTransfered
- && cbToRead)
+ vrc = RTFileWrite(hFileDest, aOutputData.raw(), aOutputData.size(), NULL /* No partial writes */);
+ if (RT_FAILURE(vrc))
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
- Guest::tr("Unexpected end of file \"%s\" (%u bytes left, %u bytes written)"),
- aTask->strSource.c_str(), cbToRead, cbTransfered);
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
+ Guest::tr("Error writing to file \"%s\" (%u bytes left), rc=%Rrc"),
+ aTask->strSource.c_str(), cbToRead, vrc);
+ break;
}
- break;
- }
- vrc = RTFileWrite(hFileDest, aOutputData.raw(), aOutputData.size(), NULL /* No partial writes */);
- if (RT_FAILURE(vrc))
- {
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
- Guest::tr("Error writing to file \"%s\" (%u bytes left), rc=%Rrc"),
- aTask->strSource.c_str(), cbToRead, vrc);
- break;
- }
+ Assert(cbToRead >= aOutputData.size());
+ cbToRead -= aOutputData.size();
+ cbTransfered += aOutputData.size();
- cbToRead -= aOutputData.size();
- cbTransfered += aOutputData.size();
+ aTask->pProgress->SetCurrentOperationProgress(cbTransfered / (lFileSize / 100.0));
+ }
- aTask->progress->SetCurrentOperationProgress(cbTransfered / (lFileSize / 100.0));
+ /* Nothing read this time; try next round. */
}
else
{
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
break;
}
}
+ RTFileClose(hFileDest);
+
if (SUCCEEDED(rc))
- aTask->progress->notifyComplete(S_OK);
+ {
+ if ( cbTransfered
+ && (cbTransfered != lFileSize))
+ {
+ /*
+ * Only bitch about an unexpected end of a file when there already
+ * was data read from that file. If this was the very first read we can
+ * be (almost) sure that this file is not meant to be read by the specified user.
+ */
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
+ Guest::tr("Unexpected end of file \"%s\" (%u bytes total, %u bytes transferred)"),
+ aTask->strSource.c_str(), lFileSize, cbTransfered);
+ }
- RTFileClose(hFileDest);
+ if (SUCCEEDED(rc))
+ aTask->pProgress->notifyComplete(S_OK);
+ }
}
}
}
@@ -636,10 +651,9 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
try
{
- Guest *pGuest = aTask->pGuest;
- AssertPtr(pGuest);
+ ComObjPtr<Guest> pGuest = aTask->pGuest;
- aTask->progress->SetCurrentOperationProgress(10);
+ aTask->pProgress->SetCurrentOperationProgress(10);
/*
* Determine guest OS type and the required installer image.
@@ -662,12 +676,12 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
* no further path processing needs to be done (yet). */
}
else /* Everything else is not supported (yet). */
- throw GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->progress,
+ throw GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
Guest::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
osTypeIdUtf8.c_str());
}
else
- throw GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->progress,
+ throw GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
Guest::tr("Could not detected guest OS type/version, please update manually"));
Assert(!installerImage.isEmpty());
@@ -678,7 +692,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
int vrc = RTIsoFsOpen(&iso, aTask->strSource.c_str());
if (RT_FAILURE(vrc))
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_FILE_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_FILE_ERROR, aTask->pProgress,
Guest::tr("Invalid installation medium detected: \"%s\""),
aTask->strSource.c_str());
}
@@ -693,7 +707,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
{
vrc = RTFileSeek(iso.file, cbOffset, RTFILE_SEEK_BEGIN, NULL);
if (RT_FAILURE(vrc))
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Could not seek to setup file on installation medium \"%s\" (%Rrc)"),
aTask->strSource.c_str(), vrc);
}
@@ -702,13 +716,13 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
switch (vrc)
{
case VERR_FILE_NOT_FOUND:
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Setup file was not found on installation medium \"%s\""),
aTask->strSource.c_str());
break;
default:
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("An unknown error (%Rrc) occured while retrieving information of setup file on installation medium \"%s\""),
vrc, aTask->strSource.c_str());
break;
@@ -721,7 +735,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
if (RT_SUCCESS(vrc))
{
/* Okay, we're ready to start our copy routine on the guest! */
- aTask->progress->SetCurrentOperationProgress(15);
+ aTask->pProgress->SetCurrentOperationProgress(15);
/* Prepare command line args. */
com::SafeArray<IN_BSTR> args;
@@ -763,7 +777,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
* support the guest execution feature in this version). */
case VERR_NOT_FOUND:
LogRel(("Guest Additions seem not to be installed yet\n"));
- rc = GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
Guest::tr("Guest Additions seem not to be installed or are not ready to update yet"));
break;
@@ -771,18 +785,18 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
* execution but not the built-in "vbox_cat" tool of VBoxService (< 4.0). */
case VERR_INVALID_PARAMETER:
LogRel(("Guest Additions are installed but don't supported automatic updating\n"));
- rc = GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_NOT_SUPPORTED, aTask->pProgress,
Guest::tr("Installed Guest Additions do not support automatic updating"));
break;
case VERR_TIMEOUT:
LogRel(("Guest was unable to start copying the Guest Additions setup within time\n"));
- rc = GuestTask::setProgressErrorInfo(E_FAIL, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(E_FAIL, aTask->pProgress,
Guest::tr("Guest was unable to start copying the Guest Additions setup within time"));
break;
default:
- rc = GuestTask::setProgressErrorInfo(E_FAIL, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(E_FAIL, aTask->pProgress,
Guest::tr("Error copying Guest Additions setup file to guest path \"%s\" (%Rrc)"),
strInstallerPath.c_str(), vrc);
break;
@@ -793,7 +807,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
LogRel(("Automatic update of Guest Additions started, using \"%s\"\n", aTask->strSource.c_str()));
LogRel(("Copying Guest Additions installer \"%s\" to \"%s\" on guest ...\n",
installerImage.c_str(), strInstallerPath.c_str()));
- aTask->progress->SetCurrentOperationProgress(20);
+ aTask->pProgress->SetCurrentOperationProgress(20);
/* Wait for process to exit ... */
SafeArray<BYTE> aInputData(_64K);
@@ -820,7 +834,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
/* Did we reach the last block which is exactly _64K? */
|| (cbToRead - cbRead == 0)
/* ... or does the user want to cancel? */
- || ( SUCCEEDED(aTask->progress->COMGETTER(Canceled(&fCanceled)))
+ || ( SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
&& fCanceled)
)
{
@@ -837,7 +851,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
ComSafeArrayAsInParam(aInputData), &uBytesWritten);
if (FAILED(rc))
{
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
break;
}
@@ -853,7 +867,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
}
else if (RT_FAILURE(vrc))
{
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Error while reading setup file \"%s\" (To read: %u, Size: %u) from installation medium (%Rrc)"),
installerImage.c_str(), cbToRead, cbLength, vrc);
}
@@ -863,7 +877,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
if ( SUCCEEDED(progressCat->COMGETTER(Canceled(&fCanceled)))
&& fCanceled)
{
- aTask->progress->Cancel();
+ aTask->pProgress->Cancel();
break;
}
}
@@ -873,7 +887,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
RTIsoFsClose(&iso);
if ( SUCCEEDED(rc)
- && ( SUCCEEDED(aTask->progress->COMGETTER(Canceled(&fCanceled)))
+ && ( SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
&& !fCanceled
)
)
@@ -883,7 +897,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
* (with system rights).
*/
LogRel(("Preparing to execute Guest Additions update ...\n"));
- aTask->progress->SetCurrentOperationProgress(66);
+ aTask->pProgress->SetCurrentOperationProgress(66);
/* Prepare command line args for installer. */
com::SafeArray<IN_BSTR> installerArgs;
@@ -926,15 +940,15 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
/* If the caller does not want to wait for out guest update process to end,
* complete the progress object now so that the caller can do other work. */
if (aTask->uFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)
- aTask->progress->notifyComplete(S_OK);
+ aTask->pProgress->notifyComplete(S_OK);
else
- aTask->progress->SetCurrentOperationProgress(70);
+ aTask->pProgress->SetCurrentOperationProgress(70);
/* Wait until the Guest Additions installer finishes ... */
while ( SUCCEEDED(progressInstaller->COMGETTER(Completed(&fCompleted)))
&& !fCompleted)
{
- if ( SUCCEEDED(aTask->progress->COMGETTER(Canceled(&fCanceled)))
+ if ( SUCCEEDED(aTask->pProgress->COMGETTER(Canceled(&fCanceled)))
&& fCanceled)
{
progressInstaller->Cancel();
@@ -959,15 +973,15 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
if (uRetExitCode == 0)
{
LogRel(("Guest Additions update successful!\n"));
- if ( SUCCEEDED(aTask->progress->COMGETTER(Completed(&fCompleted)))
+ if ( SUCCEEDED(aTask->pProgress->COMGETTER(Completed(&fCompleted)))
&& !fCompleted)
- aTask->progress->notifyComplete(S_OK);
+ aTask->pProgress->notifyComplete(S_OK);
}
else
{
LogRel(("Guest Additions update failed (Exit code=%u, Status=%u, Flags=%u)\n",
uRetExitCode, retStatus, uRetFlags));
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Guest Additions update failed with exit code=%u (status=%u, flags=%u)"),
uRetExitCode, retStatus, uRetFlags);
}
@@ -976,7 +990,7 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
&& fCanceled)
{
LogRel(("Guest Additions update was canceled\n"));
- rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
+ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,
Guest::tr("Guest Additions update was canceled by the guest with exit code=%u (status=%u, flags=%u)"),
uRetExitCode, retStatus, uRetFlags);
}
@@ -986,10 +1000,10 @@ HRESULT Guest::taskUpdateGuestAdditions(GuestTask *aTask)
}
}
else
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
}
else
- rc = GuestTask::setProgressErrorInfo(rc, aTask->progress, pGuest);
+ rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest);
}
}
}
diff --git a/src/VBox/Main/src-client/GuestDirEntryImpl.cpp b/src/VBox/Main/src-client/GuestDirEntryImpl.cpp
index 8bf50daad..6f7de2200 100644
--- a/src/VBox/Main/src-client/GuestDirEntryImpl.cpp
+++ b/src/VBox/Main/src-client/GuestDirEntryImpl.cpp
@@ -60,13 +60,17 @@ HRESULT GuestDirEntry::init(Guest *aParent, GuestProcessStreamBlock &streamBlock
mData.mNodeId = streamBlock.GetInt64("node_id");
const char *pszName = streamBlock.GetString("name");
if (pszName)
+ {
mData.mName = BstrFmt("%s", pszName);
- mData.mType = GuestDirEntry::fileTypeToEntryType(streamBlock.GetString("ftype"));
+ mData.mType = GuestDirEntry::fileTypeToEntryType(streamBlock.GetString("ftype"));
- /* Confirm a successful initialization when it's the case. */
- autoInitSpan.setSucceeded();
+ /* Confirm a successful initialization when it's the case. */
+ autoInitSpan.setSucceeded();
- return S_OK;
+ return S_OK;
+ }
+
+ return E_FAIL; /** @todo Find a better rc! */
}
/**
diff --git a/src/VBox/Main/src-client/GuestImpl.cpp b/src/VBox/Main/src-client/GuestImpl.cpp
index 47c4af6ab..51bdc750d 100644
--- a/src/VBox/Main/src-client/GuestImpl.cpp
+++ b/src/VBox/Main/src-client/GuestImpl.cpp
@@ -24,6 +24,7 @@
#include "AutoCaller.h"
#include "Logging.h"
+#include "Performance.h"
#include <VBox/VMMDev.h>
#ifdef VBOX_WITH_GUEST_CONTROL
@@ -31,7 +32,9 @@
# include <VBox/com/ErrorInfo.h>
#endif
#include <iprt/cpp/utils.h>
+#include <iprt/timer.h>
#include <VBox/vmm/pgm.h>
+#include <VBox/version.h>
// defines
/////////////////////////////////////////////////////////////////////////////
@@ -88,10 +91,18 @@ HRESULT Guest::init(Console *aParent)
mfPageFusionEnabled = false; /* Default is no page fusion*/
mStatUpdateInterval = 0; /* Default is not to report guest statistics at all */
+ mCollectVMMStats = false;
/* Clear statistics. */
for (unsigned i = 0 ; i < GUESTSTATTYPE_MAX; i++)
mCurrentGuestStat[i] = 0;
+ mGuestValidStats = pm::GUESTSTATMASK_NONE;
+
+ mMagic = GUEST_MAGIC;
+ int vrc = RTTimerLRCreate (&mStatTimer, 1000 /* ms */,
+ &Guest::staticUpdateStats, this);
+ AssertMsgRC (vrc, ("Failed to create guest statistics "
+ "update timer(%Rra)\n", vrc));
#ifdef VBOX_WITH_GUEST_CONTROL
/* Init the context ID counter at 1000. */
@@ -109,6 +120,11 @@ void Guest::uninit()
{
LogFlowThisFunc(("\n"));
+ /* Enclose the state transition Ready->InUninit->NotReady */
+ AutoUninitSpan autoUninitSpan(this);
+ if (autoUninitSpan.uninitDone())
+ return;
+
#ifdef VBOX_WITH_GUEST_CONTROL
/* Scope write lock as much as possible. */
{
@@ -119,43 +135,149 @@ void Guest::uninit()
*/
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- /* Clean up callback data. */
+ /* Notify left over callbacks that we are about to shutdown ... */
CallbackMapIter it;
for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++)
+ {
+ int rc2 = callbackNotifyEx(it->first, VERR_CANCELLED,
+ Guest::tr("VM is shutting down, canceling uncompleted guest requests ..."));
+ AssertRC(rc2);
+ }
+
+ /* Destroy left over callback data. */
+ for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++)
callbackDestroy(it->first);
- /* Clear process map. */
+ /* Clear process map (remove all callbacks). */
mGuestProcessMap.clear();
}
#endif
- /* Enclose the state transition Ready->InUninit->NotReady */
- AutoUninitSpan autoUninitSpan(this);
- if (autoUninitSpan.uninitDone())
- return;
+ /* Destroy stat update timer */
+ int vrc = RTTimerLRDestroy (mStatTimer);
+ AssertMsgRC (vrc, ("Failed to create guest statistics "
+ "update timer(%Rra)\n", vrc));
+ mStatTimer = NULL;
+ mMagic = 0;
unconst(mParent) = NULL;
}
-// IGuest properties
-/////////////////////////////////////////////////////////////////////////////
+/* static */
+void Guest::staticUpdateStats(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
+{
+ AssertReturnVoid (pvUser != NULL);
+ Guest *guest = static_cast <Guest *> (pvUser);
+ Assert(guest->mMagic == GUEST_MAGIC);
+ if (guest->mMagic == GUEST_MAGIC)
+ guest->updateStats(iTick);
-STDMETHODIMP Guest::COMGETTER(OSTypeId) (BSTR *aOSTypeId)
+ NOREF (hTimerLR);
+}
+
+void Guest::updateStats(uint64_t iTick)
{
- CheckComArgOutPointerValid(aOSTypeId);
+ uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
+ uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem;
- AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
+ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ ULONG aGuestStats[GUESTSTATTYPE_MAX];
+ RT_ZERO(aGuestStats);
+ ULONG validStats = mGuestValidStats;
+ /* Check if we have anything to report */
+ if (validStats)
+ {
+ mGuestValidStats = pm::GUESTSTATMASK_NONE;
+ memcpy(aGuestStats, mCurrentGuestStat, sizeof(aGuestStats));
+ }
+ alock.release();
+ /*
+ * Calling SessionMachine may take time as the object resides in VBoxSVC
+ * process. This is why we took a snapshot of currently collected stats
+ * and released the lock.
+ */
+ uFreeTotal = 0;
+ uAllocTotal = 0;
+ uBalloonedTotal = 0;
+ uSharedTotal = 0;
+ uTotalMem = 0;
+ uPrivateMem = 0;
+ uSharedMem = 0;
+ uZeroMem = 0;
- /* Redirect the call to IMachine if no additions are installed. */
- if (mData.mAdditionsVersion.isEmpty())
- return mParent->machine()->COMGETTER(OSTypeId)(aOSTypeId);
+ Console::SafeVMPtr pVM (mParent);
+ if (pVM.isOk())
+ {
+ int rc;
- mData.mOSTypeId.cloneTo(aOSTypeId);
+ /*
+ * There is no point in collecting VM shared memory if other memory
+ * statistics are not available yet. Or is it?
+ */
+ if (validStats)
+ {
+ /* Query the missing per-VM memory statistics. */
+ rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem);
+ if (rc == VINF_SUCCESS)
+ {
+ validStats |= pm::GUESTSTATMASK_MEMSHARED;
+ }
+ }
- return S_OK;
+ if (mCollectVMMStats)
+ {
+ rc = PGMR3QueryGlobalMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
+ AssertRC(rc);
+ if (rc == VINF_SUCCESS)
+ {
+ validStats |= pm::GUESTSTATMASK_ALLOCVMM|pm::GUESTSTATMASK_FREEVMM|
+ pm::GUESTSTATMASK_BALOONVMM|pm::GUESTSTATMASK_SHAREDVMM;
+ }
+ }
+
+ }
+
+ mParent->reportGuestStatistics(validStats,
+ aGuestStats[GUESTSTATTYPE_CPUUSER],
+ aGuestStats[GUESTSTATTYPE_CPUKERNEL],
+ aGuestStats[GUESTSTATTYPE_CPUIDLE],
+ /* Convert the units for RAM usage stats: page (4K) -> 1KB units */
+ mCurrentGuestStat[GUESTSTATTYPE_MEMTOTAL] * (_4K/_1K),
+ mCurrentGuestStat[GUESTSTATTYPE_MEMFREE] * (_4K/_1K),
+ mCurrentGuestStat[GUESTSTATTYPE_MEMBALLOON] * (_4K/_1K),
+ (ULONG)(uSharedMem / _1K), /* bytes -> KB */
+ mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K),
+ mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K),
+ (ULONG)(uAllocTotal / _1K), /* bytes -> KB */
+ (ULONG)(uFreeTotal / _1K),
+ (ULONG)(uBalloonedTotal / _1K),
+ (ULONG)(uSharedTotal / _1K));
+}
+
+// IGuest properties
+/////////////////////////////////////////////////////////////////////////////
+
+STDMETHODIMP Guest::COMGETTER(OSTypeId)(BSTR *a_pbstrOSTypeId)
+{
+ CheckComArgOutPointerValid(a_pbstrOSTypeId);
+
+ AutoCaller autoCaller(this);
+ HRESULT hrc = autoCaller.rc();
+ if (SUCCEEDED(hrc))
+ {
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+ if (!mData.mInterfaceVersion.isEmpty())
+ mData.mOSTypeId.cloneTo(a_pbstrOSTypeId);
+ else
+ {
+ /* Redirect the call to IMachine if no additions are installed. */
+ ComPtr<IMachine> ptrMachine(mParent->machine());
+ alock.release();
+ hrc = ptrMachine->COMGETTER(OSTypeId)(a_pbstrOSTypeId);
+ }
+ }
+ return hrc;
}
STDMETHODIMP Guest::COMGETTER(AdditionsRunLevel) (AdditionsRunLevelType_T *aRunLevel)
@@ -170,75 +292,69 @@ STDMETHODIMP Guest::COMGETTER(AdditionsRunLevel) (AdditionsRunLevelType_T *aRunL
return S_OK;
}
-STDMETHODIMP Guest::COMGETTER(AdditionsVersion) (BSTR *aAdditionsVersion)
+STDMETHODIMP Guest::COMGETTER(AdditionsVersion)(BSTR *a_pbstrAdditionsVersion)
{
- CheckComArgOutPointerValid(aAdditionsVersion);
+ CheckComArgOutPointerValid(a_pbstrAdditionsVersion);
AutoCaller autoCaller(this);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
- AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
- HRESULT hr = S_OK;
- if ( mData.mAdditionsVersion.isEmpty()
- /* Only try alternative way if GA are active! */
- && mData.mAdditionsRunLevel > AdditionsRunLevelType_None)
+ HRESULT hrc = autoCaller.rc();
+ if (SUCCEEDED(hrc))
{
+ AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
/*
- * If we got back an empty string from GetAdditionsVersion() we either
- * really don't have the Guest Additions version yet or the guest is running
- * older Guest Additions (< 3.2.0) which don't provide VMMDevReq_ReportGuestInfo2,
- * so get the version + revision from the (hopefully) provided guest properties
- * instead.
+ * Return the ReportGuestInfo2 version info if available.
*/
- Bstr addVersion;
- LONG64 u64Timestamp;
- Bstr flags;
- hr = mParent->machine()->GetGuestProperty(Bstr("/VirtualBox/GuestAdd/Version").raw(),
- addVersion.asOutParam(), &u64Timestamp, flags.asOutParam());
- if (hr == S_OK)
+ if (!mData.mAdditionsVersionNew.isEmpty())
{
- Bstr addRevision;
- hr = mParent->machine()->GetGuestProperty(Bstr("/VirtualBox/GuestAdd/Revision").raw(),
- addRevision.asOutParam(), &u64Timestamp, flags.asOutParam());
- if ( hr == S_OK
- && !addVersion.isEmpty()
- && !addRevision.isEmpty())
- {
- /* Some Guest Additions versions had interchanged version + revision values,
- * so check if the version value at least has a dot to identify it and change
- * both values to reflect the right content. */
- if (!Utf8Str(addVersion).contains("."))
- {
- Bstr addTemp = addVersion;
- addVersion = addRevision;
- addRevision = addTemp;
- }
-
- Bstr additionsVersion = BstrFmt("%ls r%ls",
- addVersion.raw(), addRevision.raw());
- additionsVersion.cloneTo(aAdditionsVersion);
- }
- /** @todo r=bird: else: Should not return failure! */
+ /* Since we don't have the API in 4.1 to return a separate revision, we
+ * need to ship the revision as part of the version string, separated with
+ * the "r" prefix. */
+ Bstr strVersion = mData.mAdditionsRevision
+ ? BstrFmt("%lsr%u", mData.mAdditionsVersionNew.raw(), mData.mAdditionsRevision)
+ : BstrFmt("%ls", mData.mAdditionsVersionNew.raw());
+ strVersion.cloneTo(a_pbstrAdditionsVersion);
}
else
{
- /* If getting the version + revision above fails or they simply aren't there
- * because of *really* old Guest Additions we only can report the interface
- * version to at least have something. */
- mData.mInterfaceVersion.cloneTo(aAdditionsVersion);
- /** @todo r=bird: hr is still indicating failure! */
+ /*
+ * If we're running older guest additions (< 3.2.0) try get it from
+ * the guest properties. Detected switched around Version and
+ * Revision in early 3.1.x releases (see r57115).
+ */
+ ComPtr<IMachine> ptrMachine = mParent->machine();
+ alock.release(); /* No need to hold this during the IPC fun. */
+
+ Bstr bstr;
+ hrc = ptrMachine->GetGuestPropertyValue(Bstr("/VirtualBox/GuestAdd/Version").raw(), bstr.asOutParam());
+ if ( SUCCEEDED(hrc)
+ && !bstr.isEmpty())
+ {
+ Utf8Str str(bstr);
+ if (str.count('.') == 0)
+ hrc = ptrMachine->GetGuestPropertyValue(Bstr("/VirtualBox/GuestAdd/Revision").raw(), bstr.asOutParam());
+ str = bstr;
+ if (str.count('.') != 2)
+ hrc = E_FAIL;
+ }
+
+ if (SUCCEEDED(hrc))
+ bstr.detachTo(a_pbstrAdditionsVersion);
+ else
+ {
+ /* Returning 1.4 is better than nothing. */
+ alock.acquire();
+ mData.mInterfaceVersion.cloneTo(a_pbstrAdditionsVersion);
+ hrc = S_OK;
+ }
}
}
- else
- mData.mAdditionsVersion.cloneTo(aAdditionsVersion);
-
- return hr;
+ return hrc;
}
STDMETHODIMP Guest::COMGETTER(Facilities)(ComSafeArrayOut(IAdditionsFacility*, aFacilities))
{
- CheckComArgOutPointerValid(aFacilities);
+ CheckComArgOutSafeArrayPointerValid(aFacilities);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -324,6 +440,17 @@ STDMETHODIMP Guest::COMSETTER(StatisticsUpdateInterval)(ULONG aUpdateInterval)
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+ if (mStatUpdateInterval)
+ if (aUpdateInterval == 0)
+ RTTimerLRStop(mStatTimer);
+ else
+ RTTimerLRChangeInterval(mStatTimer, aUpdateInterval);
+ else
+ if (aUpdateInterval != 0)
+ {
+ RTTimerLRChangeInterval(mStatTimer, aUpdateInterval);
+ RTTimerLRStart(mStatTimer, 0);
+ }
mStatUpdateInterval = aUpdateInterval;
/* forward the information to the VMM device */
VMMDev *pVMMDev = mParent->getVMMDev();
@@ -420,6 +547,18 @@ STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, UL
HRESULT Guest::setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal)
{
+ static ULONG indexToPerfMask[] =
+ {
+ pm::GUESTSTATMASK_CPUUSER,
+ pm::GUESTSTATMASK_CPUKERNEL,
+ pm::GUESTSTATMASK_CPUIDLE,
+ pm::GUESTSTATMASK_MEMTOTAL,
+ pm::GUESTSTATMASK_MEMFREE,
+ pm::GUESTSTATMASK_MEMBALLOON,
+ pm::GUESTSTATMASK_MEMCACHE,
+ pm::GUESTSTATMASK_PAGETOTAL,
+ pm::GUESTSTATMASK_NONE
+ };
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -429,6 +568,7 @@ HRESULT Guest::setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal)
return E_INVALIDARG;
mCurrentGuestStat[enmType] = aVal;
+ mGuestValidStats |= indexToPerfMask[enmType];
return S_OK;
}
@@ -545,11 +685,15 @@ STDMETHODIMP Guest::SetCredentials(IN_BSTR aUserName, IN_BSTR aPassword,
*/
void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
{
+ RTTIMESPEC TimeSpecTS;
+ RTTimeNow(&TimeSpecTS);
+
AutoCaller autoCaller(this);
AssertComRCReturnVoid(autoCaller.rc());
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
/*
* Note: The Guest Additions API (interface) version is deprecated
* and will not be used anymore! We might need it to at least report
@@ -571,7 +715,7 @@ void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
* So only mark the Additions as being active (run level = system) when we
* don't have the Additions version set.
*/
- if (mData.mAdditionsVersion.isEmpty())
+ if (mData.mAdditionsVersionNew.isEmpty())
{
if (aInterfaceVersion.isEmpty())
mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
@@ -584,7 +728,7 @@ void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
* "graphics" (feature) facility to active as soon as we got the Guest Additions
* interface version.
*/
- facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active);
+ facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active, 0 /*fFlags*/, &TimeSpecTS);
}
}
@@ -593,8 +737,21 @@ void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
* so enable it by default. Newer Additions will not enable this here
* and use the setSupportedFeatures function instead.
*/
- facilityUpdate(VBoxGuestFacilityType_Graphics, facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver) ?
- VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
+ /** @todo r=bird: I don't get the above comment nor the code below...
+ * One talks about capability bits, the one always does something to a facility.
+ * Then there is the comment below it all, which is placed like it addresses the
+ * mOSTypeId, but talks about something which doesn't remotely like mOSTypeId...
+ *
+ * Andy, could you please try clarify and make the comments shorter and more
+ * coherent! Also, explain why this is important and what depends on it.
+ *
+ * PS. There is the VMMDEV_GUEST_SUPPORTS_GRAPHICS capability* report... It
+ * should come in pretty quickly after this update, normally.
+ */
+ facilityUpdate(VBoxGuestFacilityType_Graphics,
+ facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver)
+ ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
+ 0 /*fFlags*/, &TimeSpecTS); /** @todo the timestamp isn't gonna be right here on saved state restore. */
/*
* Note! There is a race going on between setting mAdditionsRunLevel and
@@ -606,26 +763,49 @@ void Guest::setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType)
/**
* Sets the Guest Additions version information details.
- * Gets called by vmmdevUpdateGuestInfo2.
*
- * @param aAdditionsVersion
- * @param aVersionName
+ * Gets called by vmmdevUpdateGuestInfo2 and vmmdevUpdateGuestInfo (to clear the
+ * state).
+ *
+ * @param a_uFullVersion VBoxGuestInfo2::additionsMajor,
+ * VBoxGuestInfo2::additionsMinor and
+ * VBoxGuestInfo2::additionsBuild combined into
+ * one value by VBOX_FULL_VERSION_MAKE.
+ *
+ * When this is 0, it's vmmdevUpdateGuestInfo
+ * calling to reset the state.
+ *
+ * @param a_pszName Build type tag and/or publisher tag, empty
+ * string if neiter of those are present.
+ * @param a_uRevision See VBoxGuestInfo2::additionsRevision.
+ * @param a_fFeatures See VBoxGuestInfo2::additionsFeatures.
*/
-void Guest::setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision)
+void Guest::setAdditionsInfo2(uint32_t a_uFullVersion, const char *a_pszName, uint32_t a_uRevision, uint32_t a_fFeatures)
{
AutoCaller autoCaller(this);
AssertComRCReturnVoid(autoCaller.rc());
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- if (!aVersionName.isEmpty())
- /*
- * aVersionName could be "x.y.z_BETA1_FOOBAR", so append revision manually to
- * become "x.y.z_BETA1_FOOBAR r12345".
- */
- mData.mAdditionsVersion = BstrFmt("%ls r%ls", aVersionName.raw(), aRevision.raw());
- else /* aAdditionsVersion is in x.y.zr12345 format. */
- mData.mAdditionsVersion = aAdditionsVersion;
+ if (a_uFullVersion)
+ {
+ mData.mAdditionsVersionNew = BstrFmt(*a_pszName ? "%u.%u.%u_%s" : "%u.%u.%u",
+ VBOX_FULL_VERSION_GET_MAJOR(a_uFullVersion),
+ VBOX_FULL_VERSION_GET_MINOR(a_uFullVersion),
+ VBOX_FULL_VERSION_GET_BUILD(a_uFullVersion),
+ a_pszName);
+ mData.mAdditionsVersionFull = a_uFullVersion;
+ mData.mAdditionsRevision = a_uRevision;
+ mData.mAdditionsFeatures = a_fFeatures;
+ }
+ else
+ {
+ Assert(!a_fFeatures && !a_uRevision && !*a_pszName);
+ mData.mAdditionsVersionNew.setNull();
+ mData.mAdditionsVersionFull = 0;
+ mData.mAdditionsRevision = 0;
+ mData.mAdditionsFeatures = 0;
+ }
}
bool Guest::facilityIsActive(VBoxGuestFacilityType enmFacility)
@@ -640,96 +820,83 @@ bool Guest::facilityIsActive(VBoxGuestFacilityType enmFacility)
return false;
}
-HRESULT Guest::facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus)
+void Guest::facilityUpdate(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
{
- ComAssertRet(enmFacility < INT32_MAX, E_INVALIDARG);
+ AssertReturnVoid( a_enmFacility < VBoxGuestFacilityType_All
+ && a_enmFacility > VBoxGuestFacilityType_Unknown);
- HRESULT rc;
- RTTIMESPEC tsNow;
- RTTimeNow(&tsNow);
-
- FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)enmFacility);
+ FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)a_enmFacility);
if (it != mData.mFacilityMap.end())
{
AdditionsFacility *pFac = it->second;
- rc = pFac->update((AdditionsFacilityStatus_T)enmStatus, tsNow);
+ pFac->update((AdditionsFacilityStatus_T)a_enmStatus, a_fFlags, a_pTimeSpecTS);
}
else
{
- ComObjPtr<AdditionsFacility> pFacility;
- pFacility.createObject();
- ComAssert(!pFacility.isNull());
- rc = pFacility->init(this,
- (AdditionsFacilityType_T)enmFacility,
- (AdditionsFacilityStatus_T)enmStatus);
- if (SUCCEEDED(rc))
- mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)enmFacility, pFacility));
- }
+ if (mData.mFacilityMap.size() > 64)
+ {
+ /* The easy way out for now. We could automatically destroy
+ inactive facilities like VMMDev does if we like... */
+ AssertFailedReturnVoid();
+ }
- LogFlowFunc(("Returned with rc=%Rrc\n"));
- return rc;
+ ComObjPtr<AdditionsFacility> ptrFac;
+ ptrFac.createObject();
+ AssertReturnVoid(!ptrFac.isNull());
+
+ HRESULT hrc = ptrFac->init(this, (AdditionsFacilityType_T)a_enmFacility, (AdditionsFacilityStatus_T)a_enmStatus,
+ a_fFlags, a_pTimeSpecTS);
+ if (SUCCEEDED(hrc))
+ mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)a_enmFacility, ptrFac));
+ }
}
/**
* Sets the status of a certain Guest Additions facility.
- * Gets called by vmmdevUpdateGuestStatus.
*
- * @param enmFacility Facility to set the status for.
- * @param enmStatus Actual status to set.
- * @param aFlags
+ * Gets called by vmmdevUpdateGuestStatus, which just passes the report along.
+ *
+ * @param a_pInterface Pointer to this interface.
+ * @param a_enmFacility The facility.
+ * @param a_enmStatus The status.
+ * @param a_fFlags Flags assoicated with the update. Currently
+ * reserved and should be ignored.
+ * @param a_pTimeSpecTS Pointer to the timestamp of this report.
+ * @sa PDMIVMMDEVCONNECTOR::pfnUpdateGuestStatus, vmmdevUpdateGuestStatus
+ * @thread The emulation thread.
*/
-void Guest::setAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus, ULONG aFlags)
+void Guest::setAdditionsStatus(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus,
+ uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS)
{
+ Assert( a_enmFacility > VBoxGuestFacilityType_Unknown
+ && a_enmFacility <= VBoxGuestFacilityType_All); /* Paranoia, VMMDev checks for this. */
+
AutoCaller autoCaller(this);
AssertComRCReturnVoid(autoCaller.rc());
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
/*
- * Set overall additions run level.
+ * Set a specific facility status.
*/
+ if (a_enmFacility == VBoxGuestFacilityType_All)
+ for (FacilityMapIter it = mData.mFacilityMap.begin(); it != mData.mFacilityMap.end(); ++it)
+ facilityUpdate((VBoxGuestFacilityType)it->first, a_enmStatus, a_fFlags, a_pTimeSpecTS);
+ else /* Update one facility only. */
+ facilityUpdate(a_enmFacility, a_enmStatus, a_fFlags, a_pTimeSpecTS);
- /* First check for disabled status. */
- uint32_t uCurFacility = enmFacility + (enmStatus == VBoxGuestFacilityStatus_Active ? 0 : -1);
- if ( enmFacility < VBoxGuestFacilityType_VBoxGuestDriver
- || ( enmFacility == VBoxGuestFacilityType_All
- && enmStatus == VBoxGuestFacilityStatus_Inactive)
- )
- {
- mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
- }
- else if (uCurFacility >= VBoxGuestFacilityType_VBoxTrayClient)
- {
+ /*
+ * Recalc the runlevel.
+ */
+ if (facilityIsActive(VBoxGuestFacilityType_VBoxTrayClient))
mData.mAdditionsRunLevel = AdditionsRunLevelType_Desktop;
- }
- else if (uCurFacility >= VBoxGuestFacilityType_VBoxService)
- {
+ else if (facilityIsActive(VBoxGuestFacilityType_VBoxService))
mData.mAdditionsRunLevel = AdditionsRunLevelType_Userland;
- }
- else if (uCurFacility >= VBoxGuestFacilityType_VBoxGuestDriver)
- {
+ else if (facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver))
mData.mAdditionsRunLevel = AdditionsRunLevelType_System;
- }
- else /* Should never happen! */
- AssertMsgFailed(("Invalid facility status/run level detected! uCurFacility=%d\n", uCurFacility));
-
- /*
- * Set a specific facility status.
- */
- if (enmFacility > VBoxGuestFacilityType_Unknown)
- {
- if (enmFacility == VBoxGuestFacilityType_All)
- {
- FacilityMapIter it = mData.mFacilityMap.begin();
- while (it != mData.mFacilityMap.end())
- {
- facilityUpdate((VBoxGuestFacilityType)it->first, enmStatus);
- it++;
- }
- }
- else /* Update one facility only. */
- facilityUpdate(enmFacility, enmStatus);
- }
+ else
+ mData.mAdditionsRunLevel = AdditionsRunLevelType_None;
}
/**
@@ -744,10 +911,18 @@ void Guest::setSupportedFeatures(uint32_t aCaps)
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
- facilityUpdate(VBoxGuestFacilityType_Seamless, aCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS ?
- VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive);
+ /** @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);
+
+ facilityUpdate(VBoxGuestFacilityType_Seamless,
+ 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);
+ facilityUpdate(VBoxGuestFacilityType_Graphics,
+ aCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive,
+ 0 /*fFlags*/, &TimeSpecTS);
}
/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/src/VBox/Main/src-client/KeyboardImpl.cpp b/src/VBox/Main/src-client/KeyboardImpl.cpp
index 81b60576d..43c2776cb 100644
--- a/src/VBox/Main/src-client/KeyboardImpl.cpp
+++ b/src/VBox/Main/src-client/KeyboardImpl.cpp
@@ -415,7 +415,7 @@ const PDMDRVREG Keyboard::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_KEYBOARD,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINKEYBOARD),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-client/MouseImpl.cpp b/src/VBox/Main/src-client/MouseImpl.cpp
index 8ce0784c0..eb90e66f2 100644
--- a/src/VBox/Main/src-client/MouseImpl.cpp
+++ b/src/VBox/Main/src-client/MouseImpl.cpp
@@ -830,7 +830,7 @@ const PDMDRVREG Mouse::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_MOUSE,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINMOUSE),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-client/PciRawDevImpl.cpp b/src/VBox/Main/src-client/PciRawDevImpl.cpp
index bca5b047b..a8d723aa5 100644
--- a/src/VBox/Main/src-client/PciRawDevImpl.cpp
+++ b/src/VBox/Main/src-client/PciRawDevImpl.cpp
@@ -197,7 +197,7 @@ const PDMDRVREG PciRawDev::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_PCIRAW,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINPCIRAWDEV),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-client/SessionImpl.cpp b/src/VBox/Main/src-client/SessionImpl.cpp
index 355df5e90..0e67a7359 100644
--- a/src/VBox/Main/src-client/SessionImpl.cpp
+++ b/src/VBox/Main/src-client/SessionImpl.cpp
@@ -835,6 +835,15 @@ STDMETHODIMP Session::OnlineMergeMedium(IMediumAttachment *aMediumAttachment,
aProgress);
}
+STDMETHODIMP Session::EnableVMMStatistics(BOOL aEnable)
+{
+ AutoCaller autoCaller(this);
+ AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
+
+ mConsole->enableVMMStatistics(aEnable);
+
+ return S_OK;
+}
// private methods
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/VBox/Main/src-client/VMMDevInterface.cpp b/src/VBox/Main/src-client/VMMDevInterface.cpp
index 6e7f05c39..813179cb9 100644
--- a/src/VBox/Main/src-client/VMMDevInterface.cpp
+++ b/src/VBox/Main/src-client/VMMDevInterface.cpp
@@ -157,21 +157,12 @@ int VMMDev::SetCredentialsJudgementResult(uint32_t u32Flags)
/**
- * Reports Guest Additions status.
- * Called whenever the Additions issue a guest status report request or the VM is reset.
- *
- * @param pInterface Pointer to this interface.
- * @param guestInfo Pointer to guest information structure
- * @thread The emulation thread.
+ * @interface_method_impl{PDMIVMMDEVCONNECTOR,pfnUpdateGuestStatus}
*/
-DECLCALLBACK(void) vmmdevUpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus)
+DECLCALLBACK(void) vmmdevUpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, uint32_t uFacility, uint16_t uStatus,
+ uint32_t fFlags, PCRTTIMESPEC pTimeSpecTS)
{
PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
-
- Assert(guestStatus);
- if (!guestStatus)
- return;
-
Console *pConsole = pDrv->pVMMDev->getParent();
/* Store that information in IGuest */
@@ -180,14 +171,16 @@ DECLCALLBACK(void) vmmdevUpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, cons
if (!guest)
return;
- guest->setAdditionsStatus(guestStatus->facility, guestStatus->status, guestStatus->flags);
+ guest->setAdditionsStatus((VBoxGuestFacilityType)uFacility, (VBoxGuestFacilityStatus)uStatus, fFlags, pTimeSpecTS);
pConsole->onAdditionsStateChange();
}
/**
* Reports Guest Additions API and OS version.
- * Called whenever the Additions issue a guest version report request or the VM is reset.
+ *
+ * Called whenever the Additions issue a guest version report request or the VM
+ * is reset.
*
* @param pInterface Pointer to this interface.
* @param guestInfo Pointer to guest information structure.
@@ -231,54 +224,40 @@ DECLCALLBACK(void) vmmdevUpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const
* or driver unload.
*/
guest->setAdditionsInfo(Bstr(), guestInfo->osType); /* Clear interface version + OS type. */
- guest->setAdditionsInfo2(Bstr(), Bstr(), Bstr()); /* Clear Guest Additions version. */
- guest->setAdditionsStatus(VBoxGuestFacilityType_All,
- VBoxGuestFacilityStatus_Inactive,
- 0); /* Flags; not used. */
+ /** @todo Would be better if GuestImpl.cpp did all this in the above method call
+ * while holding down the. */
+ guest->setAdditionsInfo2(0, "", 0, 0); /* Clear Guest Additions version. */
+ RTTIMESPEC TimeSpecTS;
+ RTTimeNow(&TimeSpecTS);
+ guest->setAdditionsStatus(VBoxGuestFacilityType_All, VBoxGuestFacilityStatus_Inactive, 0 /*fFlags*/, &TimeSpecTS);
pConsole->onAdditionsStateChange();
}
}
/**
- * Reports the detailed Guest Additions version.
- * Called whenever the Additions issue a guest version report request or the VM is reset.
- *
- * @param pInterface Pointer to this interface.
- * @param guestInfo Pointer to Guest Additions information structure.
- * @thread The emulation thread.
+ * @interface_method_impl{PDMIVMMDEVCONNECTOR,pfnUpdateGuestInfo2}
*/
-DECLCALLBACK(void) vmmdevUpdateGuestInfo2(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo2 *guestInfo)
+DECLCALLBACK(void) vmmdevUpdateGuestInfo2(PPDMIVMMDEVCONNECTOR pInterface, uint32_t uFullVersion,
+ const char *pszName, uint32_t uRevision, uint32_t fFeatures)
{
PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
-
- Assert(guestInfo);
- if (!guestInfo)
- return;
+ AssertPtr(pszName);
+ Assert(uFullVersion);
/* Store that information in IGuest. */
- Guest* guest = pDrv->pVMMDev->getParent()->getGuest();
- Assert(guest);
- if (!guest)
+ Guest *pGuest = pDrv->pVMMDev->getParent()->getGuest();
+ Assert(pGuest);
+ if (!pGuest)
return;
- if ( guestInfo->additionsMajor != 0
- && guestInfo->additionsRevision != 0)
- {
- char version[32];
- RTStrPrintf(version, sizeof(version), "%d.%d.%dr%ld", guestInfo->additionsMajor,
- guestInfo->additionsMinor,
- guestInfo->additionsBuild,
- guestInfo->additionsRevision);
- char revision[16];
- RTStrPrintf(revision, sizeof(revision), "%ld", guestInfo->additionsRevision);
- guest->setAdditionsInfo2(Bstr(version), Bstr(guestInfo->szName), Bstr(revision));
+ /* Just pass it on... */
+ pGuest->setAdditionsInfo2(uFullVersion, pszName, uRevision, fFeatures);
- /*
- * No need to tell the console interface about the update;
- * vmmdevUpdateGuestInfo takes care of that when called as the
- * last event in the chain.
- */
- }
+ /*
+ * No need to tell the console interface about the update;
+ * vmmdevUpdateGuestInfo takes care of that when called as the
+ * last event in the chain.
+ */
}
/**
@@ -930,7 +909,7 @@ const PDMDRVREG VMMDev::DrvReg =
/* fClass. */
PDM_DRVREG_CLASS_VMMDEV,
/* cMaxInstances */
- ~0,
+ ~0U,
/* cbInstance */
sizeof(DRVMAINVMMDEV),
/* pfnConstruct */
diff --git a/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp b/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
index 2e8de5d49..1bc168858 100644
--- a/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
+++ b/src/VBox/Main/src-helper-apps/VBoxExtPackHelperApp.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010-2011 Oracle Corporation
+ * Copyright (C) 2010-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;
@@ -33,6 +33,7 @@
#include <iprt/param.h>
#include <iprt/path.h>
#include <iprt/process.h>
+#include <iprt/sha.h>
#include <iprt/string.h>
#include <iprt/stream.h>
#include <iprt/vfs.h>
@@ -253,7 +254,7 @@ static RTEXITCODE CommonUninstallWorker(const char *pszExtPackDir)
static RTEXITCODE OpenTarFss(RTFILE hTarballFile, PRTVFSFSSTREAM phTarFss)
{
char szError[8192];
- int rc = VBoxExtPackOpenTarFss(hTarballFile, szError, sizeof(szError), phTarFss);
+ int rc = VBoxExtPackOpenTarFss(hTarballFile, szError, sizeof(szError), phTarFss, NULL);
if (RT_FAILURE(rc))
{
Assert(szError[0]);
@@ -596,19 +597,21 @@ static RTEXITCODE UnpackExtPack(RTFILE hTarballFile, const char *pszDirDst, RTMA
* @param pszExtPackName The name of the extension pack name.
* @param pszTarball The name of the tarball in case we have to
* complain about something.
+ * @param pszTarballDigest The SHA-256 digest of the tarball.
* @param phValidManifest Where to return the handle to fully validated
* the manifest for the extension pack. This
* includes all files.
*/
static RTEXITCODE ValidateExtPackTarball(RTFILE hTarballFile, const char *pszExtPackName, const char *pszTarball,
- PRTMANIFEST phValidManifest)
+ const char *pszTarballDigest, PRTMANIFEST phValidManifest)
{
*phValidManifest = NIL_RTMANIFEST;
RTMsgInfo("Validating extension pack '%s' ('%s')...", pszTarball, pszExtPackName);
+ Assert(pszTarballDigest && *pszTarballDigest);
char szError[8192];
- int rc = VBoxExtPackValidateTarball(hTarballFile, pszExtPackName, pszTarball,
- szError, sizeof(szError), phValidManifest, NULL /*phXmlFile*/);
+ int rc = VBoxExtPackValidateTarball(hTarballFile, pszExtPackName, pszTarball, pszTarballDigest,
+ szError, sizeof(szError), phValidManifest, NULL /*phXmlFile*/, NULL /*pStrDigest*/);
if (RT_FAILURE(rc))
{
Assert(szError[0]);
@@ -626,6 +629,8 @@ static RTEXITCODE ValidateExtPackTarball(RTFILE hTarballFile, const char *pszExt
* @param pszBaseDir The base directory.
* @param pszCertDir The certificat directory.
* @param pszTarball The tarball name.
+ * @param pszTarballDigest The SHA-256 digest of the tarball. Empty string
+ * if no digest available.
* @param hTarballFile The handle to open the @a pszTarball file.
* @param hTarballFileOpt The tarball file handle (optional).
* @param pszName The extension pack name.
@@ -633,7 +638,7 @@ static RTEXITCODE ValidateExtPackTarball(RTFILE hTarballFile, const char *pszExt
* @param fReplace Whether to replace any existing ext pack.
*/
static RTEXITCODE DoInstall2(const char *pszBaseDir, const char *pszCertDir, const char *pszTarball,
- RTFILE hTarballFile, RTFILE hTarballFileOpt,
+ const char *pszTarballDigest, RTFILE hTarballFile, RTFILE hTarballFileOpt,
const char *pszName, const char *pszMangledName, bool fReplace)
{
/*
@@ -718,7 +723,7 @@ static RTEXITCODE DoInstall2(const char *pszBaseDir, const char *pszCertDir, con
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create temporary directory: %Rrc ('%s')", rc, szTmpPath);
RTMANIFEST hValidManifest = NIL_RTMANIFEST;
- RTEXITCODE rcExit = ValidateExtPackTarball(hTarballFile, pszName, pszTarball, &hValidManifest);
+ RTEXITCODE rcExit = ValidateExtPackTarball(hTarballFile, pszName, pszTarball, pszTarballDigest, &hValidManifest);
if (rcExit == RTEXITCODE_SUCCESS)
rcExit = UnpackExtPack(hTarballFile, szTmpPath, hValidManifest, pszTarball);
if (rcExit == RTEXITCODE_SUCCESS)
@@ -782,19 +787,21 @@ static RTEXITCODE DoInstall(int argc, char **argv)
{ "--name", 'n', RTGETOPT_REQ_STRING },
{ "--tarball", 't', RTGETOPT_REQ_STRING },
{ "--tarball-fd", 'd', RTGETOPT_REQ_UINT64 },
- { "--replace", 'r', RTGETOPT_REQ_NOTHING }
+ { "--replace", 'r', RTGETOPT_REQ_NOTHING },
+ { "--sha-256", 's', RTGETOPT_REQ_STRING }
};
RTGETOPTSTATE GetState;
int rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0 /*fFlags*/);
if (RT_FAILURE(rc))
return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc);
- const char *pszBaseDir = NULL;
- const char *pszCertDir = NULL;
- const char *pszName = NULL;
- const char *pszTarball = NULL;
- RTFILE hTarballFileOpt = NIL_RTFILE;
- bool fReplace = false;
+ const char *pszBaseDir = NULL;
+ const char *pszCertDir = NULL;
+ const char *pszName = NULL;
+ const char *pszTarball = NULL;
+ const char *pszTarballDigest = NULL;
+ RTFILE hTarballFileOpt = NIL_RTFILE;
+ bool fReplace = false;
RTGETOPTUNION ValueUnion;
int ch;
while ((ch = RTGetOpt(&GetState, &ValueUnion)))
@@ -848,6 +855,19 @@ static RTEXITCODE DoInstall(int argc, char **argv)
fReplace = true;
break;
+ case 's':
+ {
+ if (pszTarballDigest)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --sha-256 options");
+ pszTarballDigest = ValueUnion.psz;
+
+ uint8_t abDigest[RTSHA256_HASH_SIZE];
+ rc = RTSha256FromString(pszTarballDigest, abDigest);
+ if (RT_FAILURE(rc))
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Bad SHA-256 string: %Rrc", rc);
+ break;
+ }
+
case 'h':
case 'V':
return DoStandardOption(ch);
@@ -864,6 +884,8 @@ static RTEXITCODE DoInstall(int argc, char **argv)
return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --cert-dir option");
if (!pszTarball)
return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --tarball option");
+ if (!pszTarballDigest)
+ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --sha-256 option");
/*
* Ok, down to business.
@@ -877,7 +899,7 @@ static RTEXITCODE DoInstall(int argc, char **argv)
rc = RTFileOpen(&hTarballFile, pszTarball, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
if (RT_SUCCESS(rc))
{
- rcExit = DoInstall2(pszBaseDir, pszCertDir, pszTarball, hTarballFile, hTarballFileOpt,
+ rcExit = DoInstall2(pszBaseDir, pszCertDir, pszTarball, pszTarballDigest, hTarballFile, hTarballFileOpt,
pszName, pstrMangledName->c_str(), fReplace);
RTFileClose(hTarballFile);
}
diff --git a/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp b/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
index a5ae09485..8b35e27f9 100644
--- a/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
+++ b/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
@@ -220,12 +220,6 @@ STDMETHODIMP HostNetworkInterface::COMGETTER(IPAddress) (BSTR *aIPAddress)
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- if (m.IPAddress == 0)
- {
- getDefaultIPv4Address(mInterfaceName).detachTo(aIPAddress);
- return S_OK;
- }
-
in_addr tmp;
#if defined(RT_OS_WINDOWS)
tmp.S_un.S_addr = m.IPAddress;
@@ -255,12 +249,6 @@ STDMETHODIMP HostNetworkInterface::COMGETTER(NetworkMask) (BSTR *aNetworkMask)
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
- if (m.networkMask == 0)
- {
- Bstr(VBOXNET_IPV4MASK_DEFAULT).detachTo(aNetworkMask);
- return S_OK;
- }
-
in_addr tmp;
#if defined(RT_OS_WINDOWS)
tmp.S_un.S_addr = m.networkMask;
diff --git a/src/VBox/Main/src-server/MachineImpl.cpp b/src/VBox/Main/src-server/MachineImpl.cpp
index d6189fda6..add33a4ee 100644
--- a/src/VBox/Main/src-server/MachineImpl.cpp
+++ b/src/VBox/Main/src-server/MachineImpl.cpp
@@ -5262,7 +5262,9 @@ HRESULT Machine::setGuestPropertyToService(IN_BSTR aName, IN_BSTR aValue,
{
/** @todo r=bird: Why aren't we leaving the lock here? The
* same code in PushGuestProperty does... */
- mParent->onGuestPropertyChange(mData->mUuid, aName, aValue, aFlags);
+ mParent->onGuestPropertyChange(mData->mUuid, aName,
+ aValue ? aValue : Bstr("").raw(),
+ aFlags ? aFlags : Bstr("").raw());
}
}
catch (std::bad_alloc &)
@@ -8555,7 +8557,7 @@ HRESULT Machine::prepareSaveSettings(bool *pfNeedsGlobalSaveSettings)
path.stripFilename();
if (!RTDirExists(path.c_str()))
{
- vrc = RTDirCreateFullPath(path.c_str(), 0777);
+ vrc = RTDirCreateFullPath(path.c_str(), 0700);
if (RT_FAILURE(vrc))
{
return setError(E_FAIL,
@@ -11174,6 +11176,26 @@ RWLockHandle *SessionMachine::lockHandle() const
////////////////////////////////////////////////////////////////////////////////
/**
+ * Passes collected guest statistics to performance collector object
+ */
+STDMETHODIMP SessionMachine::ReportGuestStatistics(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM)
+{
+ if (mCollectorGuest)
+ mCollectorGuest->updateStats(aValidStats, aCpuUser, aCpuKernel, aCpuIdle,
+ aMemTotal, aMemFree, aMemBalloon, aMemShared,
+ aMemCache, aPageTotal, aAllocVMM, aFreeVMM,
+ aBalloonedVMM, aSharedVMM);
+
+ return S_OK;
+}
+
+/**
* @note Locks this object for writing.
*/
STDMETHODIMP SessionMachine::SetRemoveSavedStateFile(BOOL aRemove)
@@ -11770,8 +11792,8 @@ STDMETHODIMP SessionMachine::PushGuestProperty(IN_BSTR aName,
using namespace guestProp;
CheckComArgStrNotEmptyOrNull(aName);
- CheckComArgMaybeNull(aValue);
- CheckComArgMaybeNull(aFlags);
+ CheckComArgNotNull(aValue);
+ CheckComArgNotNull(aFlags);
try
{
diff --git a/src/VBox/Main/src-server/MachineImplCloneVM.cpp b/src/VBox/Main/src-server/MachineImplCloneVM.cpp
index 370b24fa4..6734c7079 100644
--- a/src/VBox/Main/src-server/MachineImplCloneVM.cpp
+++ b/src/VBox/Main/src-server/MachineImplCloneVM.cpp
@@ -1282,7 +1282,7 @@ HRESULT MachineCloneVM::run()
if ( !d->llSaveStateFiles.isEmpty()
&& !RTDirExists(strTrgSnapshotFolder.c_str()))
{
- int vrc = RTDirCreateFullPath(strTrgSnapshotFolder.c_str(), 0777);
+ int vrc = RTDirCreateFullPath(strTrgSnapshotFolder.c_str(), 0700);
if (RT_FAILURE(vrc))
throw p->setError(VBOX_E_IPRT_ERROR,
p->tr("Could not create snapshots folder '%s' (%Rrc)"), strTrgSnapshotFolder.c_str(), vrc);
diff --git a/src/VBox/Main/src-server/MediumImpl.cpp b/src/VBox/Main/src-server/MediumImpl.cpp
index 5d46be866..f979e428b 100644
--- a/src/VBox/Main/src-server/MediumImpl.cpp
+++ b/src/VBox/Main/src-server/MediumImpl.cpp
@@ -96,6 +96,7 @@ struct Medium::Data
autoReset(false),
hostDrive(false),
implicit(false),
+ uOpenFlagsDef(VD_OPEN_FLAGS_IGNORE_FLUSH),
numCreateDiffTasks(0),
vdDiskIfaces(NULL),
vdImageIfaces(NULL)
@@ -148,6 +149,9 @@ struct Medium::Data
bool implicit : 1;
+ /** Default flags passed to VDOpen(). */
+ unsigned uOpenFlagsDef;
+
uint32_t numCreateDiffTasks;
Utf8Str vdError; /*< Error remembered by the VD error callback. */
@@ -4906,7 +4910,7 @@ HRESULT Medium::fixParentUuidOfChildren(const MediaList &childrenToReparent)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_READONLY,
+ VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw vrc;
@@ -4920,7 +4924,7 @@ HRESULT Medium::fixParentUuidOfChildren(const MediaList &childrenToReparent)
vrc = VDOpen(hdd,
(*it)->m->strFormat.c_str(),
(*it)->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_INFO,
+ VD_OPEN_FLAGS_INFO | m->uOpenFlagsDef,
(*it)->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw vrc;
@@ -5371,7 +5375,7 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
vrc = VDOpen(hdd,
format.c_str(),
location.c_str(),
- uOpenFlags,
+ uOpenFlags | m->uOpenFlagsDef,
m->vdImageIfaces);
if (RT_FAILURE(vrc))
{
@@ -5622,7 +5626,7 @@ HRESULT Medium::queryInfo(bool fSetImageId, bool fSetParentId)
vrc = VDOpen(hdd,
format.c_str(),
location.c_str(),
- uOpenFlags & ~VD_OPEN_FLAGS_READONLY,
+ (uOpenFlags & ~VD_OPEN_FLAGS_READONLY) | m->uOpenFlagsDef,
m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw S_OK;
@@ -6435,7 +6439,7 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task)
&geo,
&geo,
id.raw(),
- VD_OPEN_FLAGS_NORMAL,
+ VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef,
m->vdImageIfaces,
task.mVDOperationIfaces);
if (RT_FAILURE(vrc))
@@ -6574,7 +6578,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_READONLY,
+ VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -6598,7 +6602,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task)
NULL,
targetId.raw(),
id.raw(),
- VD_OPEN_FLAGS_NORMAL,
+ VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef,
pTarget->m->vdImageIfaces,
task.mVDOperationIfaces);
if (RT_FAILURE(vrc))
@@ -6778,7 +6782,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- uOpenFlags,
+ uOpenFlags | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw vrc;
@@ -6810,7 +6814,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task)
vrc = VDOpen(hdd,
(*it)->m->strFormat.c_str(),
(*it)->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_INFO,
+ VD_OPEN_FLAGS_INFO | m->uOpenFlagsDef,
(*it)->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw vrc;
@@ -7064,7 +7068,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_READONLY,
+ VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7133,7 +7137,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task)
vrc = VDOpen(targetHdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- uOpenFlags,
+ uOpenFlags | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7154,7 +7158,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task)
0 /* cbSize */,
task.mVariant & ~MediumVariant_NoCreateDir,
targetId.raw(),
- VD_OPEN_FLAGS_NORMAL,
+ VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef,
NULL /* pVDIfsOperation */,
pTarget->m->vdImageIfaces,
task.mVDOperationIfaces);
@@ -7172,7 +7176,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task)
task.midxDstImageSame,
task.mVariant & ~MediumVariant_NoCreateDir,
targetId.raw(),
- VD_OPEN_FLAGS_NORMAL,
+ VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef,
NULL /* pVDIfsOperation */,
pTarget->m->vdImageIfaces,
task.mVDOperationIfaces);
@@ -7320,7 +7324,7 @@ HRESULT Medium::taskDeleteHandler(Medium::DeleteTask &task)
vrc = VDOpen(hdd,
format.c_str(),
location.c_str(),
- VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO,
+ VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | m->uOpenFlagsDef,
m->vdImageIfaces);
if (RT_SUCCESS(vrc))
vrc = VDClose(hdd, true /* fDelete */);
@@ -7418,7 +7422,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_READONLY,
+ VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7442,7 +7446,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task)
vrc = VDOpen(hdd,
parentFormat.c_str(),
parentLocation.c_str(),
- VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO,
+ VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | m->uOpenFlagsDef,
m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7548,7 +7552,7 @@ HRESULT Medium::taskCompactHandler(Medium::CompactTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- (it == mediumListLast) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY,
+ m->uOpenFlagsDef | (it == mediumListLast) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7645,7 +7649,7 @@ HRESULT Medium::taskResizeHandler(Medium::ResizeTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- (it == mediumListLast) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY,
+ m->uOpenFlagsDef | (it == mediumListLast) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7739,7 +7743,7 @@ HRESULT Medium::taskExportHandler(Medium::ExportTask &task)
vrc = VDOpen(hdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- VD_OPEN_FLAGS_READONLY,
+ VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7862,7 +7866,7 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task)
vrc = VDOpen(hdd,
task.mFormat->getId().c_str(),
task.mFilename.c_str(),
- VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SEQUENTIAL,
+ VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SEQUENTIAL | m->uOpenFlagsDef,
task.mVDImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
@@ -7929,7 +7933,7 @@ HRESULT Medium::taskImportHandler(Medium::ImportTask &task)
vrc = VDOpen(targetHdd,
pMedium->m->strFormat.c_str(),
pMedium->m->strLocationFull.c_str(),
- uOpenFlags,
+ uOpenFlags | m->uOpenFlagsDef,
pMedium->m->vdImageIfaces);
if (RT_FAILURE(vrc))
throw setError(VBOX_E_FILE_ERROR,
diff --git a/src/VBox/Main/src-server/Performance.cpp b/src/VBox/Main/src-server/Performance.cpp
index ecdd53dd1..6726e14da 100644
--- a/src/VBox/Main/src-server/Performance.cpp
+++ b/src/VBox/Main/src-server/Performance.cpp
@@ -108,6 +108,87 @@ int CollectorHAL::getHostCpuMHz(ULONG *mhz)
#ifndef VBOX_COLLECTOR_TEST_CASE
+CollectorGuestQueue::CollectorGuestQueue()
+{
+ mEvent = NIL_RTSEMEVENT;
+ RTSemEventCreate(&mEvent);
+}
+
+CollectorGuestQueue::~CollectorGuestQueue()
+{
+ RTSemEventDestroy(mEvent);
+}
+
+void CollectorGuestQueue::push(CollectorGuestRequest* rq)
+{
+ RTCLock lock(mLockMtx);
+
+ mQueue.push(rq);
+ RTSemEventSignal(mEvent);
+}
+
+CollectorGuestRequest* CollectorGuestQueue::pop()
+{
+ int rc = VINF_SUCCESS;
+ CollectorGuestRequest* rq = NULL;
+
+ do
+ {
+ {
+ RTCLock lock(mLockMtx);
+
+ if (!mQueue.empty())
+ {
+ rq = mQueue.front();
+ mQueue.pop();
+ }
+ }
+
+ if (rq)
+ return rq;
+ else
+ rc = RTSemEventWaitNoResume(mEvent, RT_INDEFINITE_WAIT);
+ }
+ while (RT_SUCCESS(rc));
+
+ return NULL;
+}
+
+int CGRQEnable::execute()
+{
+ Assert(mCGuest);
+ return mCGuest->enableInternal(mMask);
+}
+
+void CGRQEnable::debugPrint(void *aObject, const char *aFunction, const char *aText)
+{
+ LogAleksey(("{%p} " LOG_FN_FMT ": CGRQEnable(mask=0x%x) %s\n",
+ aObject, aFunction, mMask, aText));
+}
+
+int CGRQDisable::execute()
+{
+ Assert(mCGuest);
+ return mCGuest->disableInternal(mMask);
+}
+
+void CGRQDisable::debugPrint(void *aObject, const char *aFunction, const char *aText)
+{
+ LogAleksey(("{%p} " LOG_FN_FMT ": CGRQDisable(mask=0x%x) %s\n",
+ aObject, aFunction, mMask, aText));
+}
+
+int CGRQAbort::execute()
+{
+ return E_ABORT;
+}
+
+void CGRQAbort::debugPrint(void *aObject, const char *aFunction, const char *aText)
+{
+ LogAleksey(("{%p} " LOG_FN_FMT ": CGRQAbort %s\n",
+ aObject, aFunction, aText));
+}
+
CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) :
mUnregistered(false), mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
mCpuUser(0), mCpuKernel(0), mCpuIdle(0),
@@ -126,122 +207,184 @@ CollectorGuest::~CollectorGuest()
// Assert(!cEnabled); why?
}
-int CollectorGuest::enable()
+int CollectorGuest::enableVMMStats(bool mCollectVMMStats)
{
- mEnabled = true;
- /* Must make sure that the machine object does not get uninitialized
- * in the middle of enabling this collector. Causes timing-related
- * behavior otherwise, which we don't want. In particular the
- * GetRemoteConsole call below can hang if the VM didn't completely
- * terminate (the VM processes stop processing events shortly before
- * closing the session). This avoids the hang. */
- AutoCaller autoCaller(mMachine);
- if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
HRESULT ret = S_OK;
- ComPtr<IInternalSessionControl> directControl;
+ if (mGuest)
+ {
+ /* @todo: replace this with a direct call to mGuest in trunk! */
+ AutoCaller autoCaller(mMachine);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
- ret = mMachine->getDirectControl(&directControl);
- if (ret != S_OK)
- return ret;
+ ComPtr<IInternalSessionControl> directControl;
- /* get the associated console; this is a remote call (!) */
- ret = directControl->GetRemoteConsole(mConsole.asOutParam());
- if (ret != S_OK)
- return ret;
+ ret = mMachine->getDirectControl(&directControl);
+ if (ret != S_OK)
+ return ret;
- ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam());
- if (ret == S_OK)
- {
- ret = mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
- LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 1 sec (%s)\n",
- this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
+ /* enable statistics collection; this is a remote call (!) */
+ ret = directControl->EnableVMMStatistics(mCollectVMMStats);
+ LogAleksey(("{%p} " LOG_FN_FMT ": %sable VMM stats (%s)\n",
+ this, __PRETTY_FUNCTION__, mCollectVMMStats?"En":"Dis",
+ SUCCEEDED(ret)?"success":"failed"));
}
return ret;
}
-int CollectorGuest::disable()
+int CollectorGuest::enable(ULONG mask)
{
- mEnabled = false;
- Assert(mGuest && mConsole);
- HRESULT ret = mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
- NOREF(ret);
- LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n",
- this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
- invalidateStats();
+ return enqueueRequest(new CGRQEnable(mask));
+}
- return S_OK;
+int CollectorGuest::disable(ULONG mask)
+{
+ return enqueueRequest(new CGRQDisable(mask));
}
-int CollectorGuest::updateStats()
+int CollectorGuest::enableInternal(ULONG mask)
{
- if (mGuest)
+ HRESULT ret = S_OK;
+
+ if ((mEnabled & mask) == mask)
+ return E_UNEXPECTED;
+
+ if (!mEnabled)
{
- HRESULT rc;
- rc = mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
- &mMemTotal, &mMemFree, &mMemBalloon, &mMemShared, &mMemCache,
- &mPageTotal, &mAllocVMM, &mFreeVMM, &mBalloonedVMM, &mSharedVMM);
- if (SUCCEEDED(rc))
+ /* Must make sure that the machine object does not get uninitialized
+ * in the middle of enabling this collector. Causes timing-related
+ * behavior otherwise, which we don't want. In particular the
+ * GetRemoteConsole call below can hang if the VM didn't completely
+ * terminate (the VM processes stop processing events shortly before
+ * closing the session). This avoids the hang. */
+ AutoCaller autoCaller(mMachine);
+ if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+ mMachineName = mMachine->getName();
+
+ ComPtr<IInternalSessionControl> directControl;
+
+ ret = mMachine->getDirectControl(&directControl);
+ if (ret != S_OK)
+ return ret;
+
+ /* get the associated console; this is a remote call (!) */
+ ret = directControl->GetRemoteConsole(mConsole.asOutParam());
+ if (ret != S_OK)
+ return ret;
+
+ ret = mConsole->COMGETTER(Guest)(mGuest.asOutParam());
+ if (ret == S_OK)
{
- mValid = true;
+ ret = mGuest->COMSETTER(StatisticsUpdateInterval)(1 /* 1 sec */);
+ LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 1 sec (%s)\n",
+ this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
}
- LogAleksey(("{%p} " LOG_FN_FMT ": mValid=%s mCpuUser=%u mCpuKernel=%u mCpuIdle=%u\n"
- "mMemTotal=%u mMemFree=%u mMemBalloon=%u mMemShared=%u mMemCache=%u\n"
- "mPageTotal=%u mAllocVMM=%u mFreeVMM=%u mBalloonedVMM=%u mSharedVMM=%u\n",
- this, __PRETTY_FUNCTION__, mValid?"y":"n",
- mCpuUser, mCpuKernel, mCpuIdle,
- mMemTotal, mMemFree, mMemBalloon, mMemShared, mMemCache,
- mPageTotal, mAllocVMM, mFreeVMM, mBalloonedVMM, mSharedVMM));
+ }
+ if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
+ enableVMMStats(true);
+ mEnabled |= mask;
+
+ return ret;
+}
+
+int CollectorGuest::disableInternal(ULONG mask)
+{
+ if (!(mEnabled & mask))
+ return E_UNEXPECTED;
+
+ if ((mask & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
+ enableVMMStats(false);
+ mEnabled &= ~mask;
+ if (!mEnabled)
+ {
+ Assert(mGuest && mConsole);
+ HRESULT ret = mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
+ NOREF(ret);
+ LogAleksey(("{%p} " LOG_FN_FMT ": Set guest statistics update interval to 0 sec (%s)\n",
+ this, __PRETTY_FUNCTION__, SUCCEEDED(ret)?"success":"failed"));
+ invalidate(GUESTSTATS_ALL);
}
return S_OK;
}
-void CollectorGuestManager::preCollect(CollectorHints& hints, uint64_t /* iTick */)
+int CollectorGuest::enqueueRequest(CollectorGuestRequest *aRequest)
{
- /*
- * Since we are running without a lock the value of mVMMStatsProvider
- * can change at any moment. In the worst case we won't collect any data.
- */
- CollectorGuestList::iterator it;
+ if (mManager)
+ {
+ aRequest->setGuest(this);
+ return mManager->enqueueRequest(aRequest);
+ }
- LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p ramvmm=%s\n",
- this, __PRETTY_FUNCTION__, mVMMStatsProvider, hints.isHostRamVmmCollected()?"y":"n"));
- for (it = mGuests.begin(); it != mGuests.end(); it++)
+ LogAleksey(("{%p} " LOG_FN_FMT ": Attempted enqueue guest request when mManager is null\n",
+ this, __PRETTY_FUNCTION__));
+ return E_POINTER;
+}
+
+void CollectorGuest::updateStats(ULONG aValidStats, ULONG aCpuUser,
+ ULONG aCpuKernel, ULONG aCpuIdle,
+ ULONG aMemTotal, ULONG aMemFree,
+ ULONG aMemBalloon, ULONG aMemShared,
+ ULONG aMemCache, ULONG aPageTotal,
+ ULONG aAllocVMM, ULONG aFreeVMM,
+ ULONG aBalloonedVMM, ULONG aSharedVMM)
+{
+ if ((aValidStats & GUESTSTATS_CPULOAD) == GUESTSTATS_CPULOAD)
{
- LogAleksey(("{%p} " LOG_FN_FMT ": it=%p pid=%d gueststats=%s...\n",
- this, __PRETTY_FUNCTION__, *it, (*it)->getProcess(),
- hints.isGuestStatsCollected((*it)->getProcess())?"y":"n"));
- if ((*it)->isUnregistered())
- continue;
- if ( (hints.isHostRamVmmCollected() && *it == mVMMStatsProvider)
- || hints.isGuestStatsCollected((*it)->getProcess()))
- {
- /* Guest stats collection needs to be enabled */
- if ((*it)->isEnabled())
- {
- /* Already enabled, collect the data */
- (*it)->updateStats();
- }
- else
- {
- (*it)->invalidateStats();
- (*it)->enable();
- }
- }
- else
- {
- /* Guest stats collection needs to be disabled */
- if ((*it)->isEnabled())
- (*it)->disable();
- }
+ mCpuUser = aCpuUser;
+ mCpuKernel = aCpuKernel,
+ mCpuIdle = aCpuIdle;
+ }
+ if ((aValidStats & GUESTSTATS_RAMUSAGE) == GUESTSTATS_RAMUSAGE)
+ {
+ mMemTotal = aMemTotal;
+ mMemFree = aMemFree;
+ mMemBalloon = aMemBalloon;
+ mMemShared = aMemShared;
+ mMemCache = aMemCache;
+ mPageTotal = aPageTotal;
+ }
+ if ((aValidStats & GUESTSTATS_VMMRAM) == GUESTSTATS_VMMRAM)
+ {
+ mAllocVMM = aAllocVMM;
+ mFreeVMM = aFreeVMM;
+ mBalloonedVMM = aBalloonedVMM;
+ mSharedVMM = aSharedVMM;
+ }
+ mValid = aValidStats;
+}
+
+CollectorGuestManager::CollectorGuestManager()
+ : mVMMStatsProvider(NULL), mGuestBeingCalled(NULL)
+{
+ int rc = RTThreadCreate(&mThread, CollectorGuestManager::requestProcessingThread,
+ this, 0, RTTHREADTYPE_MAIN_WORKER, RTTHREADFLAGS_WAITABLE,
+ "CGMgr");
+ LogAleksey(("{%p} " LOG_FN_FMT ": RTThreadCreate returned %u (mThread=%p)\n",
+ this, __PRETTY_FUNCTION__, rc));
+}
+
+CollectorGuestManager::~CollectorGuestManager()
+{
+ Assert(mGuests.size() == 0);
+ int rcThread = 0;
+ int rc = enqueueRequest(new CGRQAbort());
+ if (SUCCEEDED(rc))
+ {
+ /* We wait only if we were able to put the abort request to a queue */
+ LogAleksey(("{%p} " LOG_FN_FMT ": Waiting for CGM request processing thread to stop...\n",
+ this, __PRETTY_FUNCTION__));
+ rc = RTThreadWait(mThread, 1000 /* 1 sec */, &rcThread);
+ LogAleksey(("{%p} " LOG_FN_FMT ": RTThreadWait returned %u (thread exit code: %u)\n",
+ this, __PRETTY_FUNCTION__, rc, rcThread));
}
}
void CollectorGuestManager::registerGuest(CollectorGuest* pGuest)
{
+ pGuest->setManager(this);
mGuests.push_back(pGuest);
/*
* If no VMM stats provider was elected previously than this is our
@@ -255,6 +398,8 @@ void CollectorGuestManager::registerGuest(CollectorGuest* pGuest)
void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
{
+ int rc = S_OK;
+
LogAleksey(("{%p} " LOG_FN_FMT ": About to unregister guest=%p provider=%p\n",
this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
//mGuests.remove(pGuest); => destroyUnregistered()
@@ -276,12 +421,32 @@ void CollectorGuestManager::unregisterGuest(CollectorGuest* pGuest)
{
/* Found the guest already collecting stats, elect it */
mVMMStatsProvider = *it;
+ rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM));
+ if (FAILED(rc))
+ {
+ /* This is not a good candidate -- try to find another */
+ mVMMStatsProvider = NULL;
+ continue;
+ }
break;
}
- else if (!mVMMStatsProvider)
+ }
+ if (!mVMMStatsProvider)
+ {
+ /* If nobody collects stats, take the first registered */
+ for (it = mGuests.begin(); it != mGuests.end(); it++)
{
- /* If nobody collects stats, take the first registered */
+ /* Skip unregistered as they are about to be destroyed */
+ if ((*it)->isUnregistered())
+ continue;
+
mVMMStatsProvider = *it;
+ //mVMMStatsProvider->enable(GUESTSTATS_VMMRAM);
+ rc = mVMMStatsProvider->enqueueRequest(new CGRQEnable(GUESTSTATS_VMMRAM));
+ if (SUCCEEDED(rc))
+ break;
+ /* This was not a good candidate -- try to find another */
+ mVMMStatsProvider = NULL;
}
}
}
@@ -305,6 +470,58 @@ void CollectorGuestManager::destroyUnregistered()
++it;
}
+int CollectorGuestManager::enqueueRequest(CollectorGuestRequest *aRequest)
+{
+#ifdef DEBUG
+ aRequest->debugPrint(this, __PRETTY_FUNCTION__, "added to CGM queue");
+#endif /* DEBUG */
+ /*
+ * It is very unlikely that we will get high frequency calls to configure
+ * guest metrics collection, so we rely on this fact to detect blocked
+ * guests. If the guest has not finished processing the previous request
+ * we consider it blocked.
+ */
+ if (aRequest->getGuest() && aRequest->getGuest() == mGuestBeingCalled)
+ {
+ /* Request execution got stalled for this guest -- report an error */
+ return E_FAIL;
+ }
+ mQueue.push(aRequest);
+ return S_OK;
+}
+
+/* static */
+DECLCALLBACK(int) CollectorGuestManager::requestProcessingThread(RTTHREAD /* aThread */, void *pvUser)
+{
+ CollectorGuestRequest *pReq;
+ CollectorGuestManager *mgr = static_cast<CollectorGuestManager*>(pvUser);
+
+ HRESULT rc = S_OK;
+
+ LogAleksey(("{%p} " LOG_FN_FMT ": Starting request processing loop...p\n",
+ mgr, __PRETTY_FUNCTION__));
+ while ((pReq = mgr->mQueue.pop()) != NULL)
+ {
+#ifdef DEBUG
+ pReq->debugPrint(mgr, __PRETTY_FUNCTION__, "is being executed...");
+#endif /* DEBUG */
+ mgr->mGuestBeingCalled = pReq->getGuest();
+ rc = pReq->execute();
+ mgr->mGuestBeingCalled = NULL;
+ delete pReq;
+ if (rc == E_ABORT)
+ break;
+ if (FAILED(rc))
+ LogAleksey(("{%p} " LOG_FN_FMT ": request::execute returned %u\n",
+ mgr, __PRETTY_FUNCTION__, rc));
+ }
+ LogAleksey(("{%p} " LOG_FN_FMT ": Exiting request processing loop... rc=%u\n",
+ mgr, __PRETTY_FUNCTION__, rc));
+
+ return VINF_SUCCESS;
+}
+
+
#endif /* !VBOX_COLLECTOR_TEST_CASE */
bool BaseMetric::collectorBeat(uint64_t nowAt)
@@ -425,6 +642,7 @@ void HostRamUsage::collect()
}
}
+#ifndef VBOX_COLLECTOR_TEST_CASE
void HostRamVmm::init(ULONG period, ULONG length)
{
mPeriod = period;
@@ -435,6 +653,26 @@ void HostRamVmm::init(ULONG period, ULONG length)
mSharedVMM->init(mLength);
}
+int HostRamVmm::enable()
+{
+ int rc = S_OK;
+ CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
+ if (provider)
+ rc = provider->enable(GUESTSTATS_VMMRAM);
+ BaseMetric::enable();
+ return rc;
+}
+
+int HostRamVmm::disable()
+{
+ int rc = S_OK;
+ BaseMetric::disable();
+ CollectorGuest *provider = mCollectorGuestManager->getVMMStatsProvider();
+ if (provider)
+ rc = provider->disable(GUESTSTATS_VMMRAM);
+ return rc;
+}
+
void HostRamVmm::preCollect(CollectorHints& hints, uint64_t /* iTick */)
{
hints.collectHostRamVmm();
@@ -447,15 +685,21 @@ void HostRamVmm::collect()
{
LogAleksey(("{%p} " LOG_FN_FMT ": provider=%p enabled=%s valid=%s...\n",
this, __PRETTY_FUNCTION__, provider, provider->isEnabled()?"y":"n",
- provider->isValid()?"y":"n"));
- if (provider->isValid())
+ provider->isValid(GUESTSTATS_VMMRAM)?"y":"n"));
+ if (provider->isValid(GUESTSTATS_VMMRAM))
{
/* Provider is ready, get updated stats */
mAllocCurrent = provider->getAllocVMM();
mFreeCurrent = provider->getFreeVMM();
mBalloonedCurrent = provider->getBalloonedVMM();
mSharedCurrent = provider->getSharedVMM();
+ provider->invalidate(GUESTSTATS_VMMRAM);
}
+ /*
+ * Note that if there are no new values from the provider we will use
+ * the ones most recently provided instead of zeros, which is probably
+ * a desirable behavior.
+ */
}
else
{
@@ -472,6 +716,7 @@ void HostRamVmm::collect()
mBalloonVMM->put(mBalloonedCurrent);
mSharedVMM->put(mSharedCurrent);
}
+#endif /* !VBOX_COLLECTOR_TEST_CASE */
@@ -545,6 +790,7 @@ void MachineRamUsage::collect()
}
+#ifndef VBOX_COLLECTOR_TEST_CASE
void GuestCpuLoad::init(ULONG period, ULONG length)
{
mPeriod = period;
@@ -562,14 +808,28 @@ void GuestCpuLoad::preCollect(CollectorHints& hints, uint64_t /* iTick */)
void GuestCpuLoad::collect()
{
- if (mCGuest->isValid())
+ if (mCGuest->isValid(GUESTSTATS_CPULOAD))
{
mUser->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuUser()) / 100);
mKernel->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuKernel()) / 100);
mIdle->put((ULONG)(PM_CPU_LOAD_MULTIPLIER * mCGuest->getCpuIdle()) / 100);
+ mCGuest->invalidate(GUESTSTATS_CPULOAD);
}
}
+int GuestCpuLoad::enable()
+{
+ int rc = mCGuest->enable(GUESTSTATS_CPULOAD);
+ BaseMetric::enable();
+ return rc;
+}
+
+int GuestCpuLoad::disable()
+{
+ BaseMetric::disable();
+ return mCGuest->disable(GUESTSTATS_CPULOAD);
+}
+
void GuestRamUsage::init(ULONG period, ULONG length)
{
mPeriod = period;
@@ -583,14 +843,9 @@ void GuestRamUsage::init(ULONG period, ULONG length)
mPagedTotal->init(mLength);
}
-void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t /* iTick */)
-{
- hints.collectGuestStats(mCGuest->getProcess());
-}
-
void GuestRamUsage::collect()
{
- if (mCGuest->isValid())
+ if (mCGuest->isValid(GUESTSTATS_RAMUSAGE))
{
mTotal->put(mCGuest->getMemTotal());
mFree->put(mCGuest->getMemFree());
@@ -598,9 +853,29 @@ void GuestRamUsage::collect()
mShared->put(mCGuest->getMemShared());
mCache->put(mCGuest->getMemCache());
mPagedTotal->put(mCGuest->getPageTotal());
+ mCGuest->invalidate(GUESTSTATS_RAMUSAGE);
}
}
+int GuestRamUsage::enable()
+{
+ int rc = mCGuest->enable(GUESTSTATS_RAMUSAGE);
+ BaseMetric::enable();
+ return rc;
+}
+
+int GuestRamUsage::disable()
+{
+ BaseMetric::disable();
+ return mCGuest->disable(GUESTSTATS_RAMUSAGE);
+}
+
+void GuestRamUsage::preCollect(CollectorHints& hints, uint64_t /* iTick */)
+{
+ hints.collectGuestStats(mCGuest->getProcess());
+}
+#endif /* !VBOX_COLLECTOR_TEST_CASE */
+
void CircularBuffer::init(ULONG ulLength)
{
if (mData)
diff --git a/src/VBox/Main/src-server/PerformanceImpl.cpp b/src/VBox/Main/src-server/PerformanceImpl.cpp
index 8da7342c9..d685b901e 100644
--- a/src/VBox/Main/src-server/PerformanceImpl.cpp
+++ b/src/VBox/Main/src-server/PerformanceImpl.cpp
@@ -138,7 +138,10 @@ static const char *g_papcszMetricNames[] =
// constructor / destructor
////////////////////////////////////////////////////////////////////////////////
-PerformanceCollector::PerformanceCollector() : mMagic(0) {}
+PerformanceCollector::PerformanceCollector()
+ : mMagic(0), mUnknownGuest("unknown guest")
+{
+}
PerformanceCollector::~PerformanceCollector() {}
@@ -298,6 +301,14 @@ HRESULT PerformanceCollector::toIPerformanceMetric(pm::BaseMetric *src, IPerform
return rc;
}
+const Utf8Str& PerformanceCollector::getFailedGuestName()
+{
+ pm::CollectorGuest *pGuest = m.gm->getBlockedGuest();
+ if (pGuest)
+ return pGuest->getVMName();
+ return mUnknownGuest;
+}
+
STDMETHODIMP PerformanceCollector::GetMetrics(ComSafeArrayIn(IN_BSTR, metricNames),
ComSafeArrayIn(IUnknown *, objects),
ComSafeArrayOut(IPerformanceMetric *, outMetrics))
@@ -366,13 +377,17 @@ STDMETHODIMP PerformanceCollector::SetupMetrics(ComSafeArrayIn(IN_BSTR, metricNa
{
LogFlow (("PerformanceCollector::SetupMetrics() disabling %s\n",
(*it)->getName()));
- (*it)->disable();
+ rc = (*it)->disable();
+ if (FAILED(rc))
+ break;
}
else
{
LogFlow (("PerformanceCollector::SetupMetrics() enabling %s\n",
(*it)->getName()));
- (*it)->enable();
+ rc = (*it)->enable();
+ if (FAILED(rc))
+ break;
}
filteredMetrics.push_back(*it);
}
@@ -385,6 +400,10 @@ STDMETHODIMP PerformanceCollector::SetupMetrics(ComSafeArrayIn(IN_BSTR, metricNa
retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
LogFlowThisFuncLeave();
+
+ if (FAILED(rc))
+ return setError(E_FAIL, "Failed to setup metrics for '%s'",
+ getFailedGuestName().c_str());
return rc;
}
@@ -408,7 +427,9 @@ STDMETHODIMP PerformanceCollector::EnableMetrics(ComSafeArrayIn(IN_BSTR, metricN
for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); ++it)
if (filter.match((*it)->getObject(), (*it)->getName()))
{
- (*it)->enable();
+ rc = (*it)->enable();
+ if (FAILED(rc))
+ break;
filteredMetrics.push_back(*it);
}
@@ -420,6 +441,10 @@ STDMETHODIMP PerformanceCollector::EnableMetrics(ComSafeArrayIn(IN_BSTR, metricN
retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
LogFlowThisFuncLeave();
+
+ if (FAILED(rc))
+ return setError(E_FAIL, "Failed to enable metrics for '%s'",
+ getFailedGuestName().c_str());
return rc;
}
@@ -443,7 +468,9 @@ STDMETHODIMP PerformanceCollector::DisableMetrics(ComSafeArrayIn(IN_BSTR, metric
for (it = m.baseMetrics.begin(); it != m.baseMetrics.end(); ++it)
if (filter.match((*it)->getObject(), (*it)->getName()))
{
- (*it)->disable();
+ rc = (*it)->disable();
+ if (FAILED(rc))
+ break;
filteredMetrics.push_back(*it);
}
@@ -455,6 +482,10 @@ STDMETHODIMP PerformanceCollector::DisableMetrics(ComSafeArrayIn(IN_BSTR, metric
retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
LogFlowThisFuncLeave();
+
+ if (FAILED(rc))
+ return setError(E_FAIL, "Failed to disable metrics for '%s'",
+ getFailedGuestName().c_str());
return rc;
}
@@ -693,8 +724,11 @@ void PerformanceCollector::samplerCallback(uint64_t iTick)
/* Let know the platform specific code what is being collected */
m.hal->preCollect(hints, iTick);
+#if 0
+ /* Guest stats are now pushed by guests themselves */
/* Collect the data in bulk from all hinted guests */
m.gm->preCollect(hints, iTick);
+#endif
AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
/*
diff --git a/src/VBox/Main/src-server/VirtualBoxImpl.cpp b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
index 43207ef5f..8d6cc0eb2 100644
--- a/src/VBox/Main/src-server/VirtualBoxImpl.cpp
+++ b/src/VBox/Main/src-server/VirtualBoxImpl.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * 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;
@@ -25,7 +25,6 @@
#include <iprt/path.h>
#include <iprt/process.h>
#include <iprt/string.h>
-#include <iprt/stream.h>
#include <iprt/thread.h>
#include <iprt/uuid.h>
#include <iprt/cpp/xml.h>
@@ -1580,7 +1579,10 @@ STDMETHODIMP VirtualBox::OpenMedium(IN_BSTR aLocation,
ComObjPtr<Medium> pMedium;
- /* we don't access non-const data members so no need to lock */
+ // have to get write lock as the whole find/update sequence must be done
+ // in one critical section, otherwise there are races which can lead to
+ // multiple Medium objects with the same content
+ AutoWriteLock treeLock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
// check if the device type is correct, and see if a medium for the
// given path has already initialized; if so, return that
@@ -1622,8 +1624,6 @@ STDMETHODIMP VirtualBox::OpenMedium(IN_BSTR aLocation,
if (SUCCEEDED(rc))
{
- AutoWriteLock treeLock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
-
switch (deviceType)
{
case DeviceType_HardDisk:
@@ -3952,7 +3952,7 @@ HRESULT VirtualBox::ensureFilePathExists(const Utf8Str &strFileName, bool fCreat
{
if (fCreate)
{
- int vrc = RTDirCreateFullPath(strDir.c_str(), 0777);
+ int vrc = RTDirCreateFullPath(strDir.c_str(), 0700);
if (RT_FAILURE(vrc))
return setErrorStatic(VBOX_E_IPRT_ERROR,
Utf8StrFmt(tr("Could not create the directory '%s' (%Rrc)"),
diff --git a/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp b/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp
index e54549c16..f38d3cc1c 100644
--- a/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp
+++ b/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp
@@ -29,6 +29,7 @@ using namespace com;
#define LOG_INSTANCE NULL
#include <VBox/log.h>
+#include <iprt/env.h>
#include <iprt/test.h>
#include <iprt/stream.h>
@@ -55,7 +56,7 @@ static struct
uint32_t uOffsetAfter;
uint32_t uMapElements;
int iResult;
-} aTests[] =
+} aTestBlock[] =
{
/*
* Single object parsing.
@@ -63,7 +64,6 @@ static struct
* separated by a single "\0". If this termination is missing it will be assumed
* that we need to collect more data to do a successful parsing.
*/
-
/* Invalid stuff. */
{ NULL, 0, 0, 0, 0, VERR_INVALID_POINTER },
{ NULL, 512, 0, 0, 0, VERR_INVALID_POINTER },
@@ -108,7 +108,7 @@ static struct
uint32_t uNumBlocks;
/** Overall result when done parsing. */
int iResult;
-} aTests2[] =
+} aTestStream[] =
{
/* No blocks. */
{ "\0\0\0\0", sizeof("\0\0\0\0"), 0, VERR_NO_DATA },
@@ -119,6 +119,46 @@ static struct
{ "b1=b1\0b2=b2\0\0\0", sizeof("b1=b1\0b2=b2\0\0\0"), 1, VERR_NO_DATA }
};
+int manualTest()
+{
+ int rc;
+ static struct
+ {
+ const char *pbData;
+ size_t cbData;
+ uint32_t uOffsetStart;
+ uint32_t uOffsetAfter;
+ uint32_t uMapElements;
+ int iResult;
+ } aTest[] =
+ {
+ { "test5=test5\0t51=t51", sizeof("test5=test5\0t51=t51"), 0, sizeof("test5=test5\0") - 1, 1, VERR_MORE_DATA },
+ { "\0\0test5=test5\0t51=t51", sizeof("\0\0test5=test5\0t51=t51"), 0, sizeof("\0\0test5=test5\0") - 1, 1, VERR_MORE_DATA },
+ };
+
+ unsigned iTest = 0;
+ for (iTest; iTest < RT_ELEMENTS(aTest); iTest++)
+ {
+ RTTestIPrintf(RTTESTLVL_DEBUG, "Manual test #%d\n", iTest);
+
+ GuestProcessStream stream;
+ rc = stream.AddData((BYTE*)aTest[iTest].pbData, aTest[iTest].cbData);
+
+ for (;;)
+ {
+ GuestProcessStreamBlock block;
+ rc = stream.ParseBlock(block);
+ RTTestIPrintf(RTTESTLVL_DEBUG, "\tReturned with rc=%Rrc, numItems=%ld\n",
+ rc, block.GetCount());
+
+ if (block.GetCount())
+ break;
+ }
+ }
+
+ return rc;
+}
+
int main()
{
RTTEST hTest;
@@ -128,13 +168,17 @@ int main()
RTTestBanner(hTest);
RTTestIPrintf(RTTESTLVL_DEBUG, "Initializing COM...\n");
- rc = com::Initialize();
- if (FAILED(rc))
+ HRESULT hrc = com::Initialize();
+ if (FAILED(hrc))
{
- RTPrintf("ERROR: failed to initialize COM!\n");
- return rc;
+ RTTestFailed(hTest, "Failed to initialize COM (%Rhrc)!\n", hrc);
+ return RTEXITCODE_FAILURE;
}
+#ifdef DEBUG_andy
+ rc = manualTest();
+#endif
+
RTTestIPrintf(RTTESTLVL_INFO, "Doing basic tests ...\n");
if (sizeof("sizecheck") != 10)
@@ -146,26 +190,30 @@ int main()
RTTestIPrintf(RTTESTLVL_INFO, "Doing line tests ...\n");
+ /* Don't let the assertions trigger here
+ * -- we rely on the return values in the test(s) below. */
+ RTAssertSetQuiet(true);
+
unsigned iTest = 0;
- for (iTest; iTest < RT_ELEMENTS(aTests); iTest++)
+ for (iTest; iTest < RT_ELEMENTS(aTestBlock); iTest++)
{
RTTestIPrintf(RTTESTLVL_DEBUG, "=> Test #%u\n", iTest);
GuestProcessStream stream;
- int iResult = stream.AddData((BYTE*)aTests[iTest].pbData, aTests[iTest].cbData);
+ int iResult = stream.AddData((BYTE*)aTestBlock[iTest].pbData, aTestBlock[iTest].cbData);
if (RT_SUCCESS(iResult))
{
GuestProcessStreamBlock curBlock;
iResult = stream.ParseBlock(curBlock);
- if (iResult != aTests[iTest].iResult)
+ if (iResult != aTestBlock[iTest].iResult)
{
RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
- iResult, aTests[iTest].iResult);
+ iResult, aTestBlock[iTest].iResult);
}
- else if (stream.GetOffset() != aTests[iTest].uOffsetAfter)
+ else if (stream.GetOffset() != aTestBlock[iTest].uOffsetAfter)
{
RTTestFailed(hTest, "\tOffset %u wrong, expected %u",
- stream.GetOffset(), aTests[iTest].uOffsetAfter);
+ stream.GetOffset(), aTestBlock[iTest].uOffsetAfter);
}
else if (iResult == VERR_MORE_DATA)
{
@@ -175,22 +223,26 @@ int main()
if ( ( RT_SUCCESS(iResult)
|| iResult == VERR_MORE_DATA))
{
- if (curBlock.GetCount() != aTests[iTest].uMapElements)
+ if (curBlock.GetCount() != aTestBlock[iTest].uMapElements)
{
RTTestFailed(hTest, "\tMap has %u elements, expected %u",
- curBlock.GetCount(), aTests[iTest].uMapElements);
+ curBlock.GetCount(), aTestBlock[iTest].uMapElements);
}
}
/* There is remaining data left in the buffer (which needs to be merged
* with a following buffer) -- print it. */
uint32_t uOffset = stream.GetOffset();
- size_t uToWrite = aTests[iTest].cbData - uOffset;
+ size_t uToWrite = aTestBlock[iTest].cbData - uOffset;
if (uToWrite)
{
- const char *pszRemaining = aTests[iTest].pbData;
+ const char *pszRemaining = aTestBlock[iTest].pbData;
RTTestIPrintf(RTTESTLVL_DEBUG, "\tRemaining (%u):\n", uToWrite);
- RTStrmWriteEx(g_pStdOut, &aTests[iTest].pbData[uOffset], uToWrite - 1, NULL);
+
+ /* How to properly get the current RTTESTLVL (aka IPRT_TEST_MAX_LEVEL) here?
+ * Hack alert: Using RTEnvGet for now. */
+ if (!RTStrICmp(RTEnvGet("IPRT_TEST_MAX_LEVEL"), "debug"))
+ RTStrmWriteEx(g_pStdOut, &aTestBlock[iTest].pbData[uOffset], uToWrite - 1, NULL);
}
}
}
@@ -198,12 +250,12 @@ int main()
RTTestIPrintf(RTTESTLVL_INFO, "Doing block tests ...\n");
iTest = 0;
- for (iTest; iTest < RT_ELEMENTS(aTests2); iTest++)
+ for (iTest; iTest < RT_ELEMENTS(aTestStream); iTest++)
{
RTTestIPrintf(RTTESTLVL_DEBUG, "=> Block test #%u\n", iTest);
GuestProcessStream stream;
- int iResult = stream.AddData((BYTE*)aTests2[iTest].pbData, aTests2[iTest].cbData);
+ int iResult = stream.AddData((BYTE*)aTestStream[iTest].pbData, aTestStream[iTest].cbData);
if (RT_SUCCESS(iResult))
{
uint32_t uNumBlocks = 0;
@@ -223,15 +275,15 @@ int main()
break;
} while (RT_SUCCESS(iResult));
- if (iResult != aTests2[iTest].iResult)
+ if (iResult != aTestStream[iTest].iResult)
{
RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
- iResult, aTests2[iTest].iResult);
+ iResult, aTestStream[iTest].iResult);
}
- else if (uNumBlocks != aTests2[iTest].uNumBlocks)
+ else if (uNumBlocks != aTestStream[iTest].uNumBlocks)
{
RTTestFailed(hTest, "\tReturned %u blocks, expected %u\n",
- uNumBlocks, aTests2[iTest].uNumBlocks);
+ uNumBlocks, aTestStream[iTest].uNumBlocks);
}
}
else
diff --git a/src/VBox/Main/webservice/Makefile.kmk b/src/VBox/Main/webservice/Makefile.kmk
index 0fc47cc7c..a1bff93ba 100644
--- a/src/VBox/Main/webservice/Makefile.kmk
+++ b/src/VBox/Main/webservice/Makefile.kmk
@@ -6,7 +6,7 @@
#
#
-# Copyright (C) 2006-2011 Oracle Corporation
+# 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;
@@ -117,6 +117,12 @@ if "$(VBOX_PATH_GSOAP_BIN)" == ""
VBOX_PATH_GSOAP_BIN := $(VBOX_PATH_GSOAP_BIN)/win32
else if "$(KBUILD_HOST)" == "linux"
VBOX_PATH_GSOAP_BIN := $(VBOX_PATH_GSOAP_BIN)/linux386
+ else if "$(KBUILD_HOST)" == "solaris"
+ if $(VBOX_SOLARIS_11_VERSION) >= 164
+ VBOX_PATH_GSOAP_BIN := $(VBOX_PATH_GSOAP_BIN)/solaris11.x86
+ else
+ VBOX_PATH_GSOAP_BIN := $(VBOX_PATH_GSOAP_BIN)/solaris.x86
+ endif
else
VBOX_PATH_GSOAP_BIN := $(VBOX_PATH_GSOAP_BIN)/$(KBUILD_HOST).x86
endif
@@ -205,6 +211,10 @@ ifdef VBOX_GSOAP_INSTALLED
$(VBOX_GSOAP_INCS) \
$(VBOXWEB_OUT_DIR) \
$(PATH_SUB_CURRENT)
+ ifdef VBOX_WITH_WEBSERVICES_SSL
+ vboxsoap_DEFS += WITH_OPENSSL
+ vboxsoap_SDKS += VBOX_OPENSSL2
+ endif
ifdef VBOX_WITHOUT_SPLIT_SOAPC
vboxsoap_SOURCES = \
$(VBOXWEB_OUT_DIR)/soapC.cpp
@@ -243,6 +253,10 @@ ifdef VBOX_GSOAP_INSTALLED
$(VBOXWEB_OUT_DIR)/gsoap_copy_all_ts
ifn1of ($(KBUILD_TARGET), win)
$(VBOX_GSOAP_CXX_SOURCES)_CXXFLAGS = -Wno-format
+ # currently necessary when compiling against OpenSSL 1.0 due to a missing
+ # typecase from 'const v3_ext_method*' to 'aka v3_ext_method*'.
+ $(VBOX_GSOAP_CXX_SOURCES)_CXXFLAGS += -fpermissive
+
endif
$(VBOXWEB_OUT_DIR)/soapC-3.cpp_CXXFLAGS.win.x86 = -Og- # VCC70 says "function too large".
@@ -280,8 +294,13 @@ endif
endif
vboxwebsrv_LIBS += \
$(PATH_STAGE_LIB)/vboxsoap$(VBOX_SUFF_LIB) \
- $(VBOX_GSOAP_CXX_LIBS)
+ $(VBOX_GSOAP_CXX_LIBS) \
+ $(LIB_RUNTIME)
vboxwebsrv_LIBS.solaris += socket nsl
+ ifdef VBOX_WITH_WEBSERVICES_SSL
+ vboxwebsrv_DEFS += WITH_OPENSSL
+ vboxwebsrv_SDKS += VBOX_OPENSSL2
+ endif
vboxwebsrv_SOURCES = \
vboxweb.cpp \
$(VBOXWEB_OUT_DIR)/methodmaps.cpp \
@@ -423,8 +442,13 @@ $$(VBOX_JWSSRC_JAR): $$(VBOX_JWS_JAR) | $$(dir $$@)
.
webtest_LIBS += \
$(PATH_STAGE_LIB)/vboxsoap$(VBOX_SUFF_LIB) \
- $(VBOX_GSOAP_CXX_LIBS)
+ $(VBOX_GSOAP_CXX_LIBS) \
+ $(LIB_RUNTIME)
webtest_LIBS.solaris += nsl
+ ifdef VBOX_WITH_WEBSERVICES_SSL
+ webtest_DEFS += WITH_OPENSSL
+ webtest_SDKS += VBOX_OPENSSL2
+ endif
webtest_SOURCES = \
webtest.cpp \
$(VBOXWEB_OUT_DIR)/soapClient.cpp
@@ -498,7 +522,8 @@ ifdef VBOX_ONLY_SDK
vboxwebinst_MODE = a+rx,u+w
vboxwebinst_SOURCES = \
samples/perl/clienttest.pl=>perl/samples/clienttest.pl \
- samples/php/clienttest.php=>php/samples/clienttest.php
+ samples/php/clienttest.php=>php/samples/clienttest.php \
+ samples/python/clienttest.py=>python/samples/clienttest.py
INSTALLS += vboxwebinst_nox
vboxwebinst_nox_INST = $(INST_SDK)bindings/webservice/
diff --git a/src/VBox/Main/webservice/samples/php/clienttest.php b/src/VBox/Main/webservice/samples/php/clienttest.php
index 371e2c682..648662c43 100644
--- a/src/VBox/Main/webservice/samples/php/clienttest.php
+++ b/src/VBox/Main/webservice/samples/php/clienttest.php
@@ -52,17 +52,18 @@ foreach ($machines as $machine)
{
$session = $websessionManager->getSessionObject($virtualbox->handle);
$uuid = $machine->id;
- $virtualbox->openExistingSession($session, $uuid);
+ $machine->lockMachine($session->handle, "Shared");
try
{
$console = $session->console;
$display = $console->display;
- $screenWidth = $display->width;
- $screenHeight = $display->height;
- $imageraw = $display->takeScreenShotSlow($screenWidth, $screenHeight);
- $session->close();
- $filename = './screenshot.png';
- echo "Saving screenshot of " . $machine->name . " (${screenWidth}x${screenHeight}) to $filename\n";
+ list($screenWidth, $screenHeight, $screenBpp) = $display->getScreenResolution(0 /* First screen */);
+
+ $imageraw = $display->takeScreenShotToArray(0 /* First screen */, $screenWidth, $screenHeight);
+ echo "Screenshot size: " . sizeof($imageraw) . "\n";
+
+ $filename = 'screenshot.png';
+ echo "Saving screenshot of " . $machine->name . " (${screenWidth}x${screenHeight}, ${screenBpp}BPP) to $filename\n";
$image = imagecreatetruecolor($screenWidth, $screenHeight);
for ($height = 0; $height < $screenHeight; $height++)
@@ -71,9 +72,9 @@ foreach ($machines as $machine)
{
$start = ($height*$screenWidth + $width)*4;
$red = $imageraw[$start];
- $green = $imageraw[$start+1];
- $blue = $imageraw[$start+2];
- //$alpha = $imageraw[$start+3];
+ $green = $imageraw[($start+1)];
+ $blue = $imageraw[($start+2)];
+ //$alpha = $image[$start+3];
$colour = imagecolorallocate($image, $red, $green, $blue);
@@ -85,12 +86,19 @@ foreach ($machines as $machine)
}
catch (Exception $ex)
{
- // Ensure we close the VM Session if we hit a error, ensure we don't have a aborted VM
echo $ex->getMessage();
- $session->close();
}
+
+ $session->unlockMachine();
+
+ $machine->releaseRemote();
+ $session->releaseRemote();
+
break;
}
}
$websessionManager->logoff($virtualbox->handle);
+
+?>
+
diff --git a/src/VBox/Main/webservice/samples/python/clienttest.py b/src/VBox/Main/webservice/samples/python/clienttest.py
new file mode 100755
index 000000000..50e5d1037
--- /dev/null
+++ b/src/VBox/Main/webservice/samples/python/clienttest.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+#
+# Copyright (C) 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.
+#
+# Things needed to be set up before running this sample:
+# - Install Python and verify it works (2.7.2 will do, 3.x is untested yet)
+# - On Windows: Install the PyWin32 extensions for your Python version
+# (see http://sourceforge.net/projects/pywin32/)
+# - If not already done, set the environment variable "VBOX_INSTALL_PATH"
+# to point to your VirtualBox installation directory (which in turn must have
+# the "sdk" subfolder")
+# - Install the VirtualBox Python bindings by doing a
+# "[python] vboxapisetup.py install"
+# - Run this sample with "[python] clienttest.py"
+
+import os,sys
+import traceback
+
+#
+# Converts an enumeration to a printable string.
+#
+def enumToString(constants, enum, elem):
+ all = constants.all_values(enum)
+ for e in all.keys():
+ if str(elem) == str(all[e]):
+ return e
+ return "<unknown>"
+
+def main(argv):
+
+ from vboxapi import VirtualBoxManager
+ wrapper = VirtualBoxManager(None, None)
+
+ # Get the VirtualBox manager
+ mgr = wrapper.mgr
+ # Get the global VirtualBox object
+ vbox = wrapper.vbox
+
+ print "Running VirtualBox version %s" %(vbox.version)
+
+ # Get all constants through the Python wrapper code
+ vboxConstants = wrapper.constants
+
+ # Enumerate all defined machines
+ for mach in vbox.machines:
+
+ try:
+
+ # Print some basic information
+ print "Machine name: %s [%s]" %(mach.name,mach.id)
+ print " State: %s" %(enumToString(vboxConstants, "MachineState", mach.state))
+ print " Session state: %s" %(enumToString(vboxConstants, "SessionState", mach.sessionState))
+
+ # Do some stuff which requires a running VM
+ if mach.state == vboxConstants.MachineState_Running:
+
+ # Get the session object
+ session = mgr.getSessionObject(vbox)
+
+ # Lock the current machine (shared mode, since we won't modify the machine)
+ mach.lockMachine(session, vboxConstants.LockType_Shared)
+
+ # Acquire the VM's console and guest object
+ console = session.console
+ guest = console.guest
+
+ # Retrieve the current Guest Additions runlevel and print
+ # the installed Guest Additions version
+ addRunLevel = guest.additionsRunLevel
+ print " Additions State: %s" %(enumToString(vboxConstants, "AdditionsRunLevelType", addRunLevel))
+ if addRunLevel != vboxConstants.AdditionsRunLevelType_None:
+ print " Additions Ver: %s" %(guest.additionsVersion)
+
+ # Get the VM's display object
+ display = console.display
+
+ # Get the VM's current display resolution + bit depth
+ screenNum = 0 # From first screen
+ (screenX, screenY, screenBPP) = display.getScreenResolution(screenNum)
+ print " Display (%d): %dx%d, %d BPP" %(screenNum, screenX, screenY, screenBPP)
+
+ # We're done -- don't forget to unlock the machine!
+ session.unlockMachine()
+
+ except Exception, e:
+ print "Errror [%s]: %s" %(mach.name, str(e))
+ traceback.print_exc()
+
+ # Call destructor and delete wrapper
+ del wrapper
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/src/VBox/Main/webservice/vboxweb.cpp b/src/VBox/Main/webservice/vboxweb.cpp
index c9c0131d5..6a4905141 100644
--- a/src/VBox/Main/webservice/vboxweb.cpp
+++ b/src/VBox/Main/webservice/vboxweb.cpp
@@ -5,7 +5,7 @@
* (plus static gSOAP server code) to implement the actual webservice
* server, to which clients can connect.
*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * 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;
@@ -22,6 +22,7 @@
// vbox headers
#include <VBox/com/com.h>
#include <VBox/com/array.h>
+#include <VBox/com/string.h>
#include <VBox/com/ErrorInfo.h>
#include <VBox/com/errorprint.h>
#include <VBox/com/EventQueue.h>
@@ -41,12 +42,14 @@
#include <iprt/process.h>
#include <iprt/rand.h>
#include <iprt/semaphore.h>
+#include <iprt/critsect.h>
#include <iprt/string.h>
#include <iprt/thread.h>
#include <iprt/time.h>
#include <iprt/path.h>
#include <iprt/system.h>
#include <iprt/base64.h>
+#include <iprt/stream.h>
// workaround for compile problems on gcc 4.1
#ifdef __GNUC__
@@ -75,6 +78,8 @@ extern DECLIMPORT(const unsigned) g_cbVBoxWebWSDL;
RT_C_DECLS_END
+static void WebLogSoapError(struct soap *soap);
+
/****************************************************************************
*
* private typedefs
@@ -116,9 +121,23 @@ int g_iWatchdogCheckInterval = 5;
const char *g_pcszBindToHost = NULL; // host; NULL = localhost
unsigned int g_uBindToPort = 18083; // port
unsigned int g_uBacklog = 100; // backlog = max queue size for requests
+
+#ifdef WITH_OPENSSL
+bool g_fSSL = false; // if SSL is enabled
+const char *g_pcszKeyFile = NULL; // server key file
+const char *g_pcszPassword = NULL; // password for server key
+const char *g_pcszCACert = NULL; // file with trusted CA certificates
+const char *g_pcszCAPath = NULL; // directory with trusted CA certificates
+const char *g_pcszDHFile = NULL; // DH file name or DH key length in bits, NULL=use RSA
+const char *g_pcszRandFile = NULL; // file with random data seed
+const char *g_pcszSID = "vboxwebsrv"; // server ID for SSL session cache
+#endif /* WITH_OPENSSL */
+
unsigned int g_cMaxWorkerThreads = 100; // max. no. of worker threads
unsigned int g_cMaxKeepAlive = 100; // maximum number of soap requests in one connection
+const char *g_pcszAuthentication = NULL; // web service authentication
+
uint32_t g_cHistory = 10; // enable log rotation, 10 files
uint32_t g_uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file
uint64_t g_uHistoryFileSize = 100 * _1M; // max 100MB per file
@@ -179,10 +198,20 @@ static const RTGETOPTDEF g_aOptions[]
#endif
{ "--host", 'H', RTGETOPT_REQ_STRING },
{ "--port", 'p', RTGETOPT_REQ_UINT32 },
+#ifdef WITH_OPENSSL
+ { "--ssl", 's', RTGETOPT_REQ_NOTHING },
+ { "--keyfile", 'K', RTGETOPT_REQ_STRING },
+ { "--passwordfile", 'a', RTGETOPT_REQ_STRING },
+ { "--cacert", 'c', RTGETOPT_REQ_STRING },
+ { "--capath", 'C', RTGETOPT_REQ_STRING },
+ { "--dhfile", 'D', RTGETOPT_REQ_STRING },
+ { "--randfile", 'r', RTGETOPT_REQ_STRING },
+#endif /* WITH_OPENSSL */
{ "--timeout", 't', RTGETOPT_REQ_UINT32 },
{ "--check-interval", 'i', RTGETOPT_REQ_UINT32 },
{ "--threads", 'T', RTGETOPT_REQ_UINT32 },
{ "--keepalive", 'k', RTGETOPT_REQ_UINT32 },
+ { "--authentication", 'A', RTGETOPT_REQ_STRING },
{ "--verbose", 'v', RTGETOPT_REQ_NOTHING },
{ "--pidfile", 'P', RTGETOPT_REQ_STRING },
{ "--logfile", 'F', RTGETOPT_REQ_STRING },
@@ -225,6 +254,36 @@ void DisplayHelp()
pcszDescr = "The port to bind to (18083).";
break;
+#ifdef WITH_OPENSSL
+ case 's':
+ pcszDescr = "Enable SSL/TLS encryption.";
+ break;
+
+ case 'K':
+ pcszDescr = "Server key and certificate file, PEM format (\"\").";
+ break;
+
+ case 'a':
+ pcszDescr = "File name for password to server key (\"\").";
+ break;
+
+ case 'c':
+ pcszDescr = "CA certificate file, PEM format (\"\").";
+ break;
+
+ case 'C':
+ pcszDescr = "CA certificate path (\"\").";
+ break;
+
+ case 'D':
+ pcszDescr = "DH file name or DH key length in bits (\"\").";
+ break;
+
+ case 'r':
+ pcszDescr = "File containing seed for random number generator (\"\").";
+ break;
+#endif /* WITH_OPENSSL */
+
case 't':
pcszDescr = "Session timeout in seconds; 0 = disable timeouts (" DEFAULT_TIMEOUT_SECS_STRING ").";
break;
@@ -237,6 +296,10 @@ void DisplayHelp()
pcszDescr = "Maximum number of requests before a socket will be closed (100).";
break;
+ case 'A':
+ pcszDescr = "Authentication method for the webservice (\"\").";
+ break;
+
case 'i':
pcszDescr = "Frequency of timeout checks in seconds (5).";
break;
@@ -515,7 +578,16 @@ void SoapThread::process()
m_soap->send_timeout = 60;
m_soap->recv_timeout = 60;
// process the request; this goes into the COM code in methodmaps.cpp
- soap_serve(m_soap);
+ do {
+#ifdef WITH_OPENSSL
+ if (g_fSSL && soap_ssl_accept(m_soap))
+ {
+ WebLogSoapError(m_soap);
+ break;
+ }
+#endif /* WITH_OPENSSL */
+ soap_serve(m_soap);
+ } while (0);
soap_destroy(m_soap); // clean up class instances
soap_end(m_soap); // clean up everything and close socket
@@ -631,6 +703,7 @@ void WebLog(const char *pszFormat, ...)
* Helper for printing SOAP error messages.
* @param soap
*/
+/*static*/
void WebLogSoapError(struct soap *soap)
{
if (soap_check_state(soap))
@@ -714,6 +787,108 @@ static void WebLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PF
}
}
+#ifdef WITH_OPENSSL
+/****************************************************************************
+ *
+ * OpenSSL convenience functions for multithread support
+ *
+ ****************************************************************************/
+
+static RTCRITSECT *g_pSSLMutexes = NULL;
+
+struct CRYPTO_dynlock_value
+{
+ RTCRITSECT mutex;
+};
+
+static unsigned long CRYPTO_id_function()
+{
+ return RTThreadNativeSelf();
+}
+
+static void CRYPTO_locking_function(int mode, int n, const char * /*file*/, int /*line*/)
+{
+ if (mode & CRYPTO_LOCK)
+ RTCritSectEnter(&g_pSSLMutexes[n]);
+ else
+ RTCritSectLeave(&g_pSSLMutexes[n]);
+}
+
+static struct CRYPTO_dynlock_value *CRYPTO_dyn_create_function(const char * /*file*/, int /*line*/)
+{
+ struct CRYPTO_dynlock_value *value = (struct CRYPTO_dynlock_value *)RTMemAlloc(sizeof(struct CRYPTO_dynlock_value));
+ if (value)
+ RTCritSectInit(&value->mutex);
+
+ return value;
+}
+
+static void CRYPTO_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *value, const char * /*file*/, int /*line*/)
+{
+ if (mode & CRYPTO_LOCK)
+ RTCritSectEnter(&value->mutex);
+ else
+ RTCritSectLeave(&value->mutex);
+}
+
+static void CRYPTO_dyn_destroy_function(struct CRYPTO_dynlock_value *value, const char * /*file*/, int /*line*/)
+{
+ if (value)
+ {
+ RTCritSectDelete(&value->mutex);
+ free(value);
+ }
+}
+
+static int CRYPTO_thread_setup()
+{
+ int num_locks = CRYPTO_num_locks();
+ g_pSSLMutexes = (RTCRITSECT *)RTMemAlloc(num_locks * sizeof(RTCRITSECT));
+ if (!g_pSSLMutexes)
+ return SOAP_EOM;
+
+ for (int i = 0; i < num_locks; i++)
+ {
+ int rc = RTCritSectInit(&g_pSSLMutexes[i]);
+ if (RT_FAILURE(rc))
+ {
+ for ( ; i >= 0; i--)
+ RTCritSectDelete(&g_pSSLMutexes[i]);
+ RTMemFree(g_pSSLMutexes);
+ g_pSSLMutexes = NULL;
+ return SOAP_EOM;
+ }
+ }
+
+ CRYPTO_set_id_callback(CRYPTO_id_function);
+ CRYPTO_set_locking_callback(CRYPTO_locking_function);
+ CRYPTO_set_dynlock_create_callback(CRYPTO_dyn_create_function);
+ CRYPTO_set_dynlock_lock_callback(CRYPTO_dyn_lock_function);
+ CRYPTO_set_dynlock_destroy_callback(CRYPTO_dyn_destroy_function);
+
+ return SOAP_OK;
+}
+
+static void CRYPTO_thread_cleanup()
+{
+ if (!g_pSSLMutexes)
+ return;
+
+ CRYPTO_set_id_callback(NULL);
+ CRYPTO_set_locking_callback(NULL);
+ CRYPTO_set_dynlock_create_callback(NULL);
+ CRYPTO_set_dynlock_lock_callback(NULL);
+ CRYPTO_set_dynlock_destroy_callback(NULL);
+
+ int num_locks = CRYPTO_num_locks();
+ for (int i = 0; i < num_locks; i++)
+ RTCritSectDelete(&g_pSSLMutexes[i]);
+
+ RTMemFree(g_pSSLMutexes);
+ g_pSSLMutexes = NULL;
+}
+#endif /* WITH_OPENSSL */
+
/****************************************************************************
*
* SOAP queue pumper thread
@@ -722,10 +897,28 @@ static void WebLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PF
void doQueuesLoop()
{
+#ifdef WITH_OPENSSL
+ if (g_fSSL && CRYPTO_thread_setup())
+ {
+ WebLog("Failed to set up OpenSSL thread mutex!");
+ exit(RTEXITCODE_FAILURE);
+ }
+#endif /* WITH_OPENSSL */
+
// set up gSOAP
struct soap soap;
soap_init(&soap);
+#ifdef WITH_OPENSSL
+ if (g_fSSL && soap_ssl_server_context(&soap, SOAP_SSL_DEFAULT, g_pcszKeyFile,
+ g_pcszPassword, g_pcszCACert, g_pcszCAPath,
+ g_pcszDHFile, g_pcszRandFile, g_pcszSID))
+ {
+ WebLogSoapError(&soap);
+ exit(RTEXITCODE_FAILURE);
+ }
+#endif /* WITH_OPENSSL */
+
soap.bind_flags |= SO_REUSEADDR;
// avoid EADDRINUSE on bind()
@@ -738,9 +931,14 @@ void doQueuesLoop()
WebLogSoapError(&soap);
else
{
- WebLog("Socket connection successful: host = %s, port = %u, master socket = %d\n",
+ WebLog("Socket connection successful: host = %s, port = %u, %smaster socket = %d\n",
(g_pcszBindToHost) ? g_pcszBindToHost : "default (localhost)",
g_uBindToPort,
+#ifdef WITH_OPENSSL
+ g_fSSL ? "SSL, " : "",
+#else /* !WITH_OPENSSL */
+ "",
+#endif /*!WITH_OPENSSL */
m);
// initialize thread queue, mutex and eventsem
@@ -765,6 +963,11 @@ void doQueuesLoop()
}
}
soap_done(&soap); // close master socket and detach environment
+
+#ifdef WITH_OPENSSL
+ if (g_fSSL)
+ CRYPTO_thread_cleanup();
+#endif /* WITH_OPENSSL */
}
/**
@@ -839,6 +1042,57 @@ int main(int argc, char *argv[])
g_uBindToPort = ValueUnion.u32;
break;
+#ifdef WITH_OPENSSL
+ case 's':
+ g_fSSL = true;
+ break;
+
+ case 'K':
+ g_pcszKeyFile = ValueUnion.psz;
+ break;
+
+ case 'a':
+ if (ValueUnion.psz[0] == '\0')
+ g_pcszPassword = NULL;
+ else
+ {
+ PRTSTREAM StrmIn;
+ if (!strcmp(ValueUnion.psz, "-"))
+ StrmIn = g_pStdIn;
+ else
+ {
+ int vrc = RTStrmOpen(ValueUnion.psz, "r", &StrmIn);
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to open password file (%s, %Rrc)", ValueUnion.psz, vrc);
+ }
+ char szPasswd[512];
+ int vrc = RTStrmGetLine(StrmIn, szPasswd, sizeof(szPasswd));
+ if (RT_FAILURE(vrc))
+ return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to read password (%s, %Rrc)", ValueUnion.psz, vrc);
+ g_pcszPassword = RTStrDup(szPasswd);
+ memset(szPasswd, '\0', sizeof(szPasswd));
+ if (StrmIn != g_pStdIn)
+ RTStrmClose(StrmIn);
+ }
+ break;
+
+ case 'c':
+ g_pcszCACert = ValueUnion.psz;
+ break;
+
+ case 'C':
+ g_pcszCAPath = ValueUnion.psz;
+ break;
+
+ case 'D':
+ g_pcszDHFile = ValueUnion.psz;
+ break;
+
+ case 'r':
+ g_pcszRandFile = ValueUnion.psz;
+ break;
+#endif /* WITH_OPENSSL */
+
case 't':
g_iWatchdogTimeoutSecs = ValueUnion.u32;
break;
@@ -875,6 +1129,10 @@ int main(int argc, char *argv[])
g_cMaxKeepAlive = ValueUnion.u32;
break;
+ case 'A':
+ g_pcszAuthentication = ValueUnion.psz;
+ break;
+
case 'h':
DisplayHelp();
return 0;
@@ -963,6 +1221,12 @@ int main(int argc, char *argv[])
}
#endif
+ // initialize SOAP SSL support if enabled
+#ifdef WITH_OPENSSL
+ if (g_fSSL)
+ soap_ssl_init();
+#endif /* WITH_OPENSSL */
+
// initialize COM/XPCOM
HRESULT hrc = com::Initialize();
if (FAILED(hrc))
@@ -990,6 +1254,15 @@ int main(int argc, char *argv[])
return RTEXITCODE_FAILURE;
}
+ // set the authentication method if requested
+ if (g_pVirtualBox && g_pcszAuthentication && g_pcszAuthentication[0])
+ {
+ ComPtr<ISystemProperties> pSystemProperties;
+ g_pVirtualBox->COMGETTER(SystemProperties)(pSystemProperties.asOutParam());
+ if (pSystemProperties)
+ pSystemProperties->COMSETTER(WebServiceAuthLibrary)(com::Bstr(g_pcszAuthentication).raw());
+ }
+
/* VirtualBoxClient events registration. */
ComPtr<IEventListener> vboxClientListener;
{
@@ -1113,6 +1386,15 @@ int fntWatchdog(RTTHREAD ThreadSelf, void *pvUser)
else
++it;
}
+
+ // re-set the authentication method in case it has been changed
+ if (g_pVirtualBox && g_pcszAuthentication && g_pcszAuthentication[0])
+ {
+ ComPtr<ISystemProperties> pSystemProperties;
+ g_pVirtualBox->COMGETTER(SystemProperties)(pSystemProperties.asOutParam());
+ if (pSystemProperties)
+ pSystemProperties->COMSETTER(WebServiceAuthLibrary)(com::Bstr(g_pcszAuthentication).raw());
+ }
}
WEBDEBUG(("Watchdog thread ending\n"));
@@ -1438,9 +1720,9 @@ int WebServiceSession::authenticate(const char *pcszUsername,
util::AutoReadLock vlock(g_pVirtualBoxLockHandle COMMA_LOCKVAL_SRC_POS);
pVirtualBox = g_pVirtualBox;
}
- pVirtualBox.queryInterfaceTo(ppVirtualBox);
if (pVirtualBox.isNull())
return rc;
+ pVirtualBox.queryInterfaceTo(ppVirtualBox);
util::AutoReadLock lock(g_pAuthLibLockHandle COMMA_LOCKVAL_SRC_POS);
@@ -1477,13 +1759,17 @@ int WebServiceSession::authenticate(const char *pcszUsername,
}
if (RT_FAILURE(rc = RTLdrGetSymbol(hlibAuth, AUTHENTRY3_NAME, (void**)&pfnAuthEntry3)))
+ {
WEBDEBUG(("%s(): Could not resolve import '%s'. Error code: %Rrc\n", __FUNCTION__, AUTHENTRY3_NAME, rc));
- if (RT_FAILURE(rc = RTLdrGetSymbol(hlibAuth, AUTHENTRY2_NAME, (void**)&pfnAuthEntry2)))
- WEBDEBUG(("%s(): Could not resolve import '%s'. Error code: %Rrc\n", __FUNCTION__, AUTHENTRY2_NAME, rc));
+ if (RT_FAILURE(rc = RTLdrGetSymbol(hlibAuth, AUTHENTRY2_NAME, (void**)&pfnAuthEntry2)))
+ {
+ WEBDEBUG(("%s(): Could not resolve import '%s'. Error code: %Rrc\n", __FUNCTION__, AUTHENTRY2_NAME, rc));
- if (RT_FAILURE(rc = RTLdrGetSymbol(hlibAuth, AUTHENTRY_NAME, (void**)&pfnAuthEntry)))
- WEBDEBUG(("%s(): Could not resolve import '%s'. Error code: %Rrc\n", __FUNCTION__, AUTHENTRY_NAME, rc));
+ if (RT_FAILURE(rc = RTLdrGetSymbol(hlibAuth, AUTHENTRY_NAME, (void**)&pfnAuthEntry)))
+ WEBDEBUG(("%s(): Could not resolve import '%s'. Error code: %Rrc\n", __FUNCTION__, AUTHENTRY_NAME, rc));
+ }
+ }
if (pfnAuthEntry || pfnAuthEntry2 || pfnAuthEntry3)
fAuthLibLoaded = true;
diff --git a/src/VBox/Main/webservice/vboxweb.h b/src/VBox/Main/webservice/vboxweb.h
index e323300e8..9803e8797 100644
--- a/src/VBox/Main/webservice/vboxweb.h
+++ b/src/VBox/Main/webservice/vboxweb.h
@@ -21,7 +21,7 @@
void WebLog(const char *pszFormat, ...);
-#define WEBDEBUG(a) if (g_fVerbose) { WebLog a; }
+#define WEBDEBUG(a) do { if (g_fVerbose) { WebLog a; } } while (0)
#ifdef DEBUG
#define LOG_GROUP LOG_GROUP_WEBSERVICE
diff --git a/src/VBox/Main/webservice/webtest.cpp b/src/VBox/Main/webservice/webtest.cpp
index 70e3d6f18..89c8064a0 100644
--- a/src/VBox/Main/webservice/webtest.cpp
+++ b/src/VBox/Main/webservice/webtest.cpp
@@ -3,7 +3,7 @@
* demo webservice client in C++. This mimics some of the
* functionality of VBoxManage for testing purposes.
*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * 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;
@@ -25,6 +25,44 @@
#include <string>
+static void usage(int exitcode)
+{
+ std::cout <<
+ "webtest: VirtualBox webservice testcase.\n"
+ "\nUsage: webtest [options] [command]...\n"
+ "\nSupported options:\n"
+ " -h: print this help message and exit.\n"
+ " -c URL: specify the webservice server URL (default http://localhost:18083/).\n"
+ "\nSupported commands:\n"
+ " - IWebsessionManager:\n"
+ " - webtest logon <user> <pass>: IWebsessionManager::logon().\n"
+ " - webtest getsession <vboxref>: IWebsessionManager::getSessionObject().\n"
+ " - webtest logoff <vboxref>: IWebsessionManager::logoff().\n"
+ " - IVirtualBox:\n"
+ " - webtest version <vboxref>: IVirtualBox::getVersion().\n"
+ " - webtest gethost <vboxref>: IVirtualBox::getHost().\n"
+ " - webtest getpc <vboxref>: IVirtualBox::getPerformanceCollector().\n"
+ " - webtest getmachines <vboxref>: IVirtualBox::getMachines().\n"
+ " - webtest createmachine <vboxref> <settingsPath> <name>: IVirtualBox::createMachine().\n"
+ " - webtest registermachine <vboxref> <machineref>: IVirtualBox::registerMachine().\n"
+ " - IHost:\n"
+ " - webtest getdvddrives <hostref>: IHost::getDVDDrives.\n"
+ " - IHostDVDDrive:\n"
+ " - webtest getdvdname <dvdref>: IHostDVDDrive::getname.\n"
+ " - IMachine:\n"
+ " - webtest getname <machineref>: IMachine::getName().\n"
+ " - webtest getid <machineref>: IMachine::getId().\n"
+ " - webtest getostype <machineref>: IMachine::getGuestOSType().\n"
+ " - webtest savesettings <machineref>: IMachine::saveSettings().\n"
+ " - IPerformanceCollector:\n"
+ " - webtest setupmetrics <pcref>: IPerformanceCollector::setupMetrics()\n"
+ " - webtest querymetricsdata <pcref>: IPerformanceCollector::QueryMetricsData()\n"
+ " - All managed object references:\n"
+ " - webtest getif <ref>: report interface of object.\n"
+ " - webtest release <ref>: IUnknown::Release().\n";
+ exit(exitcode);
+}
+
/**
*
* @param argc
@@ -33,57 +71,67 @@
*/
int main(int argc, char* argv[])
{
+ bool fSSL = false;
+ const char *pcszArgEndpoint = "http://localhost:18083/";
+
+ int ap;
+ for (ap = 1; ap <= argc; ap++)
+ {
+ if (argv[ap][0] == '-')
+ {
+ if (!strcmp(argv[ap], "-h"))
+ usage(0);
+ else if (!strcmp(argv[ap], "-c"))
+ {
+ ap++;
+ if (ap > argc)
+ usage(1);
+ pcszArgEndpoint = argv[ap];
+ fSSL = !strncmp(pcszArgEndpoint, "https://", 8);
+ }
+ else
+ usage(1);
+ }
+ else
+ break;
+ }
+
+ if (argc < 1 + ap)
+ usage(1);
+
+#ifdef WITH_OPENSSL
+ if (fSSL)
+ soap_ssl_init();
+#endif /* WITH_OPENSSL */
+
struct soap soap; // gSOAP runtime environment
soap_init(&soap); // initialize runtime environment (only once)
-
- if (argc < 2)
+#ifdef WITH_OPENSSL
+ // Use SOAP_SSL_NO_AUTHENTICATION here to accept broken server configs.
+ // In a real world setup please use at least SOAP_SSL_DEFAULT and provide
+ // the necessary CA certificate for validating the server's certificate.
+ if (fSSL && soap_ssl_client_context(&soap, SOAP_SSL_NO_AUTHENTICATION,
+ NULL /*clientkey*/, NULL /*password*/,
+ NULL /*cacert*/, NULL /*capath*/,
+ NULL /*randfile*/))
{
- std::cout <<
- "webtest: VirtualBox webservice testcase.\n"
- "Usage:\n"
- " - IWebsessionManager:\n"
- " - webtest logon <user> <pass>: IWebsessionManager::logon().\n"
- " - webtest getsession <vboxref>: IWebsessionManager::getSessionObject().\n"
- " - webtest logoff <vboxref>: IWebsessionManager::logoff().\n"
- " - IVirtualBox:\n"
- " - webtest version <vboxref>: IVirtualBox::getVersion().\n"
- " - webtest gethost <vboxref>: IVirtualBox::getHost().\n"
- " - webtest getpc <vboxref>: IVirtualBox::getPerformanceCollector().\n"
- " - webtest getmachines <vboxref>: IVirtualBox::getMachines().\n"
- " - webtest createmachine <vboxref> <settingsPath> <name>: IVirtualBox::createMachine().\n"
- " - webtest registermachine <vboxref> <machineref>: IVirtualBox::registerMachine().\n"
- " - IHost:\n"
- " - webtest getdvddrives <hostref>: IHost::getDVDDrives.\n"
- " - IHostDVDDrive:\n"
- " - webtest getdvdname <dvdref>: IHostDVDDrive::getname.\n"
- " - IMachine:\n"
- " - webtest getname <machineref>: IMachine::getName().\n"
- " - webtest getid <machineref>: IMachine::getId().\n"
- " - webtest getostype <machineref>: IMachine::getGuestOSType().\n"
- " - webtest savesettings <machineref>: IMachine::saveSettings().\n"
- " - IPerformanceCollector:\n"
- " - webtest setupmetrics <pcref>: IPerformanceCollector::setupMetrics()\n"
- " - webtest querymetricsdata <pcref>: IPerformanceCollector::QueryMetricsData()\n"
- " - All managed object references:\n"
- " - webtest getif <ref>: report interface of object.\n"
- " - webtest release <ref>: IUnknown::Release().\n";
+ soap_print_fault(&soap, stderr);
exit(1);
}
+#endif /* WITH_OPENSSL */
- const char *pcszArgEndpoint = "localhost:18083";
-
- const char *pcszMode = argv[1];
- int soaprc = 2;
+ const char *pcszMode = argv[ap];
+ int soaprc = SOAP_SVR_FAULT;
if (!strcmp(pcszMode, "logon"))
{
- if (argc < 4)
+ if (argc < 3 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IWebsessionManager_USCORElogon req;
- req.username = argv[2];
- req.password = argv[3];
+ req.username = argv[ap + 1];
+ req.password = argv[ap + 2];
_vbox__IWebsessionManager_USCORElogonResponse resp;
if (!(soaprc = soap_call___vbox__IWebsessionManager_USCORElogon(&soap,
@@ -96,12 +144,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getsession"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IWebsessionManager_USCOREgetSessionObject req;
- req.refIVirtualBox = argv[2];
+ req.refIVirtualBox = argv[ap + 1];
_vbox__IWebsessionManager_USCOREgetSessionObjectResponse resp;
if (!(soaprc = soap_call___vbox__IWebsessionManager_USCOREgetSessionObject(&soap,
@@ -114,12 +162,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "logoff"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IWebsessionManager_USCORElogoff req;
- req.refIVirtualBox = argv[2];
+ req.refIVirtualBox = argv[ap + 1];
_vbox__IWebsessionManager_USCORElogoffResponse resp;
if (!(soaprc = soap_call___vbox__IWebsessionManager_USCORElogoff(&soap,
@@ -134,12 +182,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "version"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IVirtualBox_USCOREgetVersion req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IVirtualBox_USCOREgetVersionResponse resp;
if (!(soaprc = soap_call___vbox__IVirtualBox_USCOREgetVersion(&soap,
@@ -152,12 +200,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "gethost"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IVirtualBox_USCOREgetHost req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IVirtualBox_USCOREgetHostResponse resp;
if (!(soaprc = soap_call___vbox__IVirtualBox_USCOREgetHost(&soap,
@@ -172,12 +220,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getpc"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IVirtualBox_USCOREgetPerformanceCollector req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IVirtualBox_USCOREgetPerformanceCollectorResponse resp;
if (!(soaprc = soap_call___vbox__IVirtualBox_USCOREgetPerformanceCollector(&soap,
@@ -192,12 +240,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getmachines"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IVirtualBox_USCOREgetMachines req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IVirtualBox_USCOREgetMachinesResponse resp;
if (!(soaprc = soap_call___vbox__IVirtualBox_USCOREgetMachines(&soap,
@@ -218,14 +266,14 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "createmachine"))
{
- if (argc < 5)
+ if (argc < 4 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IVirtualBox_USCOREcreateMachine req;
- req._USCOREthis = argv[2];
- req.settingsFile = argv[3];
- req.name = argv[4];
+ req._USCOREthis = argv[ap + 1];
+ req.settingsFile = argv[ap + 2];
+ req.name = argv[ap + 3];
std::cout << "createmachine: settingsFile = \"" << req.settingsFile << "\", name = \"" << req.name << "\"\n";
_vbox__IVirtualBox_USCOREcreateMachineResponse resp;
@@ -239,13 +287,13 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "registermachine"))
{
- if (argc < 4)
+ if (argc < 3 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IVirtualBox_USCOREregisterMachine req;
- req._USCOREthis = argv[2];
- req.machine = argv[3];
+ req._USCOREthis = argv[ap + 1];
+ req.machine = argv[ap + 2];
_vbox__IVirtualBox_USCOREregisterMachineResponse resp;
if (!(soaprc = soap_call___vbox__IVirtualBox_USCOREregisterMachine(&soap,
pcszArgEndpoint,
@@ -257,12 +305,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getdvddrives"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IHost_USCOREgetDVDDrives req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IHost_USCOREgetDVDDrivesResponse resp;
if (!(soaprc = soap_call___vbox__IHost_USCOREgetDVDDrives(&soap,
pcszArgEndpoint,
@@ -282,12 +330,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getname"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IMachine_USCOREgetName req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IMachine_USCOREgetNameResponse resp;
if (!(soaprc = soap_call___vbox__IMachine_USCOREgetName(&soap,
pcszArgEndpoint,
@@ -299,12 +347,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getid"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IMachine_USCOREgetId req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IMachine_USCOREgetIdResponse resp;
if (!(soaprc = soap_call___vbox__IMachine_USCOREgetId(&soap,
pcszArgEndpoint,
@@ -316,12 +364,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "getostypeid"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IMachine_USCOREgetOSTypeId req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IMachine_USCOREgetOSTypeIdResponse resp;
if (!(soaprc = soap_call___vbox__IMachine_USCOREgetOSTypeId(&soap,
pcszArgEndpoint,
@@ -333,12 +381,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "savesettings"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IMachine_USCOREsaveSettings req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IMachine_USCOREsaveSettingsResponse resp;
if (!(soaprc = soap_call___vbox__IMachine_USCOREsaveSettings(&soap,
pcszArgEndpoint,
@@ -350,12 +398,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "setupmetrics"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IPerformanceCollector_USCOREsetupMetrics req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
// req.metricNames[0] = "*";
// req.objects
req.period = 1; // seconds
@@ -379,12 +427,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "querymetricsdata"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IPerformanceCollector_USCOREqueryMetricsData req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
// req.metricNames[0] = "*";
// req.objects
_vbox__IPerformanceCollector_USCOREqueryMetricsDataResponse resp;
@@ -406,12 +454,12 @@ int main(int argc, char* argv[])
}
else if (!strcmp(pcszMode, "release"))
{
- if (argc < 3)
+ if (argc < 2 + ap)
std::cout << "Not enough arguments for \"" << pcszMode << "\" mode.\n";
else
{
_vbox__IManagedObjectRef_USCORErelease req;
- req._USCOREthis = argv[2];
+ req._USCOREthis = argv[ap + 1];
_vbox__IManagedObjectRef_USCOREreleaseResponse resp;
if (!(soaprc = soap_call___vbox__IManagedObjectRef_USCORErelease(&soap,
pcszArgEndpoint,
@@ -434,13 +482,19 @@ int main(int argc, char* argv[])
{
std::cout << "Bad object ID: " << soap.fault->detail->vbox__InvalidObjectFault->badObjectID << "\n";
}
- if (soap.fault->detail->vbox__RuntimeFault)
+ else if (soap.fault->detail->vbox__RuntimeFault)
{
std::cout << "Result code: 0x" << std::hex << soap.fault->detail->vbox__RuntimeFault->resultCode << "\n";
std::cout << "Text: " << std::hex << soap.fault->detail->vbox__RuntimeFault->text << "\n";
std::cout << "Component: " << std::hex << soap.fault->detail->vbox__RuntimeFault->component << "\n";
std::cout << "Interface ID: " << std::hex << soap.fault->detail->vbox__RuntimeFault->interfaceID << "\n";
}
+ else
+ {
+ // generic fault
+ std::cerr << "Generic fault message:\n";
+ soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
+ }
}
else
{
diff --git a/src/VBox/RDP/client/Makefile.kmk b/src/VBox/RDP/client/Makefile.kmk
index ffa84d760..e27a087b2 100644
--- a/src/VBox/RDP/client/Makefile.kmk
+++ b/src/VBox/RDP/client/Makefile.kmk
@@ -54,9 +54,11 @@ ifdef VBOX_WITH_LINUX_COMPILER_H
rdesktop-vrdp_DEFS.linux += VBOX_WITH_LINUX_COMPILER_H
endif
# @todo once rdp proxy is available on Solaris, add WITH_RDPUSB=1
+# snv_166+ dirent.h: defines dd_fd only if __USE_LEGACY_PROTOTYPES__ is defined, otherwise uses d_fd, let's just
+# define __USE_LEGACY_PROTOTYPES__ until our buildbox is updated sufficiently
rdesktop-vrdp_DEFS.solaris = \
HAVE_SYS_FILIO_H=1 RDPSND_SUN=1 HAVE_ICONV_H=1 ICONV_CONST=const STAT_STATVFS64=1 _FILE_OFFSET_BITS=64 \
- DIR_FD_MEMBER_NAME=dd_fd HAVE_SYS_VFS_H=1 HAVE_SYS_STATFS_H=1
+ DIR_FD_MEMBER_NAME=dd_fd __USE_LEGACY_PROTOTYPES__ HAVE_SYS_VFS_H=1 HAVE_SYS_STATFS_H=1
rdesktop-vrdp_DEFS.freebsd = \
RDPSND_OSS=1 HAVE_ICONV_H=1 ICONV_CONST=const HAVE_SYS_STATVFS_H=1 _FILE_OFFSET_BITS=64 HAVE_DIRFD=1
diff --git a/src/VBox/Runtime/Makefile.kmk b/src/VBox/Runtime/Makefile.kmk
index d10888f56..fe0dab178 100644
--- a/src/VBox/Runtime/Makefile.kmk
+++ b/src/VBox/Runtime/Makefile.kmk
@@ -362,7 +362,6 @@ RuntimeR3_SOURCES = \
common/string/RTStrCatP.cpp \
common/string/RTStrCatPEx.cpp \
common/string/RTStrCmp.cpp \
- common/string/RTStrConvertHexBytes.cpp \
common/string/RTStrCopy.cpp \
common/string/RTStrCopyEx.cpp \
common/string/RTStrCopyP.cpp \
@@ -379,6 +378,7 @@ RuntimeR3_SOURCES = \
common/string/strformatnum.cpp \
common/string/strformatrt.cpp \
common/string/strformattype.cpp \
+ common/string/strhash1.cpp \
common/string/stringalloc.cpp \
common/string/strprintf.cpp \
common/string/strspace.cpp \
@@ -1260,8 +1260,7 @@ VBoxRT_INCS = $(RuntimeR3_INCS)
VBoxRT_INCS.$(KBUILD_TARGET) = $(RuntimeR3_INCS.$(KBUILD_TARGET))
VBoxRT_INCS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH) = $(RuntimeR3_INCS.$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH))
VBoxRT_LIBS = \
- $(PATH_STAGE_LIB)/VBox-liblzf$(VBOX_SUFF_LIB) \
- $(SDK_VBOX_ZLIB_LIBS)
+ $(PATH_STAGE_LIB)/VBox-liblzf$(VBOX_SUFF_LIB)
if1of ($(KBUILD_TARGET_ARCH), amd64 x86)
VBoxRT_LIBS += \
$(PATH_STAGE_LIB)/SUPR3$(VBOX_SUFF_LIB)
@@ -1274,6 +1273,8 @@ ifndef SDK_VBOX_LIBXML2_LIBS
VBoxRT_LIBS += \
$(PATH_STAGE_LIB)/VBox-libxml2$(VBOX_SUFF_LIB)
endif
+VBoxRT_LIBS += \
+ $(SDK_VBOX_ZLIB_LIBS)
ifndef SDK_VBOX_OPENSSL_LIBS
VBoxRT_LIBS += \
$(PATH_STAGE_LIB)/VBox-libcrypto$(VBOX_SUFF_LIB) \
@@ -1471,6 +1472,7 @@ RuntimeR0_SOURCES = \
common/misc/sanity-cpp.cpp \
common/misc/term.cpp \
common/path/RTPathFilename.cpp \
+ common/string/strhash1.cpp \
common/string/strncmp.cpp \
common/string/strpbrk.cpp \
common/string/RTStrCat.cpp \
@@ -1636,6 +1638,7 @@ RuntimeR0Drv_SOURCES = \
common/string/strformatnum.cpp \
common/string/strformatrt.cpp \
common/string/strformattype.cpp \
+ common/string/strhash1.cpp \
common/string/strprintf.cpp \
common/string/strtonum.cpp \
common/string/stringalloc.cpp \
diff --git a/src/VBox/Runtime/VBox/VBoxRTDeps.cpp b/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
index 8e84441fa..5b8c3902c 100644
--- a/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
+++ b/src/VBox/Runtime/VBox/VBoxRTDeps.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * 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;
@@ -43,6 +43,7 @@
#include <openssl/x509.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>
+#include <openssl/rand.h>
/*******************************************************************************
@@ -62,16 +63,24 @@ PFNRT g_VBoxRTDeps[] =
(PFNRT)PEM_read_bio_X509,
(PFNRT)PEM_read_bio_PrivateKey,
(PFNRT)X509_free,
+ (PFNRT)X509_verify_cert_error_string,
+ (PFNRT)i2d_X509,
(PFNRT)i2d_X509,
(PFNRT)RSA_generate_key,
+ (PFNRT)RAND_load_file,
+ (PFNRT)CRYPTO_set_dynlock_create_callback,
+ (PFNRT)CRYPTO_set_dynlock_lock_callback,
+ (PFNRT)CRYPTO_set_dynlock_destroy_callback,
(PFNRT)RTAssertShouldPanic,
(PFNRT)ASMAtomicReadU64,
(PFNRT)ASMAtomicCmpXchgU64,
(PFNRT)RTBldCfgRevision,
(PFNRT)SSL_free,
(PFNRT)SSL_library_init,
+ (PFNRT)SSL_load_error_strings,
(PFNRT)SSL_CTX_free,
(PFNRT)SSL_CTX_use_certificate_file,
+ (PFNRT)SSLv23_method,
(PFNRT)TLSv1_server_method,
NULL
};
diff --git a/src/VBox/Runtime/VBox/VBoxRTImp.def b/src/VBox/Runtime/VBox/VBoxRTImp.def
index 3b672a047..b9e56258c 100644
--- a/src/VBox/Runtime/VBox/VBoxRTImp.def
+++ b/src/VBox/Runtime/VBox/VBoxRTImp.def
@@ -637,6 +637,7 @@ EXPORTS
RTLogSetBuffering
RTLogSetCustomPrefixCallback
RTLogSetDefaultInstance
+ RTLogSetGroupLimit
RTLogWriteCom
RTLogWriteDebugger
RTLogWriteStdErr
diff --git a/src/VBox/Runtime/common/checksum/manifest2.cpp b/src/VBox/Runtime/common/checksum/manifest2.cpp
index 534d08d9b..c08b991fa 100644
--- a/src/VBox/Runtime/common/checksum/manifest2.cpp
+++ b/src/VBox/Runtime/common/checksum/manifest2.cpp
@@ -126,7 +126,7 @@ typedef struct RTMANIFESTWRITESTDATTR
/**
- * Argument package used by RTManifestEqualsEx to pass it's arguments to the
+ * Argument package used by RTManifestEqualsEx to pass its arguments to the
* enumeration callback functions.
*/
typedef struct RTMANIFESTEQUALS
@@ -165,6 +165,20 @@ typedef struct RTMANIFESTEQUALS
/** Pointer to an RTManifestEqualEx argument packet. */
typedef RTMANIFESTEQUALS *PRTMANIFESTEQUALS;
+/**
+ * Argument package used by rtMainfestQueryAttrWorker to pass its search
+ * criteria to rtMainfestQueryAttrEnumCallback and get a result back.
+ */
+typedef struct RTMANIFESTQUERYATTRARGS
+{
+ /** The attribute types we're hunting for. */
+ uint32_t fType;
+ /** What we've found. */
+ PRTMANIFESTATTR pAttr;
+} RTMANIFESTQUERYATTRARGS;
+/** Pointer to a rtMainfestQueryAttrEnumCallback argument packet. */
+typedef RTMANIFESTQUERYATTRARGS *PRTMANIFESTQUERYATTRARGS;
+
/**
* Creates an empty manifest.
@@ -750,6 +764,102 @@ RTDECL(int) RTManifestUnsetAttr(RTMANIFEST hManifest, const char *pszAttr)
/**
+ * Callback employed by rtManifestQueryAttrWorker to search by attribute type.
+ *
+ * @returns VINF_SUCCESS or VINF_CALLBACK_RETURN.
+ * @param pStr The attribute string node.
+ * @param pvUser The argument package.
+ */
+static DECLCALLBACK(int) rtMainfestQueryAttrEnumCallback(PRTSTRSPACECORE pStr, void *pvUser)
+{
+ PRTMANIFESTATTR pAttr = (PRTMANIFESTATTR)pStr;
+ PRTMANIFESTQUERYATTRARGS pArgs = (PRTMANIFESTQUERYATTRARGS)pvUser;
+
+ if (pAttr->fType & pArgs->fType)
+ {
+ pArgs->pAttr = pAttr;
+ return VINF_CALLBACK_RETURN;
+ }
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker common to RTManifestQueryAttr and RTManifestEntryQueryAttr.
+ *
+ * @returns IPRT status code.
+ * @param pEntry The entry.
+ * @param pszAttr The attribute name. If NULL, it will be
+ * selected by @a fType alone.
+ * @param fType The attribute types the entry should match. Pass
+ * Pass RTMANIFEST_ATTR_ANY match any. If more
+ * than one is given, the first matching one is
+ * returned.
+ * @param pszValue Where to return value.
+ * @param cbValue The size of the buffer @a pszValue points to.
+ * @param pfType Where to return the attribute type value.
+ */
+static int rtManifestQueryAttrWorker(PRTMANIFESTENTRY pEntry, const char *pszAttr, uint32_t fType,
+ char *pszValue, size_t cbValue, uint32_t *pfType)
+{
+ /*
+ * Find the requested attribute.
+ */
+ PRTMANIFESTATTR pAttr;
+ if (pszAttr)
+ {
+ /* By name. */
+ pAttr = (PRTMANIFESTATTR)RTStrSpaceGet(&pEntry->Attributes, pszAttr);
+ if (!pAttr)
+ return VERR_MANIFEST_ATTR_NOT_FOUND;
+ if (!(pAttr->fType & fType))
+ return VERR_MANIFEST_ATTR_TYPE_MISMATCH;
+ }
+ else
+ {
+ /* By type. */
+ RTMANIFESTQUERYATTRARGS Args;
+ Args.fType = fType;
+ Args.pAttr = NULL;
+ int rc = RTStrSpaceEnumerate(&pEntry->Attributes, rtMainfestQueryAttrEnumCallback, &Args);
+ AssertRCReturn(rc, rc);
+ pAttr = Args.pAttr;
+ if (!pAttr)
+ return VERR_MANIFEST_ATTR_TYPE_NOT_FOUND;
+ }
+
+ /*
+ * Set the return values.
+ */
+ if (cbValue || pszValue)
+ {
+ size_t cbNeeded = strlen(pAttr->pszValue) + 1;
+ if (cbNeeded > cbValue)
+ return VERR_BUFFER_OVERFLOW;
+ memcpy(pszValue, pAttr->pszValue, cbNeeded);
+ }
+
+ if (pfType)
+ *pfType = pAttr->fType;
+
+ return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTManifestQueryAttr(RTMANIFEST hManifest, const char *pszAttr, uint32_t fType,
+ char *pszValue, size_t cbValue, uint32_t *pfType)
+{
+ RTMANIFESTINT *pThis = hManifest;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
+ AssertPtrNull(pszAttr);
+ AssertPtr(pszValue);
+
+ return rtManifestQueryAttrWorker(&pThis->SelfEntry, pszAttr, fType, pszValue, cbValue, pfType);
+}
+
+
+/**
* Validates the name entry.
*
* @returns IPRT status code.
@@ -942,6 +1052,32 @@ RTDECL(int) RTManifestEntryUnsetAttr(RTMANIFEST hManifest, const char *pszEntry,
}
+RTDECL(int) RTManifestEntryQueryAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr, uint32_t fType,
+ char *pszValue, size_t cbValue, uint32_t *pfType)
+{
+ RTMANIFESTINT *pThis = hManifest;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE);
+ AssertPtr(pszEntry);
+ AssertPtrNull(pszAttr);
+ AssertPtr(pszValue);
+
+ /*
+ * Look up the entry.
+ */
+ bool fNeedNormalization;
+ size_t cchEntry;
+ int rc = rtManifestValidateNameEntry(pszEntry, &fNeedNormalization, &cchEntry);
+ AssertRCReturn(rc, rc);
+
+ PRTMANIFESTENTRY pEntry;
+ rc = rtManifestGetEntry(pThis, pszEntry, fNeedNormalization, cchEntry, &pEntry);
+ if (RT_SUCCESS(rc))
+ rc = rtManifestQueryAttrWorker(pEntry, pszAttr, fType, pszValue, cbValue, pfType);
+ return rc;
+}
+
+
/**
* Adds a new entry to a manifest.
*
diff --git a/src/VBox/Runtime/common/checksum/manifest3.cpp b/src/VBox/Runtime/common/checksum/manifest3.cpp
index 393c130e6..f225fa339 100644
--- a/src/VBox/Runtime/common/checksum/manifest3.cpp
+++ b/src/VBox/Runtime/common/checksum/manifest3.cpp
@@ -529,6 +529,7 @@ RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsI
break;
rtManifestHashesUpdate(pHashes, pvBuf, cbRead);
}
+ RTMemTmpFree(pvBuf);
if (RT_SUCCESS(rc))
{
/*
diff --git a/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h b/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
index 755ef6a94..2262251dd 100644
--- a/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
+++ b/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
@@ -275,7 +275,7 @@ static int RTLDRELF_NAME(RelocateSection)(PRTLDRMODELF pModElf, Elf_Addr BaseAdd
/*
* Get the symbol.
*/
- const Elf_Sym *pSym;
+ const Elf_Sym *pSym = NULL;
Elf_Addr SymValue = 0; /* shut up gcc-4 */
int rc = RTLDRELF_NAME(Symbol)(pModElf, BaseAddr, pfnGetImport, pvUser, ELF_R_SYM(paRels[iRel].r_info), &pSym, &SymValue);
if (RT_FAILURE(rc))
diff --git a/src/VBox/Runtime/common/misc/s3.cpp b/src/VBox/Runtime/common/misc/s3.cpp
index c49907011..0f5de228a 100644
--- a/src/VBox/Runtime/common/misc/s3.cpp
+++ b/src/VBox/Runtime/common/misc/s3.cpp
@@ -376,7 +376,7 @@ static xmlNodePtr rtS3FindNode(xmlNodePtr pNode, const char *pszName)
static int rtS3ReadXmlFromMemory(PRTS3TMPMEMCHUNK pChunk, const char* pszRootElement, xmlDocPtr *ppDoc, xmlNodePtr *ppCur)
{
- *ppDoc = xmlReadMemory(pChunk->pszMem, (int)pChunk->cSize, "", "ISO-8859-1", XML_PARSE_NOBLANKS);
+ *ppDoc = xmlReadMemory(pChunk->pszMem, (int)pChunk->cSize, "", "ISO-8859-1", XML_PARSE_NOBLANKS | XML_PARSE_NONET);
if (*ppDoc == NULL)
return VERR_PARSE_ERROR;
diff --git a/src/VBox/Runtime/common/string/base64.cpp b/src/VBox/Runtime/common/string/base64.cpp
index 58869fe38..514d44742 100644
--- a/src/VBox/Runtime/common/string/base64.cpp
+++ b/src/VBox/Runtime/common/string/base64.cpp
@@ -423,8 +423,7 @@ RTDECL(size_t) RTBase64EncodedLength(size_t cbData)
cch += 8;
cch /= 6;
- cch += (cch / RTBASE64_LINE_LEN) * RTBASE64_EOL_SIZE;
- cch -= (cch % RTBASE64_LINE_LEN) == 0;
+ cch += ((cch - 1) / RTBASE64_LINE_LEN) * RTBASE64_EOL_SIZE;
return cch;
}
@@ -433,8 +432,7 @@ RTDECL(size_t) RTBase64EncodedLength(size_t cbData)
cch += 8;
cch /= 6;
- cch += (cch / RTBASE64_LINE_LEN) * RTBASE64_EOL_SIZE;
- cch -= (cch % RTBASE64_LINE_LEN) == 0;
+ cch += ((cch - 1) / RTBASE64_LINE_LEN) * RTBASE64_EOL_SIZE;
return cch;
}
RT_EXPORT_SYMBOL(RTBase64EncodedLength);
diff --git a/src/VBox/Runtime/common/string/ministring.cpp b/src/VBox/Runtime/common/string/ministring.cpp
index bca107c9f..f5db7bbf7 100644
--- a/src/VBox/Runtime/common/string/ministring.cpp
+++ b/src/VBox/Runtime/common/string/ministring.cpp
@@ -212,16 +212,43 @@ size_t RTCString::find(const char *pcszFind, size_t pos /*= 0*/) const
return npos;
}
-void RTCString::findReplace(char cFind, char cReplace)
+void RTCString::findReplace(char chFind, char chReplace)
{
+ Assert((unsigned int)chFind < 128U);
+ Assert((unsigned int)chReplace < 128U);
+
for (size_t i = 0; i < length(); ++i)
{
char *p = &m_psz[i];
- if (*p == cFind)
- *p = cReplace;
+ if (*p == chFind)
+ *p = chReplace;
}
}
+size_t RTCString::count(char ch) const
+{
+ Assert((unsigned int)ch < 128U);
+
+ size_t c = 0;
+ const char *psz = m_psz;
+ char chCur;
+ while ((chCur = *psz++) != '\0')
+ if (chCur == ch)
+ c++;
+ return c;
+}
+
+#if 0 /** @todo implement these when needed. */
+size_t RTCString::count(const char *psz, CaseSensitivity cs = CaseSensitive) const
+{
+}
+
+size_t RTCString::count(const RTCString *pStr, CaseSensitivity cs = CaseSensitive) const
+{
+
+}
+#endif
+
RTCString RTCString::substrCP(size_t pos /*= 0*/, size_t n /*= npos*/) const
{
RTCString ret;
diff --git a/src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp b/src/VBox/Runtime/common/string/strhash1.cpp
index 841ff4436..840f81dac 100644
--- a/src/VBox/Runtime/common/string/RTStrConvertHexBytes.cpp
+++ b/src/VBox/Runtime/common/string/strhash1.cpp
@@ -1,10 +1,10 @@
-/* $Id: RTStrConvertHexBytes.cpp $ */
+/* $Id: strhash1.cpp $ */
/** @file
- * IPRT - RTStrConvertHexBytes.
+ * IPRT - String Hashing by Algorithm \#1.
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 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;
@@ -31,16 +31,42 @@
#include "internal/iprt.h"
#include <iprt/string.h>
-#include <iprt/assert.h>
-#include <iprt/err.h>
+#include "internal/strhash.h"
-RTDECL(int) RTStrConvertHexBytes(char const *pszHex, void *pv, size_t cb, uint32_t fFlags)
+RTDECL(uint32_t) RTStrHash1(const char *pszString)
{
- AssertPtrReturn(pszHex, VERR_INVALID_POINTER);
- AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
+ size_t cchIgnored;
+ return sdbm(pszString, &cchIgnored);
+}
+
+
+RTDECL(uint32_t) RTStrHash1N(const char *pszString, size_t cchString)
+{
+ size_t cchIgnored;
+ return sdbmN(pszString, cchString, &cchIgnored);
+}
+
- AssertFailed();
- return VERR_NOT_IMPLEMENTED;
+RTDECL(uint32_t) RTStrHash1ExN(size_t cPairs, ...)
+{
+ va_list va;
+ va_start(va, cPairs);
+ uint32_t uHash = RTStrHash1ExNV(cPairs, va);
+ va_end(va);
+ return uHash;
+}
+
+
+RTDECL(uint32_t) RTStrHash1ExNV(size_t cPairs, va_list va)
+{
+ uint32_t uHash = 0;
+ for (uint32_t i = 0; i < cPairs; i++)
+ {
+ const char *psz = va_arg(va, const char *);
+ size_t cch = va_arg(va, size_t);
+ uHash += sdbmIncN(psz, cch, uHash);
+ }
+ return uHash;
}
diff --git a/src/VBox/Runtime/common/string/strtonum.cpp b/src/VBox/Runtime/common/string/strtonum.cpp
index 60285fd06..67a00528c 100644
--- a/src/VBox/Runtime/common/string/strtonum.cpp
+++ b/src/VBox/Runtime/common/string/strtonum.cpp
@@ -968,3 +968,41 @@ RTDECL(int8_t) RTStrToInt8(const char *pszValue)
}
RT_EXPORT_SYMBOL(RTStrToInt8);
+
+RTDECL(int) RTStrConvertHexBytes(char const *pszHex, void *pv, size_t cb, uint32_t fFlags)
+{
+ AssertPtrReturn(pszHex, VERR_INVALID_POINTER);
+ AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
+
+ size_t cbDst = cb;
+ uint8_t *pbDst = (uint8_t *)pv;
+ const char *pszSrc = pszHex;
+ for (;;)
+ {
+ /* Pick the next two digit from the string. */
+ char ch = *pszSrc++;
+ unsigned char uchDigit1 = g_auchDigits[(unsigned char)ch];
+ if (uchDigit1 >= 16)
+ {
+ if (!ch)
+ return cbDst == 0 ? VINF_SUCCESS : VERR_BUFFER_UNDERFLOW;
+
+ while (ch == ' ' || ch == '\t')
+ ch = *pszSrc++;
+ return ch ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
+ }
+
+ ch = *pszSrc++;
+ unsigned char uchDigit2 = g_auchDigits[(unsigned char)ch];
+ if (uchDigit2 >= 16)
+ return VERR_UNEVEN_INPUT;
+
+ /* Add the byte to the output buffer. */
+ if (!cbDst)
+ return VERR_BUFFER_OVERFLOW;
+ cbDst--;
+ *pbDst++ = (uchDigit1 << 4) | uchDigit2;
+ }
+}
+RT_EXPORT_SYMBOL(RTStrConvertHexBytes);
+
diff --git a/src/VBox/Runtime/common/table/avl_RemoveNode.cpp.h b/src/VBox/Runtime/common/table/avl_RemoveNode.cpp.h
new file mode 100644
index 000000000..179e1359b
--- /dev/null
+++ b/src/VBox/Runtime/common/table/avl_RemoveNode.cpp.h
@@ -0,0 +1,144 @@
+/* $Id: avl_RemoveNode.cpp.h $ */
+/** @file
+ * kAVLRemove2 - Remove specific node (by pointer) from an AVL tree.
+ */
+
+/*
+ * Copyright (C) 2001-2002 knut st. osmundsen (bird-src-spam@anduin.net)
+ *
+ * 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.
+ */
+
+
+/**
+ * Removes the specified node from the tree.
+ *
+ * @returns Pointer to the removed node (NULL if not in the tree)
+ * @param ppTree Pointer to the AVL-tree root structure.
+ * @param pNode Pointer to the node to be removed.
+ *
+ * @remark This implementation isn't the most efficient, but it's relatively
+ * short and easier to manage.
+ */
+KAVL_DECL(PKAVLNODECORE) KAVL_FN(RemoveNode)(PPKAVLNODECORE ppTree, PKAVLNODECORE pNode)
+{
+#ifdef KAVL_EQUAL_ALLOWED
+ /*
+ * Find the right node by key together with the parent node.
+ */
+ KAVLKEY const Key = pNode->Key;
+ PKAVLNODECORE pParent = NULL;
+ PKAVLNODECORE pCurNode = KAVL_GET_POINTER_NULL(ppTree);
+ if (!pCurNode)
+ return NULL;
+ while (KAVL_NE(pCurNode->Key, Key))
+ {
+ pParent = pCurNode;
+ if (KAVL_G(pCurNode->Key, Key))
+ {
+ if (pCurNode->pLeft != KAVL_NULL)
+ pCurNode = KAVL_GET_POINTER(&pCurNode->pLeft);
+ else
+ return NULL;
+ }
+ else
+ {
+ if (pCurNode->pRight != KAVL_NULL)
+ pCurNode = KAVL_GET_POINTER(&pCurNode->pRight);
+ else
+ return NULL;
+ }
+ }
+
+ if (pCurNode != pNode)
+ {
+ /*
+ * It's not the one we want, but it could be in the duplicate list.
+ */
+ while (pCurNode->pList != KAVL_NULL)
+ {
+ PKAVLNODECORE pNext = KAVL_GET_POINTER(&pCurNode->pList);
+ if (pNext == pNode)
+ {
+ if (pNode->pList != KAVL_NULL)
+ KAVL_SET_POINTER(&pCurNode->pList, KAVL_GET_POINTER(&pNode->pList));
+ else
+ pCurNode->pList = KAVL_NULL;
+ pNode->pList = KAVL_NULL;
+ return pNode;
+ }
+ pCurNode = pNext;
+ }
+ return NULL;
+ }
+
+ /*
+ * Ok, it's the one we want alright.
+ *
+ * Simply remove it if it's the only one with they Key, if there are
+ * duplicates we'll have to unlink it and insert the first duplicate
+ * in our place.
+ */
+ if (pNode->pList == KAVL_NULL)
+ KAVL_FN(Remove)(ppTree, pNode->Key);
+ else
+ {
+ PKAVLNODECORE pNewUs = KAVL_GET_POINTER(&pNode->pList);
+
+ pNewUs->uchHeight = pNode->uchHeight;
+
+ if (pNode->pLeft != KAVL_NULL)
+ KAVL_SET_POINTER(&pNewUs->pLeft, KAVL_GET_POINTER(&pNode->pLeft));
+ else
+ pNewUs->pLeft = KAVL_NULL;
+
+ if (pNode->pRight != KAVL_NULL)
+ KAVL_SET_POINTER(&pNewUs->pRight, KAVL_GET_POINTER(&pNode->pRight));
+ else
+ pNewUs->pRight = KAVL_NULL;
+
+ if (pParent)
+ {
+ if (KAVL_GET_POINTER_NULL(&pParent->pLeft) == pNode)
+ KAVL_SET_POINTER(&pParent->pLeft, pNewUs);
+ else
+ KAVL_SET_POINTER(&pParent->pRight, pNewUs);
+ }
+ else
+ KAVL_SET_POINTER(ppTree, pNewUs);
+ }
+
+ return pNode;
+
+#else
+ /*
+ * Delete it, if we got the wrong one, reinsert it.
+ *
+ * This ASSUMS that the caller is NOT going to hand us a lot
+ * of wrong nodes but just uses this API for his convenience.
+ */
+ KAVLNODE *pRemovedNode = KAVL_FN(Remove)(pRoot, pNode->Key);
+ if (pRemovedNode == pNode)
+ return pRemovedNode;
+
+ KAVL_FN(Insert)(pRoot, pRemovedNode);
+ return NULL;
+#endif
+}
+
+
diff --git a/src/VBox/Runtime/common/table/avllu32.cpp b/src/VBox/Runtime/common/table/avllu32.cpp
index 587a5feb3..45bc2a2f0 100644
--- a/src/VBox/Runtime/common/table/avllu32.cpp
+++ b/src/VBox/Runtime/common/table/avllu32.cpp
@@ -70,6 +70,7 @@ static const char szFileId[] = "Id: kAVLULInt.c,v 1.4 2003/02/13 02:02:38 bird E
#include "avl_Base.cpp.h"
#include "avl_Get.cpp.h"
#include "avl_GetBestFit.cpp.h"
+#include "avl_RemoveNode.cpp.h"
#include "avl_RemoveBestFit.cpp.h"
#include "avl_DoWithAll.cpp.h"
#include "avl_Destroy.cpp.h"
diff --git a/src/VBox/Runtime/generic/timerlr-generic.cpp b/src/VBox/Runtime/generic/timerlr-generic.cpp
index 6019356f7..b7400d5a9 100644
--- a/src/VBox/Runtime/generic/timerlr-generic.cpp
+++ b/src/VBox/Runtime/generic/timerlr-generic.cpp
@@ -235,6 +235,24 @@ RTDECL(int) RTTimerLRStop(RTTIMERLR hTimerLR)
}
RT_EXPORT_SYMBOL(RTTimerLRStop);
+RTDECL(int) RTTimerLRChangeInterval(RTTIMERLR hTimerLR, uint64_t u64NanoInterval)
+{
+ PRTTIMERLRINT pThis = hTimerLR;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTTIMERLR_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(!pThis->fDestroyed, VERR_INVALID_HANDLE);
+
+ if (u64NanoInterval && u64NanoInterval < 100*1000*1000)
+ return VERR_INVALID_PARAMETER;
+
+ uint64_t u64Now = RTTimeNanoTS();
+ ASMAtomicWriteU64(&pThis->iTick, 0);
+ ASMAtomicWriteU64(&pThis->u64StartTS, u64Now);
+ ASMAtomicWriteU64(&pThis->u64NextTS, u64Now);
+ ASMAtomicWriteU64(&pThis->u64NanoInterval, u64NanoInterval);
+ return RTSemEventSignal(pThis->hEvent);
+}
+RT_EXPORT_SYMBOL(RTTimerLRChangeInterval);
static DECLCALLBACK(int) rtTimerLRThread(RTTHREAD hThread, void *pvUser)
{
diff --git a/src/VBox/Runtime/include/internal/strhash.h b/src/VBox/Runtime/include/internal/strhash.h
index 85fd2a867..a7399d061 100644
--- a/src/VBox/Runtime/include/internal/strhash.h
+++ b/src/VBox/Runtime/include/internal/strhash.h
@@ -75,6 +75,7 @@ DECLINLINE(uint32_t) sdbmN(const char *str, size_t cchMax, size_t *pcch)
return hash;
}
+
/**
* Incremental hashing.
*/
@@ -89,6 +90,20 @@ DECLINLINE(uint32_t) sdbmInc(const char *str, uint32_t hash)
return hash;
}
+/**
+ * Incremental hashing with length limitation.
+ */
+DECLINLINE(uint32_t) sdbmIncN(const char *psz, size_t cchMax, uint32_t uHash)
+{
+ uint8_t *pu8 = (uint8_t *)psz;
+ int c;
+
+ while ((c = *pu8++) && cchMax-- > 0)
+ uHash = c + (uHash << 6) + (uHash << 16) - uHash;
+
+ return uHash;
+}
+
#endif
diff --git a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
index 242229801..425c1cccf 100644
--- a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
+++ b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
@@ -1,4 +1,4 @@
-/* $Revision: 70988 $ */
+/* $Revision: 75790 $ */
/** @file
* IPRT - Ring-0 Memory Objects, Linux.
*/
@@ -743,6 +743,99 @@ static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYP
}
+/**
+ * Translates a kernel virtual address to a linux page structure by walking the
+ * page tables.
+ *
+ * @note We do assume that the page tables will not change as we are walking
+ * them. This assumption is rather forced by the fact that I could not
+ * immediately see any way of preventing this from happening. So, we
+ * take some extra care when accessing them.
+ *
+ * Because of this, we don't want to use this function on memory where
+ * attribute changes to nearby pages is likely to cause large pages to
+ * be used or split up. So, don't use this for the linear mapping of
+ * physical memory.
+ *
+ * @returns Pointer to the page structur or NULL if it could not be found.
+ * @param pv The kernel virtual address.
+ */
+static struct page *rtR0MemObjLinuxVirtToPage(void *pv)
+{
+ unsigned long ulAddr = (unsigned long)pv;
+ unsigned long pfn;
+ struct page *pPage;
+ pte_t *pEntry;
+ union
+ {
+ pgd_t Global;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+ pud_t Upper;
+#endif
+ pmd_t Middle;
+ pte_t Entry;
+ } u;
+
+ /* Should this happen in a situation this code will be called in? And if
+ * so, can it change under our feet? See also
+ * "Documentation/vm/active_mm.txt" in the kernel sources. */
+ if (RT_UNLIKELY(!current->active_mm))
+ return NULL;
+ u.Global = *pgd_offset(current->active_mm, ulAddr);
+ if (RT_UNLIKELY(pgd_none(u.Global)))
+ return NULL;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+ u.Upper = *pud_offset(&u.Global, ulAddr);
+ if (RT_UNLIKELY(pud_none(u.Upper)))
+ return NULL;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+ if (pud_large(u.Upper))
+ {
+ pPage = pud_page(u.Upper);
+ AssertReturn(pPage, NULL);
+ pfn = page_to_pfn(pPage); /* doing the safe way... */
+ pfn += (ulAddr >> PAGE_SHIFT) & ((UINT32_C(1) << (PUD_SHIFT - PAGE_SHIFT)) - 1);
+ return pfn_to_page(pfn);
+ }
+# endif
+
+ u.Middle = *pmd_offset(&u.Upper, ulAddr);
+#else /* < 2.6.11 */
+ u.Middle = *pmd_offset(&u.Global, ulAddr);
+#endif /* < 2.6.11 */
+ if (RT_UNLIKELY(pmd_none(u.Middle)))
+ return NULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
+ if (pmd_large(u.Middle))
+ {
+ pPage = pmd_page(u.Middle);
+ AssertReturn(pPage, NULL);
+ pfn = page_to_pfn(pPage); /* doing the safe way... */
+ pfn += (ulAddr >> PAGE_SHIFT) & ((UINT32_C(1) << (PMD_SHIFT - PAGE_SHIFT)) - 1);
+ return pfn_to_page(pfn);
+ }
+#endif
+
+/* As usual, RHEL 3 had pte_offset_map earlier. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) || defined(pte_offset_map)
+ pEntry = pte_offset_map(&u.Middle, ulAddr);
+#else
+ pEntry = pte_offset(&u.Middle, ulAddr);
+#endif
+ if (RT_UNLIKELY(!pEntry))
+ return NULL;
+ u.Entry = *pEntry;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) || defined(pte_offset_map)
+ pte_unmap(pEntry);
+#endif
+
+ if (RT_UNLIKELY(!pte_present(u.Entry)))
+ return NULL;
+ return pte_page(u.Entry);
+}
+
+
DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
{
return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS, cb, uAlignment, PhysHighest);
@@ -886,38 +979,23 @@ DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv,
size_t iPage;
NOREF(fAccess);
+ if ( !RTR0MemKernelIsValidAddr(pv)
+ || !RTR0MemKernelIsValidAddr(pv + cb))
+ return VERR_INVALID_PARAMETER;
+
/*
- * Classify the memory and check that we can deal with it.
+ * The lower part of the kernel memory has a linear mapping between
+ * physical and virtual addresses. So we take a short cut here. This is
+ * assumed to be the cleanest way to handle those addresses (and the code
+ * is well tested, though the test for determining it is not very nice).
+ * If we ever decide it isn't we can still remove it.
*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
- fLinearMapping = virt_addr_valid(pvLast) && virt_addr_valid(pv);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)
- fLinearMapping = VALID_PAGE(virt_to_page(pvLast)) && VALID_PAGE(virt_to_page(pv));
+#if 0
+ fLinearMapping = (unsigned long)pvLast < VMALLOC_START;
#else
-# error "not supported"
+ fLinearMapping = (unsigned long)pv >= (unsigned long)__va(0)
+ && (unsigned long)pvLast < (unsigned long)high_memory;
#endif
- /*
- * kmap()'ed memory. Only relevant for 32-bit Linux kernels with HIGHMEM
- * enabled. Unfortunately there is no easy way to retrieve the page object
- * for such temporarily mapped memory, virt_to_page() does not work here.
- * There is even no function to check if a virtual address is inside the
- * kmap() area or not :-( kmap_atomic_to_page() looks promising but the test
- * 'if (vaddr < FIXADDR_START)' if wrong -- the kmap() area is located
- * below the fixmap area. vmalloc_to_page() would work but is only allowed
- * for vmalloc'ed memory.
- */
-#ifdef CONFIG_HIGHMEM
- if (pv < PKMAP_BASE + LAST_PKMAP*PAGE_SIZE && pvLast >= PKMAP_BASE)
- return VERR_INVALID_PARAMETER;
-#endif
- if (!fLinearMapping)
- {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 19)
- if ( !RTR0MemKernelIsValidAddr(pv)
- || !RTR0MemKernelIsValidAddr(pv + cb))
-#endif
- return VERR_INVALID_PARAMETER;
- }
/*
* Allocate the memory object.
@@ -928,17 +1006,16 @@ DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv,
/*
* Gather the pages.
- * We ASSUME all kernel pages are non-swappable.
+ * We ASSUME all kernel pages are non-swappable and non-movable.
*/
rc = VINF_SUCCESS;
pbPage = (uint8_t *)pvLast;
iPage = cPages;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 19)
if (!fLinearMapping)
{
while (iPage-- > 0)
{
- struct page *pPage = vmalloc_to_page(pbPage);
+ struct page *pPage = rtR0MemObjLinuxVirtToPage(pbPage);
if (RT_UNLIKELY(!pPage))
{
rc = VERR_LOCK_FAILED;
@@ -949,7 +1026,6 @@ DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv,
}
}
else
-#endif
{
while (iPage-- > 0)
{
diff --git a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
index 1e8953bc2..c58cec993 100644
--- a/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
+++ b/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
@@ -64,6 +64,9 @@
# define KBUILD_STR(s) #s
# endif
#endif
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+# include <linux/kconfig.h> /* for macro IS_ENABLED */
+# endif
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files
deleted file mode 100644
index 3a20df8bf..000000000
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files
+++ /dev/null
@@ -1,235 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "@(#)Makefile.files 1.159 08/05/26 SMI"
-#
-# This Makefile defines file modules in the directory uts/i86pc
-# and its children. These are the source files which are i86pc
-# "implementation architecture" dependent.
-#
-
-#
-# object lists
-#
-CORE_OBJS += \
- acpi_stubs.o \
- biosdisk.o \
- bios_call.o \
- cbe.o \
- cmi.o \
- cmi_hw.o \
- cms.o \
- confunix.o \
- cpuid.o \
- cpupm.o \
- dis_tables.o \
- ddi_impl.o \
- dtrace_subr.o \
- dvma.o \
- fpu_subr.o \
- fakebop.o \
- graphics.o \
- hardclk.o \
- hat_i86.o \
- hat_kdi.o \
- hment.o \
- hold_page.o \
- hrtimers.o \
- htable.o \
- i86_mmu.o \
- instr_size.o \
- intr.o \
- kboot_mmu.o \
- kdi_subr.o \
- kdi_idt.o \
- kdi_idthdl.o \
- kdi_asm.o \
- lgrpplat.o \
- mach_kdi.o \
- mach_sysconfig.o \
- machdep.o \
- mem_config_stubs.o \
- memnode.o \
- microcode.o \
- microfind.o \
- mlsetup.o \
- mp_call.o \
- mp_implfuncs.o \
- mp_machdep.o \
- mp_pc.o \
- mp_startup.o \
- memscrub.o \
- mpcore.o \
- notes.o \
- pci_bios.o \
- pci_cfgspace.o \
- pci_mech1.o \
- pci_mech2.o \
- pci_neptune.o \
- pci_orion.o \
- pmem.o \
- ppage.o \
- startup.o \
- timestamp.o \
- todpc_subr.o \
- trap.o \
- vm_machdep.o \
- x_call.o
-
-#
-# Add the SMBIOS subsystem object files directly to the list of objects
-# built into unix itself; this is all common code except for smb_dev.c.
-#
-CORE_OBJS += $(SMBIOS_OBJS)
-
-#
-# These get compiled twice:
-# - once in the dboot (direct boot) identity mapped code
-# - once for use during early startup in unix
-#
-BOOT_DRIVER_OBJS = \
- boot_console.o \
- boot_keyboard.o \
- boot_keyboard_table.o \
- boot_vga.o \
- boot_mmu.o
-
-CORE_OBJS += $(BOOT_DRIVER_OBJS)
-
-#
-# locore.o is special. It must be the first file relocated so that it
-# it is relocated just where its name implies.
-#
-SPECIAL_OBJS_32 += \
- locore.o \
- fast_trap_asm.o \
- interrupt.o \
- syscall_asm.o
-
-SPECIAL_OBJS_64 += \
- locore.o \
- fast_trap_asm.o \
- interrupt.o \
- syscall_asm_amd64.o
-
-SPECIAL_OBJS += $(SPECIAL_OBJS_$(CLASS))
-
-#
-# Objects that get compiled into the identity mapped PT_LOAD section of unix
-# to handle the earliest part of booting.
-#
-DBOOT_OBJS_32 =
-
-DBOOT_OBJS_64 += dboot_elfload.o
-
-DBOOT_OBJS += \
- dboot_asm.o \
- dboot_grub.o \
- dboot_printf.o \
- dboot_startkern.o \
- memcpy.o \
- memset.o \
- muldiv.o \
- string.o \
- $(BOOT_DRIVER_OBJS) \
- $(DBOOT_OBJS_$(CLASS))
-
-#
-# driver and misc modules
-#
-GFX_PRIVATE_OBJS += gfx_private.o gfxp_pci.o gfxp_segmap.o \
- gfxp_devmap.o gfxp_vgatext.o gfxp_vm.o vgasubr.o
-ISANEXUS_OBJS += isa.o dma_engine.o i8237A.o
-PCI_E_MISC_OBJS += pcie.o pcie_fault.o
-PCI_E_NEXUS_OBJS += npe.o npe_misc.o
-PCI_E_NEXUS_OBJS += pci_common.o pci_kstats.o pci_tools.o
-PCINEXUS_OBJS += pci.o pci_common.o pci_kstats.o pci_tools.o
-PCPLUSMP_OBJS += apic.o psm_common.o apic_introp.o mp_platform_common.o
-VBI_OBJS += vbi.o
-
-BATTERY_OBJS += battery.o
-include $(SRC)/common/mc/mc-amd/Makefile.mcamd
-MCAMD_OBJS += \
- $(MCAMD_CMN_OBJS) \
- mcamd_drv.o \
- mcamd_dimmcfg.o \
- mcamd_subr.o \
- mcamd_pcicfg.o
-
-CPUDRV_OBJS += cpudrv.o cpudrv_plat.o cpu_acpi.o speedstep.o pwrnow.o
-PPM_OBJS += ppm_subr.o ppm.o ppm_plat.o
-
-ACPIPPM_OBJS += acpippm.o acpisleep.o
-
-ROOTNEX_OBJS += rootnex.o
-TZMON_OBJS += tzmon.o
-UPPC_OBJS += uppc.o psm_common.o
-XSVC_OBJS += xsvc.o
-PV_CMDK_OBJS += pv_cmdk.o
-HVM_BOOTSTRAP_OBJS += hvm_bootstrap.o
-XDF_OBJS += xdf.o
-XNF_OBJS += xnf.o
-XPV_OBJS += xpv_support.o xvdi.o gnttab.o evtchn.o \
- xenbus_comms.o xenbus_client.o xenbus_probe.o xenbus_xs.o \
- hypercall.o hypersubr.o
-XPVD_OBJS += xpvd.o
-
-#
-# Build up defines and paths.
-#
-ALL_DEFS += -Di86pc
-INC_PATH += -I$(UTSBASE)/i86pc -I$(SRC)/common
-
-#
-# Since the assym files are derived, the dependencies must be explicit for
-# all files including this file. (This is only actually required in the
-# instance when the .nse_depinfo file does not exist.) It may seem that
-# the lint targets should also have a similar dependency, but they don't
-# since only C headers are included when #defined(__lint) is true.
-#
-
-ASSYM_DEPS += \
- copy.o \
- desctbls_asm.o \
- ddi_i86_asm.o \
- exception.o \
- fast_trap_asm.o \
- float.o \
- i86_subr.o \
- interrupt.o \
- lock_prim.o \
- locore.o \
- mpcore.o \
- sseblk.o \
- swtch.o \
- syscall_asm.o \
- syscall_asm_amd64.o \
- cpr_wakecode.o
-
-CPR_IMPL_OBJS = cpr_impl.o cpr_wakecode.o
-
-$(KDI_ASSYM_DEPS:%=$(OBJS_DIR)/%): $(DSF_DIR)/$(OBJS_DIR)/kdi_assym.h
-
-ASSYM_DEPS += kdi_asm.o
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files.patch b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files.patch
deleted file mode 100644
index 87e08ed31..000000000
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.files.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- old/usr/src/uts/i86pc/Makefile.files Tue May 27 01:20:43 2008
-+++ new/usr/src/uts/i86pc/Makefile.files Tue May 27 01:20:43 2008
-@@ -23,7 +23,7 @@
- # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- # Use is subject to license terms.
- #
--# ident "@(#)Makefile.files 1.158 08/03/29 SMI"
-+# ident "@(#)Makefile.files 1.159 08/05/26 SMI"
- #
- # This Makefile defines file modules in the directory uts/i86pc
- # and its children. These are the source files which are i86pc
-@@ -167,6 +167,7 @@
- PCI_E_NEXUS_OBJS += pci_common.o pci_kstats.o pci_tools.o
- PCINEXUS_OBJS += pci.o pci_common.o pci_kstats.o pci_tools.o
- PCPLUSMP_OBJS += apic.o psm_common.o apic_introp.o mp_platform_common.o
-+VBI_OBJS += vbi.o
-
- BATTERY_OBJS += battery.o
- include $(SRC)/common/mc/mc-amd/Makefile.mcamd
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared
deleted file mode 100644
index 4e4a54175..000000000
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared
+++ /dev/null
@@ -1,316 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# uts/i86pc/Makefile.i86pc
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "@(#)Makefile.i86pc.shared 1.25 08/05/26 SMI"
-#
-# This makefile contains the common definitions for the i86pc unix
-# and all i86pc implementation architecture dependent modules.
-#
-
-#
-# Machine type (implementation architecture):
-#
-PLATFORM = i86pc
-
-#
-# uname -m value
-#
-UNAME_M = $(PLATFORM)
-
-#
-# Everybody needs to know how to build modstubs.o and to locate unix.o
-#
-UNIX_DIR = $(UTSBASE)/$(PLATFORM)/unix
-GENLIB_DIR = $(UTSBASE)/intel/genunix
-MODSTUBS_DIR = $(UNIX_DIR)
-DSF_DIR = $(UTSBASE)/$(PLATFORM)/genassym
-LINTS_DIR = $(OBJS_DIR)
-LINT_LIB_DIR = $(UTSBASE)/$(PLATFORM)/lint-libs/$(OBJS_DIR)
-GEN_LINT_LIB_DIR = $(UTSBASE)/intel/lint-libs/$(OBJS_DIR)
-
-DTRACESTUBS_O = $(OBJS_DIR)/dtracestubs.o
-DTRACESTUBS = $(OBJS_DIR)/libdtracestubs.so
-
-SYM_MOD = $(OBJS_DIR)/unix.sym
-
-UNIX_O = $(UNIX_DIR)/$(OBJS_DIR)/unix.o
-MODSTUBS_O = $(MODSTUBS_DIR)/$(OBJS_DIR)/modstubs.o
-GENLIB = $(GENLIB_DIR)/$(OBJS_DIR)/libgenunix.so
-LINT_LIB = $(LINT_LIB_DIR)/llib-lunix.ln
-DBOOT_LINT_LIB = $(LINT_LIB_DIR)/llib-ldboot.ln
-GEN_LINT_LIB = $(GEN_LINT_LIB_DIR)/llib-lgenunix.ln
-
-#
-# Include the makefiles which define build rule templates, the
-# collection of files per module, and a few specific flags. Note
-# that order is significant, just as with an include path. The
-# first build rule template which matches the files name will be
-# used. By including these in order from most machine dependent
-# to most machine independent, we allow a machine dependent file
-# to be used in preference over a machine independent version
-# (Such as a machine specific optimization, which preserves the
-# interfaces.)
-#
-include $(UTSTREE)/$(PLATFORM)/Makefile.files
-include $(UTSTREE)/intel/Makefile.files
-include $(UTSTREE)/common/Makefile.files
-
-#
-# Include machine independent rules. Note that this does not imply
-# that the resulting module from rules in Makefile.uts is machine
-# independent. Only that the build rules are machine independent.
-#
-include $(UTSBASE)/Makefile.uts
-
-#
-# Define supported builds
-#
-DEF_BUILDS = $(DEF_BUILDS64) $(DEF_BUILDS32)
-ALL_BUILDS = $(ALL_BUILDS64) $(ALL_BUILDS32)
-
-#
-# x86 or amd64 inline templates
-#
-INLINES_32 = $(UTSBASE)/intel/ia32/ml/ia32.il \
- $(UTSBASE)/$(PLATFORM)/ml/ia32.il
-INLINES_64 = $(UTSBASE)/intel/amd64/ml/amd64.il \
- $(UTSBASE)/$(PLATFORM)/ml/amd64.il
-INLINES += $(INLINES_$(CLASS))
-
-#
-# kernel-specific optimizations; override default in Makefile.master
-#
-
-CFLAGS_XARCH_32 = $(i386_CFLAGS)
-CFLAGS_XARCH_64 = $(amd64_CFLAGS)
-CFLAGS_XARCH = $(CFLAGS_XARCH_$(CLASS))
-
-COPTFLAG_32 = $(COPTFLAG)
-COPTFLAG_64 = $(COPTFLAG64)
-COPTIMIZE = $(COPTFLAG_$(CLASS))
-
-CFLAGS = $(CFLAGS_XARCH)
-CFLAGS += $(COPTIMIZE)
-CFLAGS += $(INLINES) -D_ASM_INLINES
-CFLAGS += $(CCMODE)
-CFLAGS += $(SPACEFLAG)
-CFLAGS += $(CCUNBOUND)
-CFLAGS += $(CFLAGS_uts)
-CFLAGS += -xstrconst
-
-ASFLAGS_XARCH_32 = $(i386_ASFLAGS)
-ASFLAGS_XARCH_64 = $(amd64_ASFLAGS)
-ASFLAGS_XARCH = $(ASFLAGS_XARCH_$(CLASS))
-
-ASFLAGS += $(ASFLAGS_XARCH)
-
-AS_INC_PATH += -I$(DSF_DIR)/$(OBJS_DIR)
-
-#
-# The following must be defined for all implementations:
-#
-# MAPFILE: ld mapfile for the build of kernel/unix.
-# MODSTUBS: Module stubs source file.
-# GENASSYM_SRC: genassym.c
-#
-MAPFILE = $(UTSBASE)/$(PLATFORM)/conf/Mapfile
-MODSTUBS = $(UTSBASE)/intel/ia32/ml/modstubs.s
-GENASSYM_SRC = $(UTSBASE)/$(PLATFORM)/ml/genassym.c
-OFFSETS_SRC = $(UTSBASE)/$(PLATFORM)/ml/offsets.in
-PLATFORM_OFFSETS_32 = $(UTSBASE)/$(PLATFORM)/ml/mach_offsets.in
-PLATFORM_OFFSETS_64 = $(UTSBASE)/intel/amd64/ml/mach_offsets.in
-PLATFORM_OFFSETS_SRC = $(PLATFORM_OFFSETS_$(CLASS))
-KDI_OFFSETS_SRC = $(UTSBASE)/intel/kdi/kdi_offsets.in
-
-#
-# Define the actual specific platforms
-#
-MACHINE_DEFS = -D$(PLATFORM) -D_MACHDEP
-
-#
-# Software workarounds for hardware "features"
-#
-
-include $(UTSBASE)/$(PLATFORM)/Makefile.workarounds
-
-#
-# Debugging level
-#
-# Special knowledge of which special debugging options effect which
-# file is used to optimize the build if these flags are changed.
-#
-# XXX: The above could possibly be done for more flags and files, but
-# is left as an experiment to the interested reader. Be forewarned,
-# that excessive use could lead to maintenance difficulties.
-#
-DEBUG_DEFS_OBJ32 =
-DEBUG_DEFS_DBG32 = -DDEBUG
-DEBUG_DEFS_OBJ64 =
-DEBUG_DEFS_DBG64 = -DDEBUG
-DEBUG_DEFS = $(DEBUG_DEFS_$(BUILD_TYPE))
-
-DEBUG_COND_OBJ32 :sh = echo \\043
-DEBUG_COND_DBG32 =
-DEBUG_COND_OBJ64 :sh = echo \\043
-DEBUG_COND_DBG64 =
-IF_DEBUG_OBJ = $(DEBUG_COND_$(BUILD_TYPE))$(OBJS_DIR)/
-
-$(IF_DEBUG_OBJ)trap.o := DEBUG_DEFS += -DTRAPDEBUG -DTRAPTRACE
-$(IF_DEBUG_OBJ)syscall_asm.o := DEBUG_DEFS += -DSYSCALLTRACE -DTRAPTRACE
-$(IF_DEBUG_OBJ)syscall_asm_amd64.o := DEBUG_DEFS += -DSYSCALLTRACE -DTRAPTRACE
-$(IF_DEBUG_OBJ)fast_trap_asm.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)interrupt.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)intr.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)locore.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)mp_startup.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)machdep.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)exception.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)x_call.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)mp_call.o := DEBUG_DEFS += -DTRAPTRACE
-$(IF_DEBUG_OBJ)cbe.o := DEBUG_DEFS += -DTRAPTRACE
-
-#
-# Collect the preprocessor definitions to be associated with *all*
-# files.
-#
-ALL_DEFS = $(MACHINE_DEFS) $(WORKAROUND_DEFS) $(DEBUG_DEFS) \
- $(OPTION_DEFS)
-GENASSYM_DEFS = $(MACHINE_DEFS) $(OPTION_DEFS) \
- -_gcc=-fno-eliminate-unused-debug-symbols \
- -_gcc=-fno-eliminate-unused-debug-types
-
-#
-# ----- TRANSITIONAL SECTION --------------------------------------------------
-#
-
-#
-# Not everything which *should* be a module is a module yet. The
-# following is a list of such objects which are currently part of
-# the base kernel but should soon become kmods.
-#
-# XXX: $(KMACCT_OBJS) is neither in the MT kernel nor was it ever
-# made into a module. If it is made MT safe before being made
-# into a module, it should be added to this list. It was in
-# this list pre ON-4.0.
-#
-#
-MACH_NOT_YET_KMODS = $(AUTOCONF_OBJS)
-
-#
-# ----- END OF TRANSITIONAL SECTION -------------------------------------------
-#
-
-#
-# The kernels modules which are "implementation architecture"
-# specific for this machine are enumerated below. Note that most
-# of these modules must exist (in one form or another) for each
-# architecture.
-#
-# Machine Specific Driver Modules (/kernel/drv)
-# DRV_KMODS are built both 32-bit and 64-bit
-# DRV_KMODS_32 are built only 32-bit
-# DRV_KMODS_64 are built only 64-bit
-#
-DRV_KMODS += rootnex
-DRV_KMODS += isa
-DRV_KMODS += pcplusmp
-DRV_KMODS += cpc
-DRV_KMODS += pci
-DRV_KMODS += npe
-DRV_KMODS += pci-ide
-DRV_KMODS += xsvc
-DRV_KMODS += mc-amd
-DRV_KMODS += tzmon
-DRV_KMODS += battery
-DRV_KMODS += pv_cmdk
-DRV_KMODS += xdf
-DRV_KMODS += xnf
-DRV_KMODS += xpv
-DRV_KMODS += xpvd
-
-DRV_KMODS += cpudrv
-
-#
-# Platform Power Modules
-#
-DRV_KMODS += ppm acpippm
-
-$(CLOSED_BUILD)CLOSED_DRV_KMODS += memtest
-
-#
-# CPU Modules
-#
-CPU_KMODS += amd_opteron
-CPU_KMODS += generic_cpu
-CPU_KMODS += authenticamd
-CPU_KMODS += genuineintel
-CPU_KMODS += intel_nb5000
-
-#
-# Exec Class Modules (/kernel/exec):
-#
-EXEC_KMODS +=
-
-#
-# Scheduling Class Modules (/kernel/sched):
-#
-SCHED_KMODS +=
-
-#
-# File System Modules (/kernel/fs):
-#
-FS_KMODS +=
-
-#
-# Streams Modules (/kernel/strmod):
-#
-STRMOD_KMODS +=
-
-#
-# 'System' Modules (/kernel/sys):
-#
-SYS_KMODS +=
-
-#
-# 'Misc' Modules (/kernel/misc):
-#
-MISC_KMODS += gfx_private pcie hvm_bootstrap vbi
-
-#
-# 'Dacf' modules (/kernel/dacf)
-#
-DACF_KMODS += consconfig_dacf
-
-#
-# 'Mach' Modules (/kernel/mach):
-#
-MACH_KMODS += uppc
-
-#
-# CPR Misc Module.
-#
-MISC_KMODS += cpr
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared.patch b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared.patch
deleted file mode 100644
index bf5c49606..000000000
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/Makefile.i86pc.shared.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- old/usr/src/uts/i86pc/Makefile.i86pc.shared Tue May 27 01:20:43 2008
-+++ new/usr/src/uts/i86pc/Makefile.i86pc.shared Tue May 27 01:20:43 2008
-@@ -25,7 +25,7 @@
- # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- # Use is subject to license terms.
- #
--# ident "@(#)Makefile.i86pc.shared 1.24 08/03/28 SMI"
-+# ident "@(#)Makefile.i86pc.shared 1.25 08/05/26 SMI"
- #
- # This makefile contains the common definitions for the i86pc unix
- # and all i86pc implementation architecture dependent modules.
-@@ -298,7 +298,7 @@
- #
- # 'Misc' Modules (/kernel/misc):
- #
--MISC_KMODS += gfx_private pcie hvm_bootstrap
-+MISC_KMODS += gfx_private pcie hvm_bootstrap vbi
-
- #
- # 'Dacf' modules (/kernel/dacf)
diff --git a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
index 1216b1b29..4d97a0739 100644
--- a/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
+++ b/src/VBox/Runtime/r0drv/solaris/vbi/i86pc/os/vbi.c
@@ -271,7 +271,12 @@ vbi_init(void)
modctl_t *genunix_modctl = mod_hold_by_name("genunix");
if (genunix_modctl)
{
+ /*
+ * Hold mod_lock as ctf_modopen may update the module with uncompressed CTF data.
+ */
+ mutex_enter(&mod_lock);
ctf_file_t *ctfp = ctf_modopen(genunix_modctl->mod_mp, &err);
+ mutex_exit(&mod_lock);
if (ctfp)
{
do {
diff --git a/src/VBox/Runtime/r3/os2/pipe-os2.cpp b/src/VBox/Runtime/r3/os2/pipe-os2.cpp
index b3fbecf1d..729f09b3d 100644
--- a/src/VBox/Runtime/r3/os2/pipe-os2.cpp
+++ b/src/VBox/Runtime/r3/os2/pipe-os2.cpp
@@ -94,3 +94,9 @@ RTDECL(int) RTPipeSelectOne(RTPIPE hPipe, RTMSINTERVAL cMillies)
return VERR_NOT_IMPLEMENTED;
}
+
+RTDECL(int) RTPipeQueryReadable(RTPIPE hPipe, size_t *pcbReadable)
+{
+ return VERR_NOT_IMPLEMENTED;
+}
+
diff --git a/src/VBox/Runtime/r3/posix/pipe-posix.cpp b/src/VBox/Runtime/r3/posix/pipe-posix.cpp
index 5df36ee25..7e8ed5f9d 100644
--- a/src/VBox/Runtime/r3/posix/pipe-posix.cpp
+++ b/src/VBox/Runtime/r3/posix/pipe-posix.cpp
@@ -43,12 +43,16 @@
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
+#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <signal.h>
#ifdef RT_OS_LINUX
# include <sys/syscall.h>
#endif
+#ifdef RT_OS_SOLARIS
+# include <sys/filio.h>
+#endif
/*******************************************************************************
@@ -637,3 +641,29 @@ RTDECL(int) RTPipeSelectOne(RTPIPE hPipe, RTMSINTERVAL cMillies)
return rc > 0 ? VINF_SUCCESS : VERR_TIMEOUT;
}
+
+RTDECL(int) RTPipeQueryReadable(RTPIPE hPipe, size_t *pcbReadable)
+{
+ RTPIPEINTERNAL *pThis = hPipe;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->fRead, VERR_PIPE_NOT_READ);
+ AssertPtrReturn(pcbReadable, VERR_INVALID_POINTER);
+
+ int cb = 0;
+ int rc = ioctl(pThis->fd, FIONREAD, &cb);
+ if (rc != -1)
+ {
+ AssertStmt(cb >= 0, cb = 0);
+ *pcbReadable = cb;
+ return VINF_SUCCESS;
+ }
+
+ rc = errno;
+ if (rc == ENOTTY)
+ rc = VERR_NOT_SUPPORTED;
+ else
+ rc = RTErrConvertFromErrno(rc);
+ return rc;
+}
+
diff --git a/src/VBox/Runtime/r3/win/VBoxRT-openssl.def b/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
index 8c9a7a6a3..250394de0 100644
--- a/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
+++ b/src/VBox/Runtime/r3/win/VBoxRT-openssl.def
@@ -9,7 +9,7 @@
;
;
-; Copyright (C) 2009 Oracle Corporation
+; Copyright (C) 2009-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;
@@ -1408,6 +1408,7 @@
OPENSSL_DIR_read
OPENSSL_gmtime
OPENSSL_isservice
+ OPENSSL_issetugid
OpenSSLDie
OTHERNAME_free
OTHERNAME_new
@@ -1581,7 +1582,9 @@
RAND_egd
RAND_egd_bytes
RAND_event
+ RAND_file_name
RAND_get_rand_method
+ RAND_load_file
RAND_poll
RAND_pseudo_bytes
RAND_query_egd_bytes
@@ -1590,6 +1593,7 @@
RAND_set_rand_method
RAND_SSLeay
RAND_status
+ RAND_write_file
RC4
RC4_options
RC4_set_key
diff --git a/src/VBox/Runtime/r3/win/pipe-win.cpp b/src/VBox/Runtime/r3/win/pipe-win.cpp
index 6c12768e2..5abe809e2 100644
--- a/src/VBox/Runtime/r3/win/pipe-win.cpp
+++ b/src/VBox/Runtime/r3/win/pipe-win.cpp
@@ -1147,6 +1147,29 @@ RTDECL(int) RTPipeSelectOne(RTPIPE hPipe, RTMSINTERVAL cMillies)
}
+RTDECL(int) RTPipeQueryReadable(RTPIPE hPipe, size_t *pcbReadable)
+{
+ RTPIPEINTERNAL *pThis = hPipe;
+ AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);
+ AssertReturn(pThis->fRead, VERR_PIPE_NOT_READ);
+ AssertPtrReturn(pcbReadable, VERR_INVALID_POINTER);
+
+ int rc = RTCritSectEnter(&pThis->CritSect);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ DWORD cbAvailable = 0;
+ if (PeekNamedPipe(pThis->hPipe, NULL, 0, NULL, &cbAvailable, NULL))
+ *pcbReadable = cbAvailable;
+ else
+ rc = RTErrConvertFromWin32(GetLastError());
+
+ RTCritSectLeave(&pThis->CritSect);
+ return rc;
+}
+
+
/**
* Internal RTPollSetAdd helper that returns the handle that should be added to
* the pollset.
diff --git a/src/VBox/Runtime/r3/win/process-win.cpp b/src/VBox/Runtime/r3/win/process-win.cpp
index 2e44fa1ac..a9f458684 100644
--- a/src/VBox/Runtime/r3/win/process-win.cpp
+++ b/src/VBox/Runtime/r3/win/process-win.cpp
@@ -521,6 +521,7 @@ static bool rtProcFindProcessByName(const char * const *papszNames, PSID pSID, P
dwErr = GetLastError();
}
}
+ RTLdrClose(hPSAPI);
}
}
RTLdrClose(hKernel32);
@@ -937,7 +938,18 @@ static int rtProcCreateAsUserHlp(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUT
dwErr = rc;
if (!(fFlags & RTPROC_FLAGS_NO_PROFILE))
- pfnUnloadUserProfile(*phToken, profileInfo.hProfile);
+ {
+ fRc = pfnUnloadUserProfile(*phToken, profileInfo.hProfile);
+ if (!fRc)
+ {
+ /* In case there were some handles left open, we want to know about
+ * that -- can be tricky to debug later! */
+ DWORD dwErr2 = GetLastError();
+ AssertMsgFailed(("Unloading user profile failed with error %u (%#x)", dwErr2, dwErr2));
+ if (dwErr == NO_ERROR)
+ dwErr = dwErr2;
+ }
+ }
}
}
}
@@ -952,9 +964,8 @@ static int rtProcCreateAsUserHlp(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUT
if ( RT_SUCCESS(rc)
&& dwErr != NO_ERROR)
- {
rc = rtProcMapErrorCodes(dwErr);
- }
+
return rc;
}
diff --git a/src/VBox/Runtime/r3/xml.cpp b/src/VBox/Runtime/r3/xml.cpp
index bf030e1d1..1fa57a227 100644
--- a/src/VBox/Runtime/r3/xml.cpp
+++ b/src/VBox/Runtime/r3/xml.cpp
@@ -1500,7 +1500,7 @@ void XmlMemParser::read(const void* pvBuf, size_t cbSize,
(int)cbSize,
pcszFilename,
NULL, // encoding = auto
- XML_PARSE_NOBLANKS)))
+ XML_PARSE_NOBLANKS | XML_PARSE_NONET)))
throw XmlError(xmlCtxtGetLastError(m_ctxt));
doc.refreshInternals();
@@ -1630,7 +1630,7 @@ void XmlFileParser::read(const RTCString &strFilename,
&context,
pcszFilename,
NULL, // encoding = auto
- XML_PARSE_NOBLANKS)))
+ XML_PARSE_NOBLANKS | XML_PARSE_NONET)))
throw XmlError(xmlCtxtGetLastError(m_ctxt));
doc.refreshInternals();
diff --git a/src/VBox/Runtime/testcase/tstLdr.cpp b/src/VBox/Runtime/testcase/tstLdr.cpp
index 8003bdc2f..b31ebc4ff 100644
--- a/src/VBox/Runtime/testcase/tstLdr.cpp
+++ b/src/VBox/Runtime/testcase/tstLdr.cpp
@@ -100,12 +100,12 @@ static int testLdrOne(const char *pszFilename)
const char *pszName;
} aLoads[6] =
{
- { NULL, NULL, (int32_t)0xefefef00, "foo" },
- { NULL, NULL, (int32_t)0x40404040, "bar" },
- { NULL, NULL, (int32_t)0xefefef00, "foobar" },
- { NULL, NULL, (int32_t)0xefefef00, "kLdr-foo" },
- { NULL, NULL, (int32_t)0x40404040, "kLdr-bar" },
- { NULL, NULL, (int32_t)0xefefef00, "kLdr-foobar" }
+ { NULL, NULL, (RTUINTPTR)0xefefef00, "foo" },
+ { NULL, NULL, (RTUINTPTR)0x40404040, "bar" },
+ { NULL, NULL, (RTUINTPTR)0xefefef00, "foobar" },
+ { NULL, NULL, (RTUINTPTR)0xefefef00, "kLdr-foo" },
+ { NULL, NULL, (RTUINTPTR)0x40404040, "kLdr-bar" },
+ { NULL, NULL, (RTUINTPTR)0xefefef00, "kLdr-foobar" }
};
unsigned i;
@@ -169,15 +169,15 @@ static int testLdrOne(const char *pszFilename)
{
static RTUINTPTR aRels[] =
{
- (int32_t)0xefefef00, /* same. */
- (int32_t)0x40404040, /* the other. */
- (int32_t)0xefefef00, /* back. */
- (int32_t)0x40404040, /* the other. */
- (int32_t)0xefefef00, /* back again. */
- (int32_t)0x77773420, /* somewhere entirely else. */
- (int32_t)0xf0000000, /* somewhere entirely else. */
- (int32_t)0x40404040, /* the other. */
- (int32_t)0xefefef00 /* back again. */
+ (RTUINTPTR)0xefefef00, /* same. */
+ (RTUINTPTR)0x40404040, /* the other. */
+ (RTUINTPTR)0xefefef00, /* back. */
+ (RTUINTPTR)0x40404040, /* the other. */
+ (RTUINTPTR)0xefefef00, /* back again. */
+ (RTUINTPTR)0x77773420, /* somewhere entirely else. */
+ (RTUINTPTR)0xf0000000, /* somewhere entirely else. */
+ (RTUINTPTR)0x40404040, /* the other. */
+ (RTUINTPTR)0xefefef00 /* back again. */
};
struct Symbols
{
@@ -187,14 +187,14 @@ static int testLdrOne(const char *pszFilename)
const char *pszName;
} aSyms[] =
{
- { ~0, "Entrypoint" },
- { ~0, "SomeExportFunction1" },
- { ~0, "SomeExportFunction2" },
- { ~0, "SomeExportFunction3" },
- { ~0, "SomeExportFunction4" },
- { ~0, "SomeExportFunction5" },
- { ~0, "SomeExportFunction5" },
- { ~0, "DISCoreOne" }
+ { ~0U, "Entrypoint" },
+ { ~0U, "SomeExportFunction1" },
+ { ~0U, "SomeExportFunction2" },
+ { ~0U, "SomeExportFunction3" },
+ { ~0U, "SomeExportFunction4" },
+ { ~0U, "SomeExportFunction5" },
+ { ~0U, "SomeExportFunction5" },
+ { ~0U, "DISCoreOne" }
};
unsigned iRel = 0;
diff --git a/src/VBox/Runtime/testcase/tstRTBase64.cpp b/src/VBox/Runtime/testcase/tstRTBase64.cpp
index bbb2c38d9..57dc7d0a3 100644
--- a/src/VBox/Runtime/testcase/tstRTBase64.cpp
+++ b/src/VBox/Runtime/testcase/tstRTBase64.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2009 Oracle Corporation
+ * Copyright (C) 2009-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;
@@ -172,9 +172,39 @@ int main()
1 /* fTextData */, 0 /* fNormalEnc */);
/*
+ * Test for buffer overruns.
+ */
+ static uint8_t s_abData4[32768];
+ for (size_t i = 0; i < sizeof(s_abData4); i++)
+ s_abData4[i] = i % 256;
+ for (size_t cbSrc = 1; cbSrc <= sizeof(s_abData4); cbSrc++)
+ {
+ RTTestSubF(hTest, "Test 3-%zu", cbSrc);
+ char szEnc[49152];
+ memset(szEnc, '\0', sizeof(szEnc));
+ size_t cchEnc = RTBase64EncodedLength(cbSrc);
+ if (cchEnc >= sizeof(szEnc))
+ RTTestIFailed("RTBase64EncodedLength returned %zu bytes, too big\n", cchEnc);
+ size_t cchOut = 0;
+ rc = RTBase64Encode(s_abData4, cbSrc, szEnc, cchEnc, &cchOut);
+ if (rc != VERR_BUFFER_OVERFLOW)
+ RTTestIFailed("RTBase64Encode has no buffer overflow with too small buffer -> %Rrc\n", rc);
+ rc = RTBase64Encode(s_abData4, cbSrc, szEnc, cchEnc + 1, &cchOut);
+ if (RT_FAILURE(rc))
+ RTTestIFailed("RTBase64Encode -> %Rrc\n", rc);
+ if (cchOut != cchEnc)
+ RTTestIFailed("RTBase64EncodedLength returned %zu bytes, expected %zu.\n",
+ cchEnc, cchOut);
+ if (szEnc[cchOut + 1] != '\0')
+ RTTestIFailed("RTBase64Encode returned string which is not zero terminated\n");
+ if (strlen(szEnc) != cchOut)
+ RTTestIFailed("RTBase64Encode returned incorrect string, length %lu\n", cchOut);
+ }
+
+ /*
* Finally, a more extensive test.
*/
- RTTestSub(hTest, "Test 3");
+ RTTestSub(hTest, "Test 4");
static uint8_t s_abData3[12*256];
for (unsigned i = 0; i < 256; i++)
{
diff --git a/src/VBox/Runtime/testcase/tstRTPipe.cpp b/src/VBox/Runtime/testcase/tstRTPipe.cpp
index dfb73685d..87c95cc5d 100644
--- a/src/VBox/Runtime/testcase/tstRTPipe.cpp
+++ b/src/VBox/Runtime/testcase/tstRTPipe.cpp
@@ -350,9 +350,12 @@ static void tstRTPipe1(void)
cbWritten = ~(size_t)2;
RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "BigQ", 4, &cbWritten), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbWritten == 4);
- cbRead = ~(size_t)0;
RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 0), VINF_SUCCESS);
RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 1), VINF_SUCCESS);
+ cbRead = ~(size_t)0;
+ RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
+ RTTESTI_CHECK_MSG(cbRead == cbWritten, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
+ cbRead = ~(size_t)0;
RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbRead == 4);
RTTESTI_CHECK_RETV(!memcmp(abBuf, "BigQ", 4));
@@ -361,18 +364,33 @@ static void tstRTPipe1(void)
RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "H2G2", 4, &cbWritten), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbWritten == 4);
cbRead = ~(size_t)0;
+ RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
+ RTTESTI_CHECK_MSG(cbRead == cbWritten, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
+ cbRead = ~(size_t)0;
RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbRead == 1);
cbRead = ~(size_t)0;
+ RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
+ RTTESTI_CHECK_MSG(cbRead == cbWritten - 1, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
+ cbRead = ~(size_t)0;
RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[1], 1, &cbRead), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbRead == 1);
cbRead = ~(size_t)0;
+ RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
+ RTTESTI_CHECK_MSG(cbRead == cbWritten - 2, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
+ cbRead = ~(size_t)0;
RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[2], 1, &cbRead), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbRead == 1);
cbRead = ~(size_t)0;
+ RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
+ RTTESTI_CHECK_MSG(cbRead == cbWritten - 3, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
+ cbRead = ~(size_t)0;
RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[3], 1, &cbRead), VINF_SUCCESS);
RTTESTI_CHECK_RETV(cbRead == 1);
RTTESTI_CHECK_RETV(!memcmp(abBuf, "H2G2", 4));
+ cbRead = ~(size_t)0;
+ RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
+ RTTESTI_CHECK_MSG(cbRead == cbWritten - 4, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
diff --git a/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp b/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
index 0e3019ac4..aca309102 100644
--- a/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
+++ b/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
@@ -156,7 +156,7 @@ static void tstRTCreateProcEx5(const char *pszUser, const char *pszPassword)
NULL, NULL, "non-existing-user", "wrong-password", &hProc), VERR_AUTHENTICATION_FAILURE);
/* Test for invalid application. */
RTTESTI_CHECK_RC_RETV(RTProcCreateEx("non-existing-app", apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
- NULL, NULL, NULL, NULL, &hProc), VERR_PATH_NOT_FOUND);
+ NULL, NULL, NULL, NULL, &hProc), VERR_FILE_NOT_FOUND);
/* Test a (hopefully) valid user/password logon (given by parameters of this function). */
RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,
NULL, NULL, pszUser, pszPassword, &hProc), VINF_SUCCESS);
diff --git a/src/VBox/Runtime/testcase/tstTimerLR.cpp b/src/VBox/Runtime/testcase/tstTimerLR.cpp
index e8584fb25..d2da8cf75 100644
--- a/src/VBox/Runtime/testcase/tstTimerLR.cpp
+++ b/src/VBox/Runtime/testcase/tstTimerLR.cpp
@@ -207,6 +207,88 @@ int main()
}
/*
+ * Test changing the interval dynamically
+ */
+ RTPrintf("\n"
+ "tstTimer: Testing dynamic changes of timer interval...\n");
+ do
+ {
+ RTTIMERLR hTimerLR;
+ rc = RTTimerLRCreateEx(&hTimerLR, aTests[0].uMilliesInterval * (uint64_t)1000000, 0, TimerLRCallback, NULL);
+ if (RT_FAILURE(rc))
+ {
+ RTPrintf("RTTimerLRCreateEX(,%u*1M,,,) -> %d\n", aTests[i].uMilliesInterval, rc);
+ cErrors++;
+ continue;
+ }
+
+ for (i = 0; i < RT_ELEMENTS(aTests); i++)
+ {
+ RTPrintf("\n"
+ "tstTimer: TESTING - %d ms interval, %d ms wait, expects %d-%d ticks.\n",
+ aTests[i].uMilliesInterval, aTests[i].uMilliesWait, aTests[i].cLower, aTests[i].cUpper);
+
+ gcTicks = 0;
+ gu64Max = 0;
+ gu64Min = UINT64_MAX;
+ gu64Prev = 0;
+ /*
+ * Start the timer an actively wait for it for the period requested.
+ */
+ uTSBegin = RTTimeNanoTS();
+ if (i == 0)
+ {
+ rc = RTTimerLRStart(hTimerLR, 0);
+ if (RT_FAILURE(rc))
+ {
+ RTPrintf("tstTimer: FAILURE - RTTimerLRStart() -> %Rrc\n", rc);
+ cErrors++;
+ }
+ }
+ else
+ {
+ rc = RTTimerLRChangeInterval(hTimerLR, aTests[i].uMilliesInterval * (uint64_t)1000000);
+ if (RT_FAILURE(rc))
+ {
+ RTPrintf("tstTimer: FAILURE - RTTimerLRChangeInterval() -> %d gcTicks=%d\n", rc, gcTicks);
+ cErrors++;
+ }
+ }
+
+ while (RTTimeNanoTS() - uTSBegin < (uint64_t)aTests[i].uMilliesWait * 1000000)
+ /* nothing */;
+
+ uint64_t uTSEnd = RTTimeNanoTS();
+ uTSDiff = uTSEnd - uTSBegin;
+ RTPrintf("uTS=%RI64 (%RU64 - %RU64)\n", uTSDiff, uTSBegin, uTSEnd);
+
+ /*
+ * Check the number of ticks.
+ */
+ if (gcTicks < aTests[i].cLower)
+ {
+ RTPrintf("tstTimer: FAILURE - Too few ticks gcTicks=%d (expected %d-%d)\n", gcTicks, aTests[i].cUpper, aTests[i].cLower);
+ cErrors++;
+ }
+ else if (gcTicks > aTests[i].cUpper)
+ {
+ RTPrintf("tstTimer: FAILURE - Too many ticks gcTicks=%d (expected %d-%d)\n", gcTicks, aTests[i].cUpper, aTests[i].cLower);
+ cErrors++;
+ }
+ else
+ RTPrintf("tstTimer: OK - gcTicks=%d\n", gcTicks);
+ // RTPrintf(" min=%RU64 max=%RU64\n", gu64Min, gu64Max);
+ }
+ /* don't stop it, destroy it because there are potential races in destroying an active timer. */
+ rc = RTTimerLRDestroy(hTimerLR);
+ if (RT_FAILURE(rc))
+ {
+ RTPrintf("tstTimer: FAILURE - RTTimerLRDestroy() -> %d gcTicks=%d\n", rc, gcTicks);
+ cErrors++;
+ }
+ } while (0);
+
+ /*
* Test multiple timers running at once.
*/
/** @todo multiple LR timer testcase. */
diff --git a/src/VBox/Storage/ISCSI.cpp b/src/VBox/Storage/ISCSI.cpp
index da91ddef4..44c3be4cb 100644
--- a/src/VBox/Storage/ISCSI.cpp
+++ b/src/VBox/Storage/ISCSI.cpp
@@ -1811,8 +1811,8 @@ static int iscsiCommand(PISCSIIMAGE pImage, PSCSIREQ pRequest)
itt = iscsiNewITT(pImage);
memset(aReqBHS, 0, sizeof(aReqBHS));
- aReqBHS[0] = RT_H2N_U32( ISCSI_FINAL_BIT | ISCSI_TASK_ATTR_ORDERED | ISCSIOP_SCSI_CMD
- | (pRequest->enmXfer << 21)); /* I=0,F=1,Attr=Ordered */
+ aReqBHS[0] = RT_H2N_U32( ISCSI_FINAL_BIT | ISCSI_TASK_ATTR_SIMPLE | ISCSIOP_SCSI_CMD
+ | (pRequest->enmXfer << 21)); /* I=0,F=1,Attr=Simple */
aReqBHS[1] = RT_H2N_U32(0x00000000 | ((uint32_t)pRequest->cbI2TData & 0xffffff)); /* TotalAHSLength=0 */
aReqBHS[2] = RT_H2N_U32(pImage->LUN >> 32);
aReqBHS[3] = RT_H2N_U32(pImage->LUN & 0xffffffff);
@@ -2135,7 +2135,9 @@ static int iscsiRecvPDU(PISCSIIMAGE pImage, uint32_t itt, PISCSIRES paRes, uint3
if (RT_FAILURE(rc))
continue;
if ( !pImage->FirstRecvPDU
- && (cmd != ISCSIOP_SCSI_DATA_IN || (RT_N2H_U32(pcvResSeg[0]) & ISCSI_STATUS_BIT)))
+ && (cmd != ISCSIOP_SCSI_DATA_IN || (RT_N2H_U32(pcvResSeg[0]) & ISCSI_STATUS_BIT))
+ && ( cmd != ISCSIOP_LOGIN_RES
+ || (ISCSILOGINSTATUSCLASS)((RT_N2H_U32(pcvResSeg[9]) >> 24) == ISCSI_LOGIN_STATUS_CLASS_SUCCESS)))
{
if (pImage->ExpStatSN == RT_N2H_U32(pcvResSeg[6]))
{
@@ -2218,6 +2220,8 @@ static int iscsiRecvPDU(PISCSIIMAGE pImage, uint32_t itt, PISCSIRES paRes, uint3
}
}
}
+
+ LogFlowFunc(("returns rc=%Rrc\n"));
return rc;
}
@@ -2659,8 +2663,8 @@ static int iscsiPDUTxPrepare(PISCSIIMAGE pImage, PISCSICMD pIScsiCmd)
paReqBHS = pIScsiPDU->aBHS;
/* Setup the BHS. */
- paReqBHS[0] = RT_H2N_U32( ISCSI_FINAL_BIT | ISCSI_TASK_ATTR_ORDERED | ISCSIOP_SCSI_CMD
- | (pScsiReq->enmXfer << 21)); /* I=0,F=1,Attr=Ordered */
+ paReqBHS[0] = RT_H2N_U32( ISCSI_FINAL_BIT | ISCSI_TASK_ATTR_SIMPLE | ISCSIOP_SCSI_CMD
+ | (pScsiReq->enmXfer << 21)); /* I=0,F=1,Attr=Simple */
paReqBHS[1] = RT_H2N_U32(0x00000000 | ((uint32_t)pScsiReq->cbI2TData & 0xffffff)); /* TotalAHSLength=0 */
paReqBHS[2] = RT_H2N_U32(pImage->LUN >> 32);
paReqBHS[3] = RT_H2N_U32(pImage->LUN & 0xffffffff);
diff --git a/src/VBox/Storage/VD.cpp b/src/VBox/Storage/VD.cpp
index ce49445ec..da1978157 100644
--- a/src/VBox/Storage/VD.cpp
+++ b/src/VBox/Storage/VD.cpp
@@ -85,6 +85,8 @@ typedef struct VDIO
void *pBackendData;
/** Disk this image is part of */
PVBOXHDD pDisk;
+ /** Flag whether to ignore flush requests. */
+ bool fIgnoreFlush;
} VDIO, *PVDIO;
/**
@@ -3170,9 +3172,14 @@ static int vdIOIntReadSync(void *pvUser, PVDIOSTORAGE pIoStorage,
static int vdIOIntFlushSync(void *pvUser, PVDIOSTORAGE pIoStorage)
{
+ int rc = VINF_SUCCESS;
PVDIO pVDIo = (PVDIO)pvUser;
- return pVDIo->pInterfaceIOCallbacks->pfnFlushSync(pVDIo->pInterfaceIO->pvUser,
- pIoStorage->pStorage);
+
+ if (!pVDIo->fIgnoreFlush)
+ rc = pVDIo->pInterfaceIOCallbacks->pfnFlushSync(pVDIo->pInterfaceIO->pvUser,
+ pIoStorage->pStorage);
+
+ return rc;
}
static int vdIOIntReadUserAsync(void *pvUser, PVDIOSTORAGE pIoStorage,
@@ -3554,6 +3561,9 @@ static int vdIOIntFlushAsync(void *pvUser, PVDIOSTORAGE pIoStorage,
LogFlowFunc(("pvUser=%#p pIoStorage=%#p pIoCtx=%#p\n",
pvUser, pIoStorage, pIoCtx));
+ if (pVDIo->fIgnoreFlush)
+ return VINF_SUCCESS;
+
/* Allocate a new meta transfer. */
pMetaXfer = vdMetaXferAlloc(pIoStorage, 0, 0);
if (!pMetaXfer)
@@ -4445,9 +4455,9 @@ VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend,
&pDisk->VDIIOIntCallbacks, &pImage->VDIo, &pImage->pVDIfsImage);
AssertRC(rc);
- pImage->uOpenFlags = uOpenFlags & VD_OPEN_FLAGS_HONOR_SAME;
+ pImage->uOpenFlags = uOpenFlags & (VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_IGNORE_FLUSH);
rc = pImage->Backend->pfnOpen(pImage->pszFilename,
- uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME,
+ uOpenFlags & ~(VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_IGNORE_FLUSH),
pDisk->pVDIfsDisk,
pImage->pVDIfsImage,
pDisk->enmType,
@@ -4482,6 +4492,7 @@ VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend,
fLockWrite = true;
pImage->VDIo.pBackendData = pImage->pBackendData;
+ pImage->VDIo.fIgnoreFlush = (uOpenFlags & VD_OPEN_FLAGS_IGNORE_FLUSH) != 0;
/* Check image type. As the image itself has only partial knowledge
* whether it's a base image or not, this info is derived here. The
@@ -4981,6 +4992,7 @@ VBOXDDU_DECL(int) VDCreateBase(PVBOXHDD pDisk, const char *pszBackend,
if (RT_SUCCESS(rc))
{
pImage->VDIo.pBackendData = pImage->pBackendData;
+ pImage->VDIo.fIgnoreFlush = (uOpenFlags & VD_OPEN_FLAGS_IGNORE_FLUSH) != 0;
pImage->uImageFlags = uImageFlags;
/* Force sane optimization settings. It's not worth avoiding writes
@@ -5248,6 +5260,7 @@ VBOXDDU_DECL(int) VDCreateDiff(PVBOXHDD pDisk, const char *pszBackend,
if (RT_SUCCESS(rc))
{
pImage->VDIo.pBackendData = pImage->pBackendData;
+ pImage->VDIo.fIgnoreFlush = (uOpenFlags & VD_OPEN_FLAGS_IGNORE_FLUSH) != 0;
pImage->uImageFlags = uImageFlags;
/* Lock disk for writing, as we modify pDisk information below. */
@@ -5505,6 +5518,7 @@ VBOXDDU_DECL(int) VDCreateCache(PVBOXHDD pDisk, const char *pszBackend,
fLockWrite = true;
pCache->VDIo.pBackendData = pCache->pBackendData;
+ pCache->VDIo.fIgnoreFlush = (uOpenFlags & VD_OPEN_FLAGS_IGNORE_FLUSH) != 0;
/* Re-check state, as the lock wasn't held and another image
* creation call could have been done by another thread. */
diff --git a/src/VBox/Storage/VDI.cpp b/src/VBox/Storage/VDI.cpp
index ebae1e669..5d8ae40a7 100644
--- a/src/VBox/Storage/VDI.cpp
+++ b/src/VBox/Storage/VDI.cpp
@@ -1350,6 +1350,8 @@ static int vdiWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf,
if (ASMBitFirstSet((volatile void *)pvBuf, (uint32_t)cbToWrite * 8) == -1)
{
pImage->paBlocks[uBlock] = VDI_IMAGE_BLOCK_ZERO;
+ *pcbPreRead = 0;
+ *pcbPostRead = 0;
break;
}
}
@@ -2346,7 +2348,7 @@ static int vdiCompact(void *pBackendData, unsigned uPercentStart,
}
else if (pfnParentRead)
{
- rc = pfnParentRead(pvParent, i * cbBlock, pvBuf, cbBlock);
+ rc = pfnParentRead(pvParent, (uint64_t)i * cbBlock, pvBuf, cbBlock);
if (RT_FAILURE(rc))
break;
if (!memcmp(pvTmp, pvBuf, cbBlock))
diff --git a/src/VBox/Storage/VHD.cpp b/src/VBox/Storage/VHD.cpp
index ebe23020c..674a43281 100644
--- a/src/VBox/Storage/VHD.cpp
+++ b/src/VBox/Storage/VHD.cpp
@@ -2948,7 +2948,7 @@ static int vhdCompact(void *pBackendData, unsigned uPercentStart,
}
else if (pfnParentRead)
{
- rc = pfnParentRead(pvParent, i * pImage->cbDataBlock, pvParent, pImage->cbDataBlock);
+ rc = pfnParentRead(pvParent, (uint64_t)i * pImage->cbDataBlock, pvParent, pImage->cbDataBlock);
if (RT_FAILURE(rc))
break;
if (!memcmp(pvParent, pvBuf, pImage->cbDataBlock))
diff --git a/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp b/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
index aa25f0cc2..abd8f741b 100644
--- a/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
+++ b/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
@@ -57,14 +57,14 @@
*/
static const unsigned g_aSize2Shift[] =
{
- ~0, /* 0 - invalid */
+ ~0U, /* 0 - invalid */
0, /* *1 == 2^0 */
1, /* *2 == 2^1 */
- ~0, /* 3 - invalid */
+ ~0U, /* 3 - invalid */
2, /* *4 == 2^2 */
- ~0, /* 5 - invalid */
- ~0, /* 6 - invalid */
- ~0, /* 7 - invalid */
+ ~0U, /* 5 - invalid */
+ ~0U, /* 6 - invalid */
+ ~0U, /* 7 - invalid */
3 /* *8 == 2^3 */
};
diff --git a/src/VBox/VMM/VMMAll/PGMAllBth.h b/src/VBox/VMM/VMMAll/PGMAllBth.h
index c4ea16fb2..941d9359f 100644
--- a/src/VBox/VMM/VMMAll/PGMAllBth.h
+++ b/src/VBox/VMM/VMMAll/PGMAllBth.h
@@ -2457,7 +2457,7 @@ static int PGM_BTH_NAME(CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPD
{
if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
{
- AssertMsgFailed(("%R[pgmpage] - we don't set PGM_PTFLAGS_TRACK_DIRTY for these pages\n", pPage));
+ //AssertMsgFailed(("%R[pgmpage] - we don't set PGM_PTFLAGS_TRACK_DIRTY for these pages\n", pPage));
Assert(!PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage));
/* Assuming write handlers here as the PTE is present (otherwise we wouldn't be here). */
SHW_PTE_SET_RO(PteDst);
diff --git a/src/VBox/VMM/VMMAll/PGMAllPhys.cpp b/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
index 46c65ea4a..cf2770592 100644
--- a/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
+++ b/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
@@ -631,7 +631,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
const RTHCPHYS HCPhys = pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys;
pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys = GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
- void *pvSharedPage = NULL;
+ void const *pvSharedPage = NULL;
if (PGM_PAGE_IS_SHARED(pPage))
{
/* Mark this shared page for freeing/dereferencing. */
@@ -644,7 +644,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys)
pVM->pgm.s.cSharedPages--;
/* Grab the address of the page so we can make a copy later on. (safe) */
- rc = pgmPhysPageMap(pVM, pPage, GCPhys, &pvSharedPage);
+ rc = pgmPhysPageMapReadOnly(pVM, pPage, GCPhys, &pvSharedPage);
AssertRC(rc);
}
else
diff --git a/src/VBox/VMM/VMMR0/CPUMR0.cpp b/src/VBox/VMM/VMMR0/CPUMR0.cpp
index ebf3d64be..5227e3034 100644
--- a/src/VBox/VMM/VMMR0/CPUMR0.cpp
+++ b/src/VBox/VMM/VMMR0/CPUMR0.cpp
@@ -643,7 +643,7 @@ VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, b
* Worker for cpumR0MapLocalApics. Check each CPU for a present Local APIC.
* Play safe and treat each CPU separate.
*/
-static void cpumR0MapLocalApicWorker(RTCPUID idCpu, void *pvUser1, void *pvUser2)
+static DECLCALLBACK(void) cpumR0MapLocalApicWorker(RTCPUID idCpu, void *pvUser1, void *pvUser2)
{
int iCpu = RTMpCpuIdToSetIndex(idCpu);
AssertReturnVoid(iCpu >= 0 && (unsigned)iCpu < RT_ELEMENTS(g_aLApics));
diff --git a/src/VBox/VMM/VMMR0/GMMR0.cpp b/src/VBox/VMM/VMMR0/GMMR0.cpp
index 3e6d17378..71ab6832c 100644
--- a/src/VBox/VMM/VMMR0/GMMR0.cpp
+++ b/src/VBox/VMM/VMMR0/GMMR0.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2011 Oracle Corporation
+ * Copyright (C) 2007-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;
@@ -161,6 +161,9 @@
#include <VBox/err.h>
#include <iprt/asm.h>
#include <iprt/avl.h>
+#ifdef VBOX_STRICT
+# include <iprt/crc.h>
+#endif
#include <iprt/list.h>
#include <iprt/mem.h>
#include <iprt/memobj.h>
@@ -221,8 +224,8 @@ typedef union GMMPAGE
uint32_t pfn;
/** The reference count (64K VMs). */
uint32_t cRefs : 16;
- /** Reserved. Checksum or something? Two hGVMs for forking? */
- uint32_t u14Reserved : 14;
+ /** Used for debug checksumming. */
+ uint32_t u14Checksum : 14;
/** The page state. */
uint32_t u2State : 2;
} Shared;
@@ -488,9 +491,11 @@ typedef struct GMM
/** The shared free set. */
GMMCHUNKFREESET Shared;
- /** Shared module tree (global). */
- /** @todo separate trees for distinctly different guest OSes. */
- PAVLGCPTRNODECORE pGlobalSharedModuleTree;
+ /** Shared module tree (global).
+ * @todo separate trees for distinctly different guest OSes. */
+ PAVLLU32NODECORE pGlobalSharedModuleTree;
+ /** Sharable modules (count of nodes in pGlobalSharedModuleTree). */
+ uint32_t cShareableModules;
/** The chunk list. For simplifying the cleanup process. */
RTLISTNODE ChunkList;
@@ -587,6 +592,42 @@ typedef GMMR0CHUNKMTXSTATE *PGMMR0CHUNKMTXSTATE;
/** @} */
+/** The maximum number of shared modules per-vm. */
+#define GMM_MAX_SHARED_PER_VM_MODULES 2048
+/** The maximum number of shared modules GMM is allowed to track. */
+#define GMM_MAX_SHARED_GLOBAL_MODULES 16834
+
+
+/**
+ * Argument packet for gmmR0SharedModuleCleanup.
+ */
+typedef struct GMMR0SHMODPERVMDTORARGS
+{
+ PGVM pGVM;
+ PGMM pGMM;
+} GMMR0SHMODPERVMDTORARGS;
+
+/**
+ * Argument packet for gmmR0CheckSharedModule.
+ */
+typedef struct GMMCHECKSHAREDMODULEINFO
+{
+ PGVM pGVM;
+ VMCPUID idCpu;
+} GMMCHECKSHAREDMODULEINFO;
+
+/**
+ * Argument packet for gmmR0FindDupPageInChunk by GMMR0FindDuplicatePage.
+ */
+typedef struct GMMFINDDUPPAGEINFO
+{
+ PGVM pGVM;
+ PGMM pGMM;
+ uint8_t *pSourcePage;
+ bool fFoundDuplicate;
+} GMMFINDDUPPAGEINFO;
+
+
/*******************************************************************************
* Global Variables *
*******************************************************************************/
@@ -594,9 +635,9 @@ typedef GMMR0CHUNKMTXSTATE *PGMMR0CHUNKMTXSTATE;
static PGMM g_pGMM = NULL;
/** Macro for obtaining and validating the g_pGMM pointer.
- *
+ *
* On failure it will return from the invoking function with the specified
- * return value.
+ * return value.
*
* @param pGMM The name of the pGMM variable.
* @param rc The return value on failure. Use VERR_GMM_INSTANCE for VBox
@@ -610,9 +651,9 @@ static PGMM g_pGMM = NULL;
} while (0)
/** Macro for obtaining and validating the g_pGMM pointer, void function
- * variant.
- *
- * On failure it will return from the invoking function.
+ * variant.
+ *
+ * On failure it will return from the invoking function.
*
* @param pGMM The name of the pGMM variable.
*/
@@ -680,7 +721,12 @@ static bool gmmR0FreeChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChun
DECLINLINE(void) gmmR0FreePrivatePage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage);
DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMMPAGE pPage);
static int gmmR0UnmapChunkLocked(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk);
+#ifdef VBOX_WITH_PAGE_SHARING
static void gmmR0SharedModuleCleanup(PGMM pGMM, PGVM pGVM);
+# ifdef VBOX_STRICT
+static uint32_t gmmR0StrictPageChecksum(PGMM pGMM, PGVM pGVM, uint32_t idPage);
+# endif
+#endif
@@ -869,9 +915,9 @@ GMMR0DECL(void) GMMR0InitPerVMData(PGVM pGVM)
{
AssertCompile(RT_SIZEOFMEMB(GVM,gmm.s) <= RT_SIZEOFMEMB(GVM,gmm.padding));
- pGVM->gmm.s.enmPolicy = GMMOCPOLICY_INVALID;
- pGVM->gmm.s.enmPriority = GMMPRIORITY_INVALID;
- pGVM->gmm.s.fMayAllocate = false;
+ pGVM->gmm.s.Stats.enmPolicy = GMMOCPOLICY_INVALID;
+ pGVM->gmm.s.Stats.enmPriority = GMMPRIORITY_INVALID;
+ pGVM->gmm.s.Stats.fMayAllocate = false;
}
@@ -1148,8 +1194,8 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
* The policy is 'INVALID' until the initial reservation
* request has been serviced.
*/
- if ( pGVM->gmm.s.enmPolicy > GMMOCPOLICY_INVALID
- && pGVM->gmm.s.enmPolicy < GMMOCPOLICY_END)
+ if ( pGVM->gmm.s.Stats.enmPolicy > GMMOCPOLICY_INVALID
+ && pGVM->gmm.s.Stats.enmPolicy < GMMOCPOLICY_END)
{
/*
* If it's the last VM around, we can skip walking all the chunk looking
@@ -1166,7 +1212,7 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
* and leftover mappings. (This'll only catch private pages,
* shared pages will be 'left behind'.)
*/
- uint64_t cPrivatePages = pGVM->gmm.s.cPrivatePages; /* save */
+ uint64_t cPrivatePages = pGVM->gmm.s.Stats.cPrivatePages; /* save */
unsigned iCountDown = 64;
bool fRedoFromStart;
@@ -1196,8 +1242,8 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
}
} while (fRedoFromStart);
- if (pGVM->gmm.s.cPrivatePages)
- SUPR0Printf("GMMR0CleanupVM: hGVM=%#x has %#x private pages that cannot be found!\n", pGVM->hSelf, pGVM->gmm.s.cPrivatePages);
+ if (pGVM->gmm.s.Stats.cPrivatePages)
+ SUPR0Printf("GMMR0CleanupVM: hGVM=%#x has %#x private pages that cannot be found!\n", pGVM->hSelf, pGVM->gmm.s.Stats.cPrivatePages);
pGMM->cAllocatedPages -= cPrivatePages;
@@ -1246,26 +1292,26 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
/*
* Account for shared pages that weren't freed.
*/
- if (pGVM->gmm.s.cSharedPages)
+ if (pGVM->gmm.s.Stats.cSharedPages)
{
- Assert(pGMM->cSharedPages >= pGVM->gmm.s.cSharedPages);
- SUPR0Printf("GMMR0CleanupVM: hGVM=%#x left %#x shared pages behind!\n", pGVM->hSelf, pGVM->gmm.s.cSharedPages);
- pGMM->cLeftBehindSharedPages += pGVM->gmm.s.cSharedPages;
+ Assert(pGMM->cSharedPages >= pGVM->gmm.s.Stats.cSharedPages);
+ SUPR0Printf("GMMR0CleanupVM: hGVM=%#x left %#x shared pages behind!\n", pGVM->hSelf, pGVM->gmm.s.Stats.cSharedPages);
+ pGMM->cLeftBehindSharedPages += pGVM->gmm.s.Stats.cSharedPages;
}
/*
* Clean up balloon statistics in case the VM process crashed.
*/
- Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.cBalloonedPages);
- pGMM->cBalloonedPages -= pGVM->gmm.s.cBalloonedPages;
+ Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.Stats.cBalloonedPages);
+ pGMM->cBalloonedPages -= pGVM->gmm.s.Stats.cBalloonedPages;
/*
* Update the over-commitment management statistics.
*/
- pGMM->cReservedPages -= pGVM->gmm.s.Reserved.cBasePages
- + pGVM->gmm.s.Reserved.cFixedPages
- + pGVM->gmm.s.Reserved.cShadowPages;
- switch (pGVM->gmm.s.enmPolicy)
+ pGMM->cReservedPages -= pGVM->gmm.s.Stats.Reserved.cBasePages
+ + pGVM->gmm.s.Stats.Reserved.cFixedPages
+ + pGVM->gmm.s.Stats.Reserved.cShadowPages;
+ switch (pGVM->gmm.s.Stats.enmPolicy)
{
case GMMOCPOLICY_NO_OC:
break;
@@ -1276,9 +1322,9 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM)
}
/* zap the GVM data. */
- pGVM->gmm.s.enmPolicy = GMMOCPOLICY_INVALID;
- pGVM->gmm.s.enmPriority = GMMPRIORITY_INVALID;
- pGVM->gmm.s.fMayAllocate = false;
+ pGVM->gmm.s.Stats.enmPolicy = GMMOCPOLICY_INVALID;
+ pGVM->gmm.s.Stats.enmPriority = GMMPRIORITY_INVALID;
+ pGVM->gmm.s.Stats.fMayAllocate = false;
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
gmmR0MutexRelease(pGMM);
@@ -1334,7 +1380,7 @@ static bool gmmR0CleanupVMScanChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk)
pChunk->iFreeHead = iPage;
pChunk->cPrivate--;
pChunk->cFree++;
- pGVM->gmm.s.cPrivatePages--;
+ pGVM->gmm.s.Stats.cPrivatePages--;
cFree++;
}
else
@@ -1472,9 +1518,9 @@ GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePag
gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- if ( !pGVM->gmm.s.Reserved.cBasePages
- && !pGVM->gmm.s.Reserved.cFixedPages
- && !pGVM->gmm.s.Reserved.cShadowPages)
+ if ( !pGVM->gmm.s.Stats.Reserved.cBasePages
+ && !pGVM->gmm.s.Stats.Reserved.cFixedPages
+ && !pGVM->gmm.s.Stats.Reserved.cShadowPages)
{
/*
* Check if we can accommodate this.
@@ -1485,12 +1531,12 @@ GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePag
/*
* Update the records.
*/
- pGVM->gmm.s.Reserved.cBasePages = cBasePages;
- pGVM->gmm.s.Reserved.cFixedPages = cFixedPages;
- pGVM->gmm.s.Reserved.cShadowPages = cShadowPages;
- pGVM->gmm.s.enmPolicy = enmPolicy;
- pGVM->gmm.s.enmPriority = enmPriority;
- pGVM->gmm.s.fMayAllocate = true;
+ pGVM->gmm.s.Stats.Reserved.cBasePages = cBasePages;
+ pGVM->gmm.s.Stats.Reserved.cFixedPages = cFixedPages;
+ pGVM->gmm.s.Stats.Reserved.cShadowPages = cShadowPages;
+ pGVM->gmm.s.Stats.enmPolicy = enmPolicy;
+ pGVM->gmm.s.Stats.enmPriority = enmPriority;
+ pGVM->gmm.s.Stats.fMayAllocate = true;
pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages;
pGMM->cRegisteredVMs++;
@@ -1567,9 +1613,9 @@ GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePage
gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- if ( pGVM->gmm.s.Reserved.cBasePages
- && pGVM->gmm.s.Reserved.cFixedPages
- && pGVM->gmm.s.Reserved.cShadowPages)
+ if ( pGVM->gmm.s.Stats.Reserved.cBasePages
+ && pGVM->gmm.s.Stats.Reserved.cFixedPages
+ && pGVM->gmm.s.Stats.Reserved.cShadowPages)
{
/*
* Check if we can accommodate this.
@@ -1580,14 +1626,14 @@ GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePage
/*
* Update the records.
*/
- pGMM->cReservedPages -= pGVM->gmm.s.Reserved.cBasePages
- + pGVM->gmm.s.Reserved.cFixedPages
- + pGVM->gmm.s.Reserved.cShadowPages;
+ pGMM->cReservedPages -= pGVM->gmm.s.Stats.Reserved.cBasePages
+ + pGVM->gmm.s.Stats.Reserved.cFixedPages
+ + pGVM->gmm.s.Stats.Reserved.cShadowPages;
pGMM->cReservedPages += cBasePages + cFixedPages + cShadowPages;
- pGVM->gmm.s.Reserved.cBasePages = cBasePages;
- pGVM->gmm.s.Reserved.cFixedPages = cFixedPages;
- pGVM->gmm.s.Reserved.cShadowPages = cShadowPages;
+ pGVM->gmm.s.Stats.Reserved.cBasePages = cBasePages;
+ pGVM->gmm.s.Stats.Reserved.cFixedPages = cFixedPages;
+ pGVM->gmm.s.Stats.Reserved.cShadowPages = cShadowPages;
}
}
else
@@ -2337,12 +2383,12 @@ static bool gmmR0ShouldAllocatePagesInOtherChunks(PGVM pGVM)
/*
* Don't allocate a new chunk if we're
*/
- uint64_t cPgReserved = pGVM->gmm.s.Reserved.cBasePages
- + pGVM->gmm.s.Reserved.cFixedPages
- - pGVM->gmm.s.cBalloonedPages
+ uint64_t cPgReserved = pGVM->gmm.s.Stats.Reserved.cBasePages
+ + pGVM->gmm.s.Stats.Reserved.cFixedPages
+ - pGVM->gmm.s.Stats.cBalloonedPages
/** @todo what about shared pages? */;
- uint64_t cPgAllocated = pGVM->gmm.s.Allocated.cBasePages
- + pGVM->gmm.s.Allocated.cFixedPages;
+ uint64_t cPgAllocated = pGVM->gmm.s.Stats.Allocated.cBasePages
+ + pGVM->gmm.s.Stats.Allocated.cFixedPages;
uint64_t cPgDelta = cPgReserved - cPgAllocated;
if (cPgDelta < GMM_CHUNK_NUM_PAGES * 4)
return true;
@@ -2392,27 +2438,28 @@ static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGE
switch (enmAccount)
{
case GMMACCOUNT_BASE:
- if (RT_UNLIKELY( pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages
- > pGVM->gmm.s.Reserved.cBasePages))
+ if (RT_UNLIKELY( pGVM->gmm.s.Stats.Allocated.cBasePages + pGVM->gmm.s.Stats.cBalloonedPages + cPages
+ > pGVM->gmm.s.Stats.Reserved.cBasePages))
{
Log(("gmmR0AllocatePages:Base: Reserved=%#llx Allocated+Ballooned+Requested=%#llx+%#llx+%#x!\n",
- pGVM->gmm.s.Reserved.cBasePages, pGVM->gmm.s.Allocated.cBasePages, pGVM->gmm.s.cBalloonedPages, cPages));
+ pGVM->gmm.s.Stats.Reserved.cBasePages, pGVM->gmm.s.Stats.Allocated.cBasePages,
+ pGVM->gmm.s.Stats.cBalloonedPages, cPages));
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
break;
case GMMACCOUNT_SHADOW:
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cShadowPages + cPages > pGVM->gmm.s.Reserved.cShadowPages))
+ if (RT_UNLIKELY(pGVM->gmm.s.Stats.Allocated.cShadowPages + cPages > pGVM->gmm.s.Stats.Reserved.cShadowPages))
{
Log(("gmmR0AllocatePages:Shadow: Reserved=%#x Allocated+Requested=%#x+%#x!\n",
- pGVM->gmm.s.Reserved.cShadowPages, pGVM->gmm.s.Allocated.cShadowPages, cPages));
+ pGVM->gmm.s.Stats.Reserved.cShadowPages, pGVM->gmm.s.Stats.Allocated.cShadowPages, cPages));
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
break;
case GMMACCOUNT_FIXED:
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cFixedPages + cPages > pGVM->gmm.s.Reserved.cFixedPages))
+ if (RT_UNLIKELY(pGVM->gmm.s.Stats.Allocated.cFixedPages + cPages > pGVM->gmm.s.Stats.Reserved.cFixedPages))
{
Log(("gmmR0AllocatePages:Fixed: Reserved=%#x Allocated+Requested=%#x+%#x!\n",
- pGVM->gmm.s.Reserved.cFixedPages, pGVM->gmm.s.Allocated.cFixedPages, cPages));
+ pGVM->gmm.s.Stats.Reserved.cFixedPages, pGVM->gmm.s.Stats.Allocated.cFixedPages, cPages));
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
break;
@@ -2438,13 +2485,13 @@ static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGE
*/
switch (enmAccount)
{
- case GMMACCOUNT_BASE: pGVM->gmm.s.Allocated.cBasePages += cPages; break;
- case GMMACCOUNT_SHADOW: pGVM->gmm.s.Allocated.cShadowPages += cPages; break;
- case GMMACCOUNT_FIXED: pGVM->gmm.s.Allocated.cFixedPages += cPages; break;
+ case GMMACCOUNT_BASE: pGVM->gmm.s.Stats.Allocated.cBasePages += cPages; break;
+ case GMMACCOUNT_SHADOW: pGVM->gmm.s.Stats.Allocated.cShadowPages += cPages; break;
+ case GMMACCOUNT_FIXED: pGVM->gmm.s.Stats.Allocated.cFixedPages += cPages; break;
default: AssertMsgFailedReturn(("enmAccount=%d\n", enmAccount), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
}
- pGVM->gmm.s.cPrivatePages += cPages;
- pGMM->cAllocatedPages += cPages;
+ pGVM->gmm.s.Stats.cPrivatePages += cPages;
+ pGMM->cAllocatedPages += cPages;
/*
* Part two of it's-easy-in-legacy-memory-mode.
@@ -2523,13 +2570,13 @@ static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGE
if (RT_FAILURE(rc))
{
/* Update the statistics. */
- pGVM->gmm.s.cPrivatePages -= cPages;
- pGMM->cAllocatedPages -= cPages - iPage;
+ pGVM->gmm.s.Stats.cPrivatePages -= cPages;
+ pGMM->cAllocatedPages -= cPages - iPage;
switch (enmAccount)
{
- case GMMACCOUNT_BASE: pGVM->gmm.s.Allocated.cBasePages -= cPages; break;
- case GMMACCOUNT_SHADOW: pGVM->gmm.s.Allocated.cShadowPages -= cPages; break;
- case GMMACCOUNT_FIXED: pGVM->gmm.s.Allocated.cFixedPages -= cPages; break;
+ case GMMACCOUNT_BASE: pGVM->gmm.s.Stats.Allocated.cBasePages -= cPages; break;
+ case GMMACCOUNT_SHADOW: pGVM->gmm.s.Stats.Allocated.cShadowPages -= cPages; break;
+ case GMMACCOUNT_FIXED: pGVM->gmm.s.Stats.Allocated.cFixedPages -= cPages; break;
default: AssertMsgFailedReturn(("enmAccount=%d\n", enmAccount), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
}
@@ -2641,9 +2688,9 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
/* No allocations before the initial reservation has been made! */
- if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages
- && pGVM->gmm.s.Reserved.cFixedPages
- && pGVM->gmm.s.Reserved.cShadowPages))
+ if (RT_LIKELY( pGVM->gmm.s.Stats.Reserved.cBasePages
+ && pGVM->gmm.s.Stats.Reserved.cFixedPages
+ && pGVM->gmm.s.Stats.Reserved.cShadowPages))
{
/*
* Perform the updates.
@@ -2702,12 +2749,12 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo
{
AssertCompile(NIL_RTHCPHYS > GMM_GCPHYS_LAST && GMM_GCPHYS_UNSHAREABLE > GMM_GCPHYS_LAST);
Assert(pPage->Shared.cRefs);
- Assert(pGVM->gmm.s.cSharedPages);
- Assert(pGVM->gmm.s.Allocated.cBasePages);
+ Assert(pGVM->gmm.s.Stats.cSharedPages);
+ Assert(pGVM->gmm.s.Stats.Allocated.cBasePages);
Log(("GMMR0AllocateHandyPages: free shared page %x cRefs=%d\n", paPages[iPage].idSharedPage, pPage->Shared.cRefs));
- pGVM->gmm.s.cSharedPages--;
- pGVM->gmm.s.Allocated.cBasePages--;
+ pGVM->gmm.s.Stats.cSharedPages--;
+ pGVM->gmm.s.Stats.Allocated.cBasePages--;
if (!--pPage->Shared.cRefs)
gmmR0FreeSharedPage(pGMM, pGVM, paPages[iPage].idSharedPage, pPage);
else
@@ -2823,9 +2870,9 @@ GMMR0DECL(int) GMMR0AllocatePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMP
{
/* No allocations before the initial reservation has been made! */
- if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages
- && pGVM->gmm.s.Reserved.cFixedPages
- && pGVM->gmm.s.Reserved.cShadowPages))
+ if (RT_LIKELY( pGVM->gmm.s.Stats.Reserved.cBasePages
+ && pGVM->gmm.s.Stats.Reserved.cFixedPages
+ && pGVM->gmm.s.Stats.Reserved.cShadowPages))
rc = gmmR0AllocatePagesNew(pGMM, pGVM, cPages, paPages, enmAccount);
else
rc = VERR_WRONG_ORDER;
@@ -2911,11 +2958,11 @@ GMMR0DECL(int) GMMR0AllocateLargePage(PVM pVM, VMCPUID idCpu, uint32_t cbPage,
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
const unsigned cPages = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
- if (RT_UNLIKELY( pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cPages
- > pGVM->gmm.s.Reserved.cBasePages))
+ if (RT_UNLIKELY( pGVM->gmm.s.Stats.Allocated.cBasePages + pGVM->gmm.s.Stats.cBalloonedPages + cPages
+ > pGVM->gmm.s.Stats.Reserved.cBasePages))
{
Log(("GMMR0AllocateLargePage: Reserved=%#llx Allocated+Requested=%#llx+%#x!\n",
- pGVM->gmm.s.Reserved.cBasePages, pGVM->gmm.s.Allocated.cBasePages, cPages));
+ pGVM->gmm.s.Stats.Reserved.cBasePages, pGVM->gmm.s.Stats.Allocated.cBasePages, cPages));
gmmR0MutexRelease(pGMM);
return VERR_GMM_HIT_VM_ACCOUNT_LIMIT;
}
@@ -2957,9 +3004,9 @@ GMMR0DECL(int) GMMR0AllocateLargePage(PVM pVM, VMCPUID idCpu, uint32_t cbPage,
gmmR0AllocatePage(pGMM, pGVM->hSelf, pChunk, &PageDesc);
/* Update accounting. */
- pGVM->gmm.s.Allocated.cBasePages += cPages;
- pGVM->gmm.s.cPrivatePages += cPages;
- pGMM->cAllocatedPages += cPages;
+ pGVM->gmm.s.Stats.Allocated.cBasePages += cPages;
+ pGVM->gmm.s.Stats.cPrivatePages += cPages;
+ pGMM->cAllocatedPages += cPages;
gmmR0LinkChunk(pChunk, pSet);
gmmR0MutexRelease(pGMM);
@@ -3010,9 +3057,9 @@ GMMR0DECL(int) GMMR0FreeLargePage(PVM pVM, VMCPUID idCpu, uint32_t idPage)
{
const unsigned cPages = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages < cPages))
+ if (RT_UNLIKELY(pGVM->gmm.s.Stats.Allocated.cBasePages < cPages))
{
- Log(("GMMR0FreeLargePage: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Allocated.cBasePages, cPages));
+ Log(("GMMR0FreeLargePage: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Stats.Allocated.cBasePages, cPages));
gmmR0MutexRelease(pGMM);
return VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
}
@@ -3030,9 +3077,9 @@ GMMR0DECL(int) GMMR0FreeLargePage(PVM pVM, VMCPUID idCpu, uint32_t idPage)
gmmR0FreeChunk(pGMM, NULL, pChunk, false /*fRelaxedSem*/); /** @todo this can be relaxed too! */
/* Update accounting. */
- pGVM->gmm.s.Allocated.cBasePages -= cPages;
- pGVM->gmm.s.cPrivatePages -= cPages;
- pGMM->cAllocatedPages -= cPages;
+ pGVM->gmm.s.Stats.Allocated.cBasePages -= cPages;
+ pGVM->gmm.s.Stats.cPrivatePages -= cPages;
+ pGMM->cAllocatedPages -= cPages;
}
else
rc = VERR_GMM_PAGE_NOT_FOUND;
@@ -3241,6 +3288,15 @@ DECLINLINE(void) gmmR0FreeSharedPage(PGMM pGMM, PGVM pGVM, uint32_t idPage, PGMM
Assert(pGMM->cSharedPages > 0);
Assert(pGMM->cAllocatedPages > 0);
Assert(!pPage->Shared.cRefs);
+#if defined(VBOX_WITH_PAGE_SHARING) && defined(VBOX_STRICT) && HC_ARCH_BITS == 64
+ if (pPage->Shared.u14Checksum)
+ {
+ uint32_t uChecksum = gmmR0StrictPageChecksum(pGMM, pGVM, idPage);
+ uChecksum &= UINT32_C(0x00003fff);
+ AssertMsg(!uChecksum || uChecksum == pPage->Shared.u14Checksum,
+ ("%#x vs %#x - idPage=%#\n", uChecksum, pPage->Shared.u14Checksum, idPage));
+ }
+#endif
pChunk->cShared--;
pGMM->cAllocatedPages--;
@@ -3291,23 +3347,23 @@ static int gmmR0FreePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMFREEPAGEDES
switch (enmAccount)
{
case GMMACCOUNT_BASE:
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cBasePages < cPages))
+ if (RT_UNLIKELY(pGVM->gmm.s.Stats.Allocated.cBasePages < cPages))
{
- Log(("gmmR0FreePages: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Allocated.cBasePages, cPages));
+ Log(("gmmR0FreePages: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Stats.Allocated.cBasePages, cPages));
return VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
}
break;
case GMMACCOUNT_SHADOW:
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cShadowPages < cPages))
+ if (RT_UNLIKELY(pGVM->gmm.s.Stats.Allocated.cShadowPages < cPages))
{
- Log(("gmmR0FreePages: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Allocated.cShadowPages, cPages));
+ Log(("gmmR0FreePages: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Stats.Allocated.cShadowPages, cPages));
return VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
}
break;
case GMMACCOUNT_FIXED:
- if (RT_UNLIKELY(pGVM->gmm.s.Allocated.cFixedPages < cPages))
+ if (RT_UNLIKELY(pGVM->gmm.s.Stats.Allocated.cFixedPages < cPages))
{
- Log(("gmmR0FreePages: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Allocated.cFixedPages, cPages));
+ Log(("gmmR0FreePages: allocated=%#llx cPages=%#x!\n", pGVM->gmm.s.Stats.Allocated.cFixedPages, cPages));
return VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
}
break;
@@ -3333,8 +3389,8 @@ static int gmmR0FreePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMFREEPAGEDES
{
if (RT_LIKELY(pPage->Private.hGVM == pGVM->hSelf))
{
- Assert(pGVM->gmm.s.cPrivatePages);
- pGVM->gmm.s.cPrivatePages--;
+ Assert(pGVM->gmm.s.Stats.cPrivatePages);
+ pGVM->gmm.s.Stats.cPrivatePages--;
gmmR0FreePrivatePage(pGMM, pGVM, idPage, pPage);
}
else
@@ -3347,8 +3403,8 @@ static int gmmR0FreePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMFREEPAGEDES
}
else if (RT_LIKELY(GMM_PAGE_IS_SHARED(pPage)))
{
- Assert(pGVM->gmm.s.cSharedPages);
- pGVM->gmm.s.cSharedPages--;
+ Assert(pGVM->gmm.s.Stats.cSharedPages);
+ pGVM->gmm.s.Stats.cSharedPages--;
Assert(pPage->Shared.cRefs);
if (!--pPage->Shared.cRefs)
gmmR0FreeSharedPage(pGMM, pGVM, idPage, pPage);
@@ -3379,9 +3435,9 @@ static int gmmR0FreePages(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMFREEPAGEDES
*/
switch (enmAccount)
{
- case GMMACCOUNT_BASE: pGVM->gmm.s.Allocated.cBasePages -= iPage; break;
- case GMMACCOUNT_SHADOW: pGVM->gmm.s.Allocated.cShadowPages -= iPage; break;
- case GMMACCOUNT_FIXED: pGVM->gmm.s.Allocated.cFixedPages -= iPage; break;
+ case GMMACCOUNT_BASE: pGVM->gmm.s.Stats.Allocated.cBasePages -= iPage; break;
+ case GMMACCOUNT_SHADOW: pGVM->gmm.s.Stats.Allocated.cShadowPages -= iPage; break;
+ case GMMACCOUNT_FIXED: pGVM->gmm.s.Stats.Allocated.cFixedPages -= iPage; break;
default:
AssertMsgFailedReturn(("enmAccount=%d\n", enmAccount), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
}
@@ -3525,33 +3581,36 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
{
case GMMBALLOONACTION_INFLATE:
{
- if (RT_LIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cBalloonedPages <= pGVM->gmm.s.Reserved.cBasePages))
+ if (RT_LIKELY(pGVM->gmm.s.Stats.Allocated.cBasePages + pGVM->gmm.s.Stats.cBalloonedPages + cBalloonedPages
+ <= pGVM->gmm.s.Stats.Reserved.cBasePages))
{
/*
* Record the ballooned memory.
*/
pGMM->cBalloonedPages += cBalloonedPages;
- if (pGVM->gmm.s.cReqBalloonedPages)
+ if (pGVM->gmm.s.Stats.cReqBalloonedPages)
{
/* Codepath never taken. Might be interesting in the future to request ballooned memory from guests in low memory conditions.. */
AssertFailed();
- pGVM->gmm.s.cBalloonedPages += cBalloonedPages;
- pGVM->gmm.s.cReqActuallyBalloonedPages += cBalloonedPages;
- Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n", cBalloonedPages,
- pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqBalloonedPages, pGVM->gmm.s.cReqActuallyBalloonedPages));
+ pGVM->gmm.s.Stats.cBalloonedPages += cBalloonedPages;
+ pGVM->gmm.s.Stats.cReqActuallyBalloonedPages += cBalloonedPages;
+ Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx Req=%#llx Actual=%#llx (pending)\n",
+ cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.Stats.cBalloonedPages,
+ pGVM->gmm.s.Stats.cReqBalloonedPages, pGVM->gmm.s.Stats.cReqActuallyBalloonedPages));
}
else
{
- pGVM->gmm.s.cBalloonedPages += cBalloonedPages;
+ pGVM->gmm.s.Stats.cBalloonedPages += cBalloonedPages;
Log(("GMMR0BalloonedPages: +%#x - Global=%#llx / VM: Total=%#llx (user)\n",
- cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages));
+ cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.Stats.cBalloonedPages));
}
}
else
{
Log(("GMMR0BalloonedPages: cBasePages=%#llx Total=%#llx cBalloonedPages=%#llx Reserved=%#llx\n",
- pGVM->gmm.s.Allocated.cBasePages, pGVM->gmm.s.cBalloonedPages, cBalloonedPages, pGVM->gmm.s.Reserved.cBasePages));
+ pGVM->gmm.s.Stats.Allocated.cBasePages, pGVM->gmm.s.Stats.cBalloonedPages, cBalloonedPages,
+ pGVM->gmm.s.Stats.Reserved.cBasePages));
rc = VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH;
}
break;
@@ -3560,32 +3619,32 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
case GMMBALLOONACTION_DEFLATE:
{
/* Deflate. */
- if (pGVM->gmm.s.cBalloonedPages >= cBalloonedPages)
+ if (pGVM->gmm.s.Stats.cBalloonedPages >= cBalloonedPages)
{
/*
* Record the ballooned memory.
*/
Assert(pGMM->cBalloonedPages >= cBalloonedPages);
- pGMM->cBalloonedPages -= cBalloonedPages;
- pGVM->gmm.s.cBalloonedPages -= cBalloonedPages;
- if (pGVM->gmm.s.cReqDeflatePages)
+ pGMM->cBalloonedPages -= cBalloonedPages;
+ pGVM->gmm.s.Stats.cBalloonedPages -= cBalloonedPages;
+ if (pGVM->gmm.s.Stats.cReqDeflatePages)
{
AssertFailed(); /* This is path is for later. */
Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx Req=%#llx\n",
- cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages, pGVM->gmm.s.cReqDeflatePages));
+ cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.Stats.cBalloonedPages, pGVM->gmm.s.Stats.cReqDeflatePages));
/*
* Anything we need to do here now when the request has been completed?
*/
- pGVM->gmm.s.cReqDeflatePages = 0;
+ pGVM->gmm.s.Stats.cReqDeflatePages = 0;
}
else
Log(("GMMR0BalloonedPages: -%#x - Global=%#llx / VM: Total=%#llx (user)\n",
- cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.cBalloonedPages));
+ cBalloonedPages, pGMM->cBalloonedPages, pGVM->gmm.s.Stats.cBalloonedPages));
}
else
{
- Log(("GMMR0BalloonedPages: Total=%#llx cBalloonedPages=%#llx\n", pGVM->gmm.s.cBalloonedPages, cBalloonedPages));
+ Log(("GMMR0BalloonedPages: Total=%#llx cBalloonedPages=%#llx\n", pGVM->gmm.s.Stats.cBalloonedPages, cBalloonedPages));
rc = VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH;
}
break;
@@ -3594,10 +3653,10 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA
case GMMBALLOONACTION_RESET:
{
/* Reset to an empty balloon. */
- Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.cBalloonedPages);
+ Assert(pGMM->cBalloonedPages >= pGVM->gmm.s.Stats.cBalloonedPages);
- pGMM->cBalloonedPages -= pGVM->gmm.s.cBalloonedPages;
- pGVM->gmm.s.cBalloonedPages = 0;
+ pGMM->cBalloonedPages -= pGVM->gmm.s.Stats.cBalloonedPages;
+ pGVM->gmm.s.Stats.cBalloonedPages = 0;
break;
}
@@ -3706,9 +3765,9 @@ GMMR0DECL(int) GMMR0QueryMemoryStatsReq(PVM pVM, VMCPUID idCpu, PGMMMEMSTATSREQ
gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- pReq->cAllocPages = pGVM->gmm.s.Allocated.cBasePages;
- pReq->cBalloonedPages = pGVM->gmm.s.cBalloonedPages;
- pReq->cMaxPages = pGVM->gmm.s.Reserved.cBasePages;
+ pReq->cAllocPages = pGVM->gmm.s.Stats.Allocated.cBasePages;
+ pReq->cBalloonedPages = pGVM->gmm.s.Stats.cBalloonedPages;
+ pReq->cMaxPages = pGVM->gmm.s.Stats.Reserved.cBasePages;
pReq->cFreePages = pReq->cMaxPages - pReq->cAllocPages;
}
else
@@ -3933,7 +3992,7 @@ static int gmmR0MapChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, bool fRelaxedSe
* @param pChunk Pointer to the chunk to be mapped.
* @param ppvR3 Where to store the ring-3 address of the mapping.
*/
-static int gmmR0IsChunkMapped(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
+static bool gmmR0IsChunkMapped(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, PRTR3PTR ppvR3)
{
GMMR0CHUNKMTXSTATE MtxState;
gmmR0ChunkMutexAcquire(&MtxState, pGMM, pChunk, GMMR0CHUNK_MTX_KEEP_GIANT);
@@ -4121,38 +4180,241 @@ GMMR0DECL(int) GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3)
return rc;
}
+#ifdef VBOX_WITH_PAGE_SHARING
-typedef struct
+# ifdef VBOX_STRICT
+/**
+ * For checksumming shared pages in strict builds.
+ *
+ * The purpose is making sure that a page doesn't change.
+ *
+ * @returns Checksum, 0 on failure.
+ * @param GMM The GMM instance data.
+ * @param idPage The page ID.
+ */
+static uint32_t gmmR0StrictPageChecksum(PGMM pGMM, PGVM pGVM, uint32_t idPage)
{
- PAVLGCPTRNODECORE pNode;
- char *pszModuleName;
- char *pszVersion;
- VBOXOSFAMILY enmGuestOS;
-} GMMFINDMODULEBYNAME, *PGMMFINDMODULEBYNAME;
+ PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, idPage >> GMM_CHUNKID_SHIFT);
+ AssertMsgReturn(pChunk, ("idPage=%#x\n", idPage), 0);
+
+ uint8_t *pbChunk;
+ if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ return 0;
+ uint8_t const *pbPage = pbChunk + ((idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
+
+ return RTCrc32(pbPage, PAGE_SIZE);
+}
+# endif /* VBOX_STRICT */
+
+
+/**
+ * Calculates the module hash value.
+ *
+ * @returns Hash value.
+ * @param pszModuleName The module name.
+ * @param pszVersion The module version string.
+ */
+static uint32_t gmmR0ShModCalcHash(const char *pszModuleName, const char *pszVersion)
+{
+ return RTStrHash1ExN(3, pszModuleName, RTSTR_MAX, "::", (size_t)2, pszVersion, RTSTR_MAX);
+}
+
/**
- * Tree enumeration callback for finding identical modules by name and version
+ * Finds a global module.
+ *
+ * @returns Pointer to the global module on success, NULL if not found.
+ * @param pGMM The GMM instance data.
+ * @param uHash The hash as calculated by gmmR0ShModCalcHash.
+ * @param cbModule The module size.
+ * @param enmGuestOS The guest OS type.
+ * @param pszModuleName The module name.
+ * @param pszVersion The module version.
*/
-DECLCALLBACK(int) gmmR0CheckForIdenticalModule(PAVLGCPTRNODECORE pNode, void *pvUser)
+static PGMMSHAREDMODULE gmmR0ShModFindGlobal(PGMM pGMM, uint32_t uHash, uint32_t cbModule, VBOXOSFAMILY enmGuestOS,
+ uint32_t cRegions, const char *pszModuleName, const char *pszVersion,
+ struct VMMDEVSHAREDREGIONDESC const *paRegions)
{
- PGMMFINDMODULEBYNAME pInfo = (PGMMFINDMODULEBYNAME)pvUser;
- PGMMSHAREDMODULE pModule = (PGMMSHAREDMODULE)pNode;
-
- if ( pInfo
- && pInfo->enmGuestOS == pModule->enmGuestOS
- /** @todo replace with RTStrNCmp */
- && !strcmp(pModule->szName, pInfo->pszModuleName)
- && !strcmp(pModule->szVersion, pInfo->pszVersion))
+ for (PGMMSHAREDMODULE pGblMod = (PGMMSHAREDMODULE)RTAvllU32Get(&pGMM->pGlobalSharedModuleTree, uHash);
+ pGblMod;
+ pGblMod = (PGMMSHAREDMODULE)pGblMod->Core.pList)
{
- pInfo->pNode = pNode;
- return 1; /* stop search */
+ if (pGblMod->cbModule != cbModule)
+ continue;
+ if (pGblMod->enmGuestOS != enmGuestOS)
+ continue;
+ if (pGblMod->cRegions != cRegions)
+ continue;
+ if (strcmp(pGblMod->szName, pszModuleName))
+ continue;
+ if (strcmp(pGblMod->szVersion, pszVersion))
+ continue;
+
+ uint32_t i;
+ for (i = 0; i < cRegions; i++)
+ {
+ uint32_t off = paRegions[i].GCRegionAddr & PAGE_OFFSET_MASK;
+ if (pGblMod->aRegions[i].off != off)
+ break;
+
+ uint32_t cb = RT_ALIGN_32(paRegions[i].cbRegion + off, PAGE_SIZE);
+ if (pGblMod->aRegions[i].cb != cb)
+ break;
+ }
+
+ if (i == cRegions)
+ return pGblMod;
}
- return 0;
+
+ return NULL;
+}
+
+
+/**
+ * Creates a new global module.
+ *
+ * @returns VBox status code.
+ * @param pGMM The GMM instance data.
+ * @param uHash The hash as calculated by gmmR0ShModCalcHash.
+ * @param cbModule The module size.
+ * @param enmGuestOS The guest OS type.
+ * @param cRegions The number of regions.
+ * @param pszModuleName The module name.
+ * @param pszVersion The module version.
+ * @param paRegions The region descriptions.
+ * @param ppGblMod Where to return the new module on success.
+ */
+static int gmmR0ShModNewGlobal(PGMM pGMM, uint32_t uHash, uint32_t cbModule, VBOXOSFAMILY enmGuestOS,
+ uint32_t cRegions, const char *pszModuleName, const char *pszVersion,
+ struct VMMDEVSHAREDREGIONDESC const *paRegions, PGMMSHAREDMODULE *ppGblMod)
+{
+ Log(("gmmR0ShModNewGlobal: %s %s size %#x os %u rgn %u\n", pszModuleName, pszVersion, cbModule, cRegions));
+ if (pGMM->cShareableModules >= GMM_MAX_SHARED_GLOBAL_MODULES)
+ {
+ Log(("gmmR0ShModNewGlobal: Too many modules\n"));
+ return VERR_GMM_TOO_MANY_GLOBAL_MODULES;
+ }
+
+ PGMMSHAREDMODULE pGblMod = (PGMMSHAREDMODULE)RTMemAllocZ(RT_OFFSETOF(GMMSHAREDMODULE, aRegions[cRegions]));
+ if (!pGblMod)
+ {
+ Log(("gmmR0ShModNewGlobal: No memory\n"));
+ return VERR_NO_MEMORY;
+ }
+
+ pGblMod->Core.Key = uHash;
+ pGblMod->cbModule = cbModule;
+ pGblMod->cRegions = cRegions;
+ pGblMod->cUsers = 1;
+ pGblMod->enmGuestOS = enmGuestOS;
+ strcpy(pGblMod->szName, pszModuleName);
+ strcpy(pGblMod->szVersion, pszVersion);
+
+ for (uint32_t i = 0; i < cRegions; i++)
+ {
+ Log(("gmmR0ShModNewGlobal: rgn[%u]=%RGvLB%#x\n", i, paRegions[i].GCRegionAddr, paRegions[i].cbRegion));
+ pGblMod->aRegions[i].off = paRegions[i].GCRegionAddr & PAGE_OFFSET_MASK;
+ pGblMod->aRegions[i].cb = paRegions[i].cbRegion + pGblMod->aRegions[i].off;
+ pGblMod->aRegions[i].cb = RT_ALIGN_32(pGblMod->aRegions[i].cb, PAGE_SIZE);
+ pGblMod->aRegions[i].paidPages = NULL; /* allocated when needed. */
+ }
+
+ bool fInsert = RTAvllU32Insert(&pGMM->pGlobalSharedModuleTree, &pGblMod->Core);
+ Assert(fInsert); NOREF(fInsert);
+ pGMM->cShareableModules++;
+
+ *ppGblMod = pGblMod;
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Deletes a global module which is no longer referenced by anyone.
+ *
+ * @param pGMM The GMM instance data.
+ * @param pGblMod The module to delete.
+ */
+static void gmmR0ShModDeleteGlobal(PGMM pGMM, PGMMSHAREDMODULE pGblMod)
+{
+ Assert(pGblMod->cUsers == 0);
+ Assert(pGMM->cShareableModules > 0 && pGMM->cShareableModules <= GMM_MAX_SHARED_GLOBAL_MODULES);
+
+ void *pvTest = RTAvllU32RemoveNode(&pGMM->pGlobalSharedModuleTree, &pGblMod->Core);
+ Assert(pvTest == pGblMod); NOREF(pvTest);
+ pGMM->cShareableModules--;
+
+ uint32_t i = pGblMod->cRegions;
+ while (i-- > 0)
+ {
+ if (pGblMod->aRegions[i].paidPages)
+ {
+ /* We don't doing anything to the pages as they are handled by the
+ copy-on-write mechanism in PGM. */
+ RTMemFree(pGblMod->aRegions[i].paidPages);
+ pGblMod->aRegions[i].paidPages = NULL;
+ }
+ }
+ RTMemFree(pGblMod);
+}
+
+
+static int gmmR0ShModNewPerVM(PGVM pGVM, RTGCPTR GCBaseAddr, uint32_t cRegions, const VMMDEVSHAREDREGIONDESC *paRegions,
+ PGMMSHAREDMODULEPERVM *ppRecVM)
+{
+ if (pGVM->gmm.s.Stats.cShareableModules >= GMM_MAX_SHARED_PER_VM_MODULES)
+ return VERR_GMM_TOO_MANY_PER_VM_MODULES;
+
+ PGMMSHAREDMODULEPERVM pRecVM;
+ pRecVM = (PGMMSHAREDMODULEPERVM)RTMemAllocZ(RT_OFFSETOF(GMMSHAREDMODULEPERVM, aRegionsGCPtrs[cRegions]));
+ if (!pRecVM)
+ return VERR_NO_MEMORY;
+
+ pRecVM->Core.Key = GCBaseAddr;
+ for (uint32_t i = 0; i < cRegions; i++)
+ pRecVM->aRegionsGCPtrs[i] = paRegions[i].GCRegionAddr;
+
+ bool fInsert = RTAvlGCPtrInsert(&pGVM->gmm.s.pSharedModuleTree, &pRecVM->Core);
+ Assert(fInsert); NOREF(fInsert);
+ pGVM->gmm.s.Stats.cShareableModules++;
+
+ *ppRecVM = pRecVM;
+ return VINF_SUCCESS;
}
+static void gmmR0ShModDeletePerVM(PGMM pGMM, PGVM pGVM, PGMMSHAREDMODULEPERVM pRecVM, bool fRemove)
+{
+ /*
+ * Free the per-VM module.
+ */
+ PGMMSHAREDMODULE pGblMod = pRecVM->pGlobalModule;
+ pRecVM->pGlobalModule = NULL;
+
+ if (fRemove)
+ {
+ void *pvTest = RTAvlGCPtrRemove(&pGVM->gmm.s.pSharedModuleTree, pRecVM->Core.Key);
+ Assert(pvTest == &pRecVM->Core);
+ }
+
+ RTMemFree(pRecVM);
+
+ /*
+ * Release the global module.
+ * (In the registration bailout case, it might not be.)
+ */
+ if (pGblMod)
+ {
+ Assert(pGblMod->cUsers > 0);
+ pGblMod->cUsers--;
+ if (pGblMod->cUsers == 0)
+ gmmR0ShModDeleteGlobal(pGMM, pGblMod);
+ }
+}
+
+#endif /* VBOX_WITH_PAGE_SHARING */
+
/**
- * Registers a new shared module for the VM
+ * Registers a new shared module for the VM.
*
* @returns VBox status code.
* @param pVM VM handle
@@ -4160,17 +4422,21 @@ DECLCALLBACK(int) gmmR0CheckForIdenticalModule(PAVLGCPTRNODECORE pNode, void *pv
* @param enmGuestOS Guest OS type
* @param pszModuleName Module name
* @param pszVersion Module version
- * @param GCBaseAddr Module base address
+ * @param GCPtrModBase Module base address
* @param cbModule Module size
* @param cRegions Number of shared region descriptors
- * @param pRegions Shared region(s)
+ * @param paRegions Shared region(s)
*/
-GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule,
- unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions)
+GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY enmGuestOS, char *pszModuleName,
+ char *pszVersion, RTGCPTR GCPtrModBase, uint32_t cbModule,
+ uint32_t cRegions, struct VMMDEVSHAREDREGIONDESC const *paRegions)
{
#ifdef VBOX_WITH_PAGE_SHARING
/*
* Validate input and get the basics.
+ *
+ * Note! Turns out the module size does necessarily match the size of the
+ * regions. (iTunes on XP)
*/
PGMM pGMM;
GMM_GET_VALID_INSTANCE(pGMM, VERR_GMM_INSTANCE);
@@ -4179,7 +4445,33 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en
if (RT_FAILURE(rc))
return rc;
- Log(("GMMR0RegisterSharedModule %s %s base %RGv size %x\n", pszModuleName, pszVersion, GCBaseAddr, cbModule));
+ if (RT_UNLIKELY(cRegions > VMMDEVSHAREDREGIONDESC_MAX))
+ return VERR_GMM_TOO_MANY_REGIONS;
+
+ if (RT_UNLIKELY(cbModule == 0 || cbModule > _1G))
+ return VERR_GMM_BAD_SHARED_MODULE_SIZE;
+
+ uint32_t cbTotal = 0;
+ for (uint32_t i = 0; i < cRegions; i++)
+ {
+ if (RT_UNLIKELY(paRegions[i].cbRegion == 0 || paRegions[i].cbRegion > _1G))
+ return VERR_GMM_SHARED_MODULE_BAD_REGIONS_SIZE;
+
+ cbTotal += paRegions[i].cbRegion;
+ if (RT_UNLIKELY(cbTotal > _1G))
+ return VERR_GMM_SHARED_MODULE_BAD_REGIONS_SIZE;
+ }
+
+ AssertPtrReturn(pszModuleName, VERR_INVALID_POINTER);
+ if (RT_UNLIKELY(!memchr(pszModuleName, '\0', GMM_SHARED_MODULE_MAX_NAME_STRING)))
+ return VERR_GMM_MODULE_NAME_TOO_LONG;
+
+ AssertPtrReturn(pszVersion, VERR_INVALID_POINTER);
+ if (RT_UNLIKELY(!memchr(pszVersion, '\0', GMM_SHARED_MODULE_MAX_VERSION_STRING)))
+ return VERR_GMM_MODULE_NAME_TOO_LONG;
+
+ uint32_t const uHash = gmmR0ShModCalcHash(pszModuleName, pszVersion);
+ Log(("GMMR0RegisterSharedModule %s %s base %RGv size %x hash %x\n", pszModuleName, pszVersion, GCPtrModBase, cbModule, uHash));
/*
* Take the semaphore and do some more validations.
@@ -4187,146 +4479,82 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en
gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- bool fNewModule = false;
-
- /* Check if this module is already locally registered. */
- PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr);
- if (!pRecVM)
+ /*
+ * Check if this module is already locally registered and register
+ * it if it isn't. The base address is a unique module identifier
+ * locally.
+ */
+ PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, GCPtrModBase);
+ bool fNewModule = pRecVM == NULL;
+ if (fNewModule)
{
- pRecVM = (PGMMSHAREDMODULEPERVM)RTMemAllocZ(RT_OFFSETOF(GMMSHAREDMODULEPERVM, aRegions[cRegions]));
- if (!pRecVM)
+ rc = gmmR0ShModNewPerVM(pGVM, GCPtrModBase, cRegions, paRegions, &pRecVM);
+ if (RT_SUCCESS(rc))
{
- AssertFailed();
- rc = VERR_NO_MEMORY;
- goto end;
- }
- pRecVM->Core.Key = GCBaseAddr;
- pRecVM->cRegions = cRegions;
+ /*
+ * Find a matching global module, register a new one if needed.
+ */
+ PGMMSHAREDMODULE pGblMod = gmmR0ShModFindGlobal(pGMM, uHash, cbModule, enmGuestOS, cRegions,
+ pszModuleName, pszVersion, paRegions);
+ if (!pGblMod)
+ {
+ Assert(fNewModule);
+ rc = gmmR0ShModNewGlobal(pGMM, uHash, cbModule, enmGuestOS, cRegions,
+ pszModuleName, pszVersion, paRegions, &pGblMod);
+ if (RT_SUCCESS(rc))
+ {
+ pRecVM->pGlobalModule = pGblMod; /* (One referenced returned by gmmR0ShModNewGlobal.) */
+ Log(("GMMR0RegisterSharedModule: new module %s %s\n", pszModuleName, pszVersion));
+ }
+ else
+ gmmR0ShModDeletePerVM(pGMM, pGVM, pRecVM, true /*fRemove*/);
+ }
+ else
+ {
+ Assert(pGblMod->cUsers > 0 && pGblMod->cUsers < UINT32_MAX / 2);
+ pGblMod->cUsers++;
+ pRecVM->pGlobalModule = pGblMod;
- /* Save the region data as they can differ between VMs (address space scrambling or simply different loading order) */
- for (unsigned i = 0; i < cRegions; i++)
- {
- pRecVM->aRegions[i].GCRegionAddr = pRegions[i].GCRegionAddr;
- pRecVM->aRegions[i].cbRegion = RT_ALIGN_T(pRegions[i].cbRegion, PAGE_SIZE, uint32_t);
- pRecVM->aRegions[i].u32Alignment = 0;
- pRecVM->aRegions[i].paHCPhysPageID = NULL; /* unused */
+ Log(("GMMR0RegisterSharedModule: new per vm module %s %s, gbl users %d\n", pszModuleName, pszVersion, pGblMod->cUsers));
+ }
}
-
- bool ret = RTAvlGCPtrInsert(&pGVM->gmm.s.pSharedModuleTree, &pRecVM->Core);
- Assert(ret);
-
- Log(("GMMR0RegisterSharedModule: new local module %s\n", pszModuleName));
- fNewModule = true;
}
else
- rc = VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED;
-
- /* Check if this module is already globally registered. */
- PGMMSHAREDMODULE pGlobalModule = (PGMMSHAREDMODULE)RTAvlGCPtrGet(&pGMM->pGlobalSharedModuleTree, GCBaseAddr);
- if ( !pGlobalModule
- && enmGuestOS == VBOXOSFAMILY_Windows64)
{
- /* Two identical copies of e.g. Win7 x64 will typically not have a similar virtual address space layout for dlls or kernel modules.
- * Try to find identical binaries based on name and version.
+ /*
+ * Attempt to re-register an existing module.
*/
- GMMFINDMODULEBYNAME Info;
-
- Info.pNode = NULL;
- Info.pszVersion = pszVersion;
- Info.pszModuleName = pszModuleName;
- Info.enmGuestOS = enmGuestOS;
-
- Log(("Try to find identical module %s\n", pszModuleName));
- int ret = RTAvlGCPtrDoWithAll(&pGMM->pGlobalSharedModuleTree, true /* fFromLeft */, gmmR0CheckForIdenticalModule, &Info);
- if (ret == 1)
+ PGMMSHAREDMODULE pGblMod = gmmR0ShModFindGlobal(pGMM, uHash, cbModule, enmGuestOS, cRegions,
+ pszModuleName, pszVersion, paRegions);
+ if (pRecVM->pGlobalModule == pGblMod)
{
- Assert(Info.pNode);
- pGlobalModule = (PGMMSHAREDMODULE)Info.pNode;
- Log(("Found identical module at %RGv\n", pGlobalModule->Core.Key));
- }
- }
-
- if (!pGlobalModule)
- {
- Assert(fNewModule);
- Assert(!pRecVM->fCollision);
-
- pGlobalModule = (PGMMSHAREDMODULE)RTMemAllocZ(RT_OFFSETOF(GMMSHAREDMODULE, aRegions[cRegions]));
- if (!pGlobalModule)
- {
- AssertFailed();
- rc = VERR_NO_MEMORY;
- goto end;
- }
-
- pGlobalModule->Core.Key = GCBaseAddr;
- pGlobalModule->cbModule = cbModule;
- /* Input limit already safe; no need to check again. */
- /** @todo replace with RTStrCopy */
- strcpy(pGlobalModule->szName, pszModuleName);
- strcpy(pGlobalModule->szVersion, pszVersion);
-
- pGlobalModule->enmGuestOS = enmGuestOS;
- pGlobalModule->cRegions = cRegions;
-
- for (unsigned i = 0; i < cRegions; i++)
- {
- Log(("New region %d base=%RGv size %x\n", i, pRegions[i].GCRegionAddr, pRegions[i].cbRegion));
- pGlobalModule->aRegions[i].GCRegionAddr = pRegions[i].GCRegionAddr;
- pGlobalModule->aRegions[i].cbRegion = RT_ALIGN_T(pRegions[i].cbRegion, PAGE_SIZE, uint32_t);
- pGlobalModule->aRegions[i].u32Alignment = 0;
- pGlobalModule->aRegions[i].paHCPhysPageID = NULL; /* uninitialized. */
- }
-
- /* Save reference. */
- pRecVM->pGlobalModule = pGlobalModule;
- pRecVM->fCollision = false;
- pGlobalModule->cUsers++;
- rc = VINF_SUCCESS;
-
- bool ret = RTAvlGCPtrInsert(&pGMM->pGlobalSharedModuleTree, &pGlobalModule->Core);
- Assert(ret);
-
- Log(("GMMR0RegisterSharedModule: new global module %s\n", pszModuleName));
- }
- else
- {
- Assert(pGlobalModule->cUsers > 0);
-
- /* Make sure the name and version are identical. */
- /** @todo replace with RTStrNCmp */
- if ( !strcmp(pGlobalModule->szName, pszModuleName)
- && !strcmp(pGlobalModule->szVersion, pszVersion))
- {
- /* Save reference. */
- pRecVM->pGlobalModule = pGlobalModule;
- if ( fNewModule
- || pRecVM->fCollision == true) /* colliding module unregistered and new one registered since the last check */
- {
- pGlobalModule->cUsers++;
- Log(("GMMR0RegisterSharedModule: using existing module %s cUser=%d!\n", pszModuleName, pGlobalModule->cUsers));
- }
- pRecVM->fCollision = false;
- rc = VINF_SUCCESS;
+ Log(("GMMR0RegisterSharedModule: already registered %s %s, gbl users %d\n", pszModuleName, pszVersion, pGblMod->cUsers));
+ rc = VINF_GMM_SHARED_MODULE_ALREADY_REGISTERED;
}
else
{
- Log(("GMMR0RegisterSharedModule: module %s collision!\n", pszModuleName));
- pRecVM->fCollision = true;
- rc = VINF_PGM_SHARED_MODULE_COLLISION;
- goto end;
+ /** @todo may have to unregister+register when this happens in case it's caused
+ * by VBoxService crashing and being restarted... */
+ Log(("GMMR0RegisterSharedModule: Address clash!\n"
+ " incoming at %RGvLB%#x %s %s rgns %u\n"
+ " existing at %RGvLB%#x %s %s rgns %u\n",
+ GCPtrModBase, cbModule, pszModuleName, pszVersion, cRegions,
+ pRecVM->Core.Key, pRecVM->pGlobalModule->cbModule, pRecVM->pGlobalModule->szName,
+ pRecVM->pGlobalModule->szVersion, pRecVM->pGlobalModule->cRegions));
+ rc = VERR_GMM_SHARED_MODULE_ADDRESS_CLASH;
}
}
-
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
}
else
rc = VERR_GMM_IS_NOT_SANE;
-end:
gmmR0MutexRelease(pGMM);
return rc;
#else
+
+ NOREF(pVM); NOREF(idCpu); NOREF(enmGuestOS); NOREF(pszModuleName); NOREF(pszVersion);
+ NOREF(GCPtrModBase); NOREF(cbModule); NOREF(cRegions); NOREF(paRegions);
return VERR_NOT_IMPLEMENTED;
#endif
}
@@ -4350,7 +4578,8 @@ GMMR0DECL(int) GMMR0RegisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMREGISTE
AssertMsgReturn(pReq->Hdr.cbReq >= sizeof(*pReq) && pReq->Hdr.cbReq == RT_UOFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[pReq->cRegions]), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER);
/* Pass back return code in the request packet to preserve informational codes. (VMMR3CallR0 chokes on them) */
- pReq->rc = GMMR0RegisterSharedModule(pVM, idCpu, pReq->enmGuestOS, pReq->szName, pReq->szVersion, pReq->GCBaseAddr, pReq->cbModule, pReq->cRegions, pReq->aRegions);
+ pReq->rc = GMMR0RegisterSharedModule(pVM, idCpu, pReq->enmGuestOS, pReq->szName, pReq->szVersion,
+ pReq->GCBaseAddr, pReq->cbModule, pReq->cRegions, pReq->aRegions);
return VINF_SUCCESS;
}
@@ -4363,10 +4592,11 @@ GMMR0DECL(int) GMMR0RegisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMREGISTE
* @param idCpu VCPU id
* @param pszModuleName Module name
* @param pszVersion Module version
- * @param GCBaseAddr Module base address
+ * @param GCPtrModBase Module base address
* @param cbModule Module size
*/
-GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule)
+GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModuleName, char *pszVersion,
+ RTGCPTR GCPtrModBase, uint32_t cbModule)
{
#ifdef VBOX_WITH_PAGE_SHARING
/*
@@ -4379,7 +4609,14 @@ GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModu
if (RT_FAILURE(rc))
return rc;
- Log(("GMMR0UnregisterSharedModule %s %s base=%RGv size %x\n", pszModuleName, pszVersion, GCBaseAddr, cbModule));
+ AssertPtrReturn(pszModuleName, VERR_INVALID_POINTER);
+ AssertPtrReturn(pszVersion, VERR_INVALID_POINTER);
+ if (RT_UNLIKELY(!memchr(pszModuleName, '\0', GMM_SHARED_MODULE_MAX_NAME_STRING)))
+ return VERR_GMM_MODULE_NAME_TOO_LONG;
+ if (RT_UNLIKELY(!memchr(pszVersion, '\0', GMM_SHARED_MODULE_MAX_VERSION_STRING)))
+ return VERR_GMM_MODULE_NAME_TOO_LONG;
+
+ Log(("GMMR0UnregisterSharedModule %s %s base=%RGv size %x\n", pszModuleName, pszVersion, GCPtrModBase, cbModule));
/*
* Take the semaphore and do some more validations.
@@ -4387,53 +4624,19 @@ GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModu
gmmR0MutexAcquire(pGMM);
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr);
+ /*
+ * Locate and remove the specified module.
+ */
+ PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, GCPtrModBase);
if (pRecVM)
{
- /* Remove reference to global shared module. */
- if (!pRecVM->fCollision)
- {
- PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule;
- Assert(pRec);
-
- if (pRec) /* paranoia */
- {
- Assert(pRec->cUsers);
- pRec->cUsers--;
- if (pRec->cUsers == 0)
- {
- /* Free the ranges, but leave the pages intact as there might still be references; they will be cleared by the COW mechanism. */
- for (unsigned i = 0; i < pRec->cRegions; i++)
- if (pRec->aRegions[i].paHCPhysPageID)
- RTMemFree(pRec->aRegions[i].paHCPhysPageID);
-
- Assert(pRec->Core.Key == GCBaseAddr || pRec->enmGuestOS == VBOXOSFAMILY_Windows64);
- Assert(pRec->cRegions == pRecVM->cRegions);
-#ifdef VBOX_STRICT
- for (unsigned i = 0; i < pRecVM->cRegions; i++)
- {
- Assert(pRecVM->aRegions[i].GCRegionAddr == pRec->aRegions[i].GCRegionAddr);
- Assert(pRecVM->aRegions[i].cbRegion == pRec->aRegions[i].cbRegion);
- }
-#endif
-
- /* Remove from the tree and free memory. */
- RTAvlGCPtrRemove(&pGMM->pGlobalSharedModuleTree, pRec->Core.Key);
- RTMemFree(pRec);
- }
- }
- else
- rc = VERR_PGM_SHARED_MODULE_REGISTRATION_INCONSISTENCY;
- }
- else
- Assert(!pRecVM->pGlobalModule);
-
- /* Remove from the tree and free memory. */
- RTAvlGCPtrRemove(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr);
- RTMemFree(pRecVM);
+ /** @todo Do we need to do more validations here, like that the
+ * name + version + cbModule matches? */
+ Assert(pRecVM->pGlobalModule);
+ gmmR0ShModDeletePerVM(pGMM, pGVM, pRecVM, true /*fRemove*/);
}
else
- rc = VERR_PGM_SHARED_MODULE_NOT_FOUND;
+ rc = VERR_GMM_SHARED_MODULE_NOT_FOUND;
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
}
@@ -4443,6 +4646,8 @@ GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModu
gmmR0MutexRelease(pGMM);
return rc;
#else
+
+ NOREF(pVM); NOREF(idCpu); NOREF(pszModuleName); NOREF(pszVersion); NOREF(GCPtrModBase); NOREF(cbModule);
return VERR_NOT_IMPLEMENTED;
#endif
}
@@ -4485,8 +4690,8 @@ DECLINLINE(void) gmmR0UseSharedPage(PGMM pGMM, PGVM pGVM, PGMMPAGE pPage)
pGMM->cDuplicatePages++;
pPage->Shared.cRefs++;
- pGVM->gmm.s.cSharedPages++;
- pGVM->gmm.s.Allocated.cBasePages++;
+ pGVM->gmm.s.Stats.cSharedPages++;
+ pGVM->gmm.s.Stats.Allocated.cBasePages++;
}
@@ -4511,16 +4716,41 @@ DECLINLINE(void) gmmR0ConvertToSharedPage(PGMM pGMM, PGVM pGVM, RTHCPHYS HCPhys,
pGMM->cSharedPages++;
- pGVM->gmm.s.cSharedPages++;
- pGVM->gmm.s.cPrivatePages--;
+ pGVM->gmm.s.Stats.cSharedPages++;
+ pGVM->gmm.s.Stats.cPrivatePages--;
/* Modify the page structure. */
- pPage->Shared.pfn = (uint32_t)(uint64_t)(HCPhys >> PAGE_SHIFT);
- pPage->Shared.cRefs = 1;
- pPage->Common.u2State = GMM_PAGE_STATE_SHARED;
+ pPage->Shared.pfn = (uint32_t)(uint64_t)(HCPhys >> PAGE_SHIFT);
+ pPage->Shared.cRefs = 1;
+#ifdef VBOX_STRICT
+ pPage->Shared.u14Checksum = gmmR0StrictPageChecksum(pGMM, pGVM, idPage);
+#else
+ pPage->Shared.u14Checksum = 0;
+#endif
+ pPage->Shared.u2State = GMM_PAGE_STATE_SHARED;
}
+static int gmmR0SharedModuleCheckPageFirstTime(PGMM pGMM, PGVM pGVM, PGMMSHAREDMODULE pModule,
+ unsigned idxRegion, unsigned idxPage,
+ PGMMSHAREDPAGEDESC pPageDesc, PGMMSHAREDREGIONDESC pGlobalRegion)
+{
+ /* Easy case: just change the internal page type. */
+ PGMMPAGE pPage = gmmR0GetPage(pGMM, pPageDesc->idPage);
+ AssertMsgReturn(pPage, ("idPage=%#x (GCPhys=%RGp HCPhys=%RHp idxRegion=%#x idxPage=%#x) #1\n",
+ pPageDesc->idPage, pPageDesc->GCPhys, pPageDesc->HCPhys, idxRegion, idxPage),
+ VERR_PGM_PHYS_INVALID_PAGE_ID);
+
+ AssertMsg(pPageDesc->GCPhys == (pPage->Private.pfn << 12), ("desc %RGp gmm %RGp\n", pPageDesc->HCPhys, (pPage->Private.pfn << 12)));
+
+ gmmR0ConvertToSharedPage(pGMM, pGVM, pPageDesc->HCPhys, pPageDesc->idPage, pPage);
+
+ /* Keep track of these references. */
+ pGlobalRegion->paidPages[idxPage] = pPageDesc->idPage;
+
+ return VINF_SUCCESS;
+}
+
/**
* Checks specified shared module range for changes
*
@@ -4541,153 +4771,142 @@ DECLINLINE(void) gmmR0ConvertToSharedPage(PGMM pGMM, PGVM pGVM, RTHCPHYS HCPhys,
* @param idxPage Page index
* @param paPageDesc Page descriptor
*/
-GMMR0DECL(int) GMMR0SharedModuleCheckPage(PGVM pGVM, PGMMSHAREDMODULE pModule, unsigned idxRegion, unsigned idxPage,
+GMMR0DECL(int) GMMR0SharedModuleCheckPage(PGVM pGVM, PGMMSHAREDMODULE pModule, uint32_t idxRegion, uint32_t idxPage,
PGMMSHAREDPAGEDESC pPageDesc)
{
- int rc = VINF_SUCCESS;
- PGMM pGMM;
+ int rc;
+ PGMM pGMM;
GMM_GET_VALID_INSTANCE(pGMM, VERR_GMM_INSTANCE);
- unsigned cPages = pModule->aRegions[idxRegion].cbRegion >> PAGE_SHIFT;
- AssertReturn(idxRegion < pModule->cRegions, VERR_INVALID_PARAMETER);
- AssertReturn(idxPage < cPages, VERR_INVALID_PARAMETER);
+ AssertMsgReturn(idxRegion < pModule->cRegions,
+ ("idxRegion=%#x cRegions=%#x %s %s\n", idxRegion, pModule->cRegions, pModule->szName, pModule->szVersion),
+ VERR_INVALID_PARAMETER);
+
+ uint32_t const cPages = pModule->aRegions[idxRegion].cb >> PAGE_SHIFT;
+ AssertMsgReturn(idxPage < cPages,
+ ("idxRegion=%#x cRegions=%#x %s %s\n", idxRegion, pModule->cRegions, pModule->szName, pModule->szVersion),
+ VERR_INVALID_PARAMETER);
LogFlow(("GMMR0SharedModuleCheckRange %s base %RGv region %d idxPage %d\n", pModule->szName, pModule->Core.Key, idxRegion, idxPage));
+ /*
+ * First time; create a page descriptor array.
+ */
PGMMSHAREDREGIONDESC pGlobalRegion = &pModule->aRegions[idxRegion];
- if (!pGlobalRegion->paHCPhysPageID)
+ if (!pGlobalRegion->paidPages)
{
- /* First time; create a page descriptor array. */
Log(("Allocate page descriptor array for %d pages\n", cPages));
- pGlobalRegion->paHCPhysPageID = (uint32_t *)RTMemAlloc(cPages * sizeof(*pGlobalRegion->paHCPhysPageID));
- if (!pGlobalRegion->paHCPhysPageID)
- {
- AssertFailed();
- rc = VERR_NO_MEMORY;
- goto end;
- }
+ pGlobalRegion->paidPages = (uint32_t *)RTMemAlloc(cPages * sizeof(pGlobalRegion->paidPages[0]));
+ AssertReturn(pGlobalRegion->paidPages, VERR_NO_MEMORY);
+
/* Invalidate all descriptors. */
- for (unsigned i = 0; i < cPages; i++)
- pGlobalRegion->paHCPhysPageID[i] = NIL_GMM_PAGEID;
+ uint32_t i = cPages;
+ while (i-- > 0)
+ pGlobalRegion->paidPages[i] = NIL_GMM_PAGEID;
}
- /* We've seen this shared page for the first time? */
- if (pGlobalRegion->paHCPhysPageID[idxPage] == NIL_GMM_PAGEID)
+ /*
+ * We've seen this shared page for the first time?
+ */
+ if (pGlobalRegion->paidPages[idxPage] == NIL_GMM_PAGEID)
{
-new_shared_page:
Log(("New shared page guest %RGp host %RHp\n", pPageDesc->GCPhys, pPageDesc->HCPhys));
+ return gmmR0SharedModuleCheckPageFirstTime(pGMM, pGVM, pModule, idxRegion, idxPage, pPageDesc, pGlobalRegion);
+ }
- /* Easy case: just change the internal page type. */
- PGMMPAGE pPage = gmmR0GetPage(pGMM, pPageDesc->uHCPhysPageId);
- if (!pPage)
- {
- Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #1 (GCPhys=%RGp HCPhys=%RHp idxRegion=%#x idxPage=%#x)\n",
- pPageDesc->uHCPhysPageId, pPageDesc->GCPhys, pPageDesc->HCPhys, idxRegion, idxPage));
- AssertFailed();
- rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
- goto end;
- }
-
- AssertMsg(pPageDesc->GCPhys == (pPage->Private.pfn << 12), ("desc %RGp gmm %RGp\n", pPageDesc->HCPhys, (pPage->Private.pfn << 12)));
+ /*
+ * We've seen it before...
+ */
+ Log(("Replace existing page guest %RGp host %RHp id %#x -> id %#x\n",
+ pPageDesc->GCPhys, pPageDesc->HCPhys, pPageDesc->idPage, pGlobalRegion->paidPages[idxPage]));
+ Assert(pPageDesc->idPage != pGlobalRegion->paidPages[idxPage]);
- gmmR0ConvertToSharedPage(pGMM, pGVM, pPageDesc->HCPhys, pPageDesc->uHCPhysPageId, pPage);
+ /*
+ * Get the shared page source.
+ */
+ PGMMPAGE pPage = gmmR0GetPage(pGMM, pGlobalRegion->paidPages[idxPage]);
+ AssertMsgReturn(pPage, ("idPage=%#x (idxRegion=%#x idxPage=%#x) #2\n", pPageDesc->idPage, idxRegion, idxPage),
+ VERR_PGM_PHYS_INVALID_PAGE_ID);
- /* Keep track of these references. */
- pGlobalRegion->paHCPhysPageID[idxPage] = pPageDesc->uHCPhysPageId;
- }
- else
+ if (pPage->Common.u2State != GMM_PAGE_STATE_SHARED)
{
- uint8_t *pbLocalPage, *pbSharedPage;
- uint8_t *pbChunk;
- PGMMCHUNK pChunk;
-
- Assert(pPageDesc->uHCPhysPageId != pGlobalRegion->paHCPhysPageID[idxPage]);
+ /*
+ * Page was freed at some point; invalidate this entry.
+ */
+ /** @todo this isn't really bullet proof. */
+ Log(("Old shared page was freed -> create a new one\n"));
+ pGlobalRegion->paidPages[idxPage] = NIL_GMM_PAGEID;
+ return gmmR0SharedModuleCheckPageFirstTime(pGMM, pGVM, pModule, idxRegion, idxPage, pPageDesc, pGlobalRegion);
+ }
- Log(("Replace existing page guest %RGp host %RHp id %x -> id %x\n", pPageDesc->GCPhys, pPageDesc->HCPhys, pPageDesc->uHCPhysPageId, pGlobalRegion->paHCPhysPageID[idxPage]));
+ Log(("Replace existing page guest host %RHp -> %RHp\n", pPageDesc->HCPhys, ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT));
- /* Get the shared page source. */
- PGMMPAGE pPage = gmmR0GetPage(pGMM, pGlobalRegion->paHCPhysPageID[idxPage]);
- if (!pPage)
- {
- Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #2 (idxRegion=%#x idxPage=%#x)\n",
- pPageDesc->uHCPhysPageId, idxRegion, idxPage));
- AssertFailed();
- rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
- goto end;
- }
- if (pPage->Common.u2State != GMM_PAGE_STATE_SHARED)
- {
- /* Page was freed at some point; invalidate this entry. */
- /** @todo this isn't really bullet proof. */
- Log(("Old shared page was freed -> create a new one\n"));
- pGlobalRegion->paHCPhysPageID[idxPage] = NIL_GMM_PAGEID;
- goto new_shared_page; /* ugly goto */
- }
+ /*
+ * Calculate the virtual address of the local page.
+ */
+ PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, pPageDesc->idPage >> GMM_CHUNKID_SHIFT);
+ AssertMsgReturn(pChunk, ("idPage=%#x (idxRegion=%#x idxPage=%#x) #4\n", pPageDesc->idPage, idxRegion, idxPage),
+ VERR_PGM_PHYS_INVALID_PAGE_ID);
- Log(("Replace existing page guest host %RHp -> %RHp\n", pPageDesc->HCPhys, ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT));
+ uint8_t *pbChunk;
+ AssertMsgReturn(gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk),
+ ("idPage=%#x (idxRegion=%#x idxPage=%#x) #3\n", pPageDesc->idPage, idxRegion, idxPage),
+ VERR_PGM_PHYS_INVALID_PAGE_ID);
+ uint8_t *pbLocalPage = pbChunk + ((pPageDesc->idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
- /* Calculate the virtual address of the local page. */
- pChunk = gmmR0GetChunk(pGMM, pPageDesc->uHCPhysPageId >> GMM_CHUNKID_SHIFT);
- if (pChunk)
- {
- if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
- {
- Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #3\n", pPageDesc->uHCPhysPageId));
- AssertFailed();
- rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
- goto end;
- }
- pbLocalPage = pbChunk + ((pPageDesc->uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
- }
- else
- {
- Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #4\n", pPageDesc->uHCPhysPageId));
- AssertFailed();
- rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
- goto end;
- }
-
- /* Calculate the virtual address of the shared page. */
- pChunk = gmmR0GetChunk(pGMM, pGlobalRegion->paHCPhysPageID[idxPage] >> GMM_CHUNKID_SHIFT);
- Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */
+ /*
+ * Calculate the virtual address of the shared page.
+ */
+ pChunk = gmmR0GetChunk(pGMM, pGlobalRegion->paidPages[idxPage] >> GMM_CHUNKID_SHIFT);
+ Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */
- /* Get the virtual address of the physical page; map the chunk into the VM process if not already done. */
- if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
- {
- Log(("Map chunk into process!\n"));
- rc = gmmR0MapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/, (PRTR3PTR)&pbChunk);
- if (rc != VINF_SUCCESS)
- {
- AssertRC(rc);
- goto end;
- }
- }
- pbSharedPage = pbChunk + ((pGlobalRegion->paHCPhysPageID[idxPage] & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
+ /*
+ * Get the virtual address of the physical page; map the chunk into the VM
+ * process if not already done.
+ */
+ if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
+ {
+ Log(("Map chunk into process!\n"));
+ rc = gmmR0MapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/, (PRTR3PTR)&pbChunk);
+ AssertRCReturn(rc, rc);
+ }
+ uint8_t *pbSharedPage = pbChunk + ((pGlobalRegion->paidPages[idxPage] & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
+#ifdef VBOX_STRICT
+ if (pPage->Shared.u14Checksum)
+ {
+ uint32_t uChecksum = RTCrc32(pbSharedPage, PAGE_SIZE) & UINT32_C(0x00003fff);
+ AssertMsg(!uChecksum || uChecksum == pPage->Shared.u14Checksum,
+ ("%#x vs %#x - idPage=%# - %s %s\n", uChecksum, pPage->Shared.u14Checksum,
+ pGlobalRegion->paidPages[idxPage], pModule->szName, pModule->szVersion));
+ }
+#endif
- /** @todo write ASMMemComparePage. */
- if (memcmp(pbSharedPage, pbLocalPage, PAGE_SIZE))
- {
- Log(("Unexpected differences found between local and shared page; skip\n"));
- /* Signal to the caller that this one hasn't changed. */
- pPageDesc->uHCPhysPageId = NIL_GMM_PAGEID;
- goto end;
- }
+ /** @todo write ASMMemComparePage. */
+ if (memcmp(pbSharedPage, pbLocalPage, PAGE_SIZE))
+ {
+ Log(("Unexpected differences found between local and shared page; skip\n"));
+ /* Signal to the caller that this one hasn't changed. */
+ pPageDesc->idPage = NIL_GMM_PAGEID;
+ return VINF_SUCCESS;
+ }
- /* Free the old local page. */
- GMMFREEPAGEDESC PageDesc;
+ /*
+ * Free the old local page.
+ */
+ GMMFREEPAGEDESC PageDesc;
+ PageDesc.idPage = pPageDesc->idPage;
+ rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE);
+ AssertRCReturn(rc, rc);
- PageDesc.idPage = pPageDesc->uHCPhysPageId;
- rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE);
- AssertRCReturn(rc, rc);
+ gmmR0UseSharedPage(pGMM, pGVM, pPage);
- gmmR0UseSharedPage(pGMM, pGVM, pPage);
+ /*
+ * Pass along the new physical address & page id.
+ */
+ pPageDesc->HCPhys = ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT;
+ pPageDesc->idPage = pGlobalRegion->paidPages[idxPage];
- /* Pass along the new physical address & page id. */
- pPageDesc->HCPhys = ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT;
- pPageDesc->uHCPhysPageId = pGlobalRegion->paHCPhysPageID[idxPage];
- }
-end:
- return rc;
+ return VINF_SUCCESS;
}
@@ -4695,38 +4914,16 @@ end:
* RTAvlGCPtrDestroy callback.
*
* @returns 0 or VERR_GMM_INSTANCE.
- * @param pNode The node to destroy.
- * @param pvGVM The GVM handle.
+ * @param pNode The node to destroy.
+ * @param pvArgs Pointer to an argument packet.
*/
-static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvGVM)
+static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvArgs)
{
- PGVM pGVM = (PGVM)pvGVM;
- PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)pNode;
-
- Assert(pRecVM->pGlobalModule || pRecVM->fCollision);
- if (pRecVM->pGlobalModule)
- {
- PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule;
- AssertPtr(pRec);
- Assert(pRec->cUsers);
-
- Log(("gmmR0CleanupSharedModule: %s %s cUsers=%d\n", pRec->szName, pRec->szVersion, pRec->cUsers));
- pRec->cUsers--;
- if (pRec->cUsers == 0)
- {
- for (uint32_t i = 0; i < pRec->cRegions; i++)
- if (pRec->aRegions[i].paHCPhysPageID)
- RTMemFree(pRec->aRegions[i].paHCPhysPageID);
-
- /* Remove from the tree and free memory. */
- PGMM pGMM;
- GMM_GET_VALID_INSTANCE(pGMM, VERR_GMM_INSTANCE);
- RTAvlGCPtrRemove(&pGMM->pGlobalSharedModuleTree, pRec->Core.Key);
- RTMemFree(pRec);
- }
- }
- RTMemFree(pRecVM);
- return 0;
+ gmmR0ShModDeletePerVM(((GMMR0SHMODPERVMDTORARGS *)pvArgs)->pGMM,
+ ((GMMR0SHMODPERVMDTORARGS *)pvArgs)->pGVM,
+ (PGMMSHAREDMODULEPERVM)pNode,
+ false /*fRemove*/);
+ return VINF_SUCCESS;
}
@@ -4744,7 +4941,13 @@ static void gmmR0SharedModuleCleanup(PGMM pGMM, PGVM pGVM)
gmmR0MutexAcquire(pGMM);
GMM_CHECK_SANITY_UPON_ENTERING(pGMM);
- RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, pGVM);
+ GMMR0SHMODPERVMDTORARGS Args;
+ Args.pGVM = pGVM;
+ Args.pGMM = pGMM;
+ RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, &Args);
+
+ Assert(pGVM->gmm.s.Stats.cShareableModules == 0);
+ pGVM->gmm.s.Stats.cShareableModules = 0;
gmmR0MutexRelease(pGMM);
}
@@ -4778,7 +4981,11 @@ GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu)
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
Log(("GMMR0ResetSharedModules\n"));
- RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, pGVM);
+ GMMR0SHMODPERVMDTORARGS Args;
+ Args.pGVM = pGVM;
+ Args.pGMM = pGMM;
+ RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, &Args);
+ pGVM->gmm.s.Stats.cShareableModules = 0;
rc = VINF_SUCCESS;
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
@@ -4789,37 +4996,29 @@ GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu)
gmmR0MutexRelease(pGMM);
return rc;
#else
+ NOREF(pVM); NOREF(idCpu);
return VERR_NOT_IMPLEMENTED;
#endif
}
#ifdef VBOX_WITH_PAGE_SHARING
-typedef struct
-{
- PGVM pGVM;
- VMCPUID idCpu;
- int rc;
-} GMMCHECKSHAREDMODULEINFO, *PGMMCHECKSHAREDMODULEINFO;
-
/**
* Tree enumeration callback for checking a shared module.
*/
-DECLCALLBACK(int) gmmR0CheckSharedModule(PAVLGCPTRNODECORE pNode, void *pvUser)
+static DECLCALLBACK(int) gmmR0CheckSharedModule(PAVLGCPTRNODECORE pNode, void *pvUser)
{
- PGMMCHECKSHAREDMODULEINFO pInfo = (PGMMCHECKSHAREDMODULEINFO)pvUser;
- PGMMSHAREDMODULEPERVM pLocalModule = (PGMMSHAREDMODULEPERVM)pNode;
- PGMMSHAREDMODULE pGlobalModule = pLocalModule->pGlobalModule;
+ GMMCHECKSHAREDMODULEINFO *pArgs = (GMMCHECKSHAREDMODULEINFO*)pvUser;
+ PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)pNode;
+ PGMMSHAREDMODULE pGblMod = pRecVM->pGlobalModule;
- if ( !pLocalModule->fCollision
- && pGlobalModule)
- {
- Log(("gmmR0CheckSharedModule: check %s %s base=%RGv size=%x collision=%d\n", pGlobalModule->szName, pGlobalModule->szVersion, pGlobalModule->Core.Key, pGlobalModule->cbModule, pLocalModule->fCollision));
- pInfo->rc = PGMR0SharedModuleCheck(pInfo->pGVM->pVM, pInfo->pGVM, pInfo->idCpu, pGlobalModule, pLocalModule->cRegions, pLocalModule->aRegions);
- if (RT_FAILURE(pInfo->rc))
- return 1; /* stop enumeration. */
- }
- return 0;
+ Log(("gmmR0CheckSharedModule: check %s %s base=%RGv size=%x\n",
+ pGblMod->szName, pGblMod->szVersion, pGblMod->Core.Key, pGblMod->cbModule));
+
+ int rc = PGMR0SharedModuleCheck(pArgs->pGVM->pVM, pArgs->pGVM, pArgs->idCpu, pGblMod, pRecVM->aRegionsGCPtrs);
+ if (RT_FAILURE(rc))
+ return rc;
+ return VINF_SUCCESS;
}
#endif /* VBOX_WITH_PAGE_SHARING */
@@ -4872,7 +5071,7 @@ GMMR0DECL(int) GMMR0CheckSharedModulesEnd(PVM pVM)
#endif /* DEBUG_sandervl */
/**
- * Check all shared modules for the specified VM
+ * Check all shared modules for the specified VM.
*
* @returns VBox status code.
* @param pVM VM handle
@@ -4899,19 +5098,17 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu)
# endif
if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
{
- GMMCHECKSHAREDMODULEINFO Info;
-
+ /*
+ * Walk the tree, checking each module.
+ */
Log(("GMMR0CheckSharedModules\n"));
- Info.pGVM = pGVM;
- Info.idCpu = pVCpu->idCpu;
- Info.rc = VINF_SUCCESS;
-
- RTAvlGCPtrDoWithAll(&pGVM->gmm.s.pSharedModuleTree, true /* fFromLeft */, gmmR0CheckSharedModule, &Info);
- rc = Info.rc;
+ GMMCHECKSHAREDMODULEINFO Args;
+ Args.pGVM = pGVM;
+ Args.idCpu = pVCpu->idCpu;
+ rc = RTAvlGCPtrDoWithAll(&pGVM->gmm.s.pSharedModuleTree, true /* fFromLeft */, gmmR0CheckSharedModule, &Args);
Log(("GMMR0CheckSharedModules done!\n"));
-
GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
}
else
@@ -4922,33 +5119,26 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu)
# endif
return rc;
#else
+ NOREF(pVM); NOREF(pVCpu);
return VERR_NOT_IMPLEMENTED;
#endif
}
#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
-typedef struct
-{
- PGVM pGVM;
- PGMM pGMM;
- uint8_t *pSourcePage;
- bool fFoundDuplicate;
-} GMMFINDDUPPAGEINFO, *PGMMFINDDUPPAGEINFO;
-
/**
* RTAvlU32DoWithAll callback.
*
* @returns 0
- * @param pNode The node to search.
- * @param pvInfo Pointer to the input parameters
+ * @param pNode The node to search.
+ * @param pvUser Pointer to the input argument packet.
*/
-static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvInfo)
+static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvUser)
{
PGMMCHUNK pChunk = (PGMMCHUNK)pNode;
- PGMMFINDDUPPAGEINFO pInfo = (PGMMFINDDUPPAGEINFO)pvInfo;
- PGVM pGVM = pInfo->pGVM;
- PGMM pGMM = pInfo->pGMM;
+ GMMFINDDUPPAGEINFO *pArgs = (GMMFINDDUPPAGEINFO *)pvUser;
+ PGVM pGVM = pArgs->pGVM;
+ PGMM pGMM = pArgs->pGMM;
uint8_t *pbChunk;
/* Only take chunks not mapped into this VM process; not entirely correct. */
@@ -4967,9 +5157,9 @@ static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pv
{
uint8_t *pbDestPage = pbChunk + (iPage << PAGE_SHIFT);
- if (!memcmp(pInfo->pSourcePage, pbDestPage, PAGE_SIZE))
+ if (!memcmp(pArgs->pSourcePage, pbDestPage, PAGE_SIZE))
{
- pInfo->fFoundDuplicate = true;
+ pArgs->fFoundDuplicate = true;
break;
}
}
@@ -4977,7 +5167,7 @@ static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pv
gmmR0UnmapChunk(pGMM, pGVM, pChunk, false /*fRelaxedSem*/);
}
}
- return pInfo->fFoundDuplicate; /* (stops search if true) */
+ return pArgs->fFoundDuplicate; /* (stops search if true) */
}
@@ -5021,14 +5211,14 @@ GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq)
PGMMPAGE pPage = gmmR0GetPage(pGMM, pReq->idPage);
if (pPage)
{
- GMMFINDDUPPAGEINFO Info;
- Info.pGVM = pGVM;
- Info.pGMM = pGMM;
- Info.pSourcePage = pbSourcePage;
- Info.fFoundDuplicate = false;
- RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0FindDupPageInChunk, &Info);
-
- pReq->fDuplicate = Info.fFoundDuplicate;
+ GMMFINDDUPPAGEINFO Args;
+ Args.pGVM = pGVM;
+ Args.pGMM = pGMM;
+ Args.pSourcePage = pbSourcePage;
+ Args.fFoundDuplicate = false;
+ RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0FindDupPageInChunk, &Args);
+
+ pReq->fDuplicate = Args.fFoundDuplicate;
}
else
{
@@ -5051,3 +5241,128 @@ GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq)
#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */
+
+/**
+ * Retrieves the GMM statistics visible to the caller.
+ *
+ * @returns VBox status code.
+ *
+ * @param pStats Where to put the statistics.
+ * @param pSession The current session.
+ * @param pVM The VM to obtain statistics for. Optional.
+ */
+GMMR0DECL(int) GMMR0QueryStatistics(PGMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM)
+{
+ LogFlow(("GVMMR0QueryStatistics: pStats=%p pSession=%p pVM=%p\n", pStats, pSession, pVM));
+
+ /*
+ * Validate input.
+ */
+ AssertPtrReturn(pSession, VERR_INVALID_POINTER);
+ AssertPtrReturn(pStats, VERR_INVALID_POINTER);
+ pStats->cMaxPages = 0; /* (crash before taking the mutex...) */
+
+ PGMM pGMM;
+ GMM_GET_VALID_INSTANCE(pGMM, VERR_GMM_INSTANCE);
+
+ /*
+ * Resolve the VM handle, if not NULL, and lock the GMM.
+ */
+ int rc;
+ PGVM pGVM;
+ if (pVM)
+ {
+ rc = GVMMR0ByVM(pVM, &pGVM);
+ if (RT_FAILURE(rc))
+ return rc;
+ }
+ else
+ pGVM = NULL;
+
+ rc = gmmR0MutexAcquire(pGMM);
+ if (RT_FAILURE(rc))
+ return rc;
+
+ /*
+ * Copy out the GMM statistics.
+ */
+ pStats->cMaxPages = pGMM->cMaxPages;
+ pStats->cReservedPages = pGMM->cReservedPages;
+ pStats->cOverCommittedPages = pGMM->cOverCommittedPages;
+ pStats->cAllocatedPages = pGMM->cAllocatedPages;
+ pStats->cSharedPages = pGMM->cSharedPages;
+ pStats->cDuplicatePages = pGMM->cDuplicatePages;
+ pStats->cLeftBehindSharedPages = pGMM->cLeftBehindSharedPages;
+ pStats->cBalloonedPages = pGMM->cBalloonedPages;
+ pStats->cChunks = pGMM->cChunks;
+ pStats->cFreedChunks = pGMM->cFreedChunks;
+ pStats->cShareableModules = pGMM->cShareableModules;
+ RT_ZERO(pStats->au64Reserved);
+
+ /*
+ * Copy out the VM statistics.
+ */
+ if (pGVM)
+ pStats->VMStats = pGVM->gmm.s.Stats;
+ else
+ RT_ZERO(pStats->VMStats);
+
+ gmmR0MutexRelease(pGMM);
+ return rc;
+}
+
+
+/**
+ * VMMR0 request wrapper for GMMR0QueryStatistics.
+ *
+ * @returns see GMMR0QueryStatistics.
+ * @param pVM Pointer to the shared VM structure. Optional.
+ * @param pReq The request packet.
+ */
+GMMR0DECL(int) GMMR0QueryStatisticsReq(PVM pVM, PGMMQUERYSTATISTICSSREQ pReq)
+{
+ /*
+ * Validate input and pass it on.
+ */
+ AssertPtrReturn(pReq, VERR_INVALID_POINTER);
+ AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER);
+
+ return GMMR0QueryStatistics(&pReq->Stats, pReq->pSession, pVM);
+}
+
+
+/**
+ * Resets the specified GMM statistics.
+ *
+ * @returns VBox status code.
+ *
+ * @param pStats Which statistics to reset, that is, non-zero fields
+ * indicates which to reset.
+ * @param pSession The current session.
+ * @param pVM The VM to reset statistics for. Optional.
+ */
+GMMR0DECL(int) GMMR0ResetStatistics(PCGMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM)
+{
+ /* Currently nothing we can reset at the moment. */
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * VMMR0 request wrapper for GMMR0ResetStatistics.
+ *
+ * @returns see GMMR0ResetStatistics.
+ * @param pVM Pointer to the shared VM structure. Optional.
+ * @param pReq The request packet.
+ */
+GMMR0DECL(int) GMMR0ResetStatisticsReq(PVM pVM, PGMMRESETSTATISTICSSREQ pReq)
+{
+ /*
+ * Validate input and pass it on.
+ */
+ AssertPtrReturn(pReq, VERR_INVALID_POINTER);
+ AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER);
+
+ return GMMR0ResetStatistics(&pReq->Stats, pReq->pSession, pVM);
+}
+
diff --git a/src/VBox/VMM/VMMR0/GMMR0Internal.h b/src/VBox/VMM/VMMR0/GMMR0Internal.h
index 5dbfd70db..ca6f5e16d 100644
--- a/src/VBox/VMM/VMMR0/GMMR0Internal.h
+++ b/src/VBox/VMM/VMMR0/GMMR0Internal.h
@@ -21,22 +21,6 @@
#include <VBox/vmm/gmm.h>
#include <iprt/avl.h>
-/**
- * The allocation sizes.
- */
-typedef struct GMMVMSIZES
-{
- /** The number of pages of base memory.
- * This is the sum of RAM, ROMs and handy pages. */
- uint64_t cBasePages;
- /** The number of pages for the shadow pool. (Can be squeezed for memory.) */
- uint32_t cShadowPages;
- /** The number of pages for fixed allocations like MMIO2 and the hyper heap. */
- uint32_t cFixedPages;
-} GMMVMSIZES;
-/** Pointer to a GMMVMSIZES. */
-typedef GMMVMSIZES *PGMMVMSIZES;
-
/**
* Shared module registration info (per VM)
@@ -45,20 +29,13 @@ typedef struct GMMSHAREDMODULEPERVM
{
/** Tree node. */
AVLGCPTRNODECORE Core;
-
/** Pointer to global shared module info. */
PGMMSHAREDMODULE pGlobalModule;
-
- /** Set if another VM registered a different shared module at the same base address. */
- bool fCollision;
- /** Alignment. */
- bool bAlignment[3];
-
- /** Number of included region descriptors */
- uint32_t cRegions;
-
- /** Shared region descriptor(s). */
- GMMSHAREDREGIONDESC aRegions[1];
+ /** Pointer to the region addresses.
+ *
+ * They can differe between VMs because of address space scrambling or
+ * simply different loading order. */
+ RTGCPTR64 aRegionsGCPtrs[1];
} GMMSHAREDMODULEPERVM;
/** Pointer to a GMMSHAREDMODULEPERVM. */
typedef GMMSHAREDMODULEPERVM *PGMMSHAREDMODULEPERVM;
@@ -98,51 +75,12 @@ typedef struct GMMPERVM
{
/** Free set for use in bound mode. */
GMMCHUNKFREESET Private;
-
- /** The reservations. */
- GMMVMSIZES Reserved;
- /** The actual allocations.
- * This includes both private and shared page allocations. */
- GMMVMSIZES Allocated;
-
- /** The current number of private pages. */
- uint64_t cPrivatePages;
- /** The current number of shared pages. */
- uint64_t cSharedPages;
- /** The current over-commitment policy. */
- GMMOCPOLICY enmPolicy;
- /** The VM priority for arbitrating VMs in low and out of memory situation.
- * Like which VMs to start squeezing first. */
- GMMPRIORITY enmPriority;
- /** Hints at the last chunk we allocated some memory from. */
- uint32_t idLastChunkHint;
-
- /** The current number of ballooned pages. */
- uint64_t cBalloonedPages;
- /** The max number of pages that can be ballooned. */
- uint64_t cMaxBalloonedPages;
- /** The number of pages we've currently requested the guest to give us.
- * This is 0 if no pages currently requested. */
- uint64_t cReqBalloonedPages;
- /** The number of pages the guest has given us in response to the request.
- * This is not reset on request completed and may be used in later decisions. */
- uint64_t cReqActuallyBalloonedPages;
- /** The number of pages we've currently requested the guest to take back. */
- uint64_t cReqDeflatePages;
-
+ /** The VM statistics. */
+ GMMVMSTATS Stats;
/** Shared module tree (per-vm). */
PAVLGCPTRNODECORE pSharedModuleTree;
-
- /** Whether ballooning is enabled or not. */
- bool fBallooningEnabled;
-
- /** Whether shared paging is enabled or not. */
- bool fSharedPagingEnabled;
-
- /** Whether the VM is allowed to allocate memory or not.
- * This is used when the reservation update request fails or when the VM has
- * been told to suspend/save/die in an out-of-memory case. */
- bool fMayAllocate;
+ /** Hints at the last chunk we allocated some memory from. */
+ uint32_t idLastChunkHint;
} GMMPERVM;
/** Pointer to the per-VM GMM data. */
typedef GMMPERVM *PGMMPERVM;
diff --git a/src/VBox/VMM/VMMR0/HWVMXR0.cpp b/src/VBox/VMM/VMMR0/HWVMXR0.cpp
index 44d56b360..21917ae2a 100644
--- a/src/VBox/VMM/VMMR0/HWVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HWVMXR0.cpp
@@ -70,9 +70,9 @@ extern "C" uint32_t g_fVMXIs64bitHost;
* Local Functions *
*******************************************************************************/
static void VMXR0ReportWorldSwitchError(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc, PCPUMCTX pCtx);
-static void vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu);
-static void vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu);
-static void vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu);
+static DECLCALLBACK(void) vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu);
+static DECLCALLBACK(void) vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu);
+static DECLCALLBACK(void) vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu);
static void vmxR0FlushEPT(PVM pVM, PVMCPU pVCpu, VMX_FLUSH enmFlush, RTGCPHYS GCPhys);
static void vmxR0FlushVPID(PVM pVM, PVMCPU pVCpu, VMX_FLUSH enmFlush, RTGCPTR GCPtr);
static void vmxR0UpdateExceptionBitmap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
@@ -2150,7 +2150,7 @@ DECLINLINE(int) VMXR0SaveGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
* @param pVM The VM to operate on.
* @param pVCpu The VMCPU to operate on.
*/
-static void vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu)
+static DECLCALLBACK(void) vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu)
{
NOREF(pVM);
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_FLUSH);
@@ -2166,7 +2166,7 @@ static void vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu)
* @param pVM The VM to operate on.
* @param pVCpu The VMCPU to operate on.
*/
-static void vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu)
+static DECLCALLBACK(void) vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu)
{
PHMGLOBLCPUINFO pCpu;
@@ -2231,7 +2231,7 @@ static void vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu)
* @param pVM The VM to operate on.
* @param pVCpu The VMCPU to operate on.
*/
-static void vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu)
+static DECLCALLBACK(void) vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu)
{
PHMGLOBLCPUINFO pCpu;
diff --git a/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp b/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp
index 120428c7d..8a6ef8880 100644
--- a/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp
+++ b/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2010-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;
@@ -32,93 +32,103 @@
#ifdef VBOX_WITH_PAGE_SHARING
/**
- * Check a registered module for shared page changes
+ * Check a registered module for shared page changes.
+ *
+ * The PGM lock shall be taken prior to calling this method.
*
* @returns The following VBox status codes.
*
- * @param pVM The VM handle.
- * @param pGVM Pointer to the GVM instance data.
- * @param idCpu VCPU id
- * @param pModule Module description
- * @param cRegions Number of regions
- * @param pRegions Region array
+ * @param pVM The VM handle.
+ * @param pGVM Pointer to the GVM instance data.
+ * @param idCpu The ID of the calling virtual CPU.
+ * @param pModule Global module description
+ * @param paRegionsGCPtrs Array parallel to pModules->aRegions with the
+ * addresses of the regions in the calling
+ * process.
*/
-VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHAREDMODULE pModule, uint32_t cRegions, PGMMSHAREDREGIONDESC pRegions)
+VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHAREDMODULE pModule, PCRTGCPTR64 paRegionsGCPtrs)
{
- int rc = VINF_SUCCESS;
- GMMSHAREDPAGEDESC PageDesc;
- bool fFlushTLBs = false;
- PVMCPU pVCpu = &pVM->aCpus[idCpu];
+ PVMCPU pVCpu = &pVM->aCpus[idCpu];
+ int rc = VINF_SUCCESS;
+ bool fFlushTLBs = false;
+ bool fFlushRemTLBs = false;
+ GMMSHAREDPAGEDESC PageDesc;
Log(("PGMR0SharedModuleCheck: check %s %s base=%RGv size=%x\n", pModule->szName, pModule->szVersion, pModule->Core.Key, pModule->cbModule));
PGM_LOCK_ASSERT_OWNER(pVM); /* This cannot fail as we grab the lock in pgmR3SharedModuleRegRendezvous before calling into ring-0. */
- /* Check every region of the shared module. */
- for (unsigned idxRegion = 0; idxRegion < cRegions; idxRegion++)
+ /*
+ * Check every region of the shared module.
+ */
+ for (uint32_t idxRegion = 0; idxRegion < pModule->cRegions; idxRegion++)
{
- Assert((pRegions[idxRegion].cbRegion & 0xfff) == 0);
- Assert((pRegions[idxRegion].GCRegionAddr & 0xfff) == 0);
-
- RTGCPTR GCRegion = pRegions[idxRegion].GCRegionAddr;
- unsigned cbRegion = pRegions[idxRegion].cbRegion & ~0xfff;
- unsigned idxPage = 0;
+ RTGCPTR GCPtrPage = paRegionsGCPtrs[idxRegion] & ~(RTGCPTR)PAGE_OFFSET_MASK;
+ uint32_t cbLeft = pModule->aRegions[idxRegion].cb; Assert(!(cbLeft & PAGE_OFFSET_MASK));
+ uint32_t idxPage = 0;
- while (cbRegion)
+ while (cbLeft)
{
+ /** @todo inefficient to fetch each guest page like this... */
RTGCPHYS GCPhys;
uint64_t fFlags;
-
- /** @todo inefficient to fetch each guest page like this... */
- rc = PGMGstGetPage(pVCpu, GCRegion, &fFlags, &GCPhys);
+ rc = PGMGstGetPage(pVCpu, GCPtrPage, &fFlags, &GCPhys);
if ( rc == VINF_SUCCESS
&& !(fFlags & X86_PTE_RW)) /* important as we make assumptions about this below! */
{
PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
Assert(!pPage || !PGM_PAGE_IS_BALLOONED(pPage));
if ( pPage
- && PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED)
+ && PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED
+ && PGM_PAGE_GET_READ_LOCKS(pPage) == 0
+ && PGM_PAGE_GET_WRITE_LOCKS(pPage) == 0 )
{
- PageDesc.uHCPhysPageId = PGM_PAGE_GET_PAGEID(pPage);
- PageDesc.HCPhys = PGM_PAGE_GET_HCPHYS(pPage);
- PageDesc.GCPhys = GCPhys;
+ PageDesc.idPage = PGM_PAGE_GET_PAGEID(pPage);
+ PageDesc.HCPhys = PGM_PAGE_GET_HCPHYS(pPage);
+ PageDesc.GCPhys = GCPhys;
rc = GMMR0SharedModuleCheckPage(pGVM, pModule, idxRegion, idxPage, &PageDesc);
- if (rc == VINF_SUCCESS)
+ if (RT_FAILURE(rc))
+ break;
+
+ /*
+ * Any change for this page?
+ */
+ if (PageDesc.idPage != NIL_GMM_PAGEID)
{
- /* Any change for this page? */
- if (PageDesc.uHCPhysPageId != NIL_GMM_PAGEID)
+ Assert(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED);
+
+ Log(("PGMR0SharedModuleCheck: shared page gst virt=%RGv phys=%RGp host %RHp->%RHp\n",
+ GCPtrPage, PageDesc.GCPhys, PGM_PAGE_GET_HCPHYS(pPage), PageDesc.HCPhys));
+
+ if (PageDesc.HCPhys != PGM_PAGE_GET_HCPHYS(pPage))
{
- Assert(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED);
-
- Log(("PGMR0SharedModuleCheck: shared page gc virt=%RGv phys %RGp host %RHp->%RHp\n", pRegions[idxRegion].GCRegionAddr + idxPage * PAGE_SIZE, PageDesc.GCPhys, PGM_PAGE_GET_HCPHYS(pPage), PageDesc.HCPhys));
- if (PageDesc.HCPhys != PGM_PAGE_GET_HCPHYS(pPage))
- {
- bool fFlush = false;
-
- /* Page was replaced by an existing shared version of it; clear all references first. */
- rc = pgmPoolTrackUpdateGCPhys(pVM, PageDesc.GCPhys, pPage, true /* clear the entries */, &fFlush);
- Assert(rc == VINF_SUCCESS || (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3) && (pVCpu->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL)));
- if (rc == VINF_SUCCESS)
- fFlushTLBs |= fFlush;
-
- /* Update the physical address and page id now. */
- PGM_PAGE_SET_HCPHYS(pVM, pPage, PageDesc.HCPhys);
- PGM_PAGE_SET_PAGEID(pVM, pPage, PageDesc.uHCPhysPageId);
-
- /* Invalidate page map TLB entry for this page too. */
- pgmPhysInvalidatePageMapTLBEntry(pVM, PageDesc.GCPhys);
- pVM->pgm.s.cReusedSharedPages++;
- }
- /* else nothing changed (== this page is now a shared page), so no need to flush anything. */
-
- pVM->pgm.s.cSharedPages++;
- pVM->pgm.s.cPrivatePages--;
- PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_SHARED);
+ /* Page was replaced by an existing shared version
+ of it; clear all references first. */
+ bool fFlush = false;
+ rc = pgmPoolTrackUpdateGCPhys(pVM, PageDesc.GCPhys, pPage, true /* clear the entries */, &fFlush);
+ Assert( rc == VINF_SUCCESS
+ || ( VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3)
+ && (pVCpu->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL)));
+ if (rc == VINF_SUCCESS)
+ fFlushTLBs |= fFlush;
+ fFlushRemTLBs = true;
+
+ /* Update the physical address and page id now. */
+ PGM_PAGE_SET_HCPHYS(pVM, pPage, PageDesc.HCPhys);
+ PGM_PAGE_SET_PAGEID(pVM, pPage, PageDesc.idPage);
+
+ /* Invalidate page map TLB entry for this page too. */
+ pgmPhysInvalidatePageMapTLBEntry(pVM, PageDesc.GCPhys);
+ pVM->pgm.s.cReusedSharedPages++;
}
+ /* else: nothing changed (== this page is now a shared
+ page), so no need to flush anything. */
+
+ pVM->pgm.s.cSharedPages++;
+ pVM->pgm.s.cPrivatePages--;
+ PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_SHARED);
}
- else
- break;
}
}
else
@@ -132,14 +142,21 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA
}
idxPage++;
- GCRegion += PAGE_SIZE;
- cbRegion -= PAGE_SIZE;
+ GCPtrPage += PAGE_SIZE;
+ cbLeft -= PAGE_SIZE;
}
}
+ /*
+ * Do TLB flushing if necessary.
+ */
if (fFlushTLBs)
PGM_INVL_ALL_VCPU_TLBS(pVM);
+ if (fFlushRemTLBs)
+ for (VMCPUID idCurCpu = 0; idCurCpu < pVM->cCpus; idCurCpu++)
+ CPUMSetChangedFlags(&pVM->aCpus[idCurCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+
return rc;
}
#endif /* VBOX_WITH_PAGE_SHARING */
diff --git a/src/VBox/VMM/VMMR0/VMMR0.cpp b/src/VBox/VMM/VMMR0/VMMR0.cpp
index 04bd0c266..94c08ddfd 100644
--- a/src/VBox/VMM/VMMR0/VMMR0.cpp
+++ b/src/VBox/VMM/VMMR0/VMMR0.cpp
@@ -1078,13 +1078,21 @@ static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperatio
#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
case VMMR0_DO_GMM_FIND_DUPLICATE_PAGE:
- {
if (u64Arg)
return VERR_INVALID_PARAMETER;
return GMMR0FindDuplicatePageReq(pVM, (PGMMFINDDUPLICATEPAGEREQ)pReqHdr);
- }
#endif
+ case VMMR0_DO_GMM_QUERY_STATISTICS:
+ if (u64Arg)
+ return VERR_INVALID_PARAMETER;
+ return GMMR0QueryStatisticsReq(pVM, (PGMMQUERYSTATISTICSSREQ)pReqHdr);
+
+ case VMMR0_DO_GMM_RESET_STATISTICS:
+ if (u64Arg)
+ return VERR_INVALID_PARAMETER;
+ return GMMR0ResetStatisticsReq(pVM, (PGMMRESETSTATISTICSSREQ)pReqHdr);
+
/*
* A quick GCFGM mock-up.
*/
@@ -1243,7 +1251,7 @@ typedef VMMR0ENTRYEXARGS *PVMMR0ENTRYEXARGS;
* @returns VBox status code.
* @param pvArgs The argument package
*/
-static int vmmR0EntryExWrapper(void *pvArgs)
+static DECLCALLBACK(int) vmmR0EntryExWrapper(void *pvArgs)
{
return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
((PVMMR0ENTRYEXARGS)pvArgs)->idCpu,
diff --git a/src/VBox/VMM/VMMR3/CFGM.cpp b/src/VBox/VMM/VMMR3/CFGM.cpp
index ee89bdc2e..bd1b7acf7 100644
--- a/src/VBox/VMM/VMMR3/CFGM.cpp
+++ b/src/VBox/VMM/VMMR3/CFGM.cpp
@@ -1202,6 +1202,104 @@ VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PVM pVM)
/**
+ * Duplicates a CFGM sub-tree or a full tree.
+ *
+ * @returns Pointer to the root node. NULL if we run out of memory or the
+ * input parameter is NULL.
+ * @param pRoot The root of the tree to duplicate.
+ * @param ppCopy Where to return the root of the duplicate.
+ */
+VMMR3DECL(int) CFGMR3DuplicateSubTree(PCFGMNODE pRoot, PCFGMNODE *ppCopy)
+{
+ AssertPtrReturn(pRoot, VERR_INVALID_POINTER);
+
+ /*
+ * Create a new tree.
+ */
+ PCFGMNODE pNewRoot = CFGMR3CreateTree(pRoot->pVM);
+ if (!pNewRoot)
+ return VERR_NO_MEMORY;
+
+ /*
+ * Duplicate the content.
+ */
+ int rc = VINF_SUCCESS;
+ PCFGMNODE pSrcCur = pRoot;
+ PCFGMNODE pDstCur = pNewRoot;
+ for (;;)
+ {
+ if ( !pDstCur->pFirstChild
+ && !pDstCur->pFirstLeaf)
+ {
+ /*
+ * Values first.
+ */
+ /** @todo this isn't the most efficient way to do it. */
+ for (PCFGMLEAF pLeaf = pSrcCur->pFirstLeaf; pLeaf && RT_SUCCESS(rc); pLeaf = pLeaf->pNext)
+ rc = CFGMR3InsertValue(pDstCur, pLeaf);
+
+ /*
+ * Insert immediate child nodes.
+ */
+ /** @todo this isn't the most efficient way to do it. */
+ for (PCFGMNODE pChild = pSrcCur->pFirstChild; pChild && RT_SUCCESS(rc); pChild = pChild->pNext)
+ rc = CFGMR3InsertNode(pDstCur, pChild->szName, NULL);
+
+ AssertLogRelRCBreak(rc);
+ }
+
+ /*
+ * Deep copy of the children.
+ */
+ if (pSrcCur->pFirstChild)
+ {
+ Assert(pDstCur->pFirstChild && !strcmp(pDstCur->pFirstChild->szName, pSrcCur->pFirstChild->szName));
+ pSrcCur = pSrcCur->pFirstChild;
+ pDstCur = pDstCur->pFirstChild;
+ }
+ /*
+ * If it's the root node, we're done.
+ */
+ else if (pSrcCur == pRoot)
+ break;
+ else
+ {
+ /*
+ * Upon reaching the end of a sibling list, we must ascend and
+ * resume the sibiling walk on an previous level.
+ */
+ if (!pSrcCur->pNext)
+ {
+ do
+ {
+ pSrcCur = pSrcCur->pParent;
+ pDstCur = pDstCur->pParent;
+ } while (!pSrcCur->pNext && pSrcCur != pRoot);
+ if (pSrcCur == pRoot)
+ break;
+ }
+
+ /*
+ * Next sibling.
+ */
+ Assert(pDstCur->pNext && !strcmp(pDstCur->pNext->szName, pSrcCur->pNext->szName));
+ pSrcCur = pSrcCur->pNext;
+ pDstCur = pDstCur->pNext;
+ }
+ }
+
+ if (RT_FAILURE(rc))
+ {
+ CFGMR3RemoveNode(pNewRoot);
+ return rc;
+ }
+
+ *ppCopy = pNewRoot;
+ return VINF_SUCCESS;
+}
+
+
+/**
* Insert subtree.
*
* This function inserts (no duplication) a tree created by CFGMR3CreateTree()
@@ -1224,10 +1322,11 @@ VMMR3DECL(int) CFGMR3InsertSubTree(PCFGMNODE pNode, const char *pszName, PCFGMNO
/*
* Validate input.
*/
+ AssertPtrReturn(pNode, VERR_INVALID_POINTER);
AssertPtrReturn(pSubTree, VERR_INVALID_POINTER);
+ AssertReturn(pNode != pSubTree, VERR_INVALID_PARAMETER);
AssertReturn(!pSubTree->pParent, VERR_INVALID_PARAMETER);
AssertReturn(pSubTree->pVM, VERR_INVALID_PARAMETER);
- AssertReturn(pSubTree->pParent != pSubTree->pVM->cfgm.s.pRoot, VERR_INVALID_PARAMETER);
Assert(!pSubTree->pNext);
Assert(!pSubTree->pPrev);
@@ -1240,9 +1339,13 @@ VMMR3DECL(int) CFGMR3InsertSubTree(PCFGMNODE pNode, const char *pszName, PCFGMNO
if (RT_SUCCESS(rc))
{
Assert(!pNewChild->pFirstChild);
- pNewChild->pFirstChild = pSubTree->pFirstChild;
Assert(!pNewChild->pFirstLeaf);
+
+ pNewChild->pFirstChild = pSubTree->pFirstChild;
pNewChild->pFirstLeaf = pSubTree->pFirstLeaf;
+ for (PCFGMNODE pChild = pNewChild->pFirstChild; pChild; pChild = pChild->pNext)
+ pChild->pParent = pNewChild;
+
if (ppChild)
*ppChild = pNewChild;
@@ -1257,6 +1360,139 @@ VMMR3DECL(int) CFGMR3InsertSubTree(PCFGMNODE pNode, const char *pszName, PCFGMNO
/**
+ * Replaces a (sub-)tree with new one.
+ *
+ * This function removes the exiting (sub-)tree, completely freeing it in the
+ * process, and inserts (no duplication) the specified tree. The tree can
+ * either be created by CFGMR3CreateTree or CFGMR3DuplicateSubTree.
+ *
+ * @returns VBox status code.
+ * @param pRoot The sub-tree to replace. This node will remain valid
+ * after the call.
+ * @param pNewRoot The tree to replace @a pRoot with. This not will
+ * become invalid after a successful call.
+ */
+VMMR3DECL(int) CFGMR3ReplaceSubTree(PCFGMNODE pRoot, PCFGMNODE pNewRoot)
+{
+ /*
+ * Validate input.
+ */
+ AssertPtrReturn(pRoot, VERR_INVALID_POINTER);
+ AssertPtrReturn(pNewRoot, VERR_INVALID_POINTER);
+ AssertReturn(pRoot != pNewRoot, VERR_INVALID_PARAMETER);
+ AssertReturn(!pNewRoot->pParent, VERR_INVALID_PARAMETER);
+ AssertReturn(pNewRoot->pVM, VERR_INVALID_PARAMETER);
+ AssertReturn(pNewRoot->pVM == pRoot->pVM, VERR_INVALID_PARAMETER);
+ AssertReturn(!pNewRoot->pNext, VERR_INVALID_PARAMETER);
+ AssertReturn(!pNewRoot->pPrev, VERR_INVALID_PARAMETER);
+
+ /*
+ * Free the current properties fo pRoot.
+ */
+ while (pRoot->pFirstChild)
+ CFGMR3RemoveNode(pRoot->pFirstChild);
+
+ while (pRoot->pFirstLeaf)
+ cfgmR3RemoveLeaf(pRoot, pRoot->pFirstLeaf);
+
+ /*
+ * Copy all the properties from the new root to the current one.
+ */
+ pRoot->pFirstLeaf = pNewRoot->pFirstLeaf;
+ pRoot->pFirstChild = pNewRoot->pFirstChild;
+ for (PCFGMNODE pChild = pRoot->pFirstChild; pChild; pChild = pChild->pNext)
+ pChild->pParent = pRoot;
+
+ pNewRoot->pFirstLeaf = NULL;
+ pNewRoot->pFirstChild = NULL;
+ pNewRoot->pVM = NULL;
+ MMR3HeapFree(pNewRoot);
+
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Copies all values and keys from one tree onto another.
+ *
+ * The flags control what happens to keys and values with the same name
+ * existing in both source and destination.
+ *
+ * @returns VBox status code.
+ * @param pDstTree The destination tree.
+ * @param pSrcTree The source tree.
+ * @param fFlags Copy flags, see CFGM_COPY_FLAGS_XXX.
+ */
+VMMR3DECL(int) CFGMR3CopyTree(PCFGMNODE pDstTree, PCFGMNODE pSrcTree, uint32_t fFlags)
+{
+ /*
+ * Input validation.
+ */
+ AssertPtrReturn(pSrcTree, VERR_INVALID_POINTER);
+ AssertPtrReturn(pDstTree, VERR_INVALID_POINTER);
+ AssertReturn(pDstTree != pSrcTree, VERR_INVALID_PARAMETER);
+ AssertReturn(!(fFlags & ~(CFGM_COPY_FLAGS_VALUE_DISP_MASK | CFGM_COPY_FLAGS_KEY_DISP_MASK)), VERR_INVALID_PARAMETER);
+ AssertReturn( (fFlags & CFGM_COPY_FLAGS_VALUE_DISP_MASK) != CFGM_COPY_FLAGS_RESERVED_VALUE_DISP_0
+ && (fFlags & CFGM_COPY_FLAGS_VALUE_DISP_MASK) != CFGM_COPY_FLAGS_RESERVED_VALUE_DISP_1,
+ VERR_INVALID_PARAMETER);
+ AssertReturn((fFlags & CFGM_COPY_FLAGS_KEY_DISP_MASK) != CFGM_COPY_FLAGS_RESERVED_KEY_DISP,
+ VERR_INVALID_PARAMETER);
+
+ /*
+ * Copy the values.
+ */
+ int rc;
+ for (PCFGMLEAF pValue = CFGMR3GetFirstValue(pSrcTree); pValue; pValue = CFGMR3GetNextValue(pValue))
+ {
+ rc = CFGMR3InsertValue(pDstTree, pValue);
+ if (rc == VERR_CFGM_LEAF_EXISTS)
+ {
+ if ((fFlags & CFGM_COPY_FLAGS_VALUE_DISP_MASK) == CFGM_COPY_FLAGS_REPLACE_VALUES)
+ {
+ rc = CFGMR3RemoveValue(pDstTree, pValue->szName);
+ if (RT_FAILURE(rc))
+ break;
+ rc = CFGMR3InsertValue(pDstTree, pValue);
+ }
+ else
+ rc = VINF_SUCCESS;
+ }
+ AssertRCReturn(rc, rc);
+ }
+
+ /*
+ * Copy/merge the keys - merging results in recursion.
+ */
+ for (PCFGMNODE pSrcChild = CFGMR3GetFirstChild(pSrcTree); pSrcChild; pSrcChild = CFGMR3GetNextChild(pSrcChild))
+ {
+ PCFGMNODE pDstChild = CFGMR3GetChild(pDstTree, pSrcChild->szName);
+ if ( pDstChild
+ && (fFlags & CFGM_COPY_FLAGS_KEY_DISP_MASK) == CFGM_COPY_FLAGS_REPLACE_KEYS)
+ {
+ CFGMR3RemoveNode(pDstChild);
+ pDstChild = NULL;
+ }
+ if (!pDstChild)
+ {
+ PCFGMNODE pChildCopy;
+ rc = CFGMR3DuplicateSubTree(pSrcChild, &pChildCopy);
+ AssertRCReturn(rc, rc);
+ rc = CFGMR3InsertSubTree(pDstTree, pSrcChild->szName, pChildCopy, NULL);
+ AssertRCReturnStmt(rc, CFGMR3RemoveNode(pChildCopy), rc);
+ }
+ else if ((fFlags & CFGM_COPY_FLAGS_KEY_DISP_MASK) == CFGM_COPY_FLAGS_MERGE_KEYS)
+ {
+ rc = CFGMR3CopyTree(pDstChild, pSrcChild, fFlags);
+ AssertRCReturn(rc, rc);
+ }
+ }
+
+ return VINF_SUCCESS;
+}
+
+
+
+/**
* Compares two names.
*
* @returns Similar to memcpy.
@@ -1893,6 +2129,39 @@ VMMR3DECL(int) CFGMR3InsertBytes(PCFGMNODE pNode, const char *pszName, const voi
/**
+ * Make a copy of the specified value under the given node.
+ *
+ * @returns VBox status code.
+ * @param pNode Parent node.
+ * @param pValue The value to copy and insert.
+ */
+VMMR3DECL(int) CFGMR3InsertValue(PCFGMNODE pNode, PCFGMLEAF pValue)
+{
+ int rc;
+ switch (pValue->enmType)
+ {
+ case CFGMVALUETYPE_INTEGER:
+ rc = CFGMR3InsertInteger(pNode, pValue->szName, pValue->Value.Integer.u64);
+ break;
+
+ case CFGMVALUETYPE_BYTES:
+ rc = CFGMR3InsertBytes(pNode, pValue->szName, pValue->Value.Bytes.pau8, pValue->Value.Bytes.cb);
+ break;
+
+ case CFGMVALUETYPE_STRING:
+ rc = CFGMR3InsertStringN(pNode, pValue->szName, pValue->Value.String.psz, pValue->Value.String.cb - 1);
+ break;
+
+ default:
+ rc = VERR_CFGM_IPE_1;
+ AssertMsgFailed(("Invalid value type %d\n", pValue->enmType));
+ break;
+ }
+ return rc;
+}
+
+
+/**
* Remove a value.
*
* @returns VBox status code.
@@ -2807,7 +3076,7 @@ static void cfgmR3Dump(PCFGMNODE pRoot, unsigned iLevel, PCDBGFINFOHLP pHlp)
Assert(pChild->pPrev != pChild);
Assert(pChild->pPrev != pChild->pNext || !pChild->pPrev);
Assert(pChild->pFirstChild != pChild);
- Assert(pChild->pParent != pChild);
+ Assert(pChild->pParent == pRoot);
cfgmR3Dump(pChild, iLevel + 1, pHlp);
}
}
diff --git a/src/VBox/VMM/VMMR3/CPUM.cpp b/src/VBox/VMM/VMMR3/CPUM.cpp
index 8a9ed512a..b6939959b 100644
--- a/src/VBox/VMM/VMMR3/CPUM.cpp
+++ b/src/VBox/VMM/VMMR3/CPUM.cpp
@@ -2596,7 +2596,7 @@ static void cpumR3InfoParseArg(const char *pszArgs, CPUMDUMPTYPE *penmType, cons
{
if (!strncmp(pszArgs, "verbose", sizeof("verbose") - 1))
{
- pszArgs += 5;
+ pszArgs += 7;
*penmType = CPUMDUMPTYPE_VERBOSE;
}
else if (!strncmp(pszArgs, "terse", sizeof("terse") - 1))
diff --git a/src/VBox/VMM/VMMR3/PATMA.asm b/src/VBox/VMM/VMMR3/PATMA.asm
index cb10d6db1..cab836a80 100644
--- a/src/VBox/VMM/VMMR3/PATMA.asm
+++ b/src/VBox/VMM/VMMR3/PATMA.asm
@@ -91,6 +91,7 @@ PATMSetPIF_End:
ENDPROC PATMSetPIF
+SECTION .data
; Patch record for setting PATM_INTERRUPTFLAG
GLOBALNAME PATMSetPIFRecord
RTCCPTR_DEF PATMSetPIF_Start
@@ -102,6 +103,7 @@ GLOBALNAME PATMSetPIFRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Clear PATM_INTERRUPTFLAG
@@ -116,6 +118,7 @@ PATMClearPIF_End:
ENDPROC PATMClearPIF
+SECTION .data
; Patch record for clearing PATM_INTERRUPTFLAG
GLOBALNAME PATMClearPIFRecord
RTCCPTR_DEF PATMClearPIF_Start
@@ -127,6 +130,7 @@ GLOBALNAME PATMClearPIFRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Clear PATM_INHIBITIRQADDR and fault if IF=0
@@ -169,6 +173,7 @@ PATMClearInhibitIRQFaultIF0_End:
ENDPROC PATMClearInhibitIRQFaultIF0
+SECTION .data
; Patch record for clearing PATM_INHIBITIRQADDR
GLOBALNAME PATMClearInhibitIRQFaultIF0Record
RTCCPTR_DEF PATMClearInhibitIRQFaultIF0_Start
@@ -202,6 +207,7 @@ GLOBALNAME PATMClearInhibitIRQFaultIF0Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Clear PATM_INHIBITIRQADDR and continue if IF=0 (duplicated function only; never jump back to guest code afterwards!!)
@@ -239,6 +245,7 @@ PATMClearInhibitIRQContIF0_End:
ENDPROC PATMClearInhibitIRQContIF0
+SECTION .data
; Patch record for clearing PATM_INHIBITIRQADDR
GLOBALNAME PATMClearInhibitIRQContIF0Record
RTCCPTR_DEF PATMClearInhibitIRQContIF0_Start
@@ -270,6 +277,7 @@ GLOBALNAME PATMClearInhibitIRQContIF0Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMCliReplacement
@@ -298,6 +306,7 @@ PATMCliEnd:
ENDPROC PATMCliReplacement
+SECTION .data
; Patch record for 'cli'
GLOBALNAME PATMCliRecord
RTCCPTR_DEF PATMCliStart
@@ -321,6 +330,7 @@ GLOBALNAME PATMCliRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMStiReplacement
@@ -344,6 +354,7 @@ PATMStiStart:
PATMStiEnd:
ENDPROC PATMStiReplacement
+SECTION .data
; Patch record for 'sti'
GLOBALNAME PATMStiRecord
RTCCPTR_DEF PATMStiStart
@@ -371,6 +382,7 @@ GLOBALNAME PATMStiRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Trampoline code for trap entry (without error code on the stack)
@@ -432,6 +444,7 @@ PATMTrapEntryEnd:
ENDPROC PATMTrapEntry
+SECTION .data
; Patch record for trap gate entrypoint
GLOBALNAME PATMTrapEntryRecord
RTCCPTR_DEF PATMTrapEntryStart
@@ -455,6 +468,7 @@ GLOBALNAME PATMTrapEntryRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Trampoline code for trap entry (with error code on the stack)
@@ -517,6 +531,7 @@ PATMTrapErrorCodeEntryEnd:
ENDPROC PATMTrapEntryErrorCode
+SECTION .data
; Patch record for trap gate entrypoint
GLOBALNAME PATMTrapEntryRecordErrorCode
RTCCPTR_DEF PATMTrapErrorCodeEntryStart
@@ -540,6 +555,7 @@ GLOBALNAME PATMTrapEntryRecordErrorCode
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
@@ -599,6 +615,7 @@ PATMIntEntryEnd:
ENDPROC PATMIntEntry
+SECTION .data
; Patch record for interrupt gate entrypoint
GLOBALNAME PATMIntEntryRecord
RTCCPTR_DEF PATMIntEntryStart
@@ -622,6 +639,7 @@ GLOBALNAME PATMIntEntryRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Trampoline code for interrupt gate entry (*with* error code on the stack)
@@ -681,6 +699,7 @@ PATMIntEntryErrorCodeEnd:
ENDPROC PATMIntEntryErrorCode
+SECTION .data
; Patch record for interrupt gate entrypoint
GLOBALNAME PATMIntEntryRecordErrorCode
RTCCPTR_DEF PATMIntEntryErrorCodeStart
@@ -704,6 +723,7 @@ GLOBALNAME PATMIntEntryRecordErrorCode
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; 32 bits Popf replacement that faults when IF remains 0
@@ -766,6 +786,7 @@ PATMPopf32End:
ENDPROC PATMPopf32Replacement
+SECTION .data
; Patch record for 'popfd'
GLOBALNAME PATMPopf32Record
RTCCPTR_DEF PATMPopf32Start
@@ -805,6 +826,7 @@ GLOBALNAME PATMPopf32Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
; no need to check the IF flag when popf isn't an exit point of a patch (e.g. function duplication)
BEGINPROC PATMPopf32Replacement_NoExit
@@ -858,6 +880,7 @@ PATMPopf32_NoExitEnd:
ENDPROC PATMPopf32Replacement_NoExit
+SECTION .data
; Patch record for 'popfd'
GLOBALNAME PATMPopf32Record_NoExit
RTCCPTR_DEF PATMPopf32_NoExitStart
@@ -901,6 +924,7 @@ GLOBALNAME PATMPopf32Record_NoExit
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
@@ -940,6 +964,7 @@ PATMPopf16End:
ENDPROC PATMPopf16Replacement
+SECTION .data
; Patch record for 'popf'
GLOBALNAME PATMPopf16Record
RTCCPTR_DEF PATMPopf16Start
@@ -967,6 +992,7 @@ GLOBALNAME PATMPopf16Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; 16 bits Popf replacement that faults when IF remains 0
@@ -1001,6 +1027,7 @@ PATMPopf16End_NoExit:
ENDPROC PATMPopf16Replacement_NoExit
+SECTION .data
; Patch record for 'popf'
GLOBALNAME PATMPopf16Record_NoExit
RTCCPTR_DEF PATMPopf16Start_NoExit
@@ -1028,6 +1055,7 @@ GLOBALNAME PATMPopf16Record_NoExit
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMPushf32Replacement
@@ -1058,6 +1086,7 @@ PATMPushf32End:
ENDPROC PATMPushf32Replacement
+SECTION .data
; Patch record for 'pushfd'
GLOBALNAME PATMPushf32Record
RTCCPTR_DEF PATMPushf32Start
@@ -1081,6 +1110,7 @@ GLOBALNAME PATMPushf32Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMPushf16Replacement
@@ -1105,6 +1135,7 @@ PATMPushf16End:
ENDPROC PATMPushf16Replacement
+SECTION .data
; Patch record for 'pushf'
GLOBALNAME PATMPushf16Record
RTCCPTR_DEF PATMPushf16Start
@@ -1120,6 +1151,7 @@ GLOBALNAME PATMPushf16Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMPushCSReplacement
@@ -1145,6 +1177,7 @@ PATMPushCSEnd:
ENDPROC PATMPushCSReplacement
+SECTION .data
; Patch record for 'push cs'
GLOBALNAME PATMPushCSRecord
RTCCPTR_DEF PATMPushCSStart
@@ -1158,6 +1191,7 @@ GLOBALNAME PATMPushCSRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;;****************************************************
;; Abstract:
@@ -1357,6 +1391,7 @@ PATMIretTable:
PATMIretEnd:
ENDPROC PATMIretReplacement
+SECTION .data
; Patch record for 'iretd'
GLOBALNAME PATMIretRecord
RTCCPTR_DEF PATMIretStart
@@ -1424,6 +1459,7 @@ GLOBALNAME PATMIretRecord
DD PATM_PENDINGACTION
DD 0
DD 0ffffffffh
+SECTION .text
;
@@ -1507,6 +1543,7 @@ PATMIretFunction_Failure:
PATMIretFunction_End:
ENDPROC PATMIretFunction
+SECTION .data
GLOBALNAME PATMIretFunctionRecord
RTCCPTR_DEF PATMIretFunction_Start
DD 0
@@ -1519,6 +1556,7 @@ GLOBALNAME PATMIretFunctionRecord
DD PATM_PATCHBASE
DD 0
DD 0ffffffffh
+SECTION .text
align 32 ; yasm / nasm diff - remove me!
@@ -1573,6 +1611,7 @@ cpuid_fetch:
PATMCpuidEnd:
ENDPROC PATMCpuidReplacement
+SECTION .data
; Patch record for 'cpuid'
GLOBALNAME PATMCpuidRecord
RTCCPTR_DEF PATMCpuidStart
@@ -1600,6 +1639,7 @@ GLOBALNAME PATMCpuidRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMJEcxReplacement
@@ -1623,6 +1663,7 @@ PATMJEcxContinue:
PATMJEcxEnd:
ENDPROC PATMJEcxReplacement
+SECTION .data
; Patch record for 'JEcx'
GLOBALNAME PATMJEcxRecord
RTCCPTR_DEF PATMJEcxStart
@@ -1638,6 +1679,7 @@ GLOBALNAME PATMJEcxRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
align 32; yasm / nasm diffing. remove me!
BEGINPROC PATMLoopReplacement
@@ -1661,6 +1703,7 @@ PATMLoopContinue:
PATMLoopEnd:
ENDPROC PATMLoopReplacement
+SECTION .data
; Patch record for 'Loop'
GLOBALNAME PATMLoopRecord
RTCCPTR_DEF PATMLoopStart
@@ -1676,6 +1719,7 @@ GLOBALNAME PATMLoopRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMLoopZReplacement
PATMLoopZStart:
@@ -1701,6 +1745,7 @@ PATMLoopZContinue:
PATMLoopZEnd:
ENDPROC PATMLoopZReplacement
+SECTION .data
; Patch record for 'Loopz'
GLOBALNAME PATMLoopZRecord
RTCCPTR_DEF PATMLoopZStart
@@ -1716,6 +1761,7 @@ GLOBALNAME PATMLoopZRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
BEGINPROC PATMLoopNZReplacement
@@ -1742,6 +1788,7 @@ PATMLoopNZContinue:
PATMLoopNZEnd:
ENDPROC PATMLoopNZReplacement
+SECTION .data
; Patch record for 'LoopNZ'
GLOBALNAME PATMLoopNZRecord
RTCCPTR_DEF PATMLoopNZStart
@@ -1757,6 +1804,7 @@ GLOBALNAME PATMLoopNZRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
align 32
; Global patch function for indirect calls
@@ -1875,6 +1923,7 @@ PATMLookupAndCallEnd:
; returning here -> do not add code here or after the jmp!!!!!
ENDPROC PATMLookupAndCall
+SECTION .data
; Patch record for indirect calls and jumps
GLOBALNAME PATMLookupAndCallRecord
RTCCPTR_DEF PATMLookupAndCallStart
@@ -1910,6 +1959,7 @@ GLOBALNAME PATMLookupAndCallRecord
DD PATM_CALL_PATCH_TARGET_ADDR
DD 0
DD 0ffffffffh
+SECTION .text
align 32
@@ -1992,6 +2042,7 @@ PATMLookupAndJump_SearchEnd:
PATMLookupAndJumpEnd:
ENDPROC PATMLookupAndJump
+SECTION .data
; Patch record for indirect calls and jumps
GLOBALNAME PATMLookupAndJumpRecord
RTCCPTR_DEF PATMLookupAndJumpStart
@@ -2011,6 +2062,7 @@ GLOBALNAME PATMLookupAndJumpRecord
DD PATM_TEMP_EAX
DD 0
DD 0ffffffffh
+SECTION .text
@@ -2051,6 +2103,7 @@ PATMCallEnd:
; returning here -> do not add code here or after the jmp!!!!!
ENDPROC PATMCall
+SECTION .data
; Patch record for direct calls
GLOBALNAME PATMCallRecord
RTCCPTR_DEF PATMCallStart
@@ -2070,6 +2123,7 @@ GLOBALNAME PATMCallRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
align 32
@@ -2107,6 +2161,7 @@ PATMCallIndirectEnd:
; returning here -> do not add code here or after the jmp!!!!!
ENDPROC PATMCallIndirect
+SECTION .data
; Patch record for indirect calls
GLOBALNAME PATMCallIndirectRecord
RTCCPTR_DEF PATMCallIndirectStart
@@ -2126,6 +2181,7 @@ GLOBALNAME PATMCallIndirectRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
align 32
@@ -2168,6 +2224,7 @@ PATMJumpIndirectEnd:
; returning here -> do not add code here or after the jmp!!!!!
ENDPROC PATMJumpIndirect
+SECTION .data
; Patch record for indirect jumps
GLOBALNAME PATMJumpIndirectRecord
RTCCPTR_DEF PATMJumpIndirectStart
@@ -2187,6 +2244,7 @@ GLOBALNAME PATMJumpIndirectRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; return from duplicated function
@@ -2233,6 +2291,7 @@ PATMRet_Success:
PATMRet_End:
ENDPROC PATMRet
+SECTION .data
GLOBALNAME PATMRetRecord
RTCCPTR_DEF PATMRet_Start
DD 0
@@ -2249,6 +2308,7 @@ GLOBALNAME PATMRetRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; global function for implementing 'retn'
@@ -2398,6 +2458,7 @@ PATMRetFunction_Failure:
PATMRetFunction_End:
ENDPROC PATMRetFunction
+SECTION .data
GLOBALNAME PATMRetFunctionRecord
RTCCPTR_DEF PATMRetFunction_Start
DD 0
@@ -2432,6 +2493,7 @@ GLOBALNAME PATMRetFunctionRecord
DD 0
%endif
DD 0ffffffffh
+SECTION .text
;
@@ -2473,6 +2535,7 @@ PATMCheckIF_Jump:
PATMCheckIF_End:
ENDPROC PATMCheckIF
+SECTION .data
; Patch record for call instructions
GLOBALNAME PATMCheckIFRecord
RTCCPTR_DEF PATMCheckIF_Start
@@ -2500,6 +2563,7 @@ GLOBALNAME PATMCheckIFRecord
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
;
; Jump back to guest if IF=1, else fault
@@ -2527,6 +2591,7 @@ PATMJumpToGuest_IF1_Jump:
PATMJumpToGuest_IF1_End:
ENDPROC PATMJumpToGuest_IF1
+SECTION .data
; Patch record for call instructions
GLOBALNAME PATMJumpToGuest_IF1Record
RTCCPTR_DEF PATMJumpToGuest_IF1_Start
@@ -2544,6 +2609,7 @@ GLOBALNAME PATMJumpToGuest_IF1Record
DD PATM_INTERRUPTFLAG
DD 0
DD 0ffffffffh
+SECTION .text
; check and correct RPL of pushed ss
@@ -2563,6 +2629,7 @@ PATMMovFromSS_Continue:
PATMMovFromSS_Start_End:
ENDPROC PATMMovFromSS
+SECTION .data
GLOBALNAME PATMMovFromSSRecord
RTCCPTR_DEF PATMMovFromSS_Start
DD 0
@@ -2575,6 +2642,7 @@ GLOBALNAME PATMMovFromSSRecord
+SECTION .rodata
; For assertion during init (to make absolutely sure the flags are in sync in vm.mac & vm.h)
GLOBALNAME PATMInterruptFlag
DD VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_TIMER | VMCPU_FF_REQUEST
diff --git a/src/VBox/VMM/VMMR3/PDM.cpp b/src/VBox/VMM/VMMR3/PDM.cpp
index eb78b640c..fdde17e39 100644
--- a/src/VBox/VMM/VMMR3/PDM.cpp
+++ b/src/VBox/VMM/VMMR3/PDM.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * 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;
@@ -266,6 +266,7 @@
#include <iprt/asm.h>
#include <iprt/assert.h>
#include <iprt/alloc.h>
+#include <iprt/ctype.h>
#include <iprt/ldr.h>
#include <iprt/path.h>
#include <iprt/string.h>
@@ -2341,3 +2342,23 @@ VMMR3DECL(int) PDMR3VMMDevHeapFree(PVM pVM, RTR3PTR pv)
return VINF_SUCCESS;
}
+
+/**
+ * Checks that a PDMDRVREG::szName, PDMDEVREG::szName or PDMUSBREG::szName
+ * field contains only a limited set of ASCII characters.
+ *
+ * @returns true / false.
+ * @param pszName The name to validate.
+ */
+bool pdmR3IsValidName(const char *pszName)
+{
+ char ch;
+ while ( (ch = *pszName) != '\0'
+ && ( RT_C_IS_ALNUM(ch)
+ || ch == '-'
+ || ch == ' ' /** @todo disallow this! */
+ || ch == '_') )
+ pszName++;
+ return ch == '\0';
+}
+
diff --git a/src/VBox/VMM/VMMR3/PDMDevice.cpp b/src/VBox/VMM/VMMR3/PDMDevice.cpp
index 6542329c3..275b02dbf 100644
--- a/src/VBox/VMM/VMMR3/PDMDevice.cpp
+++ b/src/VBox/VMM/VMMR3/PDMDevice.cpp
@@ -628,8 +628,9 @@ static DECLCALLBACK(int) pdmR3DevReg_Register(PPDMDEVREGCB pCallbacks, PCPDMDEVR
VERR_PDM_UNKNOWN_DEVREG_VERSION);
AssertMsgReturn( pReg->szName[0]
- && strlen(pReg->szName) < sizeof(pReg->szName),
- ("Invalid name '%s'\n", pReg->szName),
+ && strlen(pReg->szName) < sizeof(pReg->szName)
+ && pdmR3IsValidName(pReg->szName),
+ ("Invalid name '%.s'\n", sizeof(pReg->szName), pReg->szName),
VERR_PDM_INVALID_DEVICE_REGISTRATION);
AssertMsgReturn( !(pReg->fFlags & PDM_DEVREG_FLAGS_RC)
|| ( pReg->szRCMod[0]
diff --git a/src/VBox/VMM/VMMR3/PDMDriver.cpp b/src/VBox/VMM/VMMR3/PDMDriver.cpp
index 6187532d4..0ac45bddd 100644
--- a/src/VBox/VMM/VMMR3/PDMDriver.cpp
+++ b/src/VBox/VMM/VMMR3/PDMDriver.cpp
@@ -269,7 +269,9 @@ static DECLCALLBACK(int) pdmR3DrvRegister(PCPDMDRVREGCB pCallbacks, PCPDMDRVREG
VERR_PDM_UNKNOWN_DRVREG_VERSION);
AssertReturn(pReg->szName[0], VERR_PDM_INVALID_DRIVER_REGISTRATION);
AssertMsgReturn(RTStrEnd(pReg->szName, sizeof(pReg->szName)),
- (".*s\n", sizeof(pReg->szName), pReg->szName),
+ ("%.*s\n", sizeof(pReg->szName), pReg->szName),
+ VERR_PDM_INVALID_DRIVER_REGISTRATION);
+ AssertMsgReturn(pdmR3IsValidName(pReg->szName), ("%.*s\n", pReg->szName),
VERR_PDM_INVALID_DRIVER_REGISTRATION);
AssertMsgReturn( !(pReg->fFlags & PDM_DRVREG_FLAGS_R0)
|| ( pReg->szR0Mod[0]
@@ -369,6 +371,250 @@ PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName)
/**
+ * Transforms the driver chain as it's being instantiated.
+ *
+ * Worker for pdmR3DrvInstantiate.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param pDrvAbove The driver above, NULL if top.
+ * @param pLun The LUN.
+ * @param ppNode The AttachedDriver node, replaced if any
+ * morphing took place.
+ */
+static int pdmR3DrvMaybeTransformChain(PVM pVM, PPDMDRVINS pDrvAbove, PPDMLUN pLun, PCFGMNODE *ppNode)
+{
+ /*
+ * The typical state of affairs is that there are no injections.
+ */
+ PCFGMNODE pCurTrans = CFGMR3GetFirstChild(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM/DriverTransformations"));
+ if (!pCurTrans)
+ return VINF_SUCCESS;
+
+ /*
+ * Gather the attributes used in the matching process.
+ */
+ const char *pszDevice = pLun->pDevIns->Internal.s.pDevR3->pReg->szName;
+ char szLun[32];
+ RTStrPrintf(szLun, sizeof(szLun), "%u", pLun->iLun);
+ const char *pszAbove = pDrvAbove ? pDrvAbove->Internal.s.pDrv->pReg->szName : "<top>";
+ char *pszThisDrv;
+ int rc = CFGMR3QueryStringAlloc(*ppNode, "Driver", &pszThisDrv);
+ AssertMsgRCReturn(rc, ("Query for string value of \"Driver\" -> %Rrc\n", rc),
+ rc == VERR_CFGM_VALUE_NOT_FOUND ? VERR_PDM_CFG_MISSING_DRIVER_NAME : rc);
+
+ uint64_t uInjectTransformationAbove = 0;
+ if (pDrvAbove)
+ {
+ rc = CFGMR3QueryIntegerDef(CFGMR3GetParent(*ppNode), "InjectTransformationPtr", &uInjectTransformationAbove, 0);
+ AssertLogRelRCReturn(rc, rc);
+ }
+
+
+ /*
+ * Enumerate possible driver chain transformations.
+ */
+ unsigned cTransformations = 0;
+ for (; pCurTrans != NULL; pCurTrans = CFGMR3GetNextChild(pCurTrans))
+ {
+ char szCurTransNm[256];
+ rc = CFGMR3GetName(pCurTrans, szCurTransNm, sizeof(szCurTransNm));
+ AssertLogRelRCReturn(rc, rc);
+
+ /* Match against the driver multi pattern. */
+ char *pszMultiPat;
+ rc = CFGMR3QueryStringAllocDef(pCurTrans, "Driver", &pszMultiPat, "*");
+ AssertLogRelRCReturn(rc, rc);
+ bool fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszDevice, RTSTR_MAX, NULL);
+ MMR3HeapFree(pszMultiPat);
+ if (!fMatch)
+ continue;
+
+ /* Match against the lun multi pattern. */
+ rc = CFGMR3QueryStringAllocDef(pCurTrans, "LUN", &pszMultiPat, "*");
+ AssertLogRelRCReturn(rc, rc);
+ fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, szLun, RTSTR_MAX, NULL);
+ MMR3HeapFree(pszMultiPat);
+ if (!fMatch)
+ continue;
+
+ /* Match against the below-driver multi pattern. */
+ rc = CFGMR3QueryStringAllocDef(pCurTrans, "BelowDriver", &pszMultiPat, "*");
+ AssertLogRelRCReturn(rc, rc);
+ fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszAbove, RTSTR_MAX, NULL);
+ MMR3HeapFree(pszMultiPat);
+ if (!fMatch)
+ continue;
+
+ /* Match against the above-driver multi pattern. */
+ rc = CFGMR3QueryStringAlloc(pCurTrans, "AboveDriver", &pszMultiPat);
+ if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+ rc = VINF_SUCCESS;
+ else
+ {
+ AssertLogRelRCReturn(rc, rc);
+ fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszThisDrv, RTSTR_MAX, NULL);
+ MMR3HeapFree(pszMultiPat);
+ if (!fMatch)
+ continue;
+ if (uInjectTransformationAbove == (uintptr_t)pCurTrans)
+ continue;
+ }
+
+ /*
+ * We've got a match! Now, what are we supposed to do?
+ */
+ char szAction[16];
+ rc = CFGMR3QueryStringDef(pCurTrans, "Action", szAction, sizeof(szAction), "inject");
+ AssertLogRelRCReturn(rc, rc);
+ AssertLogRelMsgReturn( !strcmp(szAction, "inject")
+ || !strcmp(szAction, "mergeconfig")
+ || !strcmp(szAction, "remove")
+ || !strcmp(szAction, "removetree")
+ || !strcmp(szAction, "replace")
+ || !strcmp(szAction, "replacetree")
+ ,
+ ("Action='%s', valid values are 'inject', 'mergeconfig', 'replace', 'replacetree', 'remove', 'removetree'.\n", szAction),
+ VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
+ LogRel(("Applying '%s' to '%s'::[%s]...'%s': %s\n", szCurTransNm, pszDevice, szLun, pszThisDrv, szAction));
+ CFGMR3Dump(*ppNode);
+ CFGMR3Dump(pCurTrans);
+
+ /* Get the attached driver to inject. */
+ PCFGMNODE pTransAttDrv = NULL;
+ if (!strcmp(szAction, "inject") || !strcmp(szAction, "replace") || !strcmp(szAction, "replacetree"))
+ {
+ pTransAttDrv = CFGMR3GetChild(pCurTrans, "AttachedDriver");
+ AssertLogRelMsgReturn(pTransAttDrv,
+ ("An %s transformation requires an AttachedDriver child node!\n", szAction),
+ VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
+ }
+
+
+ /*
+ * Remove the node.
+ */
+ if (!strcmp(szAction, "remove") || !strcmp(szAction, "removetree"))
+ {
+ PCFGMNODE pBelowThis = CFGMR3GetChild(*ppNode, "AttachedDriver");
+ if (!pBelowThis || !strcmp(szAction, "removetree"))
+ {
+ CFGMR3RemoveNode(*ppNode);
+ *ppNode = NULL;
+ }
+ else
+ {
+ PCFGMNODE pBelowThisCopy;
+ rc = CFGMR3DuplicateSubTree(pBelowThis, &pBelowThisCopy);
+ AssertLogRelRCReturn(rc, rc);
+
+ rc = CFGMR3ReplaceSubTree(*ppNode, pBelowThisCopy);
+ if (RT_FAILURE(rc))
+ {
+ CFGMR3RemoveNode(pBelowThis);
+ AssertLogRelReturn(("rc=%Rrc\n", rc), rc);
+ }
+ }
+ }
+ /*
+ * Replace the driver about to be instantiated.
+ */
+ else if (!strcmp(szAction, "replace") || !strcmp(szAction, "replacetree"))
+ {
+ PCFGMNODE pTransCopy;
+ rc = CFGMR3DuplicateSubTree(pTransAttDrv, &pTransCopy);
+ AssertLogRelRCReturn(rc, rc);
+
+ PCFGMNODE pBelowThis = CFGMR3GetChild(*ppNode, "AttachedDriver");
+ if (!pBelowThis || !strcmp(szAction, "replacetree"))
+ rc = VINF_SUCCESS;
+ else
+ {
+ PCFGMNODE pBelowThisCopy;
+ rc = CFGMR3DuplicateSubTree(pBelowThis, &pBelowThisCopy);
+ if (RT_SUCCESS(rc))
+ {
+ rc = CFGMR3InsertSubTree(pTransCopy, "AttachedDriver", pBelowThisCopy, NULL);
+ AssertLogRelRC(rc);
+ if (RT_FAILURE(rc))
+ CFGMR3RemoveNode(pBelowThisCopy);
+ }
+ }
+ if (RT_SUCCESS(rc))
+ rc = CFGMR3ReplaceSubTree(*ppNode, pTransCopy);
+ if (RT_FAILURE(rc))
+ CFGMR3RemoveNode(pTransCopy);
+ }
+ /*
+ * Inject a driver before the driver about to be instantiated.
+ */
+ else if (!strcmp(szAction, "inject"))
+ {
+ PCFGMNODE pTransCopy;
+ rc = CFGMR3DuplicateSubTree(pTransAttDrv, &pTransCopy);
+ AssertLogRelRCReturn(rc, rc);
+
+ PCFGMNODE pThisCopy;
+ rc = CFGMR3DuplicateSubTree(*ppNode, &pThisCopy);
+ if (RT_SUCCESS(rc))
+ {
+ rc = CFGMR3InsertSubTree(pTransCopy, "AttachedDriver", pThisCopy, NULL);
+ if (RT_SUCCESS(rc))
+ {
+ rc = CFGMR3InsertInteger(pTransCopy, "InjectTransformationPtr", (uintptr_t)pCurTrans);
+ AssertLogRelRC(rc);
+ rc = CFGMR3InsertString(pTransCopy, "InjectTransformationNm", szCurTransNm);
+ AssertLogRelRC(rc);
+ if (RT_SUCCESS(rc))
+ rc = CFGMR3ReplaceSubTree(*ppNode, pTransCopy);
+ }
+ else
+ {
+ AssertLogRelRC(rc);
+ CFGMR3RemoveNode(pThisCopy);
+ }
+ }
+ if (RT_FAILURE(rc))
+ CFGMR3RemoveNode(pTransCopy);
+ }
+ /*
+ * Merge the Config node of the transformation with the one of the
+ * current driver.
+ */
+ else if (!strcmp(szAction, "mergeconfig"))
+ {
+ PCFGMNODE pTransConfig = CFGMR3GetChild(pCurTrans, "Config");
+ AssertLogRelReturn(pTransConfig, VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
+
+ PCFGMNODE pDrvConfig = CFGMR3GetChild(*ppNode, "Config");
+ if (*ppNode)
+ CFGMR3InsertNode(*ppNode, "Config", &pDrvConfig);
+ AssertLogRelReturn(pDrvConfig, VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER);
+
+ rc = CFGMR3CopyTree(pDrvConfig, pTransConfig, CFGM_COPY_FLAGS_REPLACE_VALUES | CFGM_COPY_FLAGS_MERGE_KEYS);
+ AssertLogRelRCReturn(rc, rc);
+ }
+ else
+ AssertFailed();
+
+ cTransformations++;
+ if (*ppNode)
+ CFGMR3Dump(*ppNode);
+ else
+ LogRel(("The transformation removed the driver.\n"));
+ }
+
+ /*
+ * Note what happened in the release log.
+ */
+ if (cTransformations > 0)
+ LogRel(("Transformations done. Applied %u driver transformations.\n", cTransformations));
+
+ return rc;
+}
+
+
+/**
* Instantiate a driver.
*
* @returns VBox status code, including informational statuses.
@@ -386,6 +632,10 @@ PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName)
*
* @remarks Recursive calls to this function is normal as the drivers will
* attach to anything below them during the pfnContruct call.
+ *
+ * @todo Need to extend this interface a bit so that the driver
+ * transformation feature can attach drivers to unconfigured LUNs and
+ * at the end of chains.
*/
int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDMDRVINS pDrvAbove,
PPDMLUN pLun, PPDMIBASE *ppBaseInterface)
@@ -396,10 +646,19 @@ int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDM
Assert(pBaseInterface->pfnQueryInterface(pBaseInterface, PDMIBASE_IID) == pBaseInterface);
/*
+ * Do driver chain injections
+ */
+ int rc = pdmR3DrvMaybeTransformChain(pVM, pDrvAbove, pLun, &pNode);
+ if (RT_FAILURE(rc))
+ return rc;
+ if (!pNode)
+ return VERR_PDM_NO_ATTACHED_DRIVER;
+
+ /*
* Find the driver.
*/
char *pszName;
- int rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);
+ rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);
if (RT_SUCCESS(rc))
{
PPDMDRV pDrv = pdmR3DrvLookup(pVM, pszName);
diff --git a/src/VBox/VMM/VMMR3/PDMUsb.cpp b/src/VBox/VMM/VMMR3/PDMUsb.cpp
index c3aca715b..d3c0b69ae 100644
--- a/src/VBox/VMM/VMMR3/PDMUsb.cpp
+++ b/src/VBox/VMM/VMMR3/PDMUsb.cpp
@@ -221,8 +221,9 @@ static DECLCALLBACK(int) pdmR3UsbReg_Register(PCPDMUSBREGCB pCallbacks, PCPDMUSB
("Unknown struct version %#x!\n", pReg->u32Version),
VERR_PDM_UNKNOWN_USBREG_VERSION);
AssertMsgReturn( pReg->szName[0]
- && strlen(pReg->szName) < sizeof(pReg->szName),
- ("Invalid name '%s'\n", pReg->szName),
+ && strlen(pReg->szName) < sizeof(pReg->szName)
+ && pdmR3IsValidName(pReg->szName),
+ ("Invalid name '%.s'\n", sizeof(pReg->szName), pReg->szName),
VERR_PDM_INVALID_USB_REGISTRATION);
AssertMsgReturn(pReg->fFlags == 0, ("fFlags=%#x\n", pReg->fFlags), VERR_PDM_INVALID_USB_REGISTRATION);
AssertMsgReturn(pReg->cMaxInstances > 0,
diff --git a/src/VBox/VMM/VMMR3/PGM.cpp b/src/VBox/VMM/VMMR3/PGM.cpp
index 60d5defd6..45fe92f6c 100644
--- a/src/VBox/VMM/VMMR3/PGM.cpp
+++ b/src/VBox/VMM/VMMR3/PGM.cpp
@@ -671,7 +671,7 @@ static const DBGCCMD g_aCmds[] =
{ "pgmerroroff", 0, 1, &g_aPgmErrorArgs[0], 1, 0, pgmR3CmdError, "", "Disables inject runtime errors into parts of PGM." },
# ifdef VBOX_STRICT
{ "pgmassertcr3", 0, 0, NULL, 0, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." },
-# if HC_ARCH_BITS == 64
+# ifdef VBOX_WITH_PAGE_SHARING
{ "pgmcheckduppages", 0, 0, NULL, 0, 0, pgmR3CmdCheckDuplicatePages, "", "Check for duplicate pages in all running VMs." },
{ "pgmsharedmodules", 0, 0, NULL, 0, 0, pgmR3CmdShowSharedModules, "", "Print shared modules info." },
# endif
@@ -1666,6 +1666,8 @@ static int pgmR3InitStats(PVM pVM)
STAM_REL_REG(pVM, &pPGM->StatLargePageRefused, STAMTYPE_COUNTER, "/PGM/LargePage/Refused", STAMUNIT_OCCURENCES, "The number of times we couldn't use a large page.");
STAM_REL_REG(pVM, &pPGM->StatLargePageRecheck, STAMTYPE_COUNTER, "/PGM/LargePage/Recheck", STAMUNIT_OCCURENCES, "The number of times we've rechecked a disabled large page.");
+ STAM_REL_REG(pVM, &pPGM->StatShModCheck, STAMTYPE_PROFILE, "/PGM/ShMod/Check", STAMUNIT_TICKS_PER_CALL, "Profiles the shared module checking.");
+
/* Live save */
STAM_REL_REG_USED(pVM, &pPGM->LiveSave.fActive, STAMTYPE_U8, "/PGM/LiveSave/fActive", STAMUNIT_COUNT, "Active or not.");
STAM_REL_REG_USED(pVM, &pPGM->LiveSave.cIgnoredPages, STAMTYPE_U32, "/PGM/LiveSave/cIgnoredPages", STAMUNIT_COUNT, "The number of ignored pages in the RAM ranges (i.e. MMIO, MMIO2 and ROM).");
diff --git a/src/VBox/VMM/VMMR3/PGMPhys.cpp b/src/VBox/VMM/VMMR3/PGMPhys.cpp
index 1f7c8b80f..93a6734f2 100644
--- a/src/VBox/VMM/VMMR3/PGMPhys.cpp
+++ b/src/VBox/VMM/VMMR3/PGMPhys.cpp
@@ -922,6 +922,7 @@ static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, R
}
#if HC_ARCH_BITS == 64 && (defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS) || defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD))
+
/**
* Rendezvous callback used by PGMR3ChangeMemBalloon that changes the memory balloon size
*
@@ -1041,6 +1042,7 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysChangeMemBalloonRendezvous(PVM pVM, P
return rc;
}
+
/**
* Frees a range of ram pages, replacing them with ZERO pages; helper for PGMR3PhysFreeRamPages
*
@@ -1063,7 +1065,8 @@ static DECLCALLBACK(void) pgmR3PhysChangeMemBalloonHelper(PVM pVM, bool fInflate
/* Made a copy in PGMR3PhysFreeRamPages; free it here. */
RTMemFree(paPhysPage);
}
-#endif
+
+#endif /* 64-bit host && (Windows || Solaris || Linux || FreeBSD) */
/**
* Inflate or deflate a memory balloon
@@ -1108,11 +1111,14 @@ VMMR3DECL(int) PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages
AssertRC(rc);
}
return rc;
+
#else
+ NOREF(pVM); NOREF(fInflate); NOREF(cPages); NOREF(paPhysPage);
return VERR_NOT_IMPLEMENTED;
#endif
}
+
/**
* Rendezvous callback used by PGMR3WriteProtectRAM that write protects all
* physical RAM.
diff --git a/src/VBox/VMM/VMMR3/PGMPool.cpp b/src/VBox/VMM/VMMR3/PGMPool.cpp
index 6143e270d..7358dd599 100644
--- a/src/VBox/VMM/VMMR3/PGMPool.cpp
+++ b/src/VBox/VMM/VMMR3/PGMPool.cpp
@@ -460,6 +460,13 @@ VMMR3DECL(int) PGMR3PoolGrow(PVM pVM)
PPGMPOOL pPool = pVM->pgm.s.pPoolR3;
AssertReturn(pPool->cCurPages < pPool->cMaxPages, VERR_PGM_POOL_MAXED_OUT_ALREADY);
+ /* With 32-bit guests and no EPT, the CR3 limits the root pages to low
+ (below 4 GB) memory. */
+ /** @todo change the pool to handle ROOT page allocations specially when
+ * required. */
+ bool fCanUseHighMemory = HWACCMIsNestedPagingActive(pVM)
+ && HWACCMGetShwPagingMode(pVM) == PGMMODE_EPT;
+
pgmLock(pVM);
/*
@@ -467,22 +474,24 @@ VMMR3DECL(int) PGMR3PoolGrow(PVM pVM)
*/
uint32_t cPages = pPool->cMaxPages - pPool->cCurPages;
cPages = RT_MIN(PGMPOOL_CFG_MAX_GROW, cPages);
- LogFlow(("PGMR3PoolGrow: Growing the pool by %d (%#x) pages.\n", cPages, cPages));
+ LogFlow(("PGMR3PoolGrow: Growing the pool by %d (%#x) pages. fCanUseHighMemory=%RTbool\n", cPages, cPages, fCanUseHighMemory));
for (unsigned i = pPool->cCurPages; cPages-- > 0; i++)
{
PPGMPOOLPAGE pPage = &pPool->aPages[i];
- /* Allocate all pages in low (below 4 GB) memory as 32 bits guests need a page table root in low memory. */
- pPage->pvPageR3 = MMR3PageAllocLow(pVM);
+ if (fCanUseHighMemory)
+ pPage->pvPageR3 = MMR3PageAlloc(pVM);
+ else
+ pPage->pvPageR3 = MMR3PageAllocLow(pVM);
if (!pPage->pvPageR3)
{
- Log(("We're out of memory!! i=%d\n", i));
+ Log(("We're out of memory!! i=%d fCanUseHighMemory=%RTbool\n", i, fCanUseHighMemory));
pgmUnlock(pVM);
return i ? VINF_SUCCESS : VERR_NO_PAGE_MEMORY;
}
pPage->Core.Key = MMPage2Phys(pVM, pPage->pvPageR3);
- AssertFatal(pPage->Core.Key < _4G);
+ AssertFatal(pPage->Core.Key < _4G || fCanUseHighMemory);
pPage->GCPhys = NIL_RTGCPHYS;
pPage->enmKind = PGMPOOLKIND_FREE;
pPage->idx = pPage - &pPool->aPages[0];
diff --git a/src/VBox/VMM/VMMR3/PGMSharedPage.cpp b/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
index 3b965f559..2f4e04ff7 100644
--- a/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
+++ b/src/VBox/VMM/VMMR3/PGMSharedPage.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * 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;
@@ -35,39 +35,50 @@
#include "PGMInline.h"
+
+#ifdef VBOX_WITH_PAGE_SHARING
+
/*******************************************************************************
* Global Variables *
*******************************************************************************/
-#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
+# ifdef VBOX_STRICT
/** Keep a copy of all registered shared modules for the .pgmcheckduppages debugger command. */
-static PGMMREGISTERSHAREDMODULEREQ g_apSharedModules[512] = {0};
-static unsigned g_cSharedModules = 0;
-#endif
+static PGMMREGISTERSHAREDMODULEREQ g_apSharedModules[512] = {0};
+static unsigned g_cSharedModules = 0;
+# endif /* VBOX_STRICT */
+
/**
* Registers a new shared module for the VM
*
* @returns VBox status code.
- * @param pVM VM handle
- * @param enmGuestOS Guest OS type
- * @param pszModuleName Module name
- * @param pszVersion Module version
- * @param GCBaseAddr Module base address
- * @param cbModule Module size
- * @param cRegions Number of shared region descriptors
- * @param pRegions Shared region(s)
+ * @param pVM VM handle.
+ * @param enmGuestOS Guest OS type.
+ * @param pszModuleName Module name.
+ * @param pszVersion Module version.
+ * @param GCBaseAddr Module base address.
+ * @param cbModule Module size.
+ * @param cRegions Number of shared region descriptors.
+ * @param paRegions Shared region(s).
+ *
+ * @todo This should be a GMMR3 call. No need to involve GMM here.
*/
-VMMR3DECL(int) PGMR3SharedModuleRegister(PVM pVM, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule,
- unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions)
+VMMR3DECL(int) PGMR3SharedModuleRegister(PVM pVM, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
+ RTGCPTR GCBaseAddr, uint32_t cbModule, uint32_t cRegions,
+ VMMDEVSHAREDREGIONDESC const *paRegions)
{
-#ifdef VBOX_WITH_PAGE_SHARING
- PGMMREGISTERSHAREDMODULEREQ pReq;
-
- Log(("PGMR3SharedModuleRegister family=%d name=%s version=%s base=%RGv size=%x cRegions=%d\n", enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions));
+ Log(("PGMR3SharedModuleRegister family=%d name=%s version=%s base=%RGv size=%x cRegions=%d\n",
+ enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions));
- /* Sanity check. */
- AssertReturn(cRegions < VMMDEVSHAREDREGIONDESC_MAX, VERR_INVALID_PARAMETER);
+ /*
+ * Sanity check.
+ */
+ AssertReturn(cRegions <= VMMDEVSHAREDREGIONDESC_MAX, VERR_INVALID_PARAMETER);
+ /*
+ * Allocate and initialize a GMM request.
+ */
+ PGMMREGISTERSHAREDMODULEREQ pReq;
pReq = (PGMMREGISTERSHAREDMODULEREQ)RTMemAllocZ(RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions]));
AssertReturn(pReq, VERR_NO_MEMORY);
@@ -75,115 +86,118 @@ VMMR3DECL(int) PGMR3SharedModuleRegister(PVM pVM, VBOXOSFAMILY enmGuestOS, char
pReq->GCBaseAddr = GCBaseAddr;
pReq->cbModule = cbModule;
pReq->cRegions = cRegions;
- for (unsigned i = 0; i < cRegions; i++)
- pReq->aRegions[i] = pRegions[i];
-
- if ( RTStrCopy(pReq->szName, sizeof(pReq->szName), pszModuleName) != VINF_SUCCESS
- || RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion) != VINF_SUCCESS)
- {
- RTMemFree(pReq);
- return VERR_BUFFER_OVERFLOW;
- }
+ for (uint32_t i = 0; i < cRegions; i++)
+ pReq->aRegions[i] = paRegions[i];
- int rc = GMMR3RegisterSharedModule(pVM, pReq);
-# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
- if (rc == VINF_SUCCESS)
+ int rc = RTStrCopy(pReq->szName, sizeof(pReq->szName), pszModuleName);
+ if (RT_SUCCESS(rc))
{
- PGMMREGISTERSHAREDMODULEREQ *ppSharedModule = NULL;
-
- if (g_cSharedModules < RT_ELEMENTS(g_apSharedModules))
+ rc = RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion);
+ if (RT_SUCCESS(rc))
{
- for (unsigned i = 0; i < RT_ELEMENTS(g_apSharedModules); i++)
+ /*
+ * Issue the request. In strict builds, do some local tracking.
+ */
+ rc = GMMR3RegisterSharedModule(pVM, pReq);
+ if (RT_SUCCESS(rc))
+ rc = pReq->rc;
+ AssertMsg(rc == VINF_SUCCESS || rc == VINF_GMM_SHARED_MODULE_ALREADY_REGISTERED, ("%Rrc\n", rc));
+
+# ifdef VBOX_STRICT
+ if ( rc == VINF_SUCCESS
+ && g_cSharedModules < RT_ELEMENTS(g_apSharedModules))
{
- if (g_apSharedModules[i] == NULL)
- {
- ppSharedModule = &g_apSharedModules[i];
- break;
- }
- }
- Assert(ppSharedModule);
+ unsigned i;
+ for (i = 0; i < RT_ELEMENTS(g_apSharedModules); i++)
+ if (g_apSharedModules[i] == NULL)
+ {
- if (ppSharedModule)
- {
- *ppSharedModule = (PGMMREGISTERSHAREDMODULEREQ)RTMemAllocZ(RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions]));
- memcpy(*ppSharedModule, pReq, RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions]));
- g_cSharedModules++;
+ size_t const cbSharedModule = RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions]);
+ g_apSharedModules[i] = (PGMMREGISTERSHAREDMODULEREQ)RTMemDup(pReq, cbSharedModule);
+ g_cSharedModules++;
+ break;
+ }
+ Assert(i < RT_ELEMENTS(g_apSharedModules));
}
+# endif /* VBOX_STRICT */
+ if (RT_SUCCESS(rc))
+ rc = VINF_SUCCESS;
}
}
-# endif
RTMemFree(pReq);
- Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SHARED_MODULE_COLLISION || rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED);
- if (RT_FAILURE(rc))
- return rc;
-
- return VINF_SUCCESS;
-#else
- return VERR_NOT_IMPLEMENTED;
-#endif
+ return rc;
}
+
/**
* Unregisters a shared module for the VM
*
* @returns VBox status code.
- * @param pVM VM handle
- * @param pszModuleName Module name
- * @param pszVersion Module version
- * @param GCBaseAddr Module base address
- * @param cbModule Module size
+ * @param pVM VM handle.
+ * @param pszModuleName Module name.
+ * @param pszVersion Module version.
+ * @param GCBaseAddr Module base address.
+ * @param cbModule Module size.
+ *
+ * @todo This should be a GMMR3 call. No need to involve GMM here.
*/
VMMR3DECL(int) PGMR3SharedModuleUnregister(PVM pVM, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule)
{
-#ifdef VBOX_WITH_PAGE_SHARING
- PGMMUNREGISTERSHAREDMODULEREQ pReq;
-
Log(("PGMR3SharedModuleUnregister name=%s version=%s base=%RGv size=%x\n", pszModuleName, pszVersion, GCBaseAddr, cbModule));
+ AssertMsgReturn(cbModule > 0 && cbModule < _1G, ("%u\n", cbModule), VERR_OUT_OF_RANGE);
- pReq = (PGMMUNREGISTERSHAREDMODULEREQ)RTMemAllocZ(sizeof(*pReq));
+
+ /*
+ * Forward the request to GMM (ring-0).
+ */
+ PGMMUNREGISTERSHAREDMODULEREQ pReq = (PGMMUNREGISTERSHAREDMODULEREQ)RTMemAlloc(sizeof(*pReq));
AssertReturn(pReq, VERR_NO_MEMORY);
pReq->GCBaseAddr = GCBaseAddr;
+ pReq->u32Alignment = 0;
pReq->cbModule = cbModule;
- if ( RTStrCopy(pReq->szName, sizeof(pReq->szName), pszModuleName) != VINF_SUCCESS
- || RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion) != VINF_SUCCESS)
- {
- RTMemFree(pReq);
- return VERR_BUFFER_OVERFLOW;
- }
- int rc = GMMR3UnregisterSharedModule(pVM, pReq);
- RTMemFree(pReq);
-
-# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
- for (unsigned i = 0; i < g_cSharedModules; i++)
+ int rc = RTStrCopy(pReq->szName, sizeof(pReq->szName), pszModuleName);
+ if (RT_SUCCESS(rc))
{
- if ( g_apSharedModules[i]
- && !strcmp(g_apSharedModules[i]->szName, pszModuleName)
- && !strcmp(g_apSharedModules[i]->szVersion, pszVersion))
+ rc = RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion);
+ if (RT_SUCCESS(rc))
{
- RTMemFree(g_apSharedModules[i]);
- g_apSharedModules[i] = NULL;
- g_cSharedModules--;
- break;
+ rc = GMMR3UnregisterSharedModule(pVM, pReq);
+
+# ifdef VBOX_STRICT
+ /*
+ * Update our local tracking.
+ */
+ for (unsigned i = 0; i < g_cSharedModules; i++)
+ {
+ if ( g_apSharedModules[i]
+ && !strcmp(g_apSharedModules[i]->szName, pszModuleName)
+ && !strcmp(g_apSharedModules[i]->szVersion, pszVersion))
+ {
+ RTMemFree(g_apSharedModules[i]);
+ g_apSharedModules[i] = NULL;
+ g_cSharedModules--;
+ break;
+ }
+ }
+# endif /* VBOX_STRICT */
}
}
-# endif
+
+ RTMemFree(pReq);
return rc;
-#else
- return VERR_NOT_IMPLEMENTED;
-#endif
}
-#ifdef VBOX_WITH_PAGE_SHARING
+
/**
* Rendezvous callback that will be called once.
*
* @returns VBox strict status code.
* @param pVM VM handle.
* @param pVCpu The VMCPU handle for the calling EMT.
- * @param pvUser Not used;
+ * @param pvUser Pointer to a VMCPUID with the requester's ID.
*/
static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
{
@@ -205,6 +219,7 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU
rc = GMMR3CheckSharedModules(pVM);
pgmUnlock(pVM);
AssertLogRelRC(rc);
+
return rc;
}
@@ -217,10 +232,12 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU
static DECLCALLBACK(void) pgmR3CheckSharedModulesHelper(PVM pVM, VMCPUID idCpu)
{
/* We must stall other VCPUs as we'd otherwise have to send IPI flush commands for every single change we make. */
- int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, pgmR3SharedModuleRegRendezvous, &idCpu);
+ STAM_REL_PROFILE_START(&pVM->pgm.s.StatShModCheck, a);
+ int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, pgmR3SharedModuleRegRendezvous, &idCpu);
Assert(rc == VINF_SUCCESS);
+ STAM_REL_PROFILE_STOP(&pVM->pgm.s.StatShModCheck, a);
}
-#endif
+
/**
* Check all registered modules for changes.
@@ -230,26 +247,23 @@ static DECLCALLBACK(void) pgmR3CheckSharedModulesHelper(PVM pVM, VMCPUID idCpu)
*/
VMMR3DECL(int) PGMR3SharedModuleCheckAll(PVM pVM)
{
-#ifdef VBOX_WITH_PAGE_SHARING
/* Queue the actual registration as we are under the IOM lock right now. Perform this operation on the way out. */
return VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3CheckSharedModulesHelper, 2, pVM, VMMGetCpuId(pVM));
-#else
- return VERR_NOT_IMPLEMENTED;
-#endif
}
+
+# ifdef DEBUG
/**
* Query the state of a page in a shared module
*
* @returns VBox status code.
- * @param pVM VM handle
- * @param GCPtrPage Page address
- * @param pfShared Shared status (out)
- * @param puPageFlags Page flags (out)
+ * @param pVM VM handle.
+ * @param GCPtrPage Page address.
+ * @param pfShared Shared status (out).
+ * @param pfPageFlags Page flags (out).
*/
-VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *puPageFlags)
+VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags)
{
-#if defined(VBOX_WITH_PAGE_SHARING) && defined(DEBUG)
/* Debug only API for the page fusion testcase. */
RTGCPHYS GCPhys;
uint64_t fFlags;
@@ -259,40 +273,39 @@ VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *p
int rc = PGMGstGetPage(VMMGetCpu(pVM), GCPtrPage, &fFlags, &GCPhys);
switch (rc)
{
- case VINF_SUCCESS:
- {
- PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
- if (pPage)
+ case VINF_SUCCESS:
{
- *pfShared = PGM_PAGE_IS_SHARED(pPage);
- *puPageFlags = fFlags;
+ PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
+ if (pPage)
+ {
+ *pfShared = PGM_PAGE_IS_SHARED(pPage);
+ *pfPageFlags = fFlags;
+ }
+ else
+ rc = VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
+ break;
}
- else
- rc = VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS;
- break;
- }
- case VERR_PAGE_NOT_PRESENT:
- case VERR_PAGE_TABLE_NOT_PRESENT:
- case VERR_PAGE_MAP_LEVEL4_NOT_PRESENT:
- case VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT:
- *pfShared = false;
- *puPageFlags = 0;
- rc = VINF_SUCCESS;
- break;
-
- default:
- break;
+
+ case VERR_PAGE_NOT_PRESENT:
+ case VERR_PAGE_TABLE_NOT_PRESENT:
+ case VERR_PAGE_MAP_LEVEL4_NOT_PRESENT:
+ case VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT:
+ *pfShared = false;
+ *pfPageFlags = 0;
+ rc = VINF_SUCCESS;
+ break;
+
+ default:
+ break;
}
pgmUnlock(pVM);
return rc;
-#else
- return VERR_NOT_IMPLEMENTED;
-#endif
}
+# endif /* DEBUG */
+# ifdef VBOX_STRICT
-#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
/**
* The '.pgmcheckduppages' command.
*
@@ -413,4 +426,5 @@ DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp
return VINF_SUCCESS;
}
-#endif /* VBOX_STRICT && HC_ARCH_BITS == 64*/
+# endif /* VBOX_STRICT*/
+#endif /* VBOX_WITH_PAGE_SHARING */
diff --git a/src/VBox/VMM/VMMR3/STAM.cpp b/src/VBox/VMM/VMMR3/STAM.cpp
index a6a4eb055..7f1b4cca5 100644
--- a/src/VBox/VMM/VMMR3/STAM.cpp
+++ b/src/VBox/VMM/VMMR3/STAM.cpp
@@ -217,6 +217,44 @@ static const STAMR0SAMPLE g_aGVMMStats[] =
/**
+ * The GMM mapping records.
+ */
+static const STAMR0SAMPLE g_aGMMStats[] =
+{
+ { RT_UOFFSETOF(GMMSTATS, cMaxPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cMaxPages", "The maximum number of pages GMM is allowed to allocate." },
+ { RT_UOFFSETOF(GMMSTATS, cReservedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cReservedPages", "The number of pages that has been reserved." },
+ { RT_UOFFSETOF(GMMSTATS, cOverCommittedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cOverCommittedPages", "The number of pages that we have over-committed in reservations." },
+ { RT_UOFFSETOF(GMMSTATS, cAllocatedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cAllocatedPages", "The number of actually allocated (committed if you like) pages." },
+ { RT_UOFFSETOF(GMMSTATS, cSharedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cSharedPages", "The number of pages that are shared. A subset of cAllocatedPages." },
+ { RT_UOFFSETOF(GMMSTATS, cDuplicatePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cDuplicatePages", "The number of pages that are actually shared between VMs." },
+ { RT_UOFFSETOF(GMMSTATS, cLeftBehindSharedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cLeftBehindSharedPages", "The number of pages that are shared that has been left behind by VMs not doing proper cleanups." },
+ { RT_UOFFSETOF(GMMSTATS, cBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/cBalloonedPages", "The number of current ballooned pages." },
+ { RT_UOFFSETOF(GMMSTATS, cChunks), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/cChunks", "The number of allocation chunks." },
+ { RT_UOFFSETOF(GMMSTATS, cFreedChunks), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/cFreedChunks", "The number of freed chunks ever." },
+ { RT_UOFFSETOF(GMMSTATS, cShareableModules), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/cShareableModules", "The number of shareable modules." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.Reserved.cBasePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/Reserved/cBasePages", "The amount of base memory (RAM, ROM, ++) reserved by the VM." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.Reserved.cShadowPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Reserved/cShadowPages", "The amount of memory reserved for shadow/nested page tables." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.Reserved.cFixedPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Reserved/cFixedPages", "The amount of memory reserved for fixed allocations like MMIO2 and the hyper heap." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.Allocated.cBasePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/Allocated/cBasePages", "The amount of base memory (RAM, ROM, ++) allocated by the VM." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.Allocated.cShadowPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Allocated/cShadowPages", "The amount of memory allocated for shadow/nested page tables." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.Allocated.cFixedPages), STAMTYPE_U32, STAMUNIT_PAGES, "/GMM/VM/Allocated/cFixedPages", "The amount of memory allocated for fixed allocations like MMIO2 and the hyper heap." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cPrivatePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cPrivatePages", "The current number of private pages." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cSharedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cSharedPages", "The current number of shared pages." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cBalloonedPages", "The current number of ballooned pages." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cMaxBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cMaxBalloonedPages", "The max number of pages that can be ballooned." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cReqBalloonedPages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cReqBalloonedPages", "The number of pages we've currently requested the guest to give us." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cReqActuallyBalloonedPages),STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cReqActuallyBalloonedPages","The number of pages the guest has given us in response to the request." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cReqDeflatePages), STAMTYPE_U64, STAMUNIT_PAGES, "/GMM/VM/cReqDeflatePages", "The number of pages we've currently requested the guest to take back." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.cShareableModules), STAMTYPE_U32, STAMUNIT_COUNT, "/GMM/VM/cShareableModules", "The number of shareable modules traced by the VM." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.enmPolicy), STAMTYPE_U32, STAMUNIT_NONE, "/GMM/VM/enmPolicy", "The current over-commit policy." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.enmPriority), STAMTYPE_U32, STAMUNIT_NONE, "/GMM/VM/enmPriority", "The VM priority for arbitrating VMs in low and out of memory situation." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.fBallooningEnabled), STAMTYPE_BOOL, STAMUNIT_NONE, "/GMM/VM/fBallooningEnabled", "Whether ballooning is enabled or not." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.fBallooningEnabled), STAMTYPE_BOOL, STAMUNIT_NONE, "/GMM/VM/fSharedPagingEnabled", "Whether shared paging is enabled or not." },
+ { RT_UOFFSETOF(GMMSTATS, VMStats.fBallooningEnabled), STAMTYPE_BOOL, STAMUNIT_NONE, "/GMM/VM/fMayAllocate", "Whether the VM is allowed to allocate memory or not." },
+};
+
+
+/**
* Initializes the STAM.
*
* @returns VBox status code.
@@ -633,6 +671,8 @@ static int stamR3RegisterU(PUVM pUVM, void *pvSample, PFNSTAMR3CALLBACKRESET pfn
case STAMTYPE_U8_RESET:
case STAMTYPE_X8:
case STAMTYPE_X8_RESET:
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
case STAMTYPE_CALLBACK:
break;
@@ -762,11 +802,14 @@ VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat)
/* ring-0 */
GVMMRESETSTATISTICSSREQ GVMMReq;
- //GMMRESETSTATISTICSSREQ GMMReq;
+ GMMRESETSTATISTICSSREQ GMMReq;
bool fGVMMMatched = !pszPat || !*pszPat;
- //bool fGMMMatched = fGVMMMatched;
+ bool fGMMMatched = fGVMMMatched;
if (fGVMMMatched)
+ {
memset(&GVMMReq.Stats, 0xff, sizeof(GVMMReq.Stats));
+ memset(&GMMReq.Stats, 0xff, sizeof(GMMReq.Stats));
+ }
else
{
char *pszCopy;
@@ -776,7 +819,7 @@ VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat)
return VERR_NO_MEMORY;
/* GVMM */
- memset(&GVMMReq.Stats, 0, sizeof(GVMMReq.Stats));
+ RT_ZERO(GVMMReq.Stats);
for (unsigned i = 0; i < RT_ELEMENTS(g_aGVMMStats); i++)
if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGVMMStats[i].pszName))
{
@@ -789,36 +832,37 @@ VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat)
}
/* GMM */
-// memset(&GMMReq.Stats, 0, sizeof(GMMReq.Stats));
-// for (unsigned i = 0; i < RT_ELEMENTS(g_aGMMStats); i++)
-// if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGMMStats[i].pszName))
-// {
-// *((uint8_t *)&GMMReq.Stats + g_aGMMStats[i].offVar) = 0xff;
-// fGMMMatched = true;
-// }
+ RT_ZERO(GMMReq.Stats);
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aGMMStats); i++)
+ if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGMMStats[i].pszName))
+ {
+ *((uint8_t *)&GMMReq.Stats + g_aGMMStats[i].offVar) = 0xff;
+ fGMMMatched = true;
+ }
RTMemTmpFree(papszExpressions);
RTStrFree(pszCopy);
}
STAM_LOCK_WR(pUVM);
+
if (fGVMMMatched)
{
PVM pVM = pUVM->pVM;
- GVMMReq.Hdr.cbReq = sizeof(GVMMReq);
+ GVMMReq.Hdr.cbReq = sizeof(GVMMReq);
GVMMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
- GVMMReq.pSession = pVM->pSession;
+ GVMMReq.pSession = pVM->pSession;
rc = SUPR3CallVMMR0Ex(pVM->pVMR0, NIL_VMCPUID, VMMR0_DO_GVMM_RESET_STATISTICS, 0, &GVMMReq.Hdr);
}
-// if (fGMMMatched)
-// {
-// PVM pVM = pUVM->pVM;
-// GMMReq.Hdr.cbReq = sizeof(Req);
-// GMMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
-// GMMReq.pSession = pVM->pSession;
-// rc = SUPR3CallVMMR0Ex(pVM->pVMR0, VMMR0_DO_GMM_RESET_STATISTICS, 0, &Req.Hdr);
-// }
+ if (fGMMMatched)
+ {
+ PVM pVM = pUVM->pVM;
+ GMMReq.Hdr.cbReq = sizeof(GMMReq);
+ GMMReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+ GMMReq.pSession = pVM->pSession;
+ rc = SUPR3CallVMMR0Ex(pVM->pVMR0, NIL_VMCPUID, VMMR0_DO_GMM_RESET_STATISTICS, 0, &GMMReq.Hdr);
+ }
/* and the reset */
stamR3EnumU(pUVM, pszPat, false /* fUpdateRing0 */, stamR3ResetOne, pUVM->pVM);
@@ -827,6 +871,7 @@ VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat)
return rc;
}
+
/**
* Resets statistics for the specified VM.
* It's possible to select a subset of the samples.
@@ -897,6 +942,10 @@ static int stamR3ResetOne(PSTAMDESC pDesc, void *pvArg)
ASMAtomicXchgU64(pDesc->u.pu64, 0);
break;
+ case STAMTYPE_BOOL_RESET:
+ ASMAtomicXchgBool(pDesc->u.pf, false);
+ break;
+
/* These are custom and will not be touched. */
case STAMTYPE_U8:
case STAMTYPE_X8:
@@ -907,6 +956,7 @@ static int stamR3ResetOne(PSTAMDESC pDesc, void *pvArg)
case STAMTYPE_U64:
case STAMTYPE_X64:
case STAMTYPE_RATIO_U32:
+ case STAMTYPE_BOOL:
break;
default:
@@ -1091,6 +1141,13 @@ static int stamR3SnapshotOne(PSTAMDESC pDesc, void *pvArg)
stamR3SnapshotPrintf(pThis, "<X64 val=\"%#llx\"", *pDesc->u.pu64);
break;
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
+ if (pDesc->enmVisibility == STAMVISIBILITY_USED && *pDesc->u.pf == false)
+ return VINF_SUCCESS;
+ stamR3SnapshotPrintf(pThis, "<BOOL val=\"%RTbool\"", *pDesc->u.pf);
+ break;
+
default:
AssertMsgFailed(("%d\n", pDesc->enmType));
return 0;
@@ -1508,6 +1565,13 @@ static int stamR3PrintOne(PSTAMDESC pDesc, void *pvArg)
pArgs->pfnPrintf(pArgs, "%-32s %8llx %s\n", pDesc->pszName, *pDesc->u.pu64, STAMR3GetUnit(pDesc->enmUnit));
break;
+ case STAMTYPE_BOOL:
+ case STAMTYPE_BOOL_RESET:
+ if (pDesc->enmVisibility == STAMVISIBILITY_USED && *pDesc->u.pf == false)
+ return VINF_SUCCESS;
+ pArgs->pfnPrintf(pArgs, "%-32s %s %s\n", pDesc->pszName, *pDesc->u.pf ? "true " : "false ", STAMR3GetUnit(pDesc->enmUnit));
+ break;
+
default:
AssertMsgFailed(("enmType=%d\n", pDesc->enmType));
break;
@@ -1775,6 +1839,12 @@ static void stamR3Ring0StatsRegisterU(PUVM pUVM)
g_aGVMMStats[i].enmType, STAMVISIBILITY_ALWAYS, g_aGVMMStats[i].pszName,
g_aGVMMStats[i].enmUnit, g_aGVMMStats[i].pszDesc);
pUVM->stam.s.cRegisteredHostCpus = 0;
+
+ /* GMM */
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aGMMStats); i++)
+ stamR3RegisterU(pUVM, (uint8_t *)&pUVM->stam.s.GMMStats + g_aGMMStats[i].offVar, NULL, NULL,
+ g_aGMMStats[i].enmType, STAMVISIBILITY_ALWAYS, g_aGMMStats[i].pszName,
+ g_aGMMStats[i].enmUnit, g_aGMMStats[i].pszDesc);
}
@@ -1805,7 +1875,9 @@ static void stamR3Ring0StatsUpdateMultiU(PUVM pUVM, const char * const *papszExp
if (!pVM || !pVM->pSession)
return;
- /* GVMM */
+ /*
+ * GVMM
+ */
bool fUpdate = false;
for (unsigned i = 0; i < RT_ELEMENTS(g_aGVMMStats); i++)
if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGVMMStats[i].pszName))
@@ -1866,6 +1938,27 @@ static void stamR3Ring0StatsUpdateMultiU(PUVM pUVM, const char * const *papszExp
}
}
}
+
+ /*
+ * GMM
+ */
+ fUpdate = false;
+ for (unsigned i = 0; i < RT_ELEMENTS(g_aGMMStats); i++)
+ if (stamR3MultiMatch(papszExpressions, cExpressions, NULL, g_aGMMStats[i].pszName))
+ {
+ fUpdate = true;
+ break;
+ }
+ if (fUpdate)
+ {
+ GMMQUERYSTATISTICSSREQ Req;
+ Req.Hdr.cbReq = sizeof(Req);
+ Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+ Req.pSession = pVM->pSession;
+ int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, NIL_VMCPUID, VMMR0_DO_GMM_QUERY_STATISTICS, 0, &Req.Hdr);
+ if (RT_SUCCESS(rc))
+ pUVM->stam.s.GMMStats = Req.Stats;
+ }
}
diff --git a/src/VBox/VMM/VMMR3/VM.cpp b/src/VBox/VMM/VMMR3/VM.cpp
index 810c008a5..194f4022a 100644
--- a/src/VBox/VMM/VMMR3/VM.cpp
+++ b/src/VBox/VMM/VMMR3/VM.cpp
@@ -3043,8 +3043,9 @@ VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid)
*/
VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM)
{
- VM_ASSERT_VALID_EXT_RETURN(pVM, VMSTATE_TERMINATED);
- return pVM->enmVMState;
+ AssertMsgReturn(RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE), ("%p\n", pVM), VMSTATE_TERMINATED);
+ VMSTATE enmVMState = pVM->enmVMState;
+ return enmVMState >= VMSTATE_CREATING && enmVMState <= VMSTATE_TERMINATED ? enmVMState : VMSTATE_TERMINATED;
}
diff --git a/src/VBox/VMM/include/PATMA.h b/src/VBox/VMM/include/PATMA.h
index 0c5007808..f7d5435a4 100644
--- a/src/VBox/VMM/include/PATMA.h
+++ b/src/VBox/VMM/include/PATMA.h
@@ -180,7 +180,7 @@ extern PATCHASMRECORD PATMClearInhibitIRQContIF0Record;
extern PATCHASMRECORD PATMMovFromSSRecord;
-extern uint32_t PATMInterruptFlag;
+extern const uint32_t PATMInterruptFlag;
RT_C_DECLS_END
diff --git a/src/VBox/VMM/include/PDMInternal.h b/src/VBox/VMM/include/PDMInternal.h
index 6614eb3ad..09d0426ec 100644
--- a/src/VBox/VMM/include/PDMInternal.h
+++ b/src/VBox/VMM/include/PDMInternal.h
@@ -1123,6 +1123,8 @@ extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
* Internal Functions *
*******************************************************************************/
#ifdef IN_RING3
+bool pdmR3IsValidName(const char *pszName);
+
int pdmR3CritSectInitStats(PVM pVM);
void pdmR3CritSectRelocate(PVM pVM);
int pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, va_list va);
@@ -1192,3 +1194,4 @@ void pdmUnlock(PVM pVM);
RT_C_DECLS_END
#endif
+
diff --git a/src/VBox/VMM/include/PGMInternal.h b/src/VBox/VMM/include/PGMInternal.h
index ee04ed773..8e0701097 100644
--- a/src/VBox/VMM/include/PGMInternal.h
+++ b/src/VBox/VMM/include/PGMInternal.h
@@ -3307,29 +3307,31 @@ typedef struct PGM
/** @name Release Statistics
* @{ */
- uint32_t cAllPages; /**< The total number of pages. (Should be Private + Shared + Zero + Pure MMIO.) */
- uint32_t cPrivatePages; /**< The number of private pages. */
- uint32_t cSharedPages; /**< The number of shared pages. */
- uint32_t cReusedSharedPages; /**< The number of reused shared pages. */
- uint32_t cZeroPages; /**< The number of zero backed pages. */
- uint32_t cPureMmioPages; /**< The number of pure MMIO pages. */
- uint32_t cMonitoredPages; /**< The number of write monitored pages. */
- uint32_t cWrittenToPages; /**< The number of previously write monitored pages. */
- uint32_t cWriteLockedPages; /**< The number of write locked pages. */
- uint32_t cReadLockedPages; /**< The number of read locked pages. */
- uint32_t cBalloonedPages; /**< The number of ballooned pages. */
- uint32_t cMappedChunks; /**< Number of times we mapped a chunk. */
- uint32_t cUnmappedChunks; /**< Number of times we unmapped a chunk. */
- uint32_t cLargePages; /**< The number of large pages. */
- uint32_t cLargePagesDisabled;/**< The number of disabled large pages. */
+ uint32_t cAllPages; /**< The total number of pages. (Should be Private + Shared + Zero + Pure MMIO.) */
+ uint32_t cPrivatePages; /**< The number of private pages. */
+ uint32_t cSharedPages; /**< The number of shared pages. */
+ uint32_t cReusedSharedPages; /**< The number of reused shared pages. */
+ uint32_t cZeroPages; /**< The number of zero backed pages. */
+ uint32_t cPureMmioPages; /**< The number of pure MMIO pages. */
+ uint32_t cMonitoredPages; /**< The number of write monitored pages. */
+ uint32_t cWrittenToPages; /**< The number of previously write monitored pages. */
+ uint32_t cWriteLockedPages; /**< The number of write locked pages. */
+ uint32_t cReadLockedPages; /**< The number of read locked pages. */
+ uint32_t cBalloonedPages; /**< The number of ballooned pages. */
+ uint32_t cMappedChunks; /**< Number of times we mapped a chunk. */
+ uint32_t cUnmappedChunks; /**< Number of times we unmapped a chunk. */
+ uint32_t cLargePages; /**< The number of large pages. */
+ uint32_t cLargePagesDisabled; /**< The number of disabled large pages. */
/* uint32_t aAlignment4[1]; */
/** The number of times we were forced to change the hypervisor region location. */
STAMCOUNTER cRelocations;
- STAMCOUNTER StatLargePageReused; /**< The number of large pages we've reused.*/
- STAMCOUNTER StatLargePageRefused; /**< The number of times we couldn't use a large page.*/
- STAMCOUNTER StatLargePageRecheck; /**< The number of times we rechecked a disabled large page.*/
+ STAMCOUNTER StatLargePageReused; /**< The number of large pages we've reused.*/
+ STAMCOUNTER StatLargePageRefused; /**< The number of times we couldn't use a large page.*/
+ STAMCOUNTER StatLargePageRecheck; /**< The number of times we rechecked a disabled large page.*/
+
+ STAMPROFILE StatShModCheck; /**< Profiles shared module checks. */
/** @} */
#ifdef VBOX_WITH_STATISTICS
diff --git a/src/VBox/VMM/include/STAMInternal.h b/src/VBox/VMM/include/STAMInternal.h
index eeae65724..62b11bfc2 100644
--- a/src/VBox/VMM/include/STAMInternal.h
+++ b/src/VBox/VMM/include/STAMInternal.h
@@ -22,6 +22,7 @@
#include <VBox/types.h>
#include <VBox/vmm/stam.h>
#include <VBox/vmm/gvmm.h>
+#include <VBox/vmm/gmm.h>
#include <iprt/semaphore.h>
@@ -68,6 +69,8 @@ typedef struct STAMDESC
uint64_t *pu64;
/** Simple void pointer. */
void *pv;
+ /** Boolean. */
+ bool *pf;
/** */
struct STAMDESCSAMPLEDATACALLBACKS
{
@@ -104,7 +107,14 @@ typedef struct STAMUSERPERVM
GVMMSTATS GVMMStats;
/** The number of registered host CPU leaves. */
uint32_t cRegisteredHostCpus;
+
+ /** Explicit alignment padding. */
+ uint32_t uAlignment;
+ /** The copy of the GMM statistics. */
+ GMMSTATS GMMStats;
} STAMUSERPERVM;
+AssertCompileMemberAlignment(STAMUSERPERVM, GMMStats, 8);
+
/** Pointer to the STAM data kept in the UVM. */
typedef STAMUSERPERVM *PSTAMUSERPERVM;
diff --git a/src/VBox/VMM/include/VMInternal.h b/src/VBox/VMM/include/VMInternal.h
index d5d31b0ce..3a1a3ffea 100644
--- a/src/VBox/VMM/include/VMInternal.h
+++ b/src/VBox/VMM/include/VMInternal.h
@@ -168,6 +168,8 @@ typedef struct VMINT
typedef VMINT *PVMINT;
+#ifdef IN_RING3
+
/**
* VM internal data kept in the UVM.
*/
@@ -182,12 +184,12 @@ typedef struct VMINTUSERPERVM
/** Number of free request packets. */
volatile uint32_t cReqFree;
/** Array of pointers to lists of free request packets. Atomic. */
- volatile PVMREQ apReqFree[16-4];
+ volatile PVMREQ apReqFree[16 - (HC_ARCH_BITS == 32 ? 5 : 4)];
/** The reference count of the UVM handle. */
volatile uint32_t cUvmRefs;
-#ifdef VBOX_WITH_STATISTICS
+# ifdef VBOX_WITH_STATISTICS
/** Number of VMR3ReqAlloc returning a new packet. */
STAMCOUNTER StatReqAllocNew;
/** Number of VMR3ReqAlloc causing races. */
@@ -206,7 +208,7 @@ typedef struct VMINTUSERPERVM
/** Number of times we've raced someone when pushing the other requests back
* onto the list. */
STAMCOUNTER StatReqPushBackRaces;
-#endif
+# endif
/** Pointer to the support library session.
* Mainly for creation and destruction. */
@@ -304,6 +306,9 @@ typedef struct VMINTUSERPERVM
/** The VM UUID. (Set after the config constructure has been called.) */
RTUUID Uuid;
} VMINTUSERPERVM;
+# ifdef VBOX_WITH_STATISTICS
+AssertCompileMemberAlignment(VMINTUSERPERVM, StatReqAllocNew, 8);
+# endif
/** Pointer to the VM internal data kept in the UVM. */
typedef VMINTUSERPERVM *PVMINTUSERPERVM;
@@ -379,7 +384,7 @@ typedef struct VMINTUSERPERVMCPU
uint64_t u64StartSpinTS;
} Method12;
-#if 0
+# if 0
/**
* Method 3 & 4 - Same as method 1 & 2 respectivly, except that we
* sprinkle it with yields.
@@ -411,7 +416,7 @@ typedef struct VMINTUSERPERVMCPU
/** When we started spinning relentlessly in order to catch up some of the oversleeping. */
uint64_t u64StartSpinTS;
} Method34;
-#endif
+# endif
} Halt;
/** Profiling the halted state; yielding vs blocking.
@@ -425,15 +430,15 @@ typedef struct VMINTUSERPERVMCPU
STAMPROFILE StatHaltPoll;
/** @} */
} VMINTUSERPERVMCPU;
-#ifdef IN_RING3
AssertCompileMemberAlignment(VMINTUSERPERVMCPU, u64HaltsStartTS, 8);
AssertCompileMemberAlignment(VMINTUSERPERVMCPU, Halt.Method12.cNSBlockedTooLongAvg, 8);
AssertCompileMemberAlignment(VMINTUSERPERVMCPU, StatHaltYield, 8);
-#endif
/** Pointer to the VM internal data kept in the UVM. */
typedef VMINTUSERPERVMCPU *PVMINTUSERPERVMCPU;
+#endif /* IN_RING3 */
+
RT_C_DECLS_BEGIN
DECLCALLBACK(int) vmR3EmulationThread(RTTHREAD ThreadSelf, void *pvArg);
diff --git a/src/VBox/VMM/testcase/tstAnimate.cpp b/src/VBox/VMM/testcase/tstAnimate.cpp
index 2b225cadb..8bdf54579 100644
--- a/src/VBox/VMM/testcase/tstAnimate.cpp
+++ b/src/VBox/VMM/testcase/tstAnimate.cpp
@@ -53,6 +53,7 @@ static volatile bool g_fSignaled = false;
static void SigInterrupt(int iSignal)
{
+ NOREF(iSignal);
signal(SIGINT, SigInterrupt);
g_fSignaled = true;
RTPrintf("caught SIGINT\n");
@@ -62,6 +63,7 @@ typedef DECLCALLBACK(int) FNSETGUESTGPR(PVM, uint32_t);
typedef FNSETGUESTGPR *PFNSETGUESTGPR;
static int scriptGPReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
{
+ NOREF(pszVar);
uint32_t u32;
int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
if (RT_FAILURE(rc))
@@ -73,6 +75,7 @@ typedef DECLCALLBACK(int) FNSETGUESTSEL(PVM, uint16_t);
typedef FNSETGUESTSEL *PFNSETGUESTSEL;
static int scriptSelReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
{
+ NOREF(pszVar);
uint16_t u16;
int rc = RTStrToUInt16Ex(pszValue, NULL, 16, &u16);
if (RT_FAILURE(rc))
@@ -84,6 +87,7 @@ typedef DECLCALLBACK(int) FNSETGUESTSYS(PVM, uint32_t);
typedef FNSETGUESTSYS *PFNSETGUESTSYS;
static int scriptSysReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
{
+ NOREF(pszVar);
uint32_t u32;
int rc = RTStrToUInt32Ex(pszValue, NULL, 16, &u32);
if (RT_FAILURE(rc))
@@ -96,6 +100,7 @@ typedef DECLCALLBACK(int) FNSETGUESTDTR(PVM, uint32_t, uint16_t);
typedef FNSETGUESTDTR *PFNSETGUESTDTR;
static int scriptDtrReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
{
+ NOREF(pszVar);
char *pszPart2 = strchr(pszValue, ':');
if (!pszPart2)
return -1;
@@ -124,6 +129,7 @@ static int scriptDtrReg(PVM pVM, char *pszVar, char *pszValue, void *pvUser)
static int scriptCommand(PVM pVM, const char *pszIn, size_t cch)
{
+ NOREF(cch);
int rc = VINF_SUCCESS;
char *psz = RTStrDup(pszIn);
char *pszEqual = strchr(psz, '=');
diff --git a/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp b/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp
index 2105764d1..da889c3bf 100644
--- a/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp
+++ b/src/VBox/VMM/testcase/tstCompressionBenchmark.cpp
@@ -63,6 +63,7 @@ static size_t g_cbComprAlloc;
*/
static DECLCALLBACK(int) ComprOutCallback(void *pvUser, const void *pvBuf, size_t cbBuf)
{
+ NOREF(pvUser);
AssertReturn(g_cbCompr + cbBuf <= g_cbComprAlloc, VERR_BUFFER_OVERFLOW);
memcpy(&g_pabCompr[g_cbCompr], pvBuf, cbBuf);
g_cbCompr += cbBuf;
@@ -74,6 +75,7 @@ static DECLCALLBACK(int) ComprOutCallback(void *pvUser, const void *pvBuf, size_
*/
static DECLCALLBACK(int) DecomprInCallback(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf)
{
+ NOREF(pvUser);
size_t cb = RT_MIN(cbBuf, g_cbCompr - g_offComprIn);
if (pcbBuf)
*pcbBuf = cb;
diff --git a/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp b/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
index e54d0c184..64a5fabe3 100644
--- a/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
+++ b/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp
@@ -61,6 +61,7 @@ RTSEMEVENT g_FinishedEventSem;
void pfnAsyncTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rc)
{
LogFlow((TESTCASE ": %s: pVM=%p pvUser=%p pvUser2=%p\n", __FUNCTION__, pVM, pvUser, pvUser2));
+ NOREF(rc);
uint32_t cTasksStillLeft = ASMAtomicDecU32(&g_cTasksLeft);
diff --git a/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp b/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
index 25fa67995..8261e02e1 100644
--- a/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
+++ b/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp
@@ -391,6 +391,7 @@ static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvU
{
PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pvUser2;
PPDMACTESTFILETASK pTestTask = (PPDMACTESTFILETASK)pvUser;
+ NOREF(pVM); NOREF(rcReq);
if (pTestTask->fWrite)
{
diff --git a/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp b/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
index b50877027..889e2239f 100644
--- a/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
+++ b/src/VBox/VMM/testcase/tstVMM-HwAccm.cpp
@@ -38,8 +38,10 @@
VMMR3DECL(int) VMMDoHwAccmTest(PVM pVM);
-DECLCALLBACK(int) CFGMConstructor(PVM pVM, void *pvUser)
+static DECLCALLBACK(int) CFGMConstructor(PVM pVM, void *pvUser)
{
+ NOREF(pvUser);
+
/*
* Get root node first.
* This is the only node in the tree.
diff --git a/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp b/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
index 7ec223968..d07a0530d 100644
--- a/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
+++ b/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
@@ -55,6 +55,8 @@ static intptr_t volatile g_cbFooUsed;
int foo(int i, int iZero, int iMinusOne)
{
+ NOREF(iZero);
+
/* allocate a buffer which we fill up to the end. */
size_t cb = (i % 1555) + 32;
g_cbFoo = cb;
diff --git a/src/VBox/VMM/testcase/tstVMREQ.cpp b/src/VBox/VMM/testcase/tstVMREQ.cpp
index 34cf1de79..25bc65808 100644
--- a/src/VBox/VMM/testcase/tstVMREQ.cpp
+++ b/src/VBox/VMM/testcase/tstVMREQ.cpp
@@ -50,6 +50,7 @@ static int g_cErrors = 0;
*/
static DECLCALLBACK(void) MyAtRuntimeError(PVM pVM, void *pvUser, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
{
+ NOREF(pVM);
if (strcmp((const char *)pvUser, "user argument"))
{
RTPrintf(TESTCASE ": pvUser=%p:{%s}!\n", pvUser, (const char *)pvUser);
@@ -86,6 +87,7 @@ static DECLCALLBACK(void) MyAtRuntimeError(PVM pVM, void *pvUser, uint32_t fFlag
*/
static DECLCALLBACK(int) PassVACallback(PVM pVM, unsigned u4K, unsigned u1G, const char *pszFormat, va_list *pva)
{
+ NOREF(pVM);
if (u4K != _4K)
{
RTPrintf(TESTCASE ": u4K=%#x!\n", u4K);
@@ -162,10 +164,12 @@ static void PassVA(PVM pVM, const char *pszFormat, ...)
/**
* Thread function which allocates and frees requests like wildfire.
*/
-static DECLCALLBACK(int) Thread(RTTHREAD Thread, void *pvUser)
+static DECLCALLBACK(int) Thread(RTTHREAD hThreadSelf, void *pvUser)
{
int rc = VINF_SUCCESS;
PVM pVM = (PVM)pvUser;
+ NOREF(hThreadSelf);
+
for (unsigned i = 0; i < 100000; i++)
{
PVMREQ apReq[17];
diff --git a/src/VBox/VMM/testcase/tstX86-1.cpp b/src/VBox/VMM/testcase/tstX86-1.cpp
index d69e2288a..eaf79bc7b 100644
--- a/src/VBox/VMM/testcase/tstX86-1.cpp
+++ b/src/VBox/VMM/testcase/tstX86-1.cpp
@@ -88,6 +88,7 @@ static PCTRAPINFO findTrapInfo(uintptr_t uTrapPC, uintptr_t uTrapSP)
static void sigHandler(int iSig, siginfo_t *pSigInfo, void *pvSigCtx)
{
ucontext_t *pCtx = (ucontext_t *)pvSigCtx;
+ NOREF(pSigInfo);
# if defined(RT_ARCH_AMD64) && defined(RT_OS_DARWIN)
uintptr_t *puPC = (uintptr_t *)&pCtx->uc_mcontext->__ss.__rip;